Skip to content

Operator overloading

This section covers an example of overloading arithmetic and comparison operators. CppBind will generate appropriate operators for target languages by default. If the target language does not allow some of the operators to be overloaded or we don't want them to be overloaded in target languages, we can set the is_operator variable to False. In this case, we must specify the name variable so that CppBind will use it to generate a function with that name.

/**
 * An example for with overloaded methods.
 * __API__
 * action: gen_class
 * package: operators
 */
class Counter {
public:
    /**
     * Counter constructor.
     * __API__
     * action: gen_constructor
     * throws: no_throw
     */
    Counter(int count) : _count(count) {}

    Counter(const Counter& c) {
        _count = c.count();
    }

    /**
     * Getter for count.
     * __API__
     * action: gen_getter
     * throws: no_throw
     */
    int count() const {
        return _count;
    }

    /**
     * Plus operator
     * __API__
     * action: gen_method
     * throws: no_throw
     */
    Counter operator+(const Counter& counter) {
        return Counter(_count + counter.count());
    }

    /**
     * Comparison operator for kotlin
     * __API__
     * kotlin.action: gen_method
     * kotlin.is_operator: True
     * kotlin.name: compareTo
     * throws: no_throw
     */
    int compareTo(const Counter& counter) {
        if (_count > counter.count()) return 1;
        else if (_count < counter.count()) return -1;
        else return 0;
    }

    /**
     * __API__
     * python.action: gen_method
     * swift.action: gen_method
     * throws: no_throw
     */
    bool operator>(const Counter& counter) {
        return _count > counter.count();
    }

    /**
     * __API__
     * python.action: gen_method
     * swift.action: gen_method
     * throws: no_throw
     * return_value_policy: reference
     */
    Counter& operator +=(const Counter& counter) {
        this->_count += counter.count();
        return *this;
    }

   /**
    * Equality operator
    * __API__
    * action: gen_method
    * throws: no_throw
    */
    bool operator == (const Counter& counter) {
       return this->_count == counter.count();
    }

private:
    int _count;
};

Note

All comparisons in Kotlin are translated into calls to compareTo, that is required to return Int. That's why we have compareTo method in C++ with kotlin.is_operator variable set to True (this is mandatory as compareTo is not a C++ operator and by default, is_operator is False for it). Also notice we didn't specify Kotlin instruction for operator>.

Note

We have specifed binding instructions .action: gen_method for operator+= only for Python and Swift. In Kotlin, the signature of operator operator+= is different, it is covered by operator+. Therefore, we specify instructions for generating only operator+ for Kotlin.

And the usage example:

var counter1 = Counter(1)
var counter2 = Counter(2)
var counter = counter1 + counter2
assert(counter.count == 3)
counter += counter1
assert(counter.count == 4)
assert(counter1 < counter2)
assert(counter1 <= counter2)
assert(counter2 > counter1)
assert(counter2 >= counter1)
counter1 = Counter(1)
counter2 = Counter(2)
counter = counter1 + counter2
assert counter.count == 3
assert counter1 < counter2
assert counter2 > counter1
counter1 += counter2
assert counter1.count == 3
let counter1 = Counter(count: 1)
let counter2 = Counter(count: 2)
let counter = counter1 + counter2
assert(counter.count == 3)
assert(counter2 > counter1)
counter1 += counter2
assert(counter1.count == 3)
assert(counter1 > counter2)
Generated operators for target languages
/**
 *   ______ .______   .______   .______    __  .__   __.  _______  
 *  /      ||   _  \  |   _  \  |   _  \  |  | |  \ |  | |       \ 
 * |  ,----'|  |_)  | |  |_)  | |  |_)  | |  | |   \|  | |  .--.  |
 * |  |     |   ___/  |   ___/  |   _  <  |  | |  . `  | |  |  |  |
 * |  `----.|  |      |  |      |  |_)  | |  | |  |\   | |  '--'  |
 *  \______|| _|      | _|      |______/  |__| |__| \__| |_______/ 
 * 
 * This file is generated by cppbind on 08/18/2022-11:02.
 * Please do not change it manually.
 */

package com.examples.operators

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

/**
 * An example for with overloaded methods.
 */
open class Counter
internal constructor(obj: CppBindObject) : AutoCloseable {
    companion object {
        init {
            System.loadLibrary("wrapper_jni")
        }

        /**
         * Counter constructor.
         */
        protected fun constructHelper(count: Int): Long {
            val id = jConstructor(count)
            return id
        }

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

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

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

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

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

    /**
     * Counter constructor.
     */
    constructor(count: Int): this(CppBindObject(constructHelper(count), true)) {
    }

    /**
     * Getter for count.
     */
    val count: Int
        get() {
            val result = jCount(cppbindObjId)

            return result
        }

    /**
     * Plus operator
     */
    operator fun plus(counter: Counter): Counter {
        val kotlintojdkcounter = counter.cppbindObjId
        val result = jPlus(cppbindObjId, kotlintojdkcounter, counter)
        val jdktokotlinresult = Counter(CppBindObject(result, true))
        return jdktokotlinresult
    }

    /**
     * Comparison operator for kotlin
     */
    operator fun compareTo(counter: Counter): Int {
        val kotlintojdkcounter = counter.cppbindObjId
        val result = jCompareto(cppbindObjId, kotlintojdkcounter, counter)

        return result
    }

    /**
     * Equality operator
     */
    override fun equals(other: Any?): Boolean {
        other as Counter
        return jEquals(cppbindObjId, other.cppbindObjId, other)
    }

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

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

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

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

    ///// External wrapper functions ////////////
    private external fun jCount(id: Long): Int
    private external fun jPlus(id: Long, counter: Long, vararg extraObjs: Any?): Long
    private external fun jCompareto(id: Long, counter: Long, vararg extraObjs: Any?): Int
    private external fun jEquals(id: Long, counter: Long, vararg extraObjs: Any?): Boolean
    private external fun jFinalize(id: Long): Unit
    private external fun jGetcxxid(id: Long): Long
}

/**
 * A class example to the case when non-operator method is mapped to == operator
 */
open class PositiveCounter
internal constructor(obj: CppBindObject) : AutoCloseable {
    companion object {
        init {
            System.loadLibrary("wrapper_jni")
        }

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

        @JvmStatic
        private external fun jConstructor(count: Int, vararg extraObjs: Any?): Long

        protected fun constructHelper(counts: List<Int>): Long {
            val kotlintojdkcounts = IntArray(counts.size) 
            var indexCounts = 0
            for (valueCounts in counts) {

                kotlintojdkcounts[indexCounts] = valueCounts
                ++indexCounts
            }
            val id = jConstructor1(kotlintojdkcounts, counts)
            return id
        }

        @JvmStatic
        private external fun jConstructor1(counts: IntArray, vararg extraObjs: Any?): Long
        /**
         * An internal property to keep an information about the underlying C++ object type.
         * It is intended to be used by the generated code.
         */
        const val cppbindCxxTypeName: String = "cppbind::example::PositiveCounter"
    }

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

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

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

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

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

    constructor(counts: List<Int>): this(CppBindObject(constructHelper(counts), true)) {
    }

    override fun equals(other: Any?): Boolean {
        other as PositiveCounter
        return jEquals(cppbindObjId, other.cppbindObjId, other)
    }

    operator fun get(i: Int): Int {
        val result = jGet(cppbindObjId, i)

        return result
    }


    operator fun set(i: Int, value: Int){
        jSet(cppbindObjId, i, value)
    }

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

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

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

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

    ///// External wrapper functions ////////////
    private external fun jEquals(id: Long, other: Long, vararg extraObjs: Any?): Boolean
    private external fun jGet(id: Long, i: Int, vararg extraObjs: Any?): Int
    private external fun jSet(id: Long, i: Int, value: Int, vararg extraObjs: Any?)
    private external fun jFinalize(id: Long): Unit
    private external fun jGetcxxid(id: Long): Long
}

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

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

from typing import *

import examples.operators.counter as pybind_counter_pygen
from examples_lib.cppbind.cppbind_metaclass_pygen import *
from examples_lib.cppbind.cppbind_utils_pygen import *


class Counter(metaclass=CppBindMetaclass):
    """
    An example for with overloaded methods.
    """

    @bind
    def __init__(self, count: int):
        """
        Counter constructor.
        """
        pass

    @property
    @bind
    def count(self) -> int:
        """
        Getter for count.
        """
        pass

    @bind
    def __add__(self, counter: Counter) -> Counter:
        """
        Plus operator
        """
        pass

    @bind
    def __gt__(self, counter: Counter) -> bool:

        pass

    @bind
    def __iadd__(self, counter: Counter) -> Counter:

        pass

    @bind
    def __eq__(self, counter: Counter) -> bool:
        """
        Equality operator
        """
        pass

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


class PositiveCounter(metaclass=CppBindMetaclass):
    """
    A class example to the case when non-operator method is mapped to == operator
    """

    @bind
    def __init__(self, count: int):

        pass

    @bind
    def __init__(self, counts: List[int]):

        pass

    @bind
    def __eq__(self, other: PositiveCounter) -> bool:

        pass

    @bind
    def __getitem__(self, i: int) -> int:

        pass

    @bind
    def __setitem__(self, i: int, value: int):

        pass

    @bind
    def __repr__(self) -> str:
        """
        CppBind generated __repr__ method returning underlying C++ object type and id.
        """
        pass
/**
 *   ______ .______   .______   .______    __  .__   __.  _______  
 *  /      ||   _  \  |   _  \  |   _  \  |  | |  \ |  | |       \ 
 * |  ,----'|  |_)  | |  |_)  | |  |_)  | |  | |   \|  | |  .--.  |
 * |  |     |   ___/  |   ___/  |   _  <  |  | |  . `  | |  |  |  |
 * |  `----.|  |      |  |      |  |_)  | |  | |  |\   | |  '--'  |
 *  \______|| _|      | _|      |______/  |__| |__| \__| |_______/ 
 * 
 * This file is generated by cppbind on 08/14/2022-10:58.
 * Please do not change it manually.
 */

import CWrapper
import Foundation

/// An example for with overloaded methods.
public class Counter {

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

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

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

  deinit {
    release_CppbindExample_Counter(cself, owner)
  }

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

  /// Counter constructor.
  public convenience init(count: Int) {
    let swifttosccount = CInt(count)
    var cppbindErr = CppBindCObject()
    self.init(create_CppbindExample_Counter(swifttosccount, &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")
      }
    }
  }

  /// Getter for count.
  public var count: Int {
    var cppbindErr = CppBindCObject()
    let result = _prop_get_CppbindExample_Counter_count(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 sctoswiftresult = Int(result)
    return sctoswiftresult
  }

  /// Plus operator
  public static func +(cself: Counter, counter: Counter) -> Counter {
    let swifttosccounter = counter.cself
    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExample_Counter__add_(cself.cself, swifttosccounter, &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: Counter
    sctoswiftresult = Counter(result, true)
    return sctoswiftresult
  }

  public static func >(cself: Counter, counter: Counter) -> Bool {
    let swifttosccounter = counter.cself
    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExample_Counter__gt_(cself.cself, swifttosccounter, &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
  }

  public static func +=(cself: Counter, counter: Counter) -> Counter {
    let swifttosccounter = counter.cself
    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExample_Counter__iadd_(cself.cself, swifttosccounter, &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: Counter
    sctoswiftresult = Counter(result)
    return sctoswiftresult
  }

  /// Equality operator
  public static func ==(cself: Counter, counter: Counter) -> Bool {
    let swifttosccounter = counter.cself
    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExample_Counter__eq_(cself.cself, swifttosccounter, &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
  }

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

/// A class example to the case when non-operator method is mapped to == operator
public class PositiveCounter {

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

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

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

  deinit {
    release_CppbindExample_PositiveCounter(cself, owner)
  }

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

  public convenience init(count: Int) {
    let swifttosccount = CInt(count)
    var cppbindErr = CppBindCObject()
    self.init(create_CppbindExample_PositiveCounter(swifttosccount, &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(counts: Array<Int>) {
    let _swifttosccountsData = UnsafeMutablePointer<CInt>.allocate(capacity: counts.count)
    var swifttosccounts = CppBindCDataArray()
    swifttosccounts.data = UnsafeMutableRawPointer(_swifttosccountsData)
    swifttosccounts.size = Int64(counts.count)
    for i in 0..<counts.count {
      let countsVal = counts[i]
      let swifttosccountsVal = CInt(countsVal)
      _swifttosccountsData[i] = swifttosccountsVal
    }
    var cppbindErr = CppBindCObject()
    self.init(create_CppbindExample_PositiveCounter1(swifttosccounts, &cppbindErr), true)

    swifttosccounts.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 static func ==(cself: PositiveCounter, other: PositiveCounter) -> Bool {
    let swifttoscother = other.cself
    var cppbindErr = CppBindCObject()
    let result = _func_CppbindExample_PositiveCounter__eq_(cself.cself, swifttoscother, &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
  }



  public subscript(i: Int) -> Int {
    get {
      let swifttosci = CInt(i)
      let result = _func_CppbindExample_PositiveCounter__getitem_(cself, swifttosci)
      let sctoswiftresult = Int(result)
      return sctoswiftresult
    }

    set(value) {
      let swifttosci = CInt(i)
      let swifttoscvalue = CInt(value)
      _func_CppbindExample_PositiveCounter__setitem_(cself, swifttosci, swifttoscvalue)
    }
  }

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

Overloading subscript operator

Here is an example of overloading operator[].

/**
 * An example for with overloaded operators.
 * __API__
 * action: gen_interface
 * package: operators
 */
class IntArray {
public:
    /**
     * __API__
     * action: gen_constructor
     * throws: no_throw
     */
    IntArray() {
        for(int i = 0; i < ARRAY_SIZE; i++) {
           arr[i] = i;
        }
    }

    /**
     * __API__
     * action: gen_method
     * throws: no_throw
     */
    int& operator[](int i) {
         if( i > ARRAY_SIZE ) {
            return arr[0];
         }
         return arr[i];
    }

    /**
     * __API__
     * action: gen_method
     * throws: no_throw
     */
    const int& operator[](std::string i) {
         int ii = std::stoi(i);
         if( ii > ARRAY_SIZE ) {
            return arr[0];
         }
         return arr[ii];
    }

    /**
     * __API__
     * action: gen_method
     * throws: no_throw
     */
    int operator[](double i) {
         int ii = static_cast<int>(i);
         if( ii > ARRAY_SIZE ) {
            return arr[0];
         }
         return arr[ii];
    }

private:
    int arr[10];
};

Usage example:

// checking subscript operator with get and set
val counts = listOf(1, 3, 5, 10)
val multiCounter = PositiveCounter(counts)
for (i in 0..3) {
    assert(multiCounter[i] == counts[i])
}
multiCounter[0] = 10
assert(multiCounter[0] == 10)

var intArr = IntArrayImpl()
assert(intArr[0] == 0)
assert(intArr[9] == 9)
assert(intArr["9"] == 9)
assert(intArr[9.0] == 9)
intArr[9] = 10
assert(intArr[9] == 10)
assert(intArr["9"] == 10)
assert(intArr[9.0] == 10)
# checking subscript operator with get and set
counts = [1, 3, 5, 10]
multi_counter = PositiveCounter(counts)
for i, elem in enumerate(counts):
    assert multi_counter[i] == elem
multi_counter[0] = 10
assert multi_counter[0] == 10

intArr = IntArray()
assert (intArr[0] == 0)
assert (intArr[9] == 9)
assert (intArr["9"] == 9)
assert (intArr[9.0] == 9)
intArr[9] = 10
assert (intArr[9] == 10)
assert (intArr["9"] == 10)
assert (intArr[9.0] == 10)
// checking subscript operator with get and set
let counts = [1, 3, 5, 10]
let multiCounter = PositiveCounter(counts: counts)
for i in 0...3 {
    assert(multiCounter[i] == counts[i])
}
multiCounter[0] = 10
assert(multiCounter[0] == 10)

var intArr = IntArrayImpl()
assert(intArr[0] == 0)
assert(intArr[9] == 9)
assert(intArr["9"] == 9)
assert(intArr[9.0] == 9)
intArr[9] = 10
assert(intArr[9] == 10)
assert(intArr["9"] == 10)
assert(intArr[9.0] == 10)

Overloaded subscript operators for target languages
/**
 *   ______ .______   .______   .______    __  .__   __.  _______  
 *  /      ||   _  \  |   _  \  |   _  \  |  | |  \ |  | |       \ 
 * |  ,----'|  |_)  | |  |_)  | |  |_)  | |  | |   \|  | |  .--.  |
 * |  |     |   ___/  |   ___/  |   _  <  |  | |  . `  | |  |  |  |
 * |  `----.|  |      |  |      |  |_)  | |  | |  |\   | |  '--'  |
 *  \______|| _|      | _|      |______/  |__| |__| \__| |_______/ 
 * 
 * This file is generated by cppbind on 08/18/2022-11:02.
 * Please do not change it manually.
 */

package com.examples.operators

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


/**
 * An example for with overloaded operators.
 */
interface IIntArray : AutoCloseable {
    /**
     * An internal getter to get the id of an object.
     * It is intended to be used by the generated code.
     */
    val cppbindObjId: Long
    /**
     * An internal method to bind the lifetimes of the current and another object.
     * It is intended to be used by the generated code.
     */
    fun keepCppBindReference(ref: Any)


    operator fun get(i: Int): Int {
        val result = IIntArrayHelper.jGet(cppbindObjId, i)

        return result
    }


    operator fun set(i: Int, value: Int){
        IIntArrayHelper.jSet(cppbindObjId, i, value)
    }

    operator fun get(i: String): Int {
        val result = IIntArrayHelper.jGet1(cppbindObjId, i)

        return result
    }

    operator fun get(i: Double): Int {
        val result = IIntArrayHelper.jGet2(cppbindObjId, i)

        return result
    }
}


class IIntArrayHelper {
    companion object {
        @JvmStatic
        external fun jGet(id: Long, i: Int, vararg extraObjs: Any?): Int
        @JvmStatic
        external fun jSet(id: Long, i: Int, value: Int, vararg extraObjs: Any?)
        @JvmStatic
        external fun jGet1(id: Long, i: String, vararg extraObjs: Any?): Int
        @JvmStatic
        external fun jGet2(id: Long, i: Double, vararg extraObjs: Any?): Int
    }
}


open class IntArrayImpl
internal constructor(obj : CppBindObject) : IIntArray {
    companion object {
        init {
            System.loadLibrary("wrapper_jni")
        }

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

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

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

    override fun keepCppBindReference(ref: Any) {
        refs.add(ref)
    }

    override val cppbindObjId: Long
        get() {
            if (cppbindObj.id == 0L) {
                throw RuntimeException("Object is not allocated")
            }
            return cppbindObj.id
        }

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

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

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

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

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

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

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

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

    ///// External wrapper functions ////////////
    private external fun jFinalize(id: Long): Unit
    private external fun jGetcxxid(id: Long): Long
}

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

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

from typing import *

import examples.operators.intarray as pybind_intarray_pygen
from examples_lib.cppbind.cppbind_metaclass_pygen import *
from examples_lib.cppbind.cppbind_utils_pygen import *


class IntArray(metaclass=CppBindMetaclass):
    """
    An example for with overloaded operators.
    """

    @bind
    def __init__(self):

        pass

    @bind
    def __getitem__(self, i: int) -> int:

        pass

    @bind
    def __setitem__(self, i: int, value: int):

        pass

    @bind
    def __getitem__(self, i: str) -> int:

        pass

    @bind
    def __getitem__(self, i: float) -> int:

        pass

    @bind
    def __repr__(self) -> str:
        """
        CppBind generated __repr__ method returning underlying C++ object type and id.
        """
        pass
/**
 *   ______ .______   .______   .______    __  .__   __.  _______  
 *  /      ||   _  \  |   _  \  |   _  \  |  | |  \ |  | |       \ 
 * |  ,----'|  |_)  | |  |_)  | |  |_)  | |  | |   \|  | |  .--.  |
 * |  |     |   ___/  |   ___/  |   _  <  |  | |  . `  | |  |  |  |
 * |  `----.|  |      |  |      |  |_)  | |  | |  |\   | |  '--'  |
 *  \______|| _|      | _|      |______/  |__| |__| \__| |_______/ 
 * 
 * This file is generated by cppbind on 08/14/2022-10:58.
 * Please do not change it manually.
 */

import CWrapper
import Foundation

/// An example for with overloaded operators.
public protocol IntArray {
  /// An internal property to keep a reference to the original C++ object.
  /// It is intended to be used by the generated code.
  var cself: CppBindCObject { get }

  /// An internal method to bind the lifetimes of the current and another object.
  /// It is intended to be used by the generated code.
  func keepCppBindReference(_ object: Any)
  subscript(i: Int) -> Int { get set }
  subscript(i: String) -> Int { get }
  subscript(i: Double) -> Int { get }
}

extension IntArray {


  public subscript(i: Int) -> Int {
    get {
      let swifttosci = CInt(i)
      let result = _func_CppbindExample_IntArray__getitem_(cself, swifttosci)
      let sctoswiftresult = Int(result)
      return sctoswiftresult
    }

    set(value) {
      let swifttosci = CInt(i)
      let swifttoscvalue = CInt(value)
      _func_CppbindExample_IntArray__setitem_(cself, swifttosci, swifttoscvalue)
    }
  }



  public subscript(i: String) -> Int {
    let swifttosci = strdup(i)!
    let result = _func_CppbindExample_IntArray__getitem_1(cself, swifttosci)
    let sctoswiftresult = Int(result)
    return sctoswiftresult
  }



  public subscript(i: Double) -> Int {
    let result = _func_CppbindExample_IntArray__getitem_2(cself, i)
    let sctoswiftresult = Int(result)
    return sctoswiftresult
  }

}

public class IntArrayImpl: IntArray {
  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_IntArrayImpl(cself, owner)
  }

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

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

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

Note

As you can see, we have only generated one set operator. It is the case when the return value of the overloaded subscript operator is a non-const-qualified reference.


Last update: December 1, 2022