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