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_field_name_prefix: Shade
 * enum_excluded_fields:
 *   - 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 also can customize enum case field names using the enum_field_name_prefix variable, which can be used to add a user-defined prefix string to enum field names in the target language.

If there are cases when some of the original enum fields are for internal usage, and the user doesn’t want to expose them in target language bindings, then the enum_excluded_fields 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 (except Python, since currently pybind sets some constraints on CppBind).

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;
};

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 05/12/2022-10:29.
 * Please do not change it manually.
 */

package com.examples.enums

import com.examples.cppbind.alias.*
import com.examples.cppbind.exceptionUtils.*
import com.examples.cppbind.exception_helpers.*

/**
 * 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 05/12/2022-10:29.
 * Please do not change it manually.
 */

package com.examples.enums

import com.examples.cppbind.alias.*
import com.examples.cppbind.exceptionUtils.*
import com.examples.cppbind.exception_helpers.*

/**
 * Class Frame.
 */
open class Frame
internal constructor(obj: CppBindObject) : AutoCloseable {
    companion object {
        init {
            System.loadLibrary("wrapper_jni")
        }
        
        protected fun construct_helper(): Long {
            val id = jConstructor()
            return id
        }

        @JvmStatic
        private external fun jConstructor(): Long
        const val cppbindCxxTypeName: String = "cppbind::example::Frame"
    }
    
    protected var cppbindObj = obj
    private var refs: MutableList<Any> = mutableListOf()

    fun keepCppBindReference(ref: Any) {
        refs.add(ref)
    }
    
    open val id: Long
        get() {
            if (cppbindObj.id == 0L) {
                throw RuntimeException("Object is not allocated")
            }
            return cppbindObj.id
        }
    
    constructor(): this(CppBindObject(construct_helper(), true)) {
    }
    
    var backgroundColor: Color
        get() {
            val result = jBackgroundcolor(id)
            val jdktokotlinresult_optional = Color.getByValue(result)
            if (jdktokotlinresult_optional == null) {
                ExceptionHandler.handleUncaughtException("Internal error: unresolved reference to non existing field of Color enum.")
            }
            val jdktokotlinresult = jdktokotlinresult_optional!!
            return jdktokotlinresult
        }
        set(value) {
            val kotlintojdkvalue = value.value
            jSetbackgroundcolor(id, kotlintojdkvalue)
        }
        

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

    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): Unit
    private external fun jBackgroundcolorshade(id: Long): Int
    private external fun jSetbackgroundcolorshade(id: Long, value: Int): Unit
    private external fun jFinalize(id: Long): Unit
}

private external fun jGettypebyid(id: Long): String

Here is the generated Python code for Color:

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

This file is generated by cppbind on 05/12/2022-10:33.
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.bind_utils_pygen import *
from examples_lib.cppbind.metaclass_pygen import *


class Color(metaclass=CppBindEnumMetaclass):
    """
    Color Enum.
    Documentation generated from: `cxx/enums/color.hpp#L24
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/enums/color.hpp#L24>`_
    """
    # 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):
    """
    Documentation generated from: `cxx/enums/color.hpp#L47
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/enums/color.hpp#L47>`_
    """
    # Light = 1
    ShadeLight = pybind_color_pygen.ColorShade.Light
    # Dark = 2
    ShadeDark = pybind_color_pygen.ColorShade.Dark
    # SemiLight = 3
    ShadeSemiLight = pybind_color_pygen.ColorShade.SemiLight
    # SemiDark = 4
    ShadeSemiDark = pybind_color_pygen.ColorShade.SemiDark

    def __int__(self):
        return self.value

And for Frame:

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

This file is generated by cppbind on 05/12/2022-10:33.
Please do not change it manually.
"""
from __future__ import annotations

from typing import *

import examples.enums.frame as pybind_frame_pygen
import examples_lib.enums.color_pygen as color_pygen
from examples_lib.cppbind.bind_utils_pygen import *
from examples_lib.cppbind.metaclass_pygen import *


class Frame(metaclass=CppBindMetaclass):
    """
    Class Frame.
    Documentation generated from: `cxx/enums/frame.hpp#L14
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/enums/frame.hpp#L14>`_
    """
    
    @bind
    def __init__(self):
        """
        Documentation generated from: `cxx/enums/frame.hpp#L20
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/enums/frame.hpp#L20>`_
        """
        pass
    
    @property
    @bind
    def background_color(self) -> color_pygen.Color:
        """
        Documentation generated from: `cxx/enums/frame.hpp#L26
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/enums/frame.hpp#L26>`_
        """
        pass

    @background_color.setter
    @bind
    def background_color(self, value: color_pygen.Color):
        """
        Documentation generated from: `cxx/enums/frame.hpp#L26
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/enums/frame.hpp#L26>`_
        """
        pass

    @property
    @bind
    def background_color_shade(self) -> color_pygen.ColorShade:
        """
        Documentation generated from: `cxx/enums/frame.hpp#L32
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/enums/frame.hpp#L32>`_
        """
        pass

    @background_color_shade.setter
    @bind
    def background_color_shade(self, value: color_pygen.ColorShade):
        """
        Documentation generated from: `cxx/enums/frame.hpp#L32
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/enums/frame.hpp#L32>`_
        """
        pass

Here is the generated Swift code for Color:

/**
 *   ______ .______   .______   .______    __  .__   __.  _______  
 *  /      ||   _  \  |   _  \  |   _  \  |  | |  \ |  | |       \ 
 * |  ,----'|  |_)  | |  |_)  | |  |_)  | |  | |   \|  | |  .--.  |
 * |  |     |   ___/  |   ___/  |   _  <  |  | |  . `  | |  |  |  |
 * |  `----.|  |      |  |      |  |_)  | |  | |  |\   | |  '--'  |
 *  \______|| _|      | _|      |______/  |__| |__| \__| |_______/ 
 * 
 * This file is generated by cppbind on 05/12/2022-10:26.
 * 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 05/12/2022-10:26.
 * Please do not change it manually.
 */

import CWrapper
import Foundation

/**
 * Class Frame.
 */
public class Frame {

  public let cself: CppBindCObject
  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)
  }

  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)
    }
  }

  class var cppbindCxxTypeName : String { return "cppbind::example::Frame" }
}