Skip to content

Enums

Now let's generate a binding for an enum. Here is the Color enum definition:

/**
 * Color Enum.
 * __API__
 * action: gen_enum
 * package: enums
 * python.code_fragment: |
 *    def __str__(self):
 *        return str(self.value)
 * kotlin.code_fragment: |
 *    override fun toString(): String {
 *        return this.value.toString()
 *    }
 * swift.bases_list: CustomStringConvertible
 * swift.code_fragment: |
 *    public var description: String {
 *        return "\(self.rawValue)"
 *    }
 */
enum class Color {
    /**
     * Red = 1
     */
    Red = 1,
    /**
     * Green = 2
     */
    Green = 2,
    /**
     * Blue = 20
     */
    Blue = 20
};

/**
 * __API__
 * action: gen_enum
 * package: enums
 * enum_case_name_prefix: Shade
 * enum_excluded_cases:
 *   - InternalField
 */
enum class ColorShade {
    /// Light = 1
    Light = 1,
    /// Dark = 2
    ///
    Dark = 2,
    ///
    /// SemiLight = 3
    ///
    SemiLight = 3,
    /**
     * SemiDark = 4
     */
    SemiDark = 4,
    /// Unused field
    InternalField = 5
};

As shown in the above example, we can extend enums logic by using the code_fragment variable. Code fragments defined with this variable are appended to the enum definition. In this example, we added the custom conversion from enum to string for all three languages. Notice that for Swift, we have also used the bases_list variable to make the enum implement the CustomStringConvertible protocol. We can also customize enum case field names using the enum_case_name_prefix variable, which can be used to add a user-defined prefix string to enum field names in the target language.

In cases some of the original enum fields are for internal usage, and the user doesn't want to expose them in target language bindings, the enum_excluded_cases variable can be used to specify the list of excluded fields. If those fields are used as a default value for a function/constructor argument, CppBind skips that default value generation in target language bindings. If the user has a function that returns an excluded enum field, CppBind terminates the main program during the function call and provides the user with an appropriate error message.

And the Frame struct using it:

/**
 * Class Frame.
 * __API__
 * action: gen_class
 * package: enums
 */
struct Frame {
    /**
     * __API__
     * action: gen_constructor
     * throws: no_throw
     */
    Frame() {};

    /**
     * __API__
     * action: gen_property_setter
     */
    Color backgroundColor;

    /**
     * __API__
     * action: gen_property_setter
     */
    ColorShade backgroundColorShade;

    /**
     * __API__
     * action: gen_method
     * throws: no_throw
     */
     Color getNextColor(const Color& color) {
        switch(color) {
            case Color::Red: return Color::Green;
            case Color::Green: return Color::Blue;
            case Color::Blue: return Color::Red;
        }
        return Color::Red;
     }
};

Note

We are generating property_setter for public field backgroundColor. A writable property field corresponds to it in the target language. To generate a read-only field, we should use property_getter instead.

Usage examples:

assert(Color.Red.value == 1)
assert(Color.Blue.value == 20)

assert(Color.Blue.toString() == "20")

val frame = Frame()
frame.backgroundColor = Color.Red
assert(frame.backgroundColor == Color.Red)
assert Color.Red.value == 1
assert Color.Blue.value == 20
assert Color.Green.value == 2

assert int(Color.Blue) == 20
assert str(Color.Blue) == '20'

red = Color(1)
assert red == Color.Red
assert isinstance(Color.Red, Color)

frame = Frame()
frame.background_color = Color.Red
assert frame.background_color == Color.Red
assert(Color.Red.rawValue == 1)
assert(Color.Blue.rawValue == 20)

assert(String(describing: Color.Blue) == "20")

let frame = Frame()
frame.backgroundColor = Color.Red
assert(frame.backgroundColor == Color.Red)
Generated codes for Color and Frame

Here is the generated Kotlin code for Color:

/**
 *   ______ .______   .______   .______    __  .__   __.  _______  
 *  /      ||   _  \  |   _  \  |   _  \  |  | |  \ |  | |       \ 
 * |  ,----'|  |_)  | |  |_)  | |  |_)  | |  | |   \|  | |  .--.  |
 * |  |     |   ___/  |   ___/  |   _  <  |  | |  . `  | |  |  |  |
 * |  `----.|  |      |  |      |  |_)  | |  | |  |\   | |  '--'  |
 *  \______|| _|      | _|      |______/  |__| |__| \__| |_______/ 
 * 
 * This file is generated by cppbind on 08/11/2022-09:04.
 * Please do not change it manually.
 */

package com.examples.enums

import com.examples.cppbind.*
import com.examples.cppbind.exceptions.*

/**
 * Color Enum.
 */
enum class Color(val value: Int) {
    /**
     * Red = 1
     */
    Red(1),
    /**
     * Green = 2
     */
    Green(2),
    /**
     * Blue = 20
     */
    Blue(20);

    companion object {
        private val values = values()
        fun getByValue(value: Int) = values.firstOrNull { it.value == value }
    }

    override fun toString(): String {
        return this.value.toString()
    }
}

enum class ColorShade(val value: Int) {
    /**
     * Light = 1
     */
    ShadeLight(1),
    /**
     * Dark = 2
     */
    ShadeDark(2),
    /**
     * SemiLight = 3
     */
    ShadeSemiLight(3),
    /**
     * SemiDark = 4
     */
    ShadeSemiDark(4);

    companion object {
        private val values = values()
        fun getByValue(value: Int) = values.firstOrNull { it.value == value }
    }
}

private external fun jGettypebyid(id: Long): String
And for Frame:
/**
 *   ______ .______   .______   .______    __  .__   __.  _______  
 *  /      ||   _  \  |   _  \  |   _  \  |  | |  \ |  | |       \ 
 * |  ,----'|  |_)  | |  |_)  | |  |_)  | |  | |   \|  | |  .--.  |
 * |  |     |   ___/  |   ___/  |   _  <  |  | |  . `  | |  |  |  |
 * |  `----.|  |      |  |      |  |_)  | |  | |  |\   | |  '--'  |
 *  \______|| _|      | _|      |______/  |__| |__| \__| |_______/ 
 * 
 * This file is generated by cppbind on 08/18/2022-11:02.
 * Please do not change it manually.
 */

package com.examples.enums

import com.examples.cppbind.*
import com.examples.cppbind.exceptions.*

/**
 * Class Frame.
 */
open class Frame
internal constructor(obj: CppBindObject) : AutoCloseable {
    companion object {
        init {
            System.loadLibrary("wrapper_jni")
        }

        protected fun constructHelper(): Long {
            val id = jConstructor()
            return id
        }

        @JvmStatic
        private external fun jConstructor(): Long
        /**
         * An internal property to keep an information about the underlying C++ object type.
         * It is intended to be used by the generated code.
         */
        const val cppbindCxxTypeName: String = "cppbind::example::Frame"
    }

    protected var cppbindObj = obj
    private var refs: MutableList<Any> = mutableListOf()

    /**
     * An internal method to bind the lifetimes of the current and another object.
     * It is intended to be used by the generated code.
     */
    fun keepCppBindReference(ref: Any) {
        refs.add(ref)
    }
    /**
     * An internal getter to get the id of an object.
     * It is intended to be used by the generated code.
     */
    open val cppbindObjId: Long
        get() {
            if (cppbindObj.id == 0L) {
                throw RuntimeException("Object is not allocated")
            }
            return cppbindObj.id
        }

    /**
     * An internal property returning underlying C++ object id.
     * It is intended to be used by the generated code.
     */
    internal val cxxId: Long by lazy {
        jGetcxxid(cppbindObj.id)
    }

    /**
     * An internal property returning underlying C++ type name.
     * It is intended to be used by the generated code.
     */
    internal val cxxTypeName: String by lazy {
        jGettypebyid(cppbindObj.id)
    }

    constructor(): this(CppBindObject(constructHelper(), true)) {
    }

    var backgroundColor: Color
        get() {
            val result = jBackgroundcolor(cppbindObjId)
            val jdktokotlinresultOptional = Color.getByValue(result)
            if (jdktokotlinresultOptional == null) {
                ExceptionHandler.handleUncaughtException("Internal error: unresolved reference to non existing field of Color enum.")
            }
            val jdktokotlinresult = jdktokotlinresultOptional!!
            return jdktokotlinresult
        }
        set(value) {
            val kotlintojdkvalue = value.value
            jSetbackgroundcolor(cppbindObjId, kotlintojdkvalue, value)
        }


    var backgroundColorShade: ColorShade
        get() {
            val result = jBackgroundcolorshade(cppbindObjId)
            val jdktokotlinresultOptional = ColorShade.getByValue(result)
            if (jdktokotlinresultOptional == null) {
                ExceptionHandler.handleUncaughtException("Internal error: unresolved reference to non existing field of ColorShade enum.")
            }
            val jdktokotlinresult = jdktokotlinresultOptional!!
            return jdktokotlinresult
        }
        set(value) {
            val kotlintojdkvalue = value.value
            jSetbackgroundcolorshade(cppbindObjId, kotlintojdkvalue, value)
        }


    fun getNextColor(color: Color): Color {
        val kotlintojdkcolor = color.value
        val result = jGetnextcolor(cppbindObjId, kotlintojdkcolor, color)
        val jdktokotlinresultOptional = Color.getByValue(result)
        if (jdktokotlinresultOptional == null) {
            ExceptionHandler.handleUncaughtException("Internal error: unresolved reference to non existing field of Color enum.")
        }
        val jdktokotlinresult = jdktokotlinresultOptional!!
        return jdktokotlinresult
    }

    /**
     * CppBind generated hashCode method returning the hash of underlying C++ object id.
     */
    override fun hashCode(): Int {
        return cxxId.hashCode()
    }

    /**
     * CppBind generated equals method comparing the underlying C++ object ids.
     */
    override fun equals(other: Any?): Boolean {
        other as Frame
        return cxxId == other.cxxId
    }

    /**
     * CppBind generated toString method returning underlying C++ object type and id.
     */
    override fun toString(): String {
        return "<0x$cxxId: $cxxTypeName>"
    }

    override fun close() {
        if (cppbindObj.owner && cppbindObj.id != 0L) {
            jFinalize(cppbindObj.id)
            cppbindObj.id = 0L
        }
    }

    /**
     * Finalize and deletes the object
     */
    protected fun finalize() {
        close()
    }

    ///// External wrapper functions ////////////
    private external fun jBackgroundcolor(id: Long): Int
    private external fun jSetbackgroundcolor(id: Long, value: Int, valueObj: Any?): Unit
    private external fun jBackgroundcolorshade(id: Long): Int
    private external fun jSetbackgroundcolorshade(id: Long, value: Int, valueObj: Any?): Unit
    private external fun jGetnextcolor(id: Long, color: Int, vararg extraObjs: Any?): Int
    private external fun jFinalize(id: Long): Unit
    private external fun jGetcxxid(id: Long): Long
}

private external fun jGettypebyid(id: Long): String

Here is the generated Python code for Color:

"""
  ______ .______   .______   .______    __  .__   __.  _______  
 /      ||   _  \  |   _  \  |   _  \  |  | |  \ |  | |       \ 
|  ,----'|  |_)  | |  |_)  | |  |_)  | |  | |   \|  | |  .--.  |
|  |     |   ___/  |   ___/  |   _  <  |  | |  . `  | |  |  |  |
|  `----.|  |      |  |      |  |_)  | |  | |  |\   | |  '--'  |
 \______|| _|      | _|      |______/  |__| |__| \__| |_______/ 

This file is generated by cppbind on 08/11/2022-07:34.
Please do not change it manually.
"""
from __future__ import annotations

from typing import *

import examples.enums.color as pybind_color_pygen
from examples_lib.cppbind.cppbind_metaclass_pygen import *
from examples_lib.cppbind.cppbind_utils_pygen import *


class Color(metaclass=CppBindEnumMetaclass):
    """
    Color Enum.
    """
    # Red = 1
    Red = pybind_color_pygen.Color.Red
    # Green = 2
    Green = pybind_color_pygen.Color.Green
    # Blue = 20
    Blue = pybind_color_pygen.Color.Blue

    def __int__(self):
        return self.value

    def __str__(self):
        return str(self.value)


class ColorShade(metaclass=CppBindEnumMetaclass):

    # Light = 1
    ShadeLight = pybind_color_pygen.ColorShade.ShadeLight
    # Dark = 2
    ShadeDark = pybind_color_pygen.ColorShade.ShadeDark
    # SemiLight = 3
    ShadeSemiLight = pybind_color_pygen.ColorShade.ShadeSemiLight
    # SemiDark = 4
    ShadeSemiDark = pybind_color_pygen.ColorShade.ShadeSemiDark

    def __int__(self):
        return self.value
And for Frame:
"""
  ______ .______   .______   .______    __  .__   __.  _______  
 /      ||   _  \  |   _  \  |   _  \  |  | |  \ |  | |       \ 
|  ,----'|  |_)  | |  |_)  | |  |_)  | |  | |   \|  | |  .--.  |
|  |     |   ___/  |   ___/  |   _  <  |  | |  . `  | |  |  |  |
|  `----.|  |      |  |      |  |_)  | |  | |  |\   | |  '--'  |
 \______|| _|      | _|      |______/  |__| |__| \__| |_______/ 

This file is generated by cppbind on 11/24/2022-07:17.
Please do not change it manually.
"""
from __future__ import annotations

from typing import *

import examples.enums.frame as pybind_frame_pygen
from examples_lib.cppbind.cppbind_metaclass_pygen import *
from examples_lib.cppbind.cppbind_utils_pygen import *

if TYPE_CHECKING:
    import examples_lib.enums.color_pygen as color_pygen


class Frame(metaclass=CppBindMetaclass):
    """
    Class Frame.
    """

    @bind
    def __init__(self):

        pass

    @property
    @bind
    def background_color(self) -> color_pygen.Color:

        pass

    @background_color.setter
    @bind
    def background_color(self, value: color_pygen.Color):

        pass

    @property
    @bind
    def background_color_shade(self) -> color_pygen.ColorShade:

        pass

    @background_color_shade.setter
    @bind
    def background_color_shade(self, value: color_pygen.ColorShade):

        pass

    @bind
    def get_next_color(self, color: color_pygen.Color) -> color_pygen.Color:

        pass

    @bind
    def __repr__(self) -> str:
        """
        CppBind generated __repr__ method returning underlying C++ object type and id.
        """
        pass

Here is the generated Swift code for Color:

/**
 *   ______ .______   .______   .______    __  .__   __.  _______  
 *  /      ||   _  \  |   _  \  |   _  \  |  | |  \ |  | |       \ 
 * |  ,----'|  |_)  | |  |_)  | |  |_)  | |  | |   \|  | |  .--.  |
 * |  |     |   ___/  |   ___/  |   _  <  |  | |  . `  | |  |  |  |
 * |  `----.|  |      |  |      |  |_)  | |  | |  |\   | |  '--'  |
 *  \______|| _|      | _|      |______/  |__| |__| \__| |_______/ 
 * 
 * This file is generated by cppbind on 08/14/2022-10:58.
 * Please do not change it manually.
 */

import CWrapper
import Foundation

/// Color Enum.
public enum Color: CInt, CustomStringConvertible {
  /// Red = 1
  case Red = 1
  /// Green = 2
  case Green = 2
  /// Blue = 20
  case Blue = 20

  public var description: String {
      return "\(self.rawValue)"
  }
}

public enum ColorShade: CInt {
  /// Light = 1
  case ShadeLight = 1
  /// Dark = 2
  case ShadeDark = 2
  /// SemiLight = 3
  case ShadeSemiLight = 3
  /// SemiDark = 4
  case ShadeSemiDark = 4
}
And for Frame:
/**
 *   ______ .______   .______   .______    __  .__   __.  _______  
 *  /      ||   _  \  |   _  \  |   _  \  |  | |  \ |  | |       \ 
 * |  ,----'|  |_)  | |  |_)  | |  |_)  | |  | |   \|  | |  .--.  |
 * |  |     |   ___/  |   ___/  |   _  <  |  | |  . `  | |  |  |  |
 * |  `----.|  |      |  |      |  |_)  | |  | |  |\   | |  '--'  |
 *  \______|| _|      | _|      |______/  |__| |__| \__| |_______/ 
 * 
 * This file is generated by cppbind on 08/14/2022-10:58.
 * Please do not change it manually.
 */

import CWrapper
import Foundation

/// Class Frame.
public class Frame {

  /// An internal property to keep a reference to the original C++ object.
  /// It is intended to be used by the generated code.
  public let cself: CppBindCObject

  /// An internal property to keep track whether Swift is responsible for deallocating the underlying C++ object or not.
  /// It is intended to be used by the generated code.
  public let owner: Bool
  private var refs: [Any]

  /// internal main initializer
  internal required init(_ _cself: CppBindCObject, _ _owner: Bool = false) {
    self.cself = _cself
    self.owner = _owner
    self.refs = []
  }

  deinit {
    release_CppbindExample_Frame(cself, owner)
  }

  /// An internal method to bind the lifetimes of the current and another object.
  /// It is intended to be used by the generated code.
  public func keepCppBindReference(_ object: Any) {
    self.refs.append(object)
  }

  public convenience init() {
    var cppbindErr = CppBindCObject()
    self.init(create_CppbindExample_Frame(&cppbindErr), true)
    if cppbindErr.type != nil {
      let errorType = String(cString: cppbindErr.type!)
      switch errorType {
      case ("std::exception"):
        let excObj = StdException(cppbindErr, true)
        ExceptionHandler.handleUncaughtException(excObj.what())
      default:
        cppbindErr.type.deallocate()
        ExceptionHandler.handleUncaughtException("Uncaught Exception")
      }
    }
  }

  public var backgroundColor: Color {
    get {
      let result = _prop_get_CppbindExample_Frame_backgroundColor(cself)
      guard let sctoswiftresult = Color(rawValue: result) else {
         ExceptionHandler.handleUncaughtException(
            "Internal error: unresolved reference to non existing field of Color enum.")
      }
      return sctoswiftresult
    }

    set(value) {
      let swifttoscvalue = value.rawValue
      _prop_set_CppbindExample_Frame_backgroundColor(cself, swifttoscvalue)
    }
  }

  public var backgroundColorShade: ColorShade {
    get {
      let result = _prop_get_CppbindExample_Frame_backgroundColorShade(cself)
      guard let sctoswiftresult = ColorShade(rawValue: result) else {
         ExceptionHandler.handleUncaughtException(
            "Internal error: unresolved reference to non existing field of ColorShade enum.")
      }
      return sctoswiftresult
    }

    set(value) {
      let swifttoscvalue = value.rawValue
      _prop_set_CppbindExample_Frame_backgroundColorShade(cself, swifttoscvalue)
    }
  }

  public func getNextColor(color: Color) -> Color {

    let swifttosccolor = color.rawValue
    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExample_Frame_getNextColor(cself, swifttosccolor, &cppbindErr)
    if cppbindErr.type != nil {
      let errorType = String(cString: cppbindErr.type!)
      switch errorType {
      case ("std::exception"):
        let excObj = StdException(cppbindErr, true)
        ExceptionHandler.handleUncaughtException(excObj.what())
      default:
        cppbindErr.type.deallocate()
        ExceptionHandler.handleUncaughtException("Uncaught Exception")
      }
    }
    guard let sctoswiftresult = Color(rawValue: result) else {
       ExceptionHandler.handleUncaughtException(
          "Internal error: unresolved reference to non existing field of Color enum.")
    }
    return sctoswiftresult
  }

  /// An internal property to keep an information about the underlying C++ object type.
  /// It is intended to be used by the generated code.
  class var cppbindCxxTypeName : String { return "cppbind::example::Frame" }
}


Last update: December 1, 2022