Functions

For binding global and member functions, gen_function and gen_method actions should be used, respectively.

Global functions

Let’s bind a simple global function. Here is the source code of it:

    /**
     * A global function example.
     * __API__
     * action: gen_function
     * package: globs
     * swift.file: GlobUtils
     * throws: no_throw
     */
    int mul(int first, int second) {
        return first * second;
    }

    /**
     * A global function example.
     * __API__
     * action: gen_function
     * package: globs
     * swift.file: GlobUtils
     * throws: no_throw
     * overloading_postfix: Three
     */
    int mul(int first, int second, int third) {
        return first * second * third;
    }

    /**
     * A global function example.
     * __API__
     * action: gen_function
     * package: globs
     * swift.file: GlobUtils
     * throws: no_throw
     */
    std::string concat(const std::string& str1, const std::string& str2) {
        return str1 + str2;
    }

Except for the __API__ tag, we have four variables which are instructions for CppBind. With action: gen_function, we define what should be generated in the target language. package variable indicates the package for generated concat function and file shows the place of the saved file. Notice that we have a prefixed variable file with swift prefix, which means that its value will be used only for generated Swift bindings, and for other languages, the default value will be used, i.e., source file name. And finally, variable throws defines what kind of exceptions the concat function can throw. Its value is no_throw which means it does not throw any exception. For more details on variables, see Variable Definitions.

And here is a small code using generated bindings:

var mulInt = mul(5, 4)
assert(mulInt == 20)

var mulInt1 = mul(5, 4, 3)
assert(mulInt1 == 60)

var res = concat("Hello ", "Johnny")
assert(res == "Hello Johnny" )
mulInt = mul(5, 4)
assert mulInt == 20

mulInt = mul_three(5, 4, 3)
assert mulInt == 60

res = concat("Hello ", "Johnny")
assert res == "Hello Johnny"
var mulInt = mul(first:5, second: 4)
assert(mulInt == 20)

mulInt = mul(first:5, second: 4, third: 3)
assert(mulInt == 60)

var res = concat(str1: "Hello ", str2: "Johnny")
assert(res == "Hello Johnny")

Let’s bind more complex examples like template makePair and max, overloaded concat, etc.

    /**
     * A global overloaded function example.
     * __API__
     * action: gen_function
     * package: globs
     * swift.file: GlobUtils
     * throws: no_throw
     */
    std::string concat(const std::string& str1, const std::string& str2, const std::string& str3) {
        return str1 + str2 +str3;
    }

    /**
     * A global template function example.
     * __API__
     * action: gen_function
     * package: globs
     * swift.file: GlobUtils
     * throws: no_throw
     * template:
     *   T:
     *     - type: int
     *     - type: std::string
     */
    template <typename T>
    T max(T a, T b) {
       return a < b ? b:a;
}

}

namespace cppbind::example {
    /**
     * A global template function example in namespace.
     * __API__
     * action: gen_function
     * package: globs
     * swift.file: GlobUtils
     * throws: no_throw
     * template:
     *   T:
     *     - type: cppbind::example::Project
     *     - type: cppbind::example::Root
     *   V:
     *     - type: cppbind::example::Project
     * return_value_policy: reference
     */
    template <typename T, typename V>
    std::pair<T*, V*> makePair(T* a, V* b) {
       return std::make_pair(a, b);
    }
}

namespace {

Code using generated functions:

res = concat("Hello ", "Johnny ", "Jane")
assert(res == "Hello Johnny Jane")

// [custom-arg-examples]
val greeting = greet("Johnny", "Florida")
assert(greeting == "Hello Johnny from Florida")
// [custom-arg-examples]

val maxInt = max(2, 5)
assert(maxInt == 5)
val maxString = max("d", "a")
assert(maxString == "d")

val prj1 = Project("My first project")
val prj2 = Project("My second project")
val pairPrjPrj = makePair(prj1, prj2)
assert(pairPrjPrj.first.title == prj1.title)
assert(pairPrjPrj.second.title == prj2.title)

val root1 = Root("/path/to/root/")
val pairRootPrj = makePair(root1, prj1)
assert(pairRootPrj.first.path == root1.path)
assert(pairRootPrj.second.title == prj1.title)
res = concat1("Hello ", "Johnny ", "Jane")
assert res == "Hello Johnny Jane"

# [custom-arg-examples]
greeting = greet("Johnny", "Florida")
assert greeting == "Hello Johnny from Florida"

greeting = greet(person="Bob", hometown="California")
assert greeting == "Hello Bob from California"

# [custom-arg-examples]

maxInt = max_int(2, 5)
assert maxInt == 5
maxString = max_str("d", "a")
assert maxString == "d"

prj1 = Project("My first project")
prj2 = Project("My second project")
pairPrjPrj = make_pair_project_project(prj1, prj2)
assert pairPrjPrj[0].title == prj1.title
assert pairPrjPrj[1].title == prj2.title

root1 = Root("/path/to/root/")
pairRootPrj = make_pair_root_project(root1, prj1)
assert pairRootPrj[0].path == root1.path
assert pairRootPrj[1].title == prj1.title
res = concat(str1: "Hello ", str2: "Johnny ", str3: "Jane")
assert(res == "Hello Johnny Jane")

// [custom-arg-examples]
let greeting = greet(person: "Johnny", from: "Florida")
assert(greeting == "Hello Johnny from Florida")
// [custom-arg-examples]

let maxInt = max(a: 2, b: 5)
assert(maxInt == 5)
let maxString = max(a: "d", b: "a")
assert(maxString == "d")

let prj1 = Project(title: "My first project")
let prj2 = Project(title: "My second project")
let pairPrjPrj = makePair(a: prj1, b: prj2)
assert(Mirror(reflecting: pairPrjPrj).children.count == 2)
assert(pairPrjPrj.0.title == prj1.title)
assert(pairPrjPrj.1.title == prj2.title)

let root1 = Root(path: "/path/to/root/")
let pairRootPrj = makePair(a: root1, b: prj1)
assert(Mirror(reflecting: pairRootPrj).children.count == 2)
assert(pairRootPrj.0.path == root1.path)
assert(pairRootPrj.1.title == prj1.title)

Here we have overloaded concat for Kotlin and Swift, but it’s slightly different for Python as there’s no overloading. We have two concat, and concat1 in Python. Similarly, we have an overloaded function for each template combination in Kotlin and Swift. In the case of Python, a postfix generated from argument types is appended to the function name.

Generated bindings

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

package com.examples.globs

import com.examples.cppbind.alias.*
import com.examples.cppbind.exceptionUtils.*
import com.examples.cppbind.exception_helpers.*
import com.examples.simple.Project
import com.examples.simple.Root

private val INIT = run {
    System.loadLibrary("wrapper_jni");
}

/**
 * A global function example.
 */
fun mul(first: Int, second: Int): Int {
    val result = jMul(first, second)
    
    return result
}

/**
 * A global function example.
 */
fun mul(first: Int, second: Int, third: Int): Int {
    val result = jMulThree(first, second, third)
    
    return result
}

/**
 * A global function example.
 */
fun concat(str1: String, str2: String): String {
    val result = jConcat(str1, str2)
    
    return result
}

/**
 * A global overloaded function example.
 */
fun concat(str1: String, str2: String, str3: String): String {
    val result = jConcat_1(str1, str2, str3)
    
    return result
}

/**
 * A global template function example.
 */
fun max(a: Int, b: Int): Int {
    val result = jMaxInt(a, b)
    
    return result
}

/**
 * A global template function example.
 */
fun max(a: String, b: String): String {
    val result = jMaxString(a, b)
    
    return result
}

/**
 * A global template function example in namespace.
 */
fun makePair(a: Project, b: Project): Pair<Project, Project> {
    val kotlintojdka = a.id
    val kotlintojdkb = b.id
    val result = jMakepairProjectProject(kotlintojdka, kotlintojdkb)
    val first_result = result.first
    val second_result = result.second
    val jdktokotlinfirst_result = Project(CppBindObject(first_result))
    val jdktokotlinsecond_result = Project(CppBindObject(second_result))
    val jdktokotlinresult = Pair<Project, Project>(jdktokotlinfirst_result, jdktokotlinsecond_result)
    return jdktokotlinresult
}

/**
 * A global template function example in namespace.
 */
fun makePair(a: Root, b: Project): Pair<Root, Project> {
    val kotlintojdka = a.id
    val kotlintojdkb = b.id
    val result = jMakepairRootProject(kotlintojdka, kotlintojdkb)
    val first_result = result.first
    val second_result = result.second
    val jdktokotlinfirst_result = Root(CppBindObject(first_result))
    val jdktokotlinsecond_result = Project(CppBindObject(second_result))
    val jdktokotlinresult = Pair<Root, Project>(jdktokotlinfirst_result, jdktokotlinsecond_result)
    return jdktokotlinresult
}

/**
 * A global function with pointer default value and nullable return value.
 */
fun optionalFDPtr(project: Project? = null): Project? {
    val kotlintojdkproject = project?.id ?: 0L
    val result = jOptionalfdptr(kotlintojdkproject)
    val jdktokotlinresult = if (result == 0L) null else Project(CppBindObject(result))
    return jdktokotlinresult
}

/**
 * A global function with no return value.
 */
fun doNothing(): Unit {
    val result = jDonothing()
    
    return result
}

private external fun jMul(first: Int, second: Int): Int
private external fun jMulThree(first: Int, second: Int, third: Int): Int
private external fun jConcat(str1: String, str2: String): String
private external fun jConcat_1(str1: String, str2: String, str3: String): String
private external fun jMaxInt(a: Int, b: Int): Int
private external fun jMaxString(a: String, b: String): String
private external fun jMakepairProjectProject(a: Long, b: Long): Pair<Long, Long>
private external fun jMakepairRootProject(a: Long, b: Long): Pair<Long, Long>
private external fun jOptionalfdptr(project: Long): Long
private external fun jDonothing(): Unit

private external fun jGettypebyid(id: Long): String
"""
  ______ .______   .______   .______    __  .__   __.  _______  
 /      ||   _  \  |   _  \  |   _  \  |  | |  \ |  | |       \ 
|  ,----'|  |_)  | |  |_)  | |  |_)  | |  | |   \|  | |  .--.  |
|  |     |   ___/  |   ___/  |   _  <  |  | |  . `  | |  |  |  |
|  `----.|  |      |  |      |  |_)  | |  | |  |\   | |  '--'  |
 \______|| _|      | _|      |______/  |__| |__| \__| |_______/ 

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.globs.utils as pybind_utils_pygen
import examples_lib.simple.project_pygen as simple_project_pygen
import examples_lib.simple.root_pygen as simple_root_pygen
from examples_lib.cppbind.bind_utils_pygen import *
from examples_lib.cppbind.metaclass_pygen import *


@bind
def mul(first: int, second: int) -> int:
    """
    A global function example.
    Documentation generated from: `cxx/globs/utils.hpp#L23
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/globs/utils.hpp#L23>`_
    """
    pass


@bind
def mul_three(first: int, second: int, third: int) -> int:
    """
    A global function example.
    Documentation generated from: `cxx/globs/utils.hpp#L36
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/globs/utils.hpp#L36>`_
    """
    pass


@bind
def concat(str1: str, str2: str) -> str:
    """
    A global function example.
    Documentation generated from: `cxx/globs/utils.hpp#L48
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/globs/utils.hpp#L48>`_
    """
    pass


@bind
def concat1(str1: str, str2: str, str3: str) -> str:
    """
    A global overloaded function example.
    Documentation generated from: `cxx/globs/utils.hpp#L62
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/globs/utils.hpp#L62>`_
    """
    pass


@bind
def max_int(a: int, b: int) -> int:
    """
    A global template function example.
    Documentation generated from: `cxx/globs/utils.hpp#L78
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/globs/utils.hpp#L78>`_
    """
    pass


@bind
def max_str(a: str, b: str) -> str:
    """
    A global template function example.
    Documentation generated from: `cxx/globs/utils.hpp#L78
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/globs/utils.hpp#L78>`_
    """
    pass


@bind
def make_pair_project_project(a: simple_project_pygen.Project, b: simple_project_pygen.Project) -> Tuple[simple_project_pygen.Project, simple_project_pygen.Project]:
    """
    A global template function example in namespace.
    Documentation generated from: `cxx/globs/utils.hpp#L101
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/globs/utils.hpp#L101>`_
    """
    pass


@bind
def make_pair_root_project(a: simple_root_pygen.Root, b: simple_project_pygen.Project) -> Tuple[simple_root_pygen.Root, simple_project_pygen.Project]:
    """
    A global template function example in namespace.
    Documentation generated from: `cxx/globs/utils.hpp#L101
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/globs/utils.hpp#L101>`_
    """
    pass


@bind
def optional_f_d_ptr(project: Optional[simple_project_pygen.Project] = None) -> Optional[simple_project_pygen.Project]:
    """
    A global function with pointer default value and nullable return value.
    Documentation generated from: `cxx/globs/utils.hpp#L189
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/globs/utils.hpp#L189>`_
    """
    pass


@bind
def do_nothing() -> None:
    """
    A global function with no return value.
    Documentation generated from: `cxx/globs/utils.hpp#L200
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/globs/utils.hpp#L200>`_
    """
    pass
/**
 *   ______ .______   .______   .______    __  .__   __.  _______  
 *  /      ||   _  \  |   _  \  |   _  \  |  | |  \ |  | |       \ 
 * |  ,----'|  |_)  | |  |_)  | |  |_)  | |  | |   \|  | |  .--.  |
 * |  |     |   ___/  |   ___/  |   _  <  |  | |  . `  | |  |  |  |
 * |  `----.|  |      |  |      |  |_)  | |  | |  |\   | |  '--'  |
 *  \______|| _|      | _|      |______/  |__| |__| \__| |_______/ 
 * 
 * This file is generated by cppbind on 05/12/2022-10:26.
 * Please do not change it manually.
 */

import CWrapper
import Foundation

/**
 * A global function example.
 */
public func mul(first: Int, second: Int) -> Int {
  let swifttoscfirst = CInt(first)
  let swifttoscsecond = CInt(second)
  var cppbindErr = CppBindCObject()
  let result = _func__mul(swifttoscfirst, swifttoscsecond, &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")
    }
  }
  let sctoswiftresult = Int(result)
  return sctoswiftresult
}

/**
 * A global function example.
 */
public func mul(first: Int, second: Int, third: Int) -> Int {
  let swifttoscfirst = CInt(first)
  let swifttoscsecond = CInt(second)
  let swifttoscthird = CInt(third)
  var cppbindErr = CppBindCObject()
  let result = _func__mulThree(swifttoscfirst, swifttoscsecond, swifttoscthird, &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")
    }
  }
  let sctoswiftresult = Int(result)
  return sctoswiftresult
}

/**
 * A global function example.
 */
public func concat(str1: String, str2: String) -> String {
  let swifttoscstr1 = strdup(str1)!
  let swifttoscstr2 = strdup(str2)!
  var cppbindErr = CppBindCObject()
  let result = _func__concat(swifttoscstr1, swifttoscstr2, &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")
    }
  }
  let sctoswiftresult = String(cString: result)
  defer {
    result.deallocate()
  }
  return sctoswiftresult
}

/**
 * A global overloaded function example.
 */
public func concat(str1: String, str2: String, str3: String) -> String {
  let swifttoscstr1 = strdup(str1)!
  let swifttoscstr2 = strdup(str2)!
  let swifttoscstr3 = strdup(str3)!
  var cppbindErr = CppBindCObject()
  let result = _func__concat_1(swifttoscstr1, swifttoscstr2, swifttoscstr3, &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")
    }
  }
  let sctoswiftresult = String(cString: result)
  defer {
    result.deallocate()
  }
  return sctoswiftresult
}

/**
 * A global template function example.
 */
public func max(a: Int, b: Int) -> Int {
  let swifttosca = CInt(a)
  let swifttoscb = CInt(b)
  var cppbindErr = CppBindCObject()
  let result = _func__maxInt(swifttosca, swifttoscb, &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")
    }
  }
  let sctoswiftresult = Int(result)
  return sctoswiftresult
}

/**
 * A global template function example.
 */
public func max(a: String, b: String) -> String {
  let swifttosca = strdup(a)!
  let swifttoscb = strdup(b)!
  var cppbindErr = CppBindCObject()
  let result = _func__maxString(swifttosca, swifttoscb, &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")
    }
  }
  let sctoswiftresult = String(cString: result)
  defer {
    result.deallocate()
  }
  return sctoswiftresult
}

/**
 * A global template function example in namespace.
 */
public func makePair(a: Project, b: Project) -> (Project, Project) {
  let swifttosca = a.cself
  let swifttoscb = b.cself
  var cppbindErr = CppBindCObject()
  let result = _func_CppbindExample_makePairProjectProject(swifttosca, swifttoscb, &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")
    }
  }
  let _resultFirstData = UnsafeBufferPointer<CppBindCObject>(
    start: result.first.assumingMemoryBound(to: CppBindCObject.self),
    count: 1)
  let _resultSecondData = UnsafeBufferPointer<CppBindCObject>(
    start: result.second.assumingMemoryBound(to: CppBindCObject.self),
    count: 1)
  defer {
    _resultFirstData.deallocate()
    _resultSecondData.deallocate()
  }
  let resultFirst = _resultFirstData[0]
  let resultSecond = _resultSecondData[0]
  var sctoswiftresultFirst: Project
  sctoswiftresultFirst = Project(resultFirst)
  var sctoswiftresultSecond: Project
  sctoswiftresultSecond = Project(resultSecond)
  let sctoswiftresult: (Project, Project) = (sctoswiftresultFirst, sctoswiftresultSecond)
  return sctoswiftresult
}

/**
 * A global template function example in namespace.
 */
public func makePair(a: Root, b: Project) -> (Root, Project) {
  let swifttosca = a.cself
  let swifttoscb = b.cself
  var cppbindErr = CppBindCObject()
  let result = _func_CppbindExample_makePairRootProject(swifttosca, swifttoscb, &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")
    }
  }
  let _resultFirstData = UnsafeBufferPointer<CppBindCObject>(
    start: result.first.assumingMemoryBound(to: CppBindCObject.self),
    count: 1)
  let _resultSecondData = UnsafeBufferPointer<CppBindCObject>(
    start: result.second.assumingMemoryBound(to: CppBindCObject.self),
    count: 1)
  defer {
    _resultFirstData.deallocate()
    _resultSecondData.deallocate()
  }
  let resultFirst = _resultFirstData[0]
  let resultSecond = _resultSecondData[0]
  var sctoswiftresultFirst: Root
  sctoswiftresultFirst = Root(resultFirst)
  var sctoswiftresultSecond: Project
  sctoswiftresultSecond = Project(resultSecond)
  let sctoswiftresult: (Root, Project) = (sctoswiftresultFirst, sctoswiftresultSecond)
  return sctoswiftresult
}

/**
 * A global function with pointer default value and nullable return value.
 */
public func optionalFDPtr(project: Project? = nil) -> Project? {
  let swifttoscproject = project?.cself ?? CppBindCObject(type: nil, ptr: nil)
  var cppbindErr = CppBindCObject()
  let result = _func__optionalFDPtr(swifttoscproject, &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")
    }
  }
  var sctoswiftresult: Project? = nil
  if (result.ptr != nil) {
    sctoswiftresult = Project(result)
  }
  return sctoswiftresult
}

/**
 * A global function with no return value.
 */
public func doNothing() -> Void {
  var cppbindErr = CppBindCObject()
  _func__doNothing(&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")
    }
  }
}

Overloaded methods

Let’s now bind a struct with overloaded methods:

    /**
     * Sum two ints.
     * __API__
     * action: gen_method
     * throws: no_throw
     */
    static int sum(int first, int second) {
        return first + second;
    }

    /**
     * Sum two floats.
     * __API__
     * action: gen_method
     * throws: no_throw
     */
    static float sum(float first, float second) {
        return first + second;
    }

    /**
     * Concatenate with two strings.
     * __API__
     * action: gen_method
     * throws: no_throw
     */
    std::string concatenate(std::string first, std::string second) {
        return first + second;
    }

    /**
     * Concatenate with three strings.
     * __API__
     * action: gen_method
     * throws: no_throw
     */
    std::string concatenate(std::string first, std::string second, std::string third) {
        return first + second + third;
    }

As you can see, overloaded methods are like traditional methods. There’s nothing special to add to the API for them.

Note

Python does not have method overloading, but we have overloaded sum and concatenate methods here with some tricks under the hood.

We are ready to use the generated bindings:

assert(Utils.sum(1, 2) == 3)
assert(Utils.sum(2.0f, 3.0f) == 5.0f)
val utils = Utils()
assert(utils.concatenate("1", "2") == "12")
assert(utils.concatenate("a", "b", "c") == "abc")
assert Utils.sum(1, 2) == 3
assert Utils.sum(2.0, 3.0) == 5.0

utils = Utils()
assert utils.concatenate("1", "2") == "12"
assert utils.concatenate("a", "b", "c") == "abc"
assert(Utils.sum(first: 1, second: 2) == 3)
assert(Utils.sum(first: 2.0, second: 3.0) == 5.0)

let utils = Utils()
assert(utils.concatenate(first: "1", second: "2") == "12")
assert(utils.concatenate(first: "a", second: "b", third: "c") == "abc")
Generated bindings

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

package com.examples.overloads

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

/**
 * An example with overloaded methods.
 */
open class Utils
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

        /**
         * Sum two ints.
         */
        fun sum(first: Int, second: Int): Int {
            val result = jSum(first, second)
            
            return result
        }
        @JvmStatic
        private external fun jSum(first: Int, second: Int): Int

        /**
         * Sum two floats.
         */
        fun sum(first: Float, second: Float): Float {
            val result = jSum_1(first, second)
            
            return result
        }
        @JvmStatic
        private external fun jSum_1(first: Float, second: Float): Float

        /**
         * Sub two ints.
         */
        fun minus(first: Int, second: Int): Int {
            val result = jMinus(first, second)
            
            return result
        }
        @JvmStatic
        private external fun jMinus(first: Int, second: Int): Int

        /**
         * Sub two floats.
         */
        fun minus(first: Float, second: Float): Float {
            val result = jMinus_1(first, second)
            
            return result
        }
        @JvmStatic
        private external fun jMinus_1(first: Float, second: Float): Float
        const val cppbindCxxTypeName: String = "cppbind::example::Utils"
    }
    
    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)) {
    }
    
    /**
     * Concatenate with two strings.
     */
    fun concatenate(first: String, second: String): String {
        val result = jConcatenate(id, first, second)
        
        return result
    }

    /**
     * Concatenate with three strings.
     */
    fun concatenate(first: String, second: String, third: String): String {
        val result = jConcatenate_1(id, first, second, third)
        
        return result
    }

    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 jConcatenate(id: Long, first: String, second: String): String
    private external fun jConcatenate_1(id: Long, first: String, second: String, third: String): String
    private external fun jFinalize(id: Long): Unit
}

private external fun jGettypebyid(id: Long): String
"""
  ______ .______   .______   .______    __  .__   __.  _______  
 /      ||   _  \  |   _  \  |   _  \  |  | |  \ |  | |       \ 
|  ,----'|  |_)  | |  |_)  | |  |_)  | |  | |   \|  | |  .--.  |
|  |     |   ___/  |   ___/  |   _  <  |  | |  . `  | |  |  |  |
|  `----.|  |      |  |      |  |_)  | |  | |  |\   | |  '--'  |
 \______|| _|      | _|      |______/  |__| |__| \__| |_______/ 

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.overloads.utils as pybind_utils_pygen
from examples_lib.cppbind.bind_utils_pygen import *
from examples_lib.cppbind.metaclass_pygen import *


class Utils(metaclass=CppBindMetaclass):
    """
    An example with overloaded methods.
    Documentation generated from: `cxx/overloads/utils.hpp#L14
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/overloads/utils.hpp#L14>`_
    """
    
    @bind
    def __init__(self):
        """
        Documentation generated from: `cxx/overloads/utils.hpp#L20
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/overloads/utils.hpp#L20>`_
        """
        pass
    
    @classmethod
    @bind
    def sum(cls, first: int, second: int) -> int:
        """
        Sum two ints.
        Documentation generated from: `cxx/overloads/utils.hpp#L29
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/overloads/utils.hpp#L29>`_
        """
        pass

    @classmethod
    @bind
    def sum(cls, first: float, second: float) -> float:
        """
        Sum two floats.
        Documentation generated from: `cxx/overloads/utils.hpp#L39
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/overloads/utils.hpp#L39>`_
        """
        pass

    @bind
    def concatenate(self, first: str, second: str) -> str:
        """
        Concatenate with two strings.
        Documentation generated from: `cxx/overloads/utils.hpp#L49
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/overloads/utils.hpp#L49>`_
        """
        pass

    @bind
    def concatenate(self, first: str, second: str, third: str) -> str:
        """
        Concatenate with three strings.
        Documentation generated from: `cxx/overloads/utils.hpp#L59
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/overloads/utils.hpp#L59>`_
        """
        pass

    @classmethod
    @bind
    def minus(cls, first: int, second: int) -> int:
        """
        Sub two ints.
        Documentation generated from: `cxx/overloads/utils.hpp#L72
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/overloads/utils.hpp#L72>`_
        """
        pass

    @classmethod
    @bind
    def minus(cls, first: float, second: float) -> float:
        """
        Sub two floats.
        Documentation generated from: `cxx/overloads/utils.hpp#L83
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/overloads/utils.hpp#L83>`_
        """
        pass
/**
 *   ______ .______   .______   .______    __  .__   __.  _______  
 *  /      ||   _  \  |   _  \  |   _  \  |  | |  \ |  | |       \ 
 * |  ,----'|  |_)  | |  |_)  | |  |_)  | |  | |   \|  | |  .--.  |
 * |  |     |   ___/  |   ___/  |   _  <  |  | |  . `  | |  |  |  |
 * |  `----.|  |      |  |      |  |_)  | |  | |  |\   | |  '--'  |
 *  \______|| _|      | _|      |______/  |__| |__| \__| |_______/ 
 * 
 * This file is generated by cppbind on 05/12/2022-10:26.
 * Please do not change it manually.
 */

import CWrapper
import Foundation

/**
 * An example with overloaded methods.
 */
public class Utils {

  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_Utils(cself, owner)
  }

  public func keepCppBindReference(_ object: Any) {
    self.refs.append(object)
  }

  public convenience init() {
    var cppbindErr = CppBindCObject()
    self.init(create_CppbindExample_Utils(&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")
      }
    }
  }

  /**
   * Sum two ints.
   */
  public static func sum(first: Int, second: Int) -> Int {

    let swifttoscfirst = CInt(first)
    let swifttoscsecond = CInt(second)
    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExample_Utils_sum(swifttoscfirst, swifttoscsecond, &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")
      }
    }
    let sctoswiftresult = Int(result)
    return sctoswiftresult
  }

  /**
   * Sum two floats.
   */
  public static func sum(first: Float, second: Float) -> Float {

    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExample_Utils_sum_1(first, second, &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")
      }
    }
    return result
  }

  /**
   * Concatenate with two strings.
   */
  public func concatenate(first: String, second: String) -> String {

    let swifttoscfirst = strdup(first)!
    let swifttoscsecond = strdup(second)!
    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExample_Utils_concatenate(cself, swifttoscfirst, swifttoscsecond, &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")
      }
    }
    let sctoswiftresult = String(cString: result)
    defer {
      result.deallocate()
    }
    return sctoswiftresult
  }

  /**
   * Concatenate with three strings.
   */
  public func concatenate(first: String, second: String, third: String) -> String {

    let swifttoscfirst = strdup(first)!
    let swifttoscsecond = strdup(second)!
    let swifttoscthird = strdup(third)!
    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExample_Utils_concatenate_1(cself, swifttoscfirst, swifttoscsecond, swifttoscthird, &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")
      }
    }
    let sctoswiftresult = String(cString: result)
    defer {
      result.deallocate()
    }
    return sctoswiftresult
  }

  /**
   * Sub two ints.
   */
  public static func minus(first: Int, second: Int) -> Int {

    let swifttoscfirst = CInt(first)
    let swifttoscsecond = CInt(second)
    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExample_Utils_minus(swifttoscfirst, swifttoscsecond, &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")
      }
    }
    let sctoswiftresult = Int(result)
    return sctoswiftresult
  }

  /**
   * Sub two floats.
   */
  public static func minus(first: Float, second: Float) -> Float {

    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExample_Utils_minus_1(first, second, &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")
      }
    }
    return result
  }

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

Static methods

The binding mechanism of static methods is similar to the binding of regular methods. Nothing special should be added in API comments:

     /**
     * Sub two ints.
     * __API__
     * action: gen_method
     * name: minus
     * throws: no_throw
     */
    static int sub(int first, int second) {
        return first - second;
    }

    /**
     * Sub two floats.
     * __API__
     * action: gen_method
     * name: minus
     * throws: no_throw
     */
    static float sub(float first, float second) {
        return first - second;
    }

Here are the usage examples:

assert(Utils.minus(3, 2) == 1)
assert(Utils.minus(7.0f, 3.0f) == 4.0f)
assert Utils.minus(3, 2) == 1
assert Utils.minus(7.0, 3.0) == 4.0
assert(Utils.minus(first: 3, second: 2) == 1)
assert(Utils.minus(first: 7.0, second: 3.0) == 4.0)
Generated bindings

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

package com.examples.overloads

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

/**
 * An example with overloaded methods.
 */
open class Utils
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

        /**
         * Sum two ints.
         */
        fun sum(first: Int, second: Int): Int {
            val result = jSum(first, second)
            
            return result
        }
        @JvmStatic
        private external fun jSum(first: Int, second: Int): Int

        /**
         * Sum two floats.
         */
        fun sum(first: Float, second: Float): Float {
            val result = jSum_1(first, second)
            
            return result
        }
        @JvmStatic
        private external fun jSum_1(first: Float, second: Float): Float

        /**
         * Sub two ints.
         */
        fun minus(first: Int, second: Int): Int {
            val result = jMinus(first, second)
            
            return result
        }
        @JvmStatic
        private external fun jMinus(first: Int, second: Int): Int

        /**
         * Sub two floats.
         */
        fun minus(first: Float, second: Float): Float {
            val result = jMinus_1(first, second)
            
            return result
        }
        @JvmStatic
        private external fun jMinus_1(first: Float, second: Float): Float
        const val cppbindCxxTypeName: String = "cppbind::example::Utils"
    }
    
    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)) {
    }
    
    /**
     * Concatenate with two strings.
     */
    fun concatenate(first: String, second: String): String {
        val result = jConcatenate(id, first, second)
        
        return result
    }

    /**
     * Concatenate with three strings.
     */
    fun concatenate(first: String, second: String, third: String): String {
        val result = jConcatenate_1(id, first, second, third)
        
        return result
    }

    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 jConcatenate(id: Long, first: String, second: String): String
    private external fun jConcatenate_1(id: Long, first: String, second: String, third: String): String
    private external fun jFinalize(id: Long): Unit
}

private external fun jGettypebyid(id: Long): String
"""
  ______ .______   .______   .______    __  .__   __.  _______  
 /      ||   _  \  |   _  \  |   _  \  |  | |  \ |  | |       \ 
|  ,----'|  |_)  | |  |_)  | |  |_)  | |  | |   \|  | |  .--.  |
|  |     |   ___/  |   ___/  |   _  <  |  | |  . `  | |  |  |  |
|  `----.|  |      |  |      |  |_)  | |  | |  |\   | |  '--'  |
 \______|| _|      | _|      |______/  |__| |__| \__| |_______/ 

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.overloads.utils as pybind_utils_pygen
from examples_lib.cppbind.bind_utils_pygen import *
from examples_lib.cppbind.metaclass_pygen import *


class Utils(metaclass=CppBindMetaclass):
    """
    An example with overloaded methods.
    Documentation generated from: `cxx/overloads/utils.hpp#L14
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/overloads/utils.hpp#L14>`_
    """
    
    @bind
    def __init__(self):
        """
        Documentation generated from: `cxx/overloads/utils.hpp#L20
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/overloads/utils.hpp#L20>`_
        """
        pass
    
    @classmethod
    @bind
    def sum(cls, first: int, second: int) -> int:
        """
        Sum two ints.
        Documentation generated from: `cxx/overloads/utils.hpp#L29
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/overloads/utils.hpp#L29>`_
        """
        pass

    @classmethod
    @bind
    def sum(cls, first: float, second: float) -> float:
        """
        Sum two floats.
        Documentation generated from: `cxx/overloads/utils.hpp#L39
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/overloads/utils.hpp#L39>`_
        """
        pass

    @bind
    def concatenate(self, first: str, second: str) -> str:
        """
        Concatenate with two strings.
        Documentation generated from: `cxx/overloads/utils.hpp#L49
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/overloads/utils.hpp#L49>`_
        """
        pass

    @bind
    def concatenate(self, first: str, second: str, third: str) -> str:
        """
        Concatenate with three strings.
        Documentation generated from: `cxx/overloads/utils.hpp#L59
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/overloads/utils.hpp#L59>`_
        """
        pass

    @classmethod
    @bind
    def minus(cls, first: int, second: int) -> int:
        """
        Sub two ints.
        Documentation generated from: `cxx/overloads/utils.hpp#L72
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/overloads/utils.hpp#L72>`_
        """
        pass

    @classmethod
    @bind
    def minus(cls, first: float, second: float) -> float:
        """
        Sub two floats.
        Documentation generated from: `cxx/overloads/utils.hpp#L83
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/overloads/utils.hpp#L83>`_
        """
        pass
/**
 *   ______ .______   .______   .______    __  .__   __.  _______  
 *  /      ||   _  \  |   _  \  |   _  \  |  | |  \ |  | |       \ 
 * |  ,----'|  |_)  | |  |_)  | |  |_)  | |  | |   \|  | |  .--.  |
 * |  |     |   ___/  |   ___/  |   _  <  |  | |  . `  | |  |  |  |
 * |  `----.|  |      |  |      |  |_)  | |  | |  |\   | |  '--'  |
 *  \______|| _|      | _|      |______/  |__| |__| \__| |_______/ 
 * 
 * This file is generated by cppbind on 05/12/2022-10:26.
 * Please do not change it manually.
 */

import CWrapper
import Foundation

/**
 * An example with overloaded methods.
 */
public class Utils {

  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_Utils(cself, owner)
  }

  public func keepCppBindReference(_ object: Any) {
    self.refs.append(object)
  }

  public convenience init() {
    var cppbindErr = CppBindCObject()
    self.init(create_CppbindExample_Utils(&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")
      }
    }
  }

  /**
   * Sum two ints.
   */
  public static func sum(first: Int, second: Int) -> Int {

    let swifttoscfirst = CInt(first)
    let swifttoscsecond = CInt(second)
    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExample_Utils_sum(swifttoscfirst, swifttoscsecond, &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")
      }
    }
    let sctoswiftresult = Int(result)
    return sctoswiftresult
  }

  /**
   * Sum two floats.
   */
  public static func sum(first: Float, second: Float) -> Float {

    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExample_Utils_sum_1(first, second, &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")
      }
    }
    return result
  }

  /**
   * Concatenate with two strings.
   */
  public func concatenate(first: String, second: String) -> String {

    let swifttoscfirst = strdup(first)!
    let swifttoscsecond = strdup(second)!
    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExample_Utils_concatenate(cself, swifttoscfirst, swifttoscsecond, &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")
      }
    }
    let sctoswiftresult = String(cString: result)
    defer {
      result.deallocate()
    }
    return sctoswiftresult
  }

  /**
   * Concatenate with three strings.
   */
  public func concatenate(first: String, second: String, third: String) -> String {

    let swifttoscfirst = strdup(first)!
    let swifttoscsecond = strdup(second)!
    let swifttoscthird = strdup(third)!
    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExample_Utils_concatenate_1(cself, swifttoscfirst, swifttoscsecond, swifttoscthird, &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")
      }
    }
    let sctoswiftresult = String(cString: result)
    defer {
      result.deallocate()
    }
    return sctoswiftresult
  }

  /**
   * Sub two ints.
   */
  public static func minus(first: Int, second: Int) -> Int {

    let swifttoscfirst = CInt(first)
    let swifttoscsecond = CInt(second)
    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExample_Utils_minus(swifttoscfirst, swifttoscsecond, &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")
      }
    }
    let sctoswiftresult = Int(result)
    return sctoswiftresult
  }

  /**
   * Sub two floats.
   */
  public static func minus(first: Float, second: Float) -> Float {

    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExample_Utils_minus_1(first, second, &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")
      }
    }
    return result
  }

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

Note

In generated Python bindings, the sum is a classmethod as it was static in the original code.

Also, note that CppBind supports static overloaded methods.

Custom argument names and labels

You can specify argument names and argument labels (only for Swift) using argument_name and argument_label variables. Here’s an example function where the user explicitly gives the argument name and label for each argument. Those values will be used in the target language instead of the values used in C++.

     /** A global function with custom argument name and label.
     * __API__
     * action: gen_function
     * kotlin.package: globs.custom_args
     * package: globs
     * file: customArgUtils
     * throws: no_throw
     * argument_name:
        name: person
     * argument_label:
        hometown: from
     */
    std::string greet(const std::string& name, const std::string& hometown) {
        return "Hello " + name + " from " + hometown;
    }

And here is a small code example using generated bindings:

val greeting = greet("Johnny", "Florida")
assert(greeting == "Hello Johnny from Florida")
greeting = greet("Johnny", "Florida")
assert greeting == "Hello Johnny from Florida"

greeting = greet(person="Bob", hometown="California")
assert greeting == "Hello Bob from California"

let greeting = greet(person: "Johnny", from: "Florida")
assert(greeting == "Hello Johnny from Florida")

Note

If the original function does not have argument names, CppBind will generate argument names using indexing, i.e. arg1, arg2, etc. The users can override this by using generated argument names in the argument_name variable.
Here’s a small example:
action: gen_function
argument_name:
  arg1: input
  arg2: output
Generated bindings

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

package com.examples.globs.custom_args

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

private val INIT = run {
    System.loadLibrary("wrapper_jni");
}

/**
 * A global function with custom argument name and label.
 */
fun greet(person: String, hometown: String): String {
    val result = jGreet(person, hometown)
    
    return result
}

private external fun jGreet(person: String, hometown: String): String

private external fun jGettypebyid(id: Long): String
"""
  ______ .______   .______   .______    __  .__   __.  _______  
 /      ||   _  \  |   _  \  |   _  \  |  | |  \ |  | |       \ 
|  ,----'|  |_)  | |  |_)  | |  |_)  | |  | |   \|  | |  .--.  |
|  |     |   ___/  |   ___/  |   _  <  |  | |  . `  | |  |  |  |
|  `----.|  |      |  |      |  |_)  | |  | |  |\   | |  '--'  |
 \______|| _|      | _|      |______/  |__| |__| \__| |_______/ 

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.globs.customArgUtils as pybind_customArgUtils_pygen
from examples_lib.cppbind.bind_utils_pygen import *
from examples_lib.cppbind.metaclass_pygen import *


@bind
def greet(person: str, hometown: str) -> str:
    """
    A global function with custom argument name and label.
    Documentation generated from: `cxx/globs/utils.hpp#L216
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/globs/utils.hpp#L216>`_
    """
    pass
/**
 *   ______ .______   .______   .______    __  .__   __.  _______  
 *  /      ||   _  \  |   _  \  |   _  \  |  | |  \ |  | |       \ 
 * |  ,----'|  |_)  | |  |_)  | |  |_)  | |  | |   \|  | |  .--.  |
 * |  |     |   ___/  |   ___/  |   _  <  |  | |  . `  | |  |  |  |
 * |  `----.|  |      |  |      |  |_)  | |  | |  |\   | |  '--'  |
 *  \______|| _|      | _|      |______/  |__| |__| \__| |_______/ 
 * 
 * This file is generated by cppbind on 05/12/2022-10:26.
 * Please do not change it manually.
 */

import CWrapper
import Foundation

/**
 * A global function with custom argument name and label.
 */
public func greet(person: String, from hometown: String) -> String {
  let swifttoscperson = strdup(person)!
  let swifttoschometown = strdup(hometown)!
  var cppbindErr = CppBindCObject()
  let result = _func__greet(swifttoscperson, swifttoschometown, &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")
    }
  }
  let sctoswiftresult = String(cString: result)
  defer {
    result.deallocate()
  }
  return sctoswiftresult
}

Nullable arguments

Let’s take a look at the following example:

/**
 * An example with nullable arguments.
 * __API__
 * action: gen_class
 * shared_ref: true
 * swift.file: NullableUtils
 * swift.name: NullableUtils
 * package: nullables
 */
struct Utils {

    /**
     * __API__
     * action: gen_constructor
     * throws: no_throw
     * nullable_arg:
     *   - num
     */
    Utils(NumberDouble* num) : numDouble(num) {}

    /**
     * __API__
     * action: gen_method
     * throws: no_throw
     * nullable_arg:
     *   - first
     * nullable_return: True
     * return_value_policy: reference
     */
    static NumberDouble* max(NumberDouble* first, NumberDouble* second) {
        if (first && second) {
            if (first->value > second->value) {
                return first;
            }
            return second;
        }
        return nullptr;
    }

    /**
     * __API__
     * action: gen_method
     * throws: no_throw
     * nullable_arg:
     *   - first
     *   - second
     * nullable_return: True
     */
    static std::shared_ptr<NumberInt> max(std::shared_ptr<NumberInt> first, std::shared_ptr<NumberInt> second) {
        if (first && second) {
            if (first->value > second->value) {
                return first;
            }
            return second;
        }
        return std::shared_ptr<NumberInt>(nullptr);
    }

    /**
     * __API__
     * action: gen_method
     * throws: no_throw
     */
    static void checkNonnullArg(NumberDouble* number) {

    }

    /**
     * __API__
     * action: gen_method
     * throws: no_throw
     * return_value_policy: reference
     */
    static NumberDouble* checkNonnullReturn() {
        return nullptr;
    }

    /**
     * __API__
     * action: gen_getter
     * throws: no_throw
     * nullable_return: True
     * return_value_policy: reference
     */
    NumberDouble* nullable() {
        return numDouble;
    }

    /**
     * __API__
     * action: gen_setter
     * throws: no_throw
     * nullable_arg: num
     */
    void setNullable(NumberDouble* num) {
        numDouble = num;
    }

    /**
     * __API__
     * action: gen_getter
     * throws: no_throw
     * return_value_policy: reference
     */
    NumberDouble* nonNull() {
        return numDouble;
    }

    /**
     * __API__
     * action: gen_setter
     * throws: no_throw
     */
    void setNonNull(NumberDouble* num) {
        numDouble = num;
    }

    /**
     * __API__
     * action: gen_property_setter
     * nullable_return: True
     * return_value_policy: reference
     */
    NumberDouble* numDouble;

    /**
     * __API__
     * action: gen_property_setter
     * nullable_return: False
     */
    std::shared_ptr<NumberInt> numInt;

};

/**
 * __API__
 * action: gen_function
 * package: nullables
 * swift.file: NullableUtils
 * throws: no_throw
 * nullable_arg: s
 * nullable_return: True
 */
const char* reverseString(const char* s) {
    if (s) {
        auto str = std::string(s);
        std::reverse(str.begin(), str.end());
        char* res = new char[sizeof(char) * strlen(s)];
        std::strcpy(res, str.c_str());
        return res;
    }
    return nullptr;
}

CppBind uses the nullable_arg variable to identify which arguments are nullable. It is a list of argument names. And for the nullable return value, CppBind uses the nullable_return boolean variable. In the above example, we have an overloaded method max. The first one has one nullable and one non-null argument, which returns a nullable value. The second one has two nullable arguments and returns a nullable value. In this example, you can also find a constructor taking a nullable argument and nullable getters/setters.

Note

Both must be tagged similarly for getter/setter methods marked as gen_getter and gen_setter. If the getter is nullable_return: True, then setter should be marked as nullable_arg: <arg_name>. In the above example, we have a pair of nullable getter/setter: nullable and setNullable.

Note

Kotlin and Swift support nullable arguments. For Python, nullable arguments and return values are marked as Optional. Since all arguments are nullable in Python, CppBind does additional runtime checks not to allow passing null values where a non-null value is expected.

Now let’s see some usage examples for generated bindings:

val n1 = NumberInt(1)
val n2 = NumberInt(2)

var res1 = Utils.max(n1, n2)
assert(res1?.value == n2.value)

res1 = Utils.max(null, null)
assert(res1 == null)

val d1 = NumberDouble(1.0)
val d2 = NumberDouble(2.0)

var res2 = Utils.max(d1, d2)
assert(res2?.value == d2.value)

res2 = Utils.max(null, d2)
assert(res2 == null)

// nullable getter/setter
val utils = Utils(d1)
assert(utils.nullable?.value == d1.value)
utils.nullable = null

// nullable property getter/setter
assert(utils.numDouble == null)
utils.numDouble = d2
assert(utils.numDouble?.value == d2.value)

// checking char *
assert(reverseString("abc") == "cba")
assert(reverseString(null) == null)

As you can see here ValueError is thrown when None is passed but expected value is not Optional. The same is for return values.

n1 = NumberInt(1)
n2 = NumberInt(2)

res1 = Utils.max(n1, n2)
assert res1.value == n2.value

res1 = Utils.max(None, None)
assert res1 is None

d1 = NumberDouble(1.0)
d2 = NumberDouble(2.0)

res2 = Utils.max(d1, d2)
assert res2.value == d2.value

res2 = Utils.max(None, d2)
assert res2 is None

# negative examples
try:
    Utils.check_nonnull_arg(None)
except ValueError as e:
    assert str(e) == "Utils.check_nonnull_arg's number argument cannot be None."

try:
    Utils.check_nonnull_return()
except ValueError as e:
    assert str(e) == "Utils.check_nonnull_return's return value cannot be None."

# nullable getter/setter
utils = Utils(d1)
assert utils.nullable.value == d1.value
utils.nullable = None


# negative examples
try:
    assert utils.non_null
except ValueError as e:
    assert str(e) == "Utils.non_null's return value cannot be None."

try:
    utils.non_null = None
except ValueError as e:
    assert str(e) == "Utils.non_null's value argument cannot be None."


# nullable property getter/setter
assert utils.num_double is None
utils.num_double = d2
assert utils.num_double.value == d2.value


# negative examples
try:
    utils.num_int = None
except ValueError as e:
    assert str(e) == "Utils.num_int's value argument cannot be None."

# checking char *
assert reverse_string("abc") == "cba"
assert reverse_string(None) is None

let n1 = NumInt(val: 1)
let n2 = NumInt(val: 2)

let res1 = NullableUtils.max(first: n1, second: n2)
assert(res1!.value == n2.value)

let d1 = NumDouble(val: 1.0)
let d2 = NumDouble(val: 2.0)

var res2 = NullableUtils.max(first: d1, second: d2)
assert(res2!.value == d2.value)

res2 = NullableUtils.max(first: nil, second: d2)
assert(res2 == nil)

// incorrect example for swift
// res1 = NullableUtils.max(first: nil, second: nil)
// assert(res1 == nil)

// negative examples
// NullableUtils.checkNonnullArg(number: nil)

// nullable getter/setter
let utils = NullableUtils(num: d1)
assert(utils.nullable!.value == d1.value)
utils.nullable = nil


// nullable property getter/setter
assert(utils.numDouble == nil)
utils.numDouble = d2
assert(utils.numDouble!.value == d2.value)

// negative examples
// utils.numInt = nil

// checking char *
assert(reverseString(s: "abc") == "cba")
assert(reverseString(s: nil) == nil)
Generated bindings

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

package com.examples.nullables

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

private val INIT = run {
    System.loadLibrary("wrapper_jni");
}

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

        @JvmStatic
        private external fun jConstructor(val_: Int): Long
        const val cppbindCxxTypeName: String = "cppbind::example::nullable::NumberInt"
    }
    
    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(val_: Int): this(CppBindObject(construct_helper(val_), true)) {
    }
    
    val value: Int
        get() {
            val result = jValue(id)
            
            return result
        }

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

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

        @JvmStatic
        private external fun jConstructor(val_: Double): Long
        const val cppbindCxxTypeName: String = "cppbind::example::nullable::NumberDouble"
    }
    
    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(val_: Double): this(CppBindObject(construct_helper(val_), true)) {
    }
    
    val value: Double
        get() {
            val result = jValue(id)
            
            return result
        }

    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 jValue(id: Long): Double
    private external fun jFinalize(id: Long): Unit
}

/**
 * An example with nullable arguments.
 */
open class Utils
internal constructor(obj: CppBindObject) : AutoCloseable {
    companion object {
        init {
            System.loadLibrary("wrapper_jni")
        }
        
        protected fun construct_helper(num: NumberDouble?): Long {
            val kotlintojdknum = num?.id ?: 0L
            val id = jConstructor(kotlintojdknum)
            return id
        }

        @JvmStatic
        private external fun jConstructor(num: Long): Long

        fun max(first: NumberDouble?, second: NumberDouble): NumberDouble? {
            val kotlintojdkfirst = first?.id ?: 0L
            val kotlintojdksecond = second.id
            val result = jMax(kotlintojdkfirst, kotlintojdksecond)
            val jdktokotlinresult = if (result == 0L) null else NumberDouble(CppBindObject(result))
            return jdktokotlinresult
        }
        @JvmStatic
        private external fun jMax(first: Long, second: Long): Long

        fun max(first: NumberInt?, second: NumberInt?): NumberInt? {
            val kotlintojdkfirst = first?.id ?: 0L
            val kotlintojdksecond = second?.id ?: 0L
            val result = jMax_1(kotlintojdkfirst, kotlintojdksecond)
            val jdktokotlinresult = if (result == 0L) null else NumberInt(CppBindObject(result, true))
            return jdktokotlinresult
        }
        @JvmStatic
        private external fun jMax_1(first: Long, second: Long): Long

        fun checkNonnullArg(number: NumberDouble): Unit {
            val kotlintojdknumber = number.id
            val result = jChecknonnullarg(kotlintojdknumber)
            
            return result
        }
        @JvmStatic
        private external fun jChecknonnullarg(number: Long): Unit

        fun checkNonnullReturn(): NumberDouble {
            val result = jChecknonnullreturn()
            val jdktokotlinresult = NumberDouble(CppBindObject(result))
            return jdktokotlinresult
        }
        @JvmStatic
        private external fun jChecknonnullreturn(): Long
        const val cppbindCxxTypeName: String = "cppbind::example::nullable::Utils"
    }
    
    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(num: NumberDouble?): this(CppBindObject(construct_helper(num), true)) {
    }
    
    var nullable: NumberDouble?
        get() {
            val result = jNullable(id)
            val jdktokotlinresult = if (result == 0L) null else NumberDouble(CppBindObject(result))
            return jdktokotlinresult
        }
        set(value) {
            val kotlintojdkvalue = value?.id ?: 0L
            jSetnullable(id, kotlintojdkvalue)
        }

    var nonNull: NumberDouble
        get() {
            val result = jNonnull(id)
            val jdktokotlinresult = NumberDouble(CppBindObject(result))
            return jdktokotlinresult
        }
        set(value) {
            val kotlintojdkvalue = value.id
            jSetnonnull(id, kotlintojdkvalue)
        }

    var numDouble: NumberDouble?
        get() {
            val result = jNumdouble(id)
            val jdktokotlinresult = if (result == 0L) null else NumberDouble(CppBindObject(result))
            return jdktokotlinresult
        }
        set(value) {
            val kotlintojdkvalue = value?.id ?: 0L
            jSetnumdouble(id, kotlintojdkvalue)
        }
        

    var numInt: NumberInt
        get() {
            val result = jNumint(id)
            val jdktokotlinresult = NumberInt(CppBindObject(result, true))
            return jdktokotlinresult
        }
        set(value) {
            val kotlintojdkvalue = value.id
            jSetnumint(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 jNullable(id: Long): Long
    private external fun jSetnullable(id: Long, value: Long): Unit
    private external fun jNonnull(id: Long): Long
    private external fun jSetnonnull(id: Long, value: Long): Unit
    private external fun jNumdouble(id: Long): Long
    private external fun jSetnumdouble(id: Long, value: Long): Unit
    private external fun jNumint(id: Long): Long
    private external fun jSetnumint(id: Long, value: Long): Unit
    private external fun jFinalize(id: Long): Unit
}

fun reverseString(s: String?): String? {
    val kotlintojdks = if (s != null) s!! else null
    val result = jReversestring(kotlintojdks)
    val jdktokotlinresult = if (result != null) result!! else null
    return jdktokotlinresult
}

private external fun jReversestring(s: String?): String?

private external fun jGettypebyid(id: Long): String
"""
  ______ .______   .______   .______    __  .__   __.  _______  
 /      ||   _  \  |   _  \  |   _  \  |  | |  \ |  | |       \ 
|  ,----'|  |_)  | |  |_)  | |  |_)  | |  | |   \|  | |  .--.  |
|  |     |   ___/  |   ___/  |   _  <  |  | |  . `  | |  |  |  |
|  `----.|  |      |  |      |  |_)  | |  | |  |\   | |  '--'  |
 \______|| _|      | _|      |______/  |__| |__| \__| |_______/ 

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.nullables.nullable_utils as pybind_nullable_utils_pygen
from examples_lib.cppbind.bind_utils_pygen import *
from examples_lib.cppbind.metaclass_pygen import *


class NumberInt(metaclass=CppBindMetaclass):
    """
    Documentation generated from: `cxx/nullables/nullable_utils.hpp#L20
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/nullables/nullable_utils.hpp#L20>`_
    """
    
    @bind
    def __init__(self, val_: int):
        """
        Documentation generated from: `cxx/nullables/nullable_utils.hpp#L26
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/nullables/nullable_utils.hpp#L26>`_
        """
        pass
    
    @property
    @bind
    def value(self) -> int:
        """
        Documentation generated from: `cxx/nullables/nullable_utils.hpp#L32
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/nullables/nullable_utils.hpp#L32>`_
        """
        pass



class NumberDouble(metaclass=CppBindMetaclass):
    """
    Documentation generated from: `cxx/nullables/nullable_utils.hpp#L43
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/nullables/nullable_utils.hpp#L43>`_
    """
    
    @bind
    def __init__(self, val_: float):
        """
        Documentation generated from: `cxx/nullables/nullable_utils.hpp#L49
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/nullables/nullable_utils.hpp#L49>`_
        """
        pass
    
    @property
    @bind
    def value(self) -> float:
        """
        Documentation generated from: `cxx/nullables/nullable_utils.hpp#L55
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/nullables/nullable_utils.hpp#L55>`_
        """
        pass



class Utils(metaclass=CppBindMetaclass):
    """
    An example with nullable arguments.
    Documentation generated from: `cxx/nullables/nullable_utils.hpp#L69
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/nullables/nullable_utils.hpp#L69>`_
    """
    
    @bind
    def __init__(self, num: Optional[NumberDouble]):
        """
        Documentation generated from: `cxx/nullables/nullable_utils.hpp#L78
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/nullables/nullable_utils.hpp#L78>`_
        """
        pass
    
    @property
    @bind
    def nullable(self) -> Optional[NumberDouble]:
        """
        Documentation generated from: `cxx/nullables/nullable_utils.hpp#L144
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/nullables/nullable_utils.hpp#L144>`_
        """
        pass

    @nullable.setter
    @bind
    def nullable(self, value: Optional[NumberDouble]):
        """
        Documentation generated from: `cxx/nullables/nullable_utils.hpp#L144
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/nullables/nullable_utils.hpp#L144>`_
        """
        pass

    @property
    @bind
    def non_null(self) -> NumberDouble:
        """
        Documentation generated from: `cxx/nullables/nullable_utils.hpp#L164
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/nullables/nullable_utils.hpp#L164>`_
        """
        pass

    @non_null.setter
    @bind
    def non_null(self, value: NumberDouble):
        """
        Documentation generated from: `cxx/nullables/nullable_utils.hpp#L164
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/nullables/nullable_utils.hpp#L164>`_
        """
        pass

    @property
    @bind
    def num_double(self) -> Optional[NumberDouble]:
        """
        Documentation generated from: `cxx/nullables/nullable_utils.hpp#L183
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/nullables/nullable_utils.hpp#L183>`_
        """
        pass

    @num_double.setter
    @bind
    def num_double(self, value: Optional[NumberDouble]):
        """
        Documentation generated from: `cxx/nullables/nullable_utils.hpp#L183
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/nullables/nullable_utils.hpp#L183>`_
        """
        pass

    @property
    @bind
    def num_int(self) -> NumberInt:
        """
        Documentation generated from: `cxx/nullables/nullable_utils.hpp#L190
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/nullables/nullable_utils.hpp#L190>`_
        """
        pass

    @num_int.setter
    @bind
    def num_int(self, value: NumberInt):
        """
        Documentation generated from: `cxx/nullables/nullable_utils.hpp#L190
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/nullables/nullable_utils.hpp#L190>`_
        """
        pass
    
    @classmethod
    @bind
    def max(cls, first: Optional[NumberDouble], second: NumberDouble) -> Optional[NumberDouble]:
        """
        Documentation generated from: `cxx/nullables/nullable_utils.hpp#L89
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/nullables/nullable_utils.hpp#L89>`_
        """
        pass

    @classmethod
    @bind
    def max(cls, first: Optional[NumberInt], second: Optional[NumberInt]) -> Optional[NumberInt]:
        """
        Documentation generated from: `cxx/nullables/nullable_utils.hpp#L108
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/nullables/nullable_utils.hpp#L108>`_
        """
        pass

    @classmethod
    @bind
    def check_nonnull_arg(cls, number: NumberDouble) -> None:
        """
        Documentation generated from: `cxx/nullables/nullable_utils.hpp#L123
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/nullables/nullable_utils.hpp#L123>`_
        """
        pass

    @classmethod
    @bind
    def check_nonnull_return(cls) -> NumberDouble:
        """
        Documentation generated from: `cxx/nullables/nullable_utils.hpp#L133
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/nullables/nullable_utils.hpp#L133>`_
        """
        pass


@bind
def reverse_string(s: Optional[str]) -> Optional[str]:
    """
    Documentation generated from: `cxx/nullables/nullable_utils.hpp#L203
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/nullables/nullable_utils.hpp#L203>`_
    """
    pass
/**
 *   ______ .______   .______   .______    __  .__   __.  _______  
 *  /      ||   _  \  |   _  \  |   _  \  |  | |  \ |  | |       \ 
 * |  ,----'|  |_)  | |  |_)  | |  |_)  | |  | |   \|  | |  .--.  |
 * |  |     |   ___/  |   ___/  |   _  <  |  | |  . `  | |  |  |  |
 * |  `----.|  |      |  |      |  |_)  | |  | |  |\   | |  '--'  |
 *  \______|| _|      | _|      |______/  |__| |__| \__| |_______/ 
 * 
 * This file is generated by cppbind on 05/12/2022-10:26.
 * Please do not change it manually.
 */

import CWrapper
import Foundation

public class NumInt {

  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_CppbindExampleNullable_NumInt(cself, owner)
  }

  public func keepCppBindReference(_ object: Any) {
    self.refs.append(object)
  }

  public convenience init(val: Int) {
    let swifttoscval = CInt(val)
    var cppbindErr = CppBindCObject()
    self.init(create_CppbindExampleNullable_NumInt(swifttoscval, &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 value: Int {
    let result = _prop_get_CppbindExampleNullable_NumInt_value(cself)
    let sctoswiftresult = Int(result)
    return sctoswiftresult
  }

  class var cppbindCxxTypeName : String { return "cppbind::example::nullable::NumberInt" }
}

public class NumDouble {

  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_CppbindExampleNullable_NumDouble(cself, owner)
  }

  public func keepCppBindReference(_ object: Any) {
    self.refs.append(object)
  }

  public convenience init(val: Double) {
    var cppbindErr = CppBindCObject()
    self.init(create_CppbindExampleNullable_NumDouble(val, &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 value: Double {
    let result = _prop_get_CppbindExampleNullable_NumDouble_value(cself)
    return result
  }

  class var cppbindCxxTypeName : String { return "cppbind::example::nullable::NumberDouble" }
}

/**
 * An example with nullable arguments.
 */
public class NullableUtils {

  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_CppbindExampleNullable_NullableUtils(cself, owner)
  }

  public func keepCppBindReference(_ object: Any) {
    self.refs.append(object)
  }

  public convenience init(num: NumDouble?) {
    let swifttoscnum = num?.cself ?? CppBindCObject(type: nil, ptr: nil)
    var cppbindErr = CppBindCObject()
    self.init(create_CppbindExampleNullable_NullableUtils(swifttoscnum, &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 nullable: NumDouble? {
    get {
      var cppbindErr = CppBindCObject()
      let result = _prop_get_CppbindExampleNullable_NullableUtils_nullable(cself, &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")
        }
      }
      var sctoswiftresult: NumDouble? = nil
      if (result.ptr != nil) {
        sctoswiftresult = NumDouble(result)
      }
      return sctoswiftresult
    }

    set(value) {
      let swifttoscvalue = value?.cself ?? CppBindCObject(type: nil, ptr: nil)
      var cppbindErr = CppBindCObject()
      _prop_set_CppbindExampleNullable_NullableUtils_nullable(cself, swifttoscvalue, &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")
        }
      }
    }
  }

  public var nonNull: NumDouble {
    get {
      var cppbindErr = CppBindCObject()
      let result = _prop_get_CppbindExampleNullable_NullableUtils_nonNull(cself, &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")
        }
      }
      var sctoswiftresult: NumDouble
      sctoswiftresult = NumDouble(result)
      return sctoswiftresult
    }

    set(value) {
      let swifttoscvalue = value.cself
      var cppbindErr = CppBindCObject()
      _prop_set_CppbindExampleNullable_NullableUtils_nonNull(cself, swifttoscvalue, &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")
        }
      }
    }
  }

  public var numDouble: NumDouble? {
    get {
      let result = _prop_get_CppbindExampleNullable_NullableUtils_numDouble(cself)
      var sctoswiftresult: NumDouble? = nil
      if (result.ptr != nil) {
        sctoswiftresult = NumDouble(result)
      }
      return sctoswiftresult
    }

    set(value) {
      let swifttoscvalue = value?.cself ?? CppBindCObject(type: nil, ptr: nil)
      _prop_set_CppbindExampleNullable_NullableUtils_numDouble(cself, swifttoscvalue)
    }
  }

  public var numInt: NumInt {
    get {
      let result = _prop_get_CppbindExampleNullable_NullableUtils_numInt(cself)
      var sctoswiftresult: NumInt
      sctoswiftresult = NumInt(result, true)
      return sctoswiftresult
    }

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

  public static func max(first: NumDouble?, second: NumDouble) -> NumDouble? {

    let swifttoscfirst = first?.cself ?? CppBindCObject(type: nil, ptr: nil)
    let swifttoscsecond = second.cself
    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExampleNullable_NullableUtils_max(swifttoscfirst, swifttoscsecond, &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")
      }
    }
    var sctoswiftresult: NumDouble? = nil
    if (result.ptr != nil) {
      sctoswiftresult = NumDouble(result)
    }
    return sctoswiftresult
  }

  public static func max(first: NumInt?, second: NumInt?) -> NumInt? {

    let swifttoscfirst = first?.cself ?? CppBindCObject(type: nil, ptr: nil)
    let swifttoscsecond = second?.cself ?? CppBindCObject(type: nil, ptr: nil)
    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExampleNullable_NullableUtils_max_1(swifttoscfirst, swifttoscsecond, &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")
      }
    }
    var sctoswiftresult: NumInt? = nil
    if (result.ptr != nil) {
      sctoswiftresult = NumInt(result, true)
    }
    return sctoswiftresult
  }

  public static func checkNonnullArg(number: NumDouble) -> Void {

    let swifttoscnumber = number.cself
    var cppbindErr = CppBindCObject()
    _func_CppbindExampleNullable_NullableUtils_checkNonnullArg(swifttoscnumber, &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")
      }
    }
  }

  public static func checkNonnullReturn() -> NumDouble {

    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExampleNullable_NullableUtils_checkNonnullReturn(&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")
      }
    }
    var sctoswiftresult: NumDouble
    sctoswiftresult = NumDouble(result)
    return sctoswiftresult
  }

  class var cppbindCxxTypeName : String { return "cppbind::example::nullable::Utils" }
}

public func reverseString(s: String?) -> String? {
  let swifttoscs = s?.cString(using: String.Encoding.utf8)
  var cppbindErr = CppBindCObject()
  let result = _func_CppbindExampleNullable_reverseString(swifttoscs, &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")
    }
  }
  let sctoswiftresult = result != nil ? String(cString: result!) : nil
  return sctoswiftresult
}

Default arguments

Default argument support for built-in types(e.g., bool, int, nullptr, etc.), enums, and strings differ from the support for user-defined project types. Let’s go through these two cases.

Here are some sample functions having default arguments:

/**
 * A global function with enum default argument.
 * __API__
 * action: gen_function
 * kotlin.package: globs.primitives
 * package: globs
 * file: primitiveDefaults
 * throws: no_throw
 */
    Color optionalColor(cppbind::example::Color c = cppbind::example::Color::Red) {
        return c;
    }

    /**
     * A global function with string default argument.
     * __API__
     * action: gen_function
     * kotlin.package: globs.primitives
     * package: globs
     * file: primitiveDefaults
     * throws: no_throw
     */
    std::string optionalString(std::string optionalStr = "abc") {
        return optionalStr;
    }

    /** A global function with primitive default value.
     * __API__
     * action: gen_function
     * kotlin.package: globs.primitives
     * package: globs
     * file: primitiveDefaults
     * throws: no_throw
     */
    int optionalInt(int i = 5) {
        return i;
    }

Here’s a sample code using the above functions:

assert(optionalColor() == Color.Red)
assert(optionalColor(Color.Blue) == Color.Blue)
assert(optionalInt() == 5)
assert(optionalInt(1) == 1)
assert(optionalString() == "abc")
assert(optionalString("def") == "def")
assert optional_color() == Color.Red
assert optional_color(Color.Blue) == Color.Blue
assert optional_int() == 5
assert optional_int(1) == 1
assert optional_string() == 'abc'
assert optional_string('def') == 'def'
assert(optionalColor() == Color.Red)
assert(optionalColor(c: Color.Blue) == Color.Blue)
assert(optionalInt() == 5)
assert(optionalInt(i: 1) == 1)
assert(optionalString() == "abc")
assert(optionalString(optionalStr: "def") == "def")
Generated bindings

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

package com.examples.globs.primitives

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

private val INIT = run {
    System.loadLibrary("wrapper_jni");
}

/**
 * A global function with enum default argument.
 */
fun optionalColor(c: Color = Color.Red): Color {
    val kotlintojdkc = c.value
    val result = jOptionalcolor(kotlintojdkc)
    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
}

/**
 * A global function with string default argument.
 */
fun optionalString(optionalStr: String = "abc"): String {
    val result = jOptionalstring(optionalStr)
    
    return result
}

/**
 * A global function with primitive default value.
 */
fun optionalInt(i: Int = 5): Int {
    val result = jOptionalint(i)
    
    return result
}

private external fun jOptionalcolor(c: Int): Int
private external fun jOptionalstring(optionalStr: String): String
private external fun jOptionalint(i: Int): Int

private external fun jGettypebyid(id: Long): String
"""
  ______ .______   .______   .______    __  .__   __.  _______  
 /      ||   _  \  |   _  \  |   _  \  |  | |  \ |  | |       \ 
|  ,----'|  |_)  | |  |_)  | |  |_)  | |  | |   \|  | |  .--.  |
|  |     |   ___/  |   ___/  |   _  <  |  | |  . `  | |  |  |  |
|  `----.|  |      |  |      |  |_)  | |  | |  |\   | |  '--'  |
 \______|| _|      | _|      |______/  |__| |__| \__| |_______/ 

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.globs.primitiveDefaults as pybind_primitiveDefaults_pygen
import examples_lib.enums.color_pygen as enums_color_pygen
from examples_lib.cppbind.bind_utils_pygen import *
from examples_lib.cppbind.metaclass_pygen import *


@bind
def optional_color(c: enums_color_pygen.Color = enums_color_pygen.Color.Red) -> enums_color_pygen.Color:
    """
    A global function with enum default argument.
    Documentation generated from: `cxx/globs/utils.hpp#L120
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/globs/utils.hpp#L120>`_
    """
    pass


@bind
def optional_string(optional_str: str = "abc") -> str:
    """
    A global function with string default argument.
    Documentation generated from: `cxx/globs/utils.hpp#L133
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/globs/utils.hpp#L133>`_
    """
    pass


@bind
def optional_int(i: int = 5) -> int:
    """
    A global function with primitive default value.
    Documentation generated from: `cxx/globs/utils.hpp#L145
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/globs/utils.hpp#L145>`_
    """
    pass
/**
 *   ______ .______   .______   .______    __  .__   __.  _______  
 *  /      ||   _  \  |   _  \  |   _  \  |  | |  \ |  | |       \ 
 * |  ,----'|  |_)  | |  |_)  | |  |_)  | |  | |   \|  | |  .--.  |
 * |  |     |   ___/  |   ___/  |   _  <  |  | |  . `  | |  |  |  |
 * |  `----.|  |      |  |      |  |_)  | |  | |  |\   | |  '--'  |
 *  \______|| _|      | _|      |______/  |__| |__| \__| |_______/ 
 * 
 * This file is generated by cppbind on 05/12/2022-10:26.
 * Please do not change it manually.
 */

import CWrapper
import Foundation

/**
 * A global function with enum default argument.
 */
public func optionalColor(c: Color = Color.Red) -> Color {
  let swifttoscc = c.rawValue
  var cppbindErr = CppBindCObject()
  let result = _func__optionalColor(swifttoscc, &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
}

/**
 * A global function with string default argument.
 */
public func optionalString(optionalStr: String = "abc") -> String {
  let swifttoscoptionalStr = strdup(optionalStr)!
  var cppbindErr = CppBindCObject()
  let result = _func__optionalString(swifttoscoptionalStr, &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")
    }
  }
  let sctoswiftresult = String(cString: result)
  defer {
    result.deallocate()
  }
  return sctoswiftresult
}

/**
 * A global function with primitive default value.
 */
public func optionalInt(i: Int = 5) -> Int {
  let swifttosci = CInt(i)
  var cppbindErr = CppBindCObject()
  let result = _func__optionalInt(swifttosci, &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")
    }
  }
  let sctoswiftresult = Int(result)
  return sctoswiftresult
}

Complex cases like t=Task("MyTask") or t=24>>2 are handled differently. Let’s take a look at the following example:

    /**
     * __API__
     * action: gen_function
     * kotlin.package: globs.complex
     * package: globs
     * file: complexDefaults
     * throws: no_throw
     */
    Task singleComplexDefaultValue(Task task = Task("MyTask")) {
        return task;
    }

    /**
     * A global function with mixed default values.
     * __API__
     * action: gen_function
     * kotlin.package: globs.complex
     * package: globs
     * file: complexDefaults
     * throws: no_throw
     */
    std::string multipleMixedDefaultValues(Task task = Task("DefaultTask"), int i = 1,
                                           Root r = Root("DefaultRoot")) {
        return task.title() + std::to_string(i) + r.path;
    }

In the above example, we have two functions. The first one has one argument of type Task with a default value. In this case, CppBind generates two overloaded functions for Kotlin and Swift: one without arguments and the other with one argument without a default value. The second function has three arguments of``Task``, Color and Root. The second argument is an enum, and its’ default value is generated in all target languages. CppBind will generate appropriate overloaded options for Kotlin and Swift for the other two arguments. For Python, CppBind does not generate overloaded functions; instead, the None default value is generated. Although the actual default values for complex types are not visible in generated code, they work as expected.

Generated functions

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

package com.examples.globs.complex

import com.examples.cppbind.alias.*
import com.examples.cppbind.exceptionUtils.*
import com.examples.cppbind.exception_helpers.*
import com.examples.simple.Root
import com.examples.simple.Task

private val INIT = run {
    System.loadLibrary("wrapper_jni");
}

fun singleComplexDefaultValue(): Task {
    val result = jSinglecomplexdefaultvalue_1()
    val jdktokotlinresult = Task(CppBindObject(result, true))
    return jdktokotlinresult
}


fun singleComplexDefaultValue(task: Task): Task {
    val kotlintojdktask = task.id
    val result = jSinglecomplexdefaultvalue(kotlintojdktask)
    val jdktokotlinresult = Task(CppBindObject(result, true))
    return jdktokotlinresult
}

/**
 * A global function with mixed default values.
 */
fun multipleMixedDefaultValues(): String {
    val result = jMultiplemixeddefaultvalues_1()
    
    return result
}


/**
 * A global function with mixed default values.
 */
fun multipleMixedDefaultValues(task: Task, i: Int = 1): String {
    val kotlintojdktask = task.id
    val result = jMultiplemixeddefaultvalues_2(kotlintojdktask, i)
    
    return result
}


/**
 * A global function with mixed default values.
 */
fun multipleMixedDefaultValues(task: Task, i: Int = 1, r: Root): String {
    val kotlintojdktask = task.id
    val kotlintojdkr = r.id
    val result = jMultiplemixeddefaultvalues(kotlintojdktask, i, kotlintojdkr)
    
    return result
}

private external fun jSinglecomplexdefaultvalue_1(): Long

private external fun jSinglecomplexdefaultvalue(task: Long): Long
private external fun jMultiplemixeddefaultvalues_1(): String

private external fun jMultiplemixeddefaultvalues_2(task: Long, i: Int): String

private external fun jMultiplemixeddefaultvalues(task: Long, i: Int, r: Long): String

private external fun jGettypebyid(id: Long): String
"""
  ______ .______   .______   .______    __  .__   __.  _______  
 /      ||   _  \  |   _  \  |   _  \  |  | |  \ |  | |       \ 
|  ,----'|  |_)  | |  |_)  | |  |_)  | |  | |   \|  | |  .--.  |
|  |     |   ___/  |   ___/  |   _  <  |  | |  . `  | |  |  |  |
|  `----.|  |      |  |      |  |_)  | |  | |  |\   | |  '--'  |
 \______|| _|      | _|      |______/  |__| |__| \__| |_______/ 

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.globs.complexDefaults as pybind_complexDefaults_pygen
import examples_lib.simple.root_pygen as simple_root_pygen
import examples_lib.simple.task.task_pygen as simple_task_task_pygen
from examples_lib.cppbind.bind_utils_pygen import *
from examples_lib.cppbind.metaclass_pygen import *


@bind
def single_complex_default_value(task: simple_task_task_pygen.PyTask = None) -> simple_task_task_pygen.PyTask:
    """
    Documentation generated from: `cxx/globs/utils.hpp#L159
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/globs/utils.hpp#L159>`_
    """
    pass


@bind
def multiple_mixed_default_values(task: simple_task_task_pygen.PyTask = None, i: int = 1, r: simple_root_pygen.Root = None) -> str:
    """
    A global function with mixed default values.
    Documentation generated from: `cxx/globs/utils.hpp#L172
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/globs/utils.hpp#L172>`_
    """
    pass
/**
 *   ______ .______   .______   .______    __  .__   __.  _______  
 *  /      ||   _  \  |   _  \  |   _  \  |  | |  \ |  | |       \ 
 * |  ,----'|  |_)  | |  |_)  | |  |_)  | |  | |   \|  | |  .--.  |
 * |  |     |   ___/  |   ___/  |   _  <  |  | |  . `  | |  |  |  |
 * |  `----.|  |      |  |      |  |_)  | |  | |  |\   | |  '--'  |
 *  \______|| _|      | _|      |______/  |__| |__| \__| |_______/ 
 * 
 * This file is generated by cppbind on 05/12/2022-10:26.
 * Please do not change it manually.
 */

import CWrapper
import Foundation

public func singleComplexDefaultValue() -> Task {
  var cppbindErr = CppBindCObject()
  let result = _func__singleComplexDefaultValue_1(&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")
    }
  }
  var sctoswiftresult: Task
  sctoswiftresult = Task(result, true)
  return sctoswiftresult
}

public func singleComplexDefaultValue(task: Task) -> Task {
  let swifttosctask = task.cself
  var cppbindErr = CppBindCObject()
  let result = _func__singleComplexDefaultValue(swifttosctask, &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")
    }
  }
  var sctoswiftresult: Task
  sctoswiftresult = Task(result, true)
  return sctoswiftresult
}

/**
 * A global function with mixed default values.
 */
public func multipleMixedDefaultValues() -> String {
  var cppbindErr = CppBindCObject()
  let result = _func__multipleMixedDefaultValues_1(&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")
    }
  }
  let sctoswiftresult = String(cString: result)
  defer {
    result.deallocate()
  }
  return sctoswiftresult
}

/**
 * A global function with mixed default values.
 */
public func multipleMixedDefaultValues(task: Task, i: Int = 1) -> String {
  let swifttosctask = task.cself
  let swifttosci = CInt(i)
  var cppbindErr = CppBindCObject()
  let result = _func__multipleMixedDefaultValues_2(swifttosctask, swifttosci, &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")
    }
  }
  let sctoswiftresult = String(cString: result)
  defer {
    result.deallocate()
  }
  return sctoswiftresult
}

/**
 * A global function with mixed default values.
 */
public func multipleMixedDefaultValues(task: Task, i: Int = 1, r: Root) -> String {
  let swifttosctask = task.cself
  let swifttosci = CInt(i)
  let swifttoscr = r.cself
  var cppbindErr = CppBindCObject()
  let result = _func__multipleMixedDefaultValues(swifttosctask, swifttosci, swifttoscr, &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")
    }
  }
  let sctoswiftresult = String(cString: result)
  defer {
    result.deallocate()
  }
  return sctoswiftresult
}

And here are some usage examples:

assert(multipleMixedDefaultValues() == "DefaultTask1DefaultRoot")
assert(multipleMixedDefaultValues(Task("ABC")) == "ABC1DefaultRoot")
assert(multipleMixedDefaultValues(Task("ABC"), 2) == "ABC2DefaultRoot")
assert(multipleMixedDefaultValues(Task("ABC"), r=Root("Path") ) == "ABC1Path")
assert(multipleMixedDefaultValues(Task("ABC"), 2, Root("Path") ) == "ABC2Path")
assert multiple_mixed_default_values() == "DefaultTask1DefaultRoot"
assert multiple_mixed_default_values(Task("ABC")) == "ABC1DefaultRoot"
assert multiple_mixed_default_values(Task("ABC"), i=2) == "ABC2DefaultRoot"
assert multiple_mixed_default_values(Task("ABC"), r=Root("Path")) == "ABC1Path"
assert multiple_mixed_default_values(Task("ABC"), i=2, r=Root("Path")) == "ABC2Path"
assert(multipleMixedDefaultValues() == "DefaultTask1DefaultRoot")
assert(multipleMixedDefaultValues(task: Task(title: "ABC")) == "ABC1DefaultRoot")
assert(multipleMixedDefaultValues(task: Task(title: "ABC"), i: 2) == "ABC2DefaultRoot")
assert(multipleMixedDefaultValues(task: Task(title: "ABC"), r: Root(path: "Path") ) == "ABC1Path")
assert(multipleMixedDefaultValues(task: Task(title: "ABC"), i: 2, r: Root(path: "Path") ) == "ABC2Path")

Return value policies

C++ and other languages may differently manage the memory and lifetime of the objects. Just by return value type, CppBind cannot decide whether the binding language should take care of deallocating the returned object or C++ is responsible for that. For this reason, CppBind provides a variable named return_value_policy. Using this variable user can override the default policies.

Let’s take a look at the following example:

/**
 * __API__
 * action: gen_class
 * shared_ref: False
 * package: rv_policies
 */
class Singleton {
public:
    /**
     * __API__
     * action: gen_method
     * throws: no_throw
     * return_value_policy: reference
     */
    static Singleton& getInstance();
    /**
     * __API__
     * action: gen_method
     * throws: no_throw
     * return_value_policy: reference
     */
    static Singleton* getInstancePtr();

    Singleton(const Singleton&) = delete;
    void operator=(const Singleton&) = delete;

private:
    Singleton();
    static Singleton* _instance;
};

In this example, we have two members returning the same singleton instance by reference and pointer. The default return value policy for member functions is automatic, which falls back to take_ownership for pointers. This means ownership is given to the binding language responsible for deallocating the returned object. In the case of references, it falls back to the copy policy, which creates a copy of the returned object, and its owner is the target language. Notice that if the default policy is used, the generated code for the first one won’t compile as the copy constructor is deleted. In this example, the default policies for both cases are not what we want. We have specified reference policy for both cases not to pass the ownership to the binding language or not create a new copy.

Now let’s take a look at another example:

/**
 * __API__
 * action: gen_class
 * shared_ref: False
 * package: rv_policies
 */
class Factory {
public:
    /**
     * __API__
     * action: gen_method
     * throws: no_throw
     */
    static Factory* create();

private:
    Factory();
};

Here we have a factory method create. In this case, the default policy is the right policy as it refers to the returned object and gives ownership to the target language.

Note

The default policies for getters and methods are different. For getters and properties, the default policy is reference_internal. For methods, the default policy is automatic.

Note

Object caching for Kotlin and Swift is not supported yet. Each function call creates a new binding object with different ownership depending on the function’s return value policy.

Supported return values policies are:

  • copy - Create a new object and give ownership to the target language. The lifetimes of these two objects are decoupled.

  • move - Move the returned object into a new one and give ownership to the target language. The lifetimes of these two objects are decoupled.

  • take_ownership - Reference an existing object but give ownership to the target language. The target language is responsible for deallocating it.

  • reference - Reference an existing object but do not give ownership to the target language. C++ is responsible for deallocating it.

  • automatic - This policy falls back to take_ownership when the return value is a pointer and move and copy for rvalue and lvalue references.

  • automatic_reference - Falls back to move and copy for lvalue and rvalue references, respectively, but falls back to reference when the return type is a pointer.

  • reference_internal - This policy is like reference but also binds the returned object’s lifetime with the lifetime of its parent object, i.e., the parent object won’t be deallocated until the returned object is not deallocated.

Note

copy and move are used, respectively, if the object is returned by value or by rvalue reference.

Note

For shared pointers, take_ownership is always used.

Keep alive policy

Besides the return value policies, CppBind supports the keep_alive policy to bind the argument’s lifetime to this object’s lifetime. This ensures that the argument won’t be deallocated until the object that keeps a reference on it is alive.

Let’s take a look at the following example:

/**
 * __API__
 * action: gen_class
 * shared_ref: False
 * package: rv_policies
 */
class Employer {
public:
    /**
     * __API__
     * action: gen_constructor
     * throws: no_throw
     * keep_alive: [1]
     */
    Employer(const std::vector<Employee*>& employees);

    /**
     * __API__
     * action: gen_constructor
     * throws: no_throw
     * keep_alive: [1]
     */
    void addEmployee(Employee* employee);


private:
    std::vector<Employee*> _employees;
};

In the above example, Employer holds references for Employee. The constructor and the method addEmployee are annotated with the keep_alive variable to keep added employees alive at least until the employer is alive. Otherwise, added employees might be deallocated before the destruction of employer, which causes employer to hold invalid data.

Note

If the argument is a container(e.g., std::vector), then the policy is applied to all its elements.

Note

The indexing of arguments starts with one, and the policy can be applied to all arguments.

Note

When applying the keep_alive policy, strong reference cycles may occur. Let’s assume we have two types, and each keeps a reference to the other. Applying the keep_alive policy for both, a strong reference cycle will occurs. Currently, CppBind does not detect reference cycles, so it’s up to users to be careful not to create them.

Note

For shared pointers, it’s redundant to specify the keep_alive policy.