Templates

In this section, we cover function and class templates. For templates, the user must specify all expected values of template parameters with the template variable. The value of this variable is a mapping between template parameters and their expected arguments.

Let’s see an example:

/**
 * __API__
 * action: gen_class
 * package: templates
 */
class TemplateMethods  {
    public:
    /**
     * __API__
     * action: gen_constructor
     * throws: no_throw
     */
    TemplateMethods() {};

    /**
     * __API__
     * action: gen_method
     * throws: no_throw
     * template:
     *   T:
     *     - type: int
     *     - type: std::string
     */
    template <typename T>
    T const& max(T const& a, T const& b) {
       return a < b ? b:a;
    }

    /**
     * __API__
     * action: gen_method
     * 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);
    }
};

Here we have two template member functions: max and makePair. As you can see, we have specified all possible types for each parameter. CppBind generates overloaded methods in target languages with each combination of template arguments.

Note

Keys in __API__ should be in the same order as the template parameter list.

Note

We specified the template argument’s type full name in __API__, i.e., cppbind::example::Task, not just Task. It is mandatory; otherwise, CppBind cannot find the required information about the specified type.

Generated bindings

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

package com.examples.templates

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

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

        @JvmStatic
        private external fun jConstructor(): Long
        const val cppbindCxxTypeName: String = "cppbind::example::TemplateMethods"
    }
    
    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)) {
    }
    
    open fun max(a: Int, b: Int): Int {
        val result = jMaxInt(id, a, b)
        
        return result
    }

    open fun max(a: String, b: String): String {
        val result = jMaxString(id, a, b)
        
        return result
    }

    open fun makePair(a: Project, b: Project): Pair<Project, Project> {
        val kotlintojdka = a.id
        val kotlintojdkb = b.id
        val result = jMakepairProjectProject(id, 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
    }

    open fun makePair(a: Root, b: Project): Pair<Root, Project> {
        val kotlintojdka = a.id
        val kotlintojdkb = b.id
        val result = jMakepairRootProject(id, 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
    }

    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 jMaxInt(id: Long, a: Int, b: Int): Int
    private external fun jMaxString(id: Long, a: String, b: String): String
    private external fun jMakepairProjectProject(id: Long, a: Long, b: Long): Pair<Long, Long>
    private external fun jMakepairRootProject(id: Long, a: Long, b: Long): Pair<Long, Long>
    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.templates.template_methods as pybind_template_methods_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 *


class TemplateMethods(metaclass=CppBindMetaclass):
    """
    Documentation generated from: `cxx/templates/template_methods.hpp#L14
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/templates/template_methods.hpp#L14>`_
    """
    
    @bind
    def __init__(self):
        """
        Documentation generated from: `cxx/templates/template_methods.hpp#L21
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/templates/template_methods.hpp#L21>`_
        """
        pass
    
    @bind
    def max(self, a: int, b: int) -> int:
        """
        Documentation generated from: `cxx/templates/template_methods.hpp#L32
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/templates/template_methods.hpp#L32>`_
        """
        pass

    @bind
    def max(self, a: str, b: str) -> str:
        """
        Documentation generated from: `cxx/templates/template_methods.hpp#L32
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/templates/template_methods.hpp#L32>`_
        """
        pass

    @bind
    def make_pair(self, a: simple_project_pygen.Project, b: simple_project_pygen.Project) -> Tuple[simple_project_pygen.Project, simple_project_pygen.Project]:
        """
        Documentation generated from: `cxx/templates/template_methods.hpp#L49
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/templates/template_methods.hpp#L49>`_
        """
        pass

    @bind
    def make_pair(self, a: simple_root_pygen.Root, b: simple_project_pygen.Project) -> Tuple[simple_root_pygen.Root, simple_project_pygen.Project]:
        """
        Documentation generated from: `cxx/templates/template_methods.hpp#L49
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/templates/template_methods.hpp#L49>`_
        """
        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 TemplateMethods {

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

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

  public convenience init() {
    var cppbindErr = CppBindCObject()
    self.init(create_CppbindExample_TemplateMethods(&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 func max(a: Int, b: Int) -> Int {

    let swifttosca = CInt(a)
    let swifttoscb = CInt(b)
    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExample_TemplateMethods_maxInt(cself, 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
  }

  public func max(a: String, b: String) -> String {

    let swifttosca = strdup(a)!
    let swifttoscb = strdup(b)!
    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExample_TemplateMethods_maxString(cself, 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
  }

  public func makePair(a: Project, b: Project) -> (Project, Project) {

    let swifttosca = a.cself
    let swifttoscb = b.cself
    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExample_TemplateMethods_makePairProjectProject(cself, 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
  }

  public func makePair(a: Root, b: Project) -> (Root, Project) {

    let swifttosca = a.cself
    let swifttoscb = b.cself
    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExample_TemplateMethods_makePairRootProject(cself, 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
  }

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

As we can see, CppBind generated two overloaded methods for both max and makePair. And here are some usage examples:

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

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

val root1 = Root("/path/to/root/")
var pairRootPrj = tm.makePair(root1, prj1)
assert(pairRootPrj.first.path == root1.path)
assert(pairRootPrj.second.title == prj1.title)
tm = TemplateMethods()
max_int = tm.max(a=2, b=5)
assert max_int == 5
max_string = tm.max(a="d", b="a")
assert max_string == "d"

prj1 = Project(title="My first project")
prj2 = Project(title="My second project")
pair_prj_prj = tm.make_pair(a=prj1, b=prj2)
assert len(pair_prj_prj) == 2
assert pair_prj_prj[0].title == prj1.title
assert pair_prj_prj[1].title == prj2.title

root1 = Root("/path/to/root/")
pair_root_prj = tm.make_pair(a=root1, b=prj1)
assert len(pair_root_prj) == 2
assert pair_root_prj[0].path == root1.path
assert pair_root_prj[1].title == prj1.title
let tm = TemplateMethods()
let maxInt = tm.max(a: 2, b: 5)
assert(maxInt == 5)
let maxString = tm.max(a: "d", b: "a")
assert(maxString == "d")

let prj1 = Project(title: "My first project")
let prj2 = Project(title: "My second project")
let pairPrjPrj = tm.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 = tm.makePair(a: root1, b: prj1)
assert(Mirror(reflecting: pairRootPrj).children.count == 2)
assert(pairRootPrj.0.path == root1.path)
assert(pairRootPrj.1.title == prj1.title)

Class templates

For a class template, CppBind generates a new type for each specialization. Let’s generate bindings for a template class Stack. We should specify all expected types for template parameter T.

Here is the code in C++:

/**
 * An example of a class template.
 * __API__
 * action: gen_class
 * template:
 *   T:
 *     - type: cppbind::example::Project
 *       name: Prj
 *     - type: cppbind::example::Task
 *     - type: cppbind::example::Number<int>
 *       name: NumInt
 * package: templates
 */
template <class T>
class Stack: public Container {

    public:
    /**
     * __API__
     * action: gen_constructor
     * throws: no_throw
     */
    Stack() {};

    /**
     * __API__
     * action: gen_constructor
     * throws: no_throw
     */
    Stack(T& st) {};

    /**
     * __API__
     * action: gen_method
     * throws: no_throw
     */
    void push(T* item) {
        _elements.push_back(item);
    };
    /**
     * __API__
     * action: gen_method
     * throws: no_throw
     */
    void pop() {
        _elements.pop_back();
    };
    /**
     * __API__
     * action: gen_method
     * throws: no_throw
     * return_value_policy: reference
     */
     T* top() const {
        return _elements.back();
     };
     /**
      * __API__
      * action: gen_method
      * throws: no_throw
      */
     bool empty() const {
        return _elements.empty();
     }

   private:
   std::vector<T*> _elements;

};

We specified three possible values for template parameter T which means there can be three specializations of Stack (cppbind::example::Stack<cppbind::example::Task>, cppbind::example::Stack<cppbind::example::Project>, cppbind::example::Stack<cppbind::example::Number<int>>). CppBind will generate a new class for each of this specializations.

Note that we have specified name property for cppbind::example::Project and cppbind::example::Number<int>. This property is used as a type name postfix in target language, i.e. StackPrj will be generated for cppbind::example::Stack<cppbind::example::Project> and StackNumInt for cppbind::example::Stack<cppbind::example::Number<int>>.

For cppbind::example::Task, we have not specified the property name, which means its name in the target language is used as a postfix, i.e., StackPyTask is generated for Python and StackTask for other languages.

Now let’s see the usages of our example, Stack. Here is the source code:

/**
 * __API__
 * action: gen_class
 * package: templates
 */
class StackUsage  {
    public:
    /**
     * __API__
     * action: gen_constructor
     * throws: no_throw
     */
    StackUsage() {};

    /**
     * __API__
     * action: gen_method
     * throws: no_throw
     * return_value_policy: reference
     */
    Project* firstItemOfSpecializedStack(Stack<Project>* p) {
        return p->top();
    };

    /**
     * __API__
     * action: gen_method
     * template:
     *   V:
     *     - type: cppbind::example::Project
     * throws: no_throw
     * return_value_policy: reference
     */
    template <typename V>
    V* firstItemOfTemplateStack(cppbind::example::Stack<V>* p) {
        return p->top();
    };

    /**
     * Example to check typedef argument types
     * __API__
     * action: gen_method
     * throws: no_throw
     * return_value_policy: reference
     */
    Project* firstItemOfSpecializedStackWithTypedefArg(StackProjectType* p) {
        return p->top();
    };

    // not supported usage example
    template <typename V>
    V* firstItemOfTemplateStackNotSupported(Stack<V>* p) {
        return p->top();
    };

};

Here we have four methods to take Stack as an argument and return its first element. CppBind supports the first three methods, but you cannot generate bindings for the fourth. To generate bindings for a function taking template arguments, you must specify their full type names. The fourth one does not meet this requirement.

Note

CppBind supports types inherited from a specialized template, e.g., class TaskList: public Stack<Task>. And to generate bindings for a type inherited from a template(has CppBind API), you must specify the base type’s full name, e.g.,`` class TaskList<T>: public cppbind::example::Stack<T>``.

Generated bindings

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

package com.examples.templates

import com.examples.cppbind.alias.*
import com.examples.cppbind.exceptionUtils.*
import com.examples.cppbind.exception_helpers.*
import com.examples.getters.NumberInt
import com.examples.simple.Project
import com.examples.simple.Task

/**
 * An example of a class template.
 */
open class StackPrj
internal constructor(obj: CppBindObject) : IContainer, AutoCloseable {
    companion object {
        init {
            System.loadLibrary("wrapper_jni")
        }
        
        protected fun construct_helper(): Long {
            val id = jConstructor()
            return id
        }

        @JvmStatic
        private external fun jConstructor(): Long

        protected fun construct_helper(st: Project): Long {
            val kotlintojdkst = st.id
            val id = jConstructor_1(kotlintojdkst)
            return id
        }

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

    override fun keepCppBindReference(ref: Any) {
        refs.add(ref)
    }
    override val id: Long
        get() {
            if (cppbindObj.id == 0L) {
                throw RuntimeException("Object is not allocated")
            }
            return cppbindObj.id
        }
    
    constructor(): this(CppBindObject(construct_helper(), true)) {
    }

    constructor(st: Project): this(CppBindObject(construct_helper(st), true)) {
    }
    
    fun push(item: Project): Unit {
        val kotlintojdkitem = item.id
        val result = jPush(id, kotlintojdkitem)
        
        return result
    }

    fun pop(): Unit {
        val result = jPop(id)
        
        return result
    }

    fun top(): Project {
        val result = jTop(id)
        val jdktokotlinresult = Project(CppBindObject(result))
        return jdktokotlinresult
    }

    fun empty(): Boolean {
        val result = jEmpty(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 jPush(id: Long, item: Long): Unit
    private external fun jPop(id: Long): Unit
    private external fun jTop(id: Long): Long
    private external fun jEmpty(id: Long): Boolean
    private external fun jFinalize(id: Long): Unit
}

/**
 * An example of a class template.
 */
open class StackTask
internal constructor(obj: CppBindObject) : IContainer, AutoCloseable {
    companion object {
        init {
            System.loadLibrary("wrapper_jni")
        }
        
        protected fun construct_helper(): Long {
            val id = jConstructor()
            return id
        }

        @JvmStatic
        private external fun jConstructor(): Long

        protected fun construct_helper(st: Task): Long {
            val kotlintojdkst = st.id
            val id = jConstructor_1(kotlintojdkst)
            return id
        }

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

    override fun keepCppBindReference(ref: Any) {
        refs.add(ref)
    }
    override val id: Long
        get() {
            if (cppbindObj.id == 0L) {
                throw RuntimeException("Object is not allocated")
            }
            return cppbindObj.id
        }
    
    constructor(): this(CppBindObject(construct_helper(), true)) {
    }

    constructor(st: Task): this(CppBindObject(construct_helper(st), true)) {
    }
    
    fun push(item: Task): Unit {
        val kotlintojdkitem = item.id
        val result = jPush(id, kotlintojdkitem)
        
        return result
    }

    fun pop(): Unit {
        val result = jPop(id)
        
        return result
    }

    fun top(): Task {
        val result = jTop(id)
        val jdktokotlinresult = Task(CppBindObject(result))
        return jdktokotlinresult
    }

    fun empty(): Boolean {
        val result = jEmpty(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 jPush(id: Long, item: Long): Unit
    private external fun jPop(id: Long): Unit
    private external fun jTop(id: Long): Long
    private external fun jEmpty(id: Long): Boolean
    private external fun jFinalize(id: Long): Unit
}

/**
 * An example of a class template.
 */
open class StackNumInt
internal constructor(obj: CppBindObject) : IContainer, AutoCloseable {
    companion object {
        init {
            System.loadLibrary("wrapper_jni")
        }
        
        protected fun construct_helper(): Long {
            val id = jConstructor()
            return id
        }

        @JvmStatic
        private external fun jConstructor(): Long

        protected fun construct_helper(st: NumberInt): Long {
            val kotlintojdkst = st.id
            val id = jConstructor_1(kotlintojdkst)
            return id
        }

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

    override fun keepCppBindReference(ref: Any) {
        refs.add(ref)
    }
    override val id: Long
        get() {
            if (cppbindObj.id == 0L) {
                throw RuntimeException("Object is not allocated")
            }
            return cppbindObj.id
        }
    
    constructor(): this(CppBindObject(construct_helper(), true)) {
    }

    constructor(st: NumberInt): this(CppBindObject(construct_helper(st), true)) {
    }
    
    fun push(item: NumberInt): Unit {
        val kotlintojdkitem = item.id
        val result = jPush(id, kotlintojdkitem)
        
        return result
    }

    fun pop(): Unit {
        val result = jPop(id)
        
        return result
    }

    fun top(): NumberInt {
        val result = jTop(id)
        val jdktokotlinresult = NumberInt(CppBindObject(result))
        return jdktokotlinresult
    }

    fun empty(): Boolean {
        val result = jEmpty(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 jPush(id: Long, item: Long): Unit
    private external fun jPop(id: Long): Unit
    private external fun jTop(id: Long): Long
    private external fun jEmpty(id: Long): Boolean
    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.templates.stack as pybind_stack_pygen
import examples_lib.getters.number_pygen as getters_number_pygen
import examples_lib.simple.project_pygen as simple_project_pygen
import examples_lib.simple.task.task_pygen as simple_task_task_pygen
import examples_lib.templates.container_pygen as container_pygen
from examples_lib.cppbind.bind_utils_pygen import *
from examples_lib.cppbind.metaclass_pygen import *


class StackPrj(container_pygen.Container, metaclass=CppBindMetaclass):
    """
    An example of a class template.
    Documentation generated from: `cxx/templates/stack.hpp#L33
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/templates/stack.hpp#L33>`_
    """
    
    @bind
    def __init__(self):
        """
        Documentation generated from: `cxx/templates/stack.hpp#L42
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/templates/stack.hpp#L42>`_
        """
        pass

    @bind
    def __init__(self, st: simple_project_pygen.Project):
        """
        Documentation generated from: `cxx/templates/stack.hpp#L49
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/templates/stack.hpp#L49>`_
        """
        pass
    
    @bind
    def push(self, item: simple_project_pygen.Project) -> None:
        """
        Documentation generated from: `cxx/templates/stack.hpp#L56
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/templates/stack.hpp#L56>`_
        """
        pass

    @bind
    def pop(self) -> None:
        """
        Documentation generated from: `cxx/templates/stack.hpp#L64
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/templates/stack.hpp#L64>`_
        """
        pass

    @bind
    def top(self) -> simple_project_pygen.Project:
        """
        Documentation generated from: `cxx/templates/stack.hpp#L73
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/templates/stack.hpp#L73>`_
        """
        pass

    @bind
    def empty(self) -> bool:
        """
        Documentation generated from: `cxx/templates/stack.hpp#L81
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/templates/stack.hpp#L81>`_
        """
        pass


class StackPyTask(container_pygen.Container, metaclass=CppBindMetaclass):
    """
    An example of a class template.
    Documentation generated from: `cxx/templates/stack.hpp#L33
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/templates/stack.hpp#L33>`_
    """
    
    @bind
    def __init__(self):
        """
        Documentation generated from: `cxx/templates/stack.hpp#L42
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/templates/stack.hpp#L42>`_
        """
        pass

    @bind
    def __init__(self, st: simple_task_task_pygen.PyTask):
        """
        Documentation generated from: `cxx/templates/stack.hpp#L49
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/templates/stack.hpp#L49>`_
        """
        pass
    
    @bind
    def push(self, item: simple_task_task_pygen.PyTask) -> None:
        """
        Documentation generated from: `cxx/templates/stack.hpp#L56
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/templates/stack.hpp#L56>`_
        """
        pass

    @bind
    def pop(self) -> None:
        """
        Documentation generated from: `cxx/templates/stack.hpp#L64
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/templates/stack.hpp#L64>`_
        """
        pass

    @bind
    def top(self) -> simple_task_task_pygen.PyTask:
        """
        Documentation generated from: `cxx/templates/stack.hpp#L73
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/templates/stack.hpp#L73>`_
        """
        pass

    @bind
    def empty(self) -> bool:
        """
        Documentation generated from: `cxx/templates/stack.hpp#L81
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/templates/stack.hpp#L81>`_
        """
        pass


class StackNumInt(container_pygen.Container, metaclass=CppBindMetaclass):
    """
    An example of a class template.
    Documentation generated from: `cxx/templates/stack.hpp#L33
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/templates/stack.hpp#L33>`_
    """
    
    @bind
    def __init__(self):
        """
        Documentation generated from: `cxx/templates/stack.hpp#L42
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/templates/stack.hpp#L42>`_
        """
        pass

    @bind
    def __init__(self, st: getters_number_pygen.NumberInt):
        """
        Documentation generated from: `cxx/templates/stack.hpp#L49
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/templates/stack.hpp#L49>`_
        """
        pass
    
    @bind
    def push(self, item: getters_number_pygen.NumberInt) -> None:
        """
        Documentation generated from: `cxx/templates/stack.hpp#L56
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/templates/stack.hpp#L56>`_
        """
        pass

    @bind
    def pop(self) -> None:
        """
        Documentation generated from: `cxx/templates/stack.hpp#L64
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/templates/stack.hpp#L64>`_
        """
        pass

    @bind
    def top(self) -> getters_number_pygen.NumberInt:
        """
        Documentation generated from: `cxx/templates/stack.hpp#L73
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/templates/stack.hpp#L73>`_
        """
        pass

    @bind
    def empty(self) -> bool:
        """
        Documentation generated from: `cxx/templates/stack.hpp#L81
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/templates/stack.hpp#L81>`_
        """
        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 of a class template.
 */
public class StackPrj: Container {

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

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

  public convenience init() {
    var cppbindErr = CppBindCObject()
    self.init(create_CppbindExample_StackPrj(&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 convenience init(st: Project) {
    let swifttoscst = st.cself
    var cppbindErr = CppBindCObject()
    self.init(create_CppbindExample_StackPrj_1(swifttoscst, &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 func push(item: Project) -> Void {

    let swifttoscitem = item.cself
    var cppbindErr = CppBindCObject()
    _func_CppbindExample_StackPrj_push(cself, swifttoscitem, &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 func pop() -> Void {

    var cppbindErr = CppBindCObject()
    _func_CppbindExample_StackPrj_pop(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")
      }
    }
  }

  public func top() -> Project {

    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExample_StackPrj_top(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: Project
    sctoswiftresult = Project(result)
    return sctoswiftresult
  }

  public func empty() -> Bool {

    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExample_StackPrj_empty(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")
      }
    }
    return result
  }

  class var cppbindCxxTypeName : String { return "cppbind::example::Stack<cppbind::example::Project>" }
}

/**
 * An example of a class template.
 */
public class StackTask: Container {

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

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

  public convenience init() {
    var cppbindErr = CppBindCObject()
    self.init(create_CppbindExample_StackTask(&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 convenience init(st: Task) {
    let swifttoscst = st.cself
    var cppbindErr = CppBindCObject()
    self.init(create_CppbindExample_StackTask_1(swifttoscst, &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 func push(item: Task) -> Void {

    let swifttoscitem = item.cself
    var cppbindErr = CppBindCObject()
    _func_CppbindExample_StackTask_push(cself, swifttoscitem, &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 func pop() -> Void {

    var cppbindErr = CppBindCObject()
    _func_CppbindExample_StackTask_pop(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")
      }
    }
  }

  public func top() -> Task {

    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExample_StackTask_top(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: Task
    sctoswiftresult = Task(result)
    return sctoswiftresult
  }

  public func empty() -> Bool {

    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExample_StackTask_empty(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")
      }
    }
    return result
  }

  class var cppbindCxxTypeName : String { return "cppbind::example::Stack<cppbind::example::Task>" }
}

/**
 * An example of a class template.
 */
public class StackNumInt: Container {

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

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

  public convenience init() {
    var cppbindErr = CppBindCObject()
    self.init(create_CppbindExample_StackNumInt(&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 convenience init(st: NumberInt) {
    let swifttoscst = st.cself
    var cppbindErr = CppBindCObject()
    self.init(create_CppbindExample_StackNumInt_1(swifttoscst, &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 func push(item: NumberInt) -> Void {

    let swifttoscitem = item.cself
    var cppbindErr = CppBindCObject()
    _func_CppbindExample_StackNumInt_push(cself, swifttoscitem, &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 func pop() -> Void {

    var cppbindErr = CppBindCObject()
    _func_CppbindExample_StackNumInt_pop(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")
      }
    }
  }

  public func top() -> NumberInt {

    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExample_StackNumInt_top(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: NumberInt
    sctoswiftresult = NumberInt(result)
    return sctoswiftresult
  }

  public func empty() -> Bool {

    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExample_StackNumInt_empty(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")
      }
    }
    return result
  }

  class var cppbindCxxTypeName : String { return "cppbind::example::Stack<cppbind::example::Number<int>>" }
}

Template Getters/Setters

Now let’s see how the name is used for template getters/setters.

/**
 * __API__
 * action: gen_enum
 * package: getters
 */
enum class FruitType {
    Apple = 1,
    Pineapple = 2,
};


/**
 * __API__
 * action: gen_class
 * package: getters
 */
struct Fruit  {

    Fruit() {};

    /**
     * __API__
     * action: gen_getter
     * throws: no_throw
     */
    virtual FruitType type() const = 0;

    virtual ~Fruit() = default;
};


/**
 * __API__
 * action: gen_class
 * package: getters
 */
struct Apple : public Fruit  {

    /**
     * __API__
     * action: gen_constructor
     * throws: no_throw
     */
    Apple() : Fruit() {};

    /**
     * __API__
     * action: gen_getter
     * throws: no_throw
     */
    FruitType type() const override {
        return FruitType::Apple;
    }

    static const FruitType Type = FruitType::Apple;
};

/**
 * __API__
 * action: gen_class
 * package: getters
 */
struct Pineapple : public Fruit  {

    /**
     * __API__
     * action: gen_constructor
     * throws: no_throw
     */
    Pineapple() : Fruit() {};

    /**
     * __API__
     * action: gen_getter
     * throws: no_throw
     */
    FruitType type() const override {
        return FruitType::Pineapple;
    }
    static const FruitType Type = FruitType::Pineapple;

};

/**
 * An example class containing template getters.
 * __API__
 * action: gen_class
 * package: getters
 */
class Fruits  {
    public:
    /**
     * __API__
     * action: gen_constructor
     * throws: no_throw
     */
    Fruits(const std::vector<Fruit*>& fruits) : _fruits(fruits) {};

    /**
     * __API__
     * action: gen_getter
     * throws: no_throw
     * template:
     *   T:
     *     - type: cppbind::example::Apple
     *       name: apples
     *     - type: cppbind::example::Pineapple
     *       name: pineapple
     */
    template <typename T>
    std::vector<T*> fruits() const {
        std::vector<T*> res;
        std::for_each(_fruits.begin(), _fruits.end(), [&res](const auto& f) {
            if (f->type() == T::Type) {
                res.push_back(static_cast<T*>(f));
            }
        });
        return res;
    }

    /**
     * __API__
     * action: gen_getter
     * throws: no_throw
     * template:
     *   T:
     *     - type: cppbind::example::Apple
     *       name: applesWith
     *   U:
     *     - type: cppbind::example::Pineapple
     *       name: Pineapples
     */
    template <typename T, typename U>
    const std::vector<Fruit*> & allFruits() const {
        return _fruits;
    }

    /**
     * __API__
     * action: gen_setter
     * throws: no_throw
     * template:
     *   T:
     *     - type: cppbind::example::Apple
     *   U:
     *     - type: cppbind::example::Pineapple
     */
    template <typename T, typename U>
    void setAllFruits(const std::vector<Fruit*> & fruits) {
        _fruits = fruits;
    }


private:
    std::vector<Fruit*> _fruits;
};

In the above example, we have a template getter fruits, and we have specified two possible types for parameter T: cppbind::example::Apple and cppbind::example::Pineapple. Notice that the name is specified for both, which is used as a generated property name. As a result, we’ll have apple and pineapple correspondingly. If name is not specified, then the target language type name is used. For this example, we would have Apple and Pineapple correspondingly. In the above example, we have another template getter/setter, allFruits with two template parameters, T and U. Again, we have specified name for both parameters. In the case of multiple template parameters, target property name is constructed by joining user-provided names. For this example, it is applesWithPineapples for Kotlin and Swift, apples_with_pineapples for Python. Notice that the name is snake-cased for Python. The API for this getter could also be written in the following way:

T:
  - type: cppbind::example::Apple
    name: applesWithPineapples
U:
  - type: cppbind::example::Pineapple

The result will be the same.

If the name is not specified, the target property name is constructed by joining the names of target language types. For this example, we would have applePineapple (Swift, Kotlin) and apple_pineapple (Python).

And here are some usage examples:

val apple1 = Apple()
val apple2 = Apple()
val papple1 = Pineapple()
val papple2 = Pineapple()
val fruits = Fruits(listOf(apple1, apple2, papple1, papple2))

assert(fruits.apples.size == 2)
assert(fruits.pineapple.size == 2)
var applesPineapples = fruits.applesWithPineapples
assert(applesPineapples.size == 4)
fruits.applesWithPineapples = listOf(papple1, papple2, apple1, apple2)
applesPineapples = fruits.applesWithPineapples
assert(applesPineapples[0].type == FruitType.Pineapple)
assert(applesPineapples[3].type == FruitType.Apple)
apple1 = Apple()
apple2 = Apple()
papple1 = Pineapple()
papple2 = Pineapple()
fruits = Fruits([apple1, apple2, papple1, papple2])

assert len(fruits.apples) == 2
assert len(fruits.pineapple) == 2
apples_pineapples = fruits.apples_with_pineapples
assert len(apples_pineapples) == 4
fruits.apples_with_pineapples = [papple1, papple2, apple1, apple2]
apples_pineapples = fruits.apples_with_pineapples
assert apples_pineapples[0].type == FruitType.Pineapple
assert apples_pineapples[3].type == FruitType.Apple
let apple1 = Apple()
let apple2 = Apple()
let papple1 = Pineapple()
let papple2 = Pineapple()
let fruits = Fruits(fruits: [apple1, apple2, papple1, papple2])

assert(fruits.apples.count == 2)
assert(fruits.pineapple.count == 2)
var applesPineapples = fruits.applesWithPineapples
assert(applesPineapples.count == 4)
fruits.applesWithPineapples = [papple1, papple2, apple1, apple2]
applesPineapples = fruits.applesWithPineapples
assert(applesPineapples[0].type == FruitType.Pineapple)
assert(applesPineapples[3].type == FruitType.Apple)
Generated bindings for the target languages

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

package com.examples.getters

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

enum class FruitType(val value: Int) {
    Apple(1),
    Pineapple(2);

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

open class Fruit
internal constructor(obj: CppBindObject) : AutoCloseable {
    companion object {
        init {
            System.loadLibrary("wrapper_jni")
        }
        
        const val cppbindCxxTypeName: String = "cppbind::example::Fruit"

        public fun cppbindConstructObject(id: Long, owner: Boolean = false): Fruit {
            val idType = jGettypebyid(id)
            when (idType) {
                Apple.cppbindCxxTypeName -> return Apple(CppBindObject(id, owner))
                Pineapple.cppbindCxxTypeName -> return Pineapple(CppBindObject(id, owner))
                else -> return Fruit(CppBindObject(id, owner))
            }
        }
    }
    
    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
        }
    
    open val type: FruitType
        get() {
            val result = jType(id)
            val jdktokotlinresult_optional = FruitType.getByValue(result)
            if (jdktokotlinresult_optional == null) {
                ExceptionHandler.handleUncaughtException("Internal error: unresolved reference to non existing field of FruitType enum.")
            }
            val jdktokotlinresult = jdktokotlinresult_optional!!
            return jdktokotlinresult
        }

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

open class Apple
internal constructor(obj: CppBindObject) : Fruit(obj) {
    companion object {
        
        protected fun construct_helper(): Long {
            val id = jConstructor()
            return id
        }

        @JvmStatic
        private external fun jConstructor(): Long
        const val cppbindCxxTypeName: String = "cppbind::example::Apple"
    }
    
    
    constructor(): this(CppBindObject(construct_helper(), true)) {
    }
    
    open override val type: FruitType
        get() {
            val result = jType(id)
            val jdktokotlinresult_optional = FruitType.getByValue(result)
            if (jdktokotlinresult_optional == null) {
                ExceptionHandler.handleUncaughtException("Internal error: unresolved reference to non existing field of FruitType enum.")
            }
            val jdktokotlinresult = jdktokotlinresult_optional!!
            return jdktokotlinresult
        }

    ///// External wrapper functions ////////////
    private external fun jType(id: Long): Int
}

open class Pineapple
internal constructor(obj: CppBindObject) : Fruit(obj) {
    companion object {
        
        protected fun construct_helper(): Long {
            val id = jConstructor()
            return id
        }

        @JvmStatic
        private external fun jConstructor(): Long
        const val cppbindCxxTypeName: String = "cppbind::example::Pineapple"
    }
    
    
    constructor(): this(CppBindObject(construct_helper(), true)) {
    }
    
    open override val type: FruitType
        get() {
            val result = jType(id)
            val jdktokotlinresult_optional = FruitType.getByValue(result)
            if (jdktokotlinresult_optional == null) {
                ExceptionHandler.handleUncaughtException("Internal error: unresolved reference to non existing field of FruitType enum.")
            }
            val jdktokotlinresult = jdktokotlinresult_optional!!
            return jdktokotlinresult
        }

    ///// External wrapper functions ////////////
    private external fun jType(id: Long): Int
}

/**
 * An example class containing template getters.
 */
open class Fruits
internal constructor(obj: CppBindObject) : AutoCloseable {
    companion object {
        init {
            System.loadLibrary("wrapper_jni")
        }
        
        protected fun construct_helper(fruits: List<Fruit>): Long {
            val kotlintojdkfruits = LongArray(fruits.size) 
            var index_fruits = 0
            for (value_fruits in fruits) {
                val kotlintojdkvalue_fruits = value_fruits.id
                kotlintojdkfruits[index_fruits] = kotlintojdkvalue_fruits
                ++index_fruits
            }
            val id = jConstructor(kotlintojdkfruits)
            return id
        }

        @JvmStatic
        private external fun jConstructor(fruits: LongArray): Long
        const val cppbindCxxTypeName: String = "cppbind::example::Fruits"
    }
    
    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(fruits: List<Fruit>): this(CppBindObject(construct_helper(fruits), true)) {
    }
    
    open val apples: List<Apple>
        get() {
            val result = jFruitsApple(id)
            val jdktokotlinresult: MutableList<Apple> = mutableListOf()
            for (value_result in result) {
                val jdktokotlinvalue_result = Apple(CppBindObject(value_result))
                jdktokotlinresult.add(jdktokotlinvalue_result)
            }
            return jdktokotlinresult
        }

    open val pineapple: List<Pineapple>
        get() {
            val result = jFruitsPineapple(id)
            val jdktokotlinresult: MutableList<Pineapple> = mutableListOf()
            for (value_result in result) {
                val jdktokotlinvalue_result = Pineapple(CppBindObject(value_result))
                jdktokotlinresult.add(jdktokotlinvalue_result)
            }
            return jdktokotlinresult
        }

    open var applesWithPineapples: List<Fruit>
        get() {
            val result = jAllfruitsApplePineapple(id)
            val jdktokotlinresult: MutableList<Fruit> = mutableListOf()
            for (value_result in result) {
                
                val jdktokotlinvalue_result : Fruit
                jdktokotlinvalue_result = Fruit.cppbindConstructObject(value_result)
                jdktokotlinresult.add(jdktokotlinvalue_result)
            }
            for (valuejdktokotlinresult in jdktokotlinresult) {
                valuejdktokotlinresult.keepCppBindReference(this)
            }
            return jdktokotlinresult
        }
        set(value) {
            val kotlintojdkvalue = LongArray(value.size) 
            var index_value = 0
            for (value_value in value) {
                val kotlintojdkvalue_value = value_value.id
                kotlintojdkvalue[index_value] = kotlintojdkvalue_value
                ++index_value
            }
            jSetallfruitsApplePineapple(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 jFruitsApple(id: Long): LongArray
    private external fun jFruitsPineapple(id: Long): LongArray
    private external fun jAllfruitsApplePineapple(id: Long): LongArray
    private external fun jSetallfruitsApplePineapple(id: Long, value: LongArray): Unit
    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 abc import abstractmethod
from typing import *

import examples.getters.fruits as pybind_fruits_pygen
from examples_lib.cppbind.bind_utils_pygen import *
from examples_lib.cppbind.metaclass_pygen import *


class FruitType(metaclass=CppBindEnumMetaclass):
    """
    Documentation generated from: `cxx/getters/fruits.hpp#L16
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/getters/fruits.hpp#L16>`_
    """
    Apple = pybind_fruits_pygen.FruitType.Apple
    Pineapple = pybind_fruits_pygen.FruitType.Pineapple

    def __int__(self):
        return self.value


class Fruit(metaclass=CppBindMetaclass):
    """
    Documentation generated from: `cxx/getters/fruits.hpp#L27
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/getters/fruits.hpp#L27>`_
    """
    @abstractmethod
    def __init__(self, *args, **kwargs):
        pass
    
    @property
    @bind
    def type(self) -> FruitType:
        """
        Documentation generated from: `cxx/getters/fruits.hpp#L36
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/getters/fruits.hpp#L36>`_
        """
        pass


class Apple(Fruit, metaclass=CppBindMetaclass):
    """
    Documentation generated from: `cxx/getters/fruits.hpp#L47
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/getters/fruits.hpp#L47>`_
    """
    
    @bind
    def __init__(self):
        """
        Documentation generated from: `cxx/getters/fruits.hpp#L54
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/getters/fruits.hpp#L54>`_
        """
        pass
    
    @property
    @bind
    def type(self) -> FruitType:
        """
        Documentation generated from: `cxx/getters/fruits.hpp#L61
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/getters/fruits.hpp#L61>`_
        """
        pass


class Pineapple(Fruit, metaclass=CppBindMetaclass):
    """
    Documentation generated from: `cxx/getters/fruits.hpp#L73
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/getters/fruits.hpp#L73>`_
    """
    
    @bind
    def __init__(self):
        """
        Documentation generated from: `cxx/getters/fruits.hpp#L80
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/getters/fruits.hpp#L80>`_
        """
        pass
    
    @property
    @bind
    def type(self) -> FruitType:
        """
        Documentation generated from: `cxx/getters/fruits.hpp#L87
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/getters/fruits.hpp#L87>`_
        """
        pass


class Fruits(metaclass=CppBindMetaclass):
    """
    An example class containing template getters.
    Documentation generated from: `cxx/getters/fruits.hpp#L100
    <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/getters/fruits.hpp#L100>`_
    """
    
    @bind
    def __init__(self, fruits: List[Fruit]):
        """
        Documentation generated from: `cxx/getters/fruits.hpp#L107
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/getters/fruits.hpp#L107>`_
        """
        pass
    
    @property
    @bind
    def apples(self) -> List[Apple]:
        """
        Documentation generated from: `cxx/getters/fruits.hpp#L120
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/getters/fruits.hpp#L120>`_
        """
        pass

    @property
    @bind
    def pineapple(self) -> List[Pineapple]:
        """
        Documentation generated from: `cxx/getters/fruits.hpp#L120
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/getters/fruits.hpp#L120>`_
        """
        pass

    @property
    @bind
    def apples_with_pineapples(self) -> List[Fruit]:
        """
        Documentation generated from: `cxx/getters/fruits.hpp#L143
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/getters/fruits.hpp#L143>`_
        """
        pass

    @apples_with_pineapples.setter
    @bind
    def apples_with_pineapples(self, value: List[Fruit]):
        """
        Documentation generated from: `cxx/getters/fruits.hpp#L143
        <https://github.com/PicsArt/cppbind/tree/master/examples/primitives/cxx/getters/fruits.hpp#L143>`_
        """
        pass
/**
 *   ______ .______   .______   .______    __  .__   __.  _______  
 *  /      ||   _  \  |   _  \  |   _  \  |  | |  \ |  | |       \ 
 * |  ,----'|  |_)  | |  |_)  | |  |_)  | |  | |   \|  | |  .--.  |
 * |  |     |   ___/  |   ___/  |   _  <  |  | |  . `  | |  |  |  |
 * |  `----.|  |      |  |      |  |_)  | |  | |  |\   | |  '--'  |
 *  \______|| _|      | _|      |______/  |__| |__| \__| |_______/ 
 * 
 * This file is generated by cppbind on 05/12/2022-10:26.
 * Please do not change it manually.
 */

import CWrapper
import Foundation

public enum FruitType: CInt {
  case Apple = 1
  case Pineapple = 2
}

public class Fruit {

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

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

  /// internal dummy initializer to prevent automatic initializer inheritance
  internal init(_cself: CppBindCObject, _self: Fruit) {
    fatalError("A dummy internal initializer should not be called.")
  }

  public var type: FruitType {
    var cppbindErr = CppBindCObject()
    let result = _prop_get_CppbindExample_Fruit_type(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")
      }
    }
    guard let sctoswiftresult = FruitType(rawValue: result) else {
       ExceptionHandler.handleUncaughtException(
          "Internal error: unresolved reference to non existing field of FruitType enum.")
    }
    return sctoswiftresult
  }

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

  class func cppbindConstructObject(_ cppbindObj: CppBindCObject, _ owner: Bool = false) -> Fruit {
    let typeName = String(cString: cppbindObj.type)
    switch(typeName) {
    case(Apple.cppbindCxxTypeName):
      return Apple(cppbindObj, owner)
    case(Pineapple.cppbindCxxTypeName):
      return Pineapple(cppbindObj, owner)
    default:
      return Fruit(cppbindObj, owner)
    }
  }
}

public class Apple: Fruit {
  /// internal main initializer
  internal required init(_ _cself: CppBindCObject, _ _owner: Bool = false) {
    super.init(_cself, _owner)
  }

  public convenience init() {
    var cppbindErr = CppBindCObject()
    self.init(create_CppbindExample_Apple(&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 override var type: FruitType {
    var cppbindErr = CppBindCObject()
    let result = _prop_get_CppbindExample_Apple_type(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")
      }
    }
    guard let sctoswiftresult = FruitType(rawValue: result) else {
       ExceptionHandler.handleUncaughtException(
          "Internal error: unresolved reference to non existing field of FruitType enum.")
    }
    return sctoswiftresult
  }

  override class var cppbindCxxTypeName : String { return "cppbind::example::Apple" }
}

public class Pineapple: Fruit {
  /// internal main initializer
  internal required init(_ _cself: CppBindCObject, _ _owner: Bool = false) {
    super.init(_cself, _owner)
  }

  public convenience init() {
    var cppbindErr = CppBindCObject()
    self.init(create_CppbindExample_Pineapple(&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 override var type: FruitType {
    var cppbindErr = CppBindCObject()
    let result = _prop_get_CppbindExample_Pineapple_type(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")
      }
    }
    guard let sctoswiftresult = FruitType(rawValue: result) else {
       ExceptionHandler.handleUncaughtException(
          "Internal error: unresolved reference to non existing field of FruitType enum.")
    }
    return sctoswiftresult
  }

  override class var cppbindCxxTypeName : String { return "cppbind::example::Pineapple" }
}

/**
 * An example class containing template getters.
 */
public class Fruits {

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

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

  public convenience init(fruits: Array<Fruit>) {
    let _swifttoscfruitsData = UnsafeMutablePointer<CppBindCObject>.allocate(capacity: fruits.count)
    var swifttoscfruits = CppBindCDataArray()
    swifttoscfruits.data = UnsafeMutableRawPointer(_swifttoscfruitsData)
    swifttoscfruits.size = Int64(fruits.count)
    for i in 0..<fruits.count {
      let fruitsVal = fruits[i]
      let swifttoscfruitsVal = fruitsVal.cself
      _swifttoscfruitsData[i] = swifttoscfruitsVal
    }
    var cppbindErr = CppBindCObject()
    self.init(create_CppbindExample_Fruits(swifttoscfruits, &cppbindErr), true)
    
    swifttoscfruits.data.deallocate()
    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 apples: Array<Apple> {
    var cppbindErr = CppBindCObject()
    let result = _prop_get_CppbindExample_Fruits_fruitsApple(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")
      }
    }
    let _resultBuffer = UnsafeBufferPointer<CppBindCObject>(
      start: result.data.assumingMemoryBound(to: CppBindCObject.self),
      count: Int(result.size))
    var sctoswiftresult: [Apple] = []
    defer {
      _resultBuffer.deallocate()
    }
    for i in 0..<Int(result.size) {
      let resultValue = _resultBuffer[i]
      var sctoswiftresultValue: Apple
      sctoswiftresultValue = Apple(resultValue)
      sctoswiftresult.append(sctoswiftresultValue)
    }
    return sctoswiftresult
  }

  public var pineapple: Array<Pineapple> {
    var cppbindErr = CppBindCObject()
    let result = _prop_get_CppbindExample_Fruits_fruitsPineapple(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")
      }
    }
    let _resultBuffer = UnsafeBufferPointer<CppBindCObject>(
      start: result.data.assumingMemoryBound(to: CppBindCObject.self),
      count: Int(result.size))
    var sctoswiftresult: [Pineapple] = []
    defer {
      _resultBuffer.deallocate()
    }
    for i in 0..<Int(result.size) {
      let resultValue = _resultBuffer[i]
      var sctoswiftresultValue: Pineapple
      sctoswiftresultValue = Pineapple(resultValue)
      sctoswiftresult.append(sctoswiftresultValue)
    }
    return sctoswiftresult
  }

  public var applesWithPineapples: Array<Fruit> {
    get {
      var cppbindErr = CppBindCObject()
      let result = _prop_get_CppbindExample_Fruits_allFruitsApplePineapple(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")
        }
      }
      let _resultBuffer = UnsafeBufferPointer<CppBindCObject>(
        start: result.data.assumingMemoryBound(to: CppBindCObject.self),
        count: Int(result.size))
      var sctoswiftresult: [Fruit] = []
      defer {
        _resultBuffer.deallocate()
      }
      for i in 0..<Int(result.size) {
        let resultValue = _resultBuffer[i]
        var sctoswiftresultValue: Fruit
        sctoswiftresultValue = Fruit.cppbindConstructObject(resultValue)
        sctoswiftresult.append(sctoswiftresultValue)
      }
      for valuesctoswiftresult in sctoswiftresult {
        valuesctoswiftresult.keepCppBindReference(self)
      }
      return sctoswiftresult
    }

    set(value) {
      let _swifttoscvalueData = UnsafeMutablePointer<CppBindCObject>.allocate(capacity: value.count)
      var swifttoscvalue = CppBindCDataArray()
      swifttoscvalue.data = UnsafeMutableRawPointer(_swifttoscvalueData)
      swifttoscvalue.size = Int64(value.count)
      for i in 0..<value.count {
        let valueVal = value[i]
        let swifttoscvalueVal = valueVal.cself
        _swifttoscvalueData[i] = swifttoscvalueVal
      }
      var cppbindErr = CppBindCObject()
      _prop_set_CppbindExample_Fruits_allFruitsApplePineapple(cself, swifttoscvalue, &cppbindErr)
      
      swifttoscvalue.data.deallocate()
      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")
        }
      }
    }
  }

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