diff options
Diffstat (limited to 'tests/embind/embind_test.cpp')
-rw-r--r-- | tests/embind/embind_test.cpp | 1926 |
1 files changed, 1850 insertions, 76 deletions
diff --git a/tests/embind/embind_test.cpp b/tests/embind/embind_test.cpp index dc052d1a..f2359955 100644 --- a/tests/embind/embind_test.cpp +++ b/tests/embind/embind_test.cpp @@ -1,5 +1,6 @@ #include <string>
#include <malloc.h>
+#include <functional>
#include <emscripten/bind.h>
using namespace emscripten;
@@ -27,6 +28,10 @@ val emval_test_new_string() { return val("Hello everyone");
}
+std::string emval_test_get_string_from_val(val v) {
+ return v["key"].as<std::string>();
+}
+
val emval_test_new_object() {
val rv(val::object());
rv.set("foo", val("bar"));
@@ -54,22 +59,44 @@ unsigned emval_test_as_unsigned(val v) { }
unsigned emval_test_get_length(val v) {
- return v.get("length").as<unsigned>();
+ return v["length"].as<unsigned>();
}
double emval_test_add(char c, signed char sc, unsigned char uc, signed short ss, unsigned short us, signed int si, unsigned int ui, signed long sl, unsigned long ul, float f, double d) {
return c + sc + uc + ss + us + si + ui + sl + ul + f + d;
}
+float const_ref_adder(const int& i, const float& f) {
+ return i + f;
+}
+
unsigned emval_test_sum(val v) {
- unsigned length = v.get("length").as<unsigned>();
+ unsigned length = v["length"].as<unsigned>();
double rv = 0;
for (unsigned i = 0; i < length; ++i) {
- rv += v.get(i).as<double>();
+ rv += v[i].as<double>();
}
return rv;
}
+std::string get_non_ascii_string() {
+ char c[128 + 1];
+ c[128] = 0;
+ for (int i = 0; i < 128; ++i) {
+ c[i] = 128 + i;
+ }
+ return c;
+}
+
+std::wstring get_non_ascii_wstring() {
+ std::wstring ws(4, 0);
+ ws[0] = 10;
+ ws[1] = 1234;
+ ws[2] = 2345;
+ ws[3] = 65535;
+ return ws;
+}
+
std::string emval_test_take_and_return_const_char_star(const char* str) {
return str;
}
@@ -82,30 +109,74 @@ std::string emval_test_take_and_return_std_string_const_ref(const std::string& s return str;
}
+std::wstring take_and_return_std_wstring(std::wstring str) {
+ return str;
+}
+
+std::function<std::string (std::string)> emval_test_get_function_ptr() {
+ return emval_test_take_and_return_std_string;
+}
+
+std::string emval_test_take_and_call_functor(std::function<std::string(std::string)> func) {
+ return func("asdf");
+}
+
class ValHolder {
public:
ValHolder(val v)
- : v(v)
+ : v_(v)
{}
val getVal() const {
- return v;
+ return v_;
}
- void setVal(val v) {
- this->v = v;
+ val getValNonConst() {
+ return v_;
+ }
+
+ const val getConstVal() const {
+ return v_;
+ }
+
+ const val& getValConstRef() const {
+ return v_;
}
- int returnIntPlusFive( int x ) {
- return x + 5;
+ void setVal(val v) {
+ this->v_ = v;
}
static int some_class_method(int i) {
return i;
}
+ static const ValHolder* makeConst(val v) {
+ return new ValHolder(v);
+ }
+
+ static ValHolder makeValHolder(val v) {
+ return ValHolder(v);
+ }
+
+ static void set_via_raw_pointer(ValHolder* vh, val v) {
+ vh->setVal(v);
+ }
+
+ static val get_via_raw_pointer(const ValHolder* vh) {
+ return vh->getVal();
+ }
+
+ static void transfer_via_raw_pointer(ValHolder* target, const ValHolder* source) {
+ target->setVal(source->getVal());
+ }
+
+ static val getValNonMember(const ValHolder& target) {
+ return target.getVal();
+ }
+
private:
- val v;
+ val v_;
};
ValHolder emval_test_return_ValHolder() {
@@ -119,42 +190,612 @@ void emval_test_set_ValHolder_to_empty_object(ValHolder& vh) { class StringHolder {
public:
StringHolder(const std::string& s)
- : str(s)
+ : str_(s)
{}
void set(const std::string& s) {
- str = s;
+ str_ = s;
}
+
std::string get() const {
- return str;
+ return str_;
+ }
+
+ std::string& get_ref() {
+ return str_;
+ }
+
+ const std::string& get_const_ref() const {
+ return str_;
+ }
+
+private:
+ std::string str_;
+};
+
+class SharedPtrHolder {
+public:
+ SharedPtrHolder()
+ : ptr_(new StringHolder("a string"))
+ {}
+
+ std::shared_ptr<StringHolder> get() const {
+ return ptr_;
+ }
+
+ void set(std::shared_ptr<StringHolder> p) {
+ ptr_ = p;
+ }
+private:
+ std::shared_ptr<StringHolder> ptr_;
+};
+
+class VectorHolder {
+public:
+ VectorHolder() {
+ v_.push_back(StringHolder("string #1"));
+ v_.push_back(StringHolder("string #2"));
+ }
+
+ std::vector<StringHolder> get() const {
+ return v_;
+ }
+
+ void set(std::vector<StringHolder> vec) {
+ v_ = vec;
+ }
+
+private:
+ std::vector<StringHolder> v_;
+};
+
+class SmallClass {
+public:
+ SmallClass(): member(7) {};
+ int member;
+};
+
+class BigClass {
+public:
+ BigClass(): member(11) {};
+ int member;
+ int otherMember;
+ int yetAnotherMember;
+
+ int getMember() {
+ return member;
+ }
+};
+
+class ParentClass {
+public:
+ ParentClass(): bigClass() {};
+
+ BigClass bigClass;
+
+ const BigClass& getBigClass() {
+ return bigClass;
+ };
+};
+
+template<typename T>
+class TemplateClass {
+public:
+ TemplateClass(T a, T b, T c) {
+ members[0] = a;
+ members[1] = b;
+ members[2] = c;
+ };
+
+ const T getMember(int n) {
+ return members[n];
+ }
+
+protected:
+ T members[3];
+};
+
+class ContainsTemplatedMemberClass {
+public:
+ ContainsTemplatedMemberClass(): testTemplate(86, 87, 88) {};
+
+ TemplateClass<int> testTemplate;
+
+ const TemplateClass<int>& getTestTemplate() {
+ return testTemplate;
+ };
+};
+
+// Begin Inheritance Hierarchy Class Definitions
+
+class Base {
+public:
+ Base(): name("Base"),
+ member(0),
+ baseMember(0)
+ {}
+
+ std::string getClassName() const {
+ return name;
+ }
+ std::string getClassNameFromBase() const {
+ return name;
+ }
+ std::string getClassNameNotAvailableInDerivedClasses() {
+ // but wait -- if you act now we will throw in a SECOND base class method ABSOLUTELY FREE!!
+ return name;
+ }
+ void setMember(int value) {
+ member = value;
+ }
+ int getMember() {
+ return member;
+ }
+ void setBaseMember(int value) {
+ baseMember = value;
+ }
+ int getBaseMember() {
+ return baseMember;
+ }
+ std::string name;
+ int member;
+ int baseMember;
+};
+
+class SecondBase {
+public:
+ SecondBase()
+ : name("SecondBase"),
+ member(0),
+ secondBaseMember(0)
+ {}
+
+ std::string getClassName() const {
+ return name;
+ }
+ std::string getClassNameNotAvailableInDerivedClasses() {
+ return name;
+ }
+ std::string getClassNameFromSecondBase() const {
+ return name;
+ }
+ void setMember(int value) {
+ member = value;
+ }
+ int getMember() {
+ return member;
+ }
+ void setSecondBaseMember(int value) {
+ secondBaseMember = value;
+ }
+ int getSecondBaseMember() {
+ return secondBaseMember;
+ }
+ std::string name;
+ int member;
+ int secondBaseMember;
+};
+
+class Derived : public Base{
+public:
+ Derived()
+ : Base()
+ , member(0)
+ , name_("Derived")
+ {}
+
+ std::string getClassName() const {
+ return name_;
+ }
+ void setMember(int value) {
+ member = value;
+ }
+ int getMember() {
+ return member;
+ }
+ int member;
+private:
+ std::string name_;
+};
+
+class DerivedHolder {
+public:
+ DerivedHolder() {
+ derived_.reset();
+ }
+ void newDerived() {
+ deleteDerived();
+ derived_ = std::shared_ptr<Derived>(new Derived());
+ }
+ void deleteDerived() {
+ derived_.reset();
+ }
+ std::shared_ptr<Derived> getDerived() {
+ return derived_;
+ }
+ std::string getDerivedClassName() {
+ return derived_->getClassName();
+ }
+private:
+ std::shared_ptr<Derived> derived_;
+};
+
+class SiblingDerived : public Base {
+public:
+ SiblingDerived()
+ : Base(),
+ name_("SiblingDerived")
+ {}
+
+ std::string getClassName() const {
+ return name_;
+ }
+
+private:
+ std::string name_;
+};
+
+class MultiplyDerived : public Base, public SecondBase {
+public:
+ MultiplyDerived()
+ : Base(), SecondBase(),
+ name_("MultiplyDerived")
+ { instanceCount_ ++; }
+
+ ~MultiplyDerived()
+ { instanceCount_ --; }
+
+ std::string getClassName() const {
+ return name_;
+ }
+
+ static int getInstanceCount() {
+ return instanceCount_;
+ }
+private:
+ std::string name_;
+ static int instanceCount_;
+};
+int MultiplyDerived::instanceCount_ = 0;
+
+class DerivedTwice : public Derived {
+public:
+ DerivedTwice()
+ : Derived(),
+ name_("DerivedTwice")
+ {}
+
+ std::string getClassName() const {
+ return name_;
+ }
+private:
+ std::string name_;
+};
+
+class DerivedTwiceNotBound : public Derived {
+public:
+ DerivedTwiceNotBound()
+ : Derived(),
+ name_("DerivedTwiceNotBound")
+ {}
+
+ std::string getClassName() const {
+ return name_;
+ }
+private:
+ std::string name_;
+};
+
+class DerivedThrice: public DerivedTwiceNotBound {
+public:
+ DerivedThrice()
+ : DerivedTwiceNotBound(),
+ name_("DerivedThrice")
+ {}
+
+ std::string getClassName() const {
+ return name_;
+ }
+private:
+ std::string name_;
+};
+
+class DerivedFourTimesNotBound: public DerivedThrice {
+public:
+ DerivedFourTimesNotBound()
+ : DerivedThrice(),
+ name_("DerivedFourTimesNotBound")
+ {}
+
+ std::string getClassName() const {
+ return name_;
+ }
+private:
+ std::string name_;
+};
+
+class PolyBase {
+public:
+ PolyBase(const std::string& s)
+ : str_(s),
+ name_("PolyBase")
+ {}
+
+ PolyBase(): name_("PolyBase") {}
+
+ virtual ~PolyBase() {}
+
+ virtual std::string virtualGetClassName() const {
+ return name_;
+ }
+
+ std::string getClassName() const {
+ return name_;
+ }
+
+private:
+ std::string str_;
+ std::string name_;
+};
+
+class PolySecondBase {
+public:
+ PolySecondBase(): name_("PolySecondBase")
+ {}
+
+ virtual ~PolySecondBase() {}
+
+ std::string getClassName() const {
+ return name_;
+ }
+private:
+ std::string name_;
+};
+
+class PolyDerived : public PolyBase{
+public:
+ PolyDerived()
+ : PolyBase("PolyDerived"),
+ name_("PolyDerived")
+ {}
+
+ std::string virtualGetClassName() const {
+ return name_;
+ }
+
+ std::string getClassName() const {
+ return name_;
+ }
+
+ static void setPtrDerived() {
+ ptr_ = std::shared_ptr<PolyDerived>(new PolyDerived());
+ }
+
+ static void releasePtr() {
+ ptr_.reset();
+ }
+
+ static std::string getPtrClassName() {
+ return ptr_->getClassName();
+ }
+
+ static std::shared_ptr<PolyBase> getPtr() {
+ return ptr_;
+ }
+
+private:
+ std::string name_;
+ static std::shared_ptr<PolyBase> ptr_;
+};
+std::shared_ptr<PolyBase> PolyDerived::ptr_;
+
+class PolySiblingDerived : public PolyBase {
+public:
+ PolySiblingDerived()
+ : PolyBase(),
+ name_("PolySiblingDerived")
+ {}
+
+ std::string getClassName() const {
+ return name_;
+ }
+private:
+ std::string name_;
+};
+
+class PolyMultiplyDerived : public PolyBase, public PolySecondBase {
+public:
+ PolyMultiplyDerived()
+ : PolyBase(), PolySecondBase(),
+ name_("PolyMultiplyDerived")
+ {}
+
+ std::string getClassName() const {
+ return name_;
+ }
+private:
+ std::string name_;
+};
+
+class PolyDerivedTwiceWithoutSmartPointer: public PolyDerived {
+public:
+ PolyDerivedTwiceWithoutSmartPointer()
+ : PolyDerived(),
+ name_("PolyDerivedTwiceWithoutSmartPointer")
+ {}
+
+ std::string getClassName() const {
+ return name_;
+ }
+private:
+ std::string name_;
+};
+
+class PolyDerivedTwiceNotBound : public PolyDerived {
+public:
+ PolyDerivedTwiceNotBound()
+ : PolyDerived(),
+ name_("PolyDerivedTwiceNotBound")
+ {}
+
+ std::string getClassName() const {
+ return name_;
+ }
+private:
+ std::string name_;
+};
+
+class PolyDerivedThrice: public PolyDerivedTwiceNotBound {
+public:
+ PolyDerivedThrice()
+ : PolyDerivedTwiceNotBound(),
+ name_("PolyDerivedThrice")
+ {}
+
+ std::string getClassName() const {
+ return name_;
+ }
+private:
+ std::string name_;
+};
+
+class PolyDerivedFourTimesNotBound: public PolyDerivedThrice {
+public:
+ PolyDerivedFourTimesNotBound()
+ : PolyDerivedThrice(),
+ name_("PolyDerivedFourTimesNotBound")
+ {}
+
+ std::string getClassName() const {
+ return name_;
}
+private:
+ std::string name_;
+};
+
+class PolyDiamondBase {
+public:
+ PolyDiamondBase():
+ name_("PolyBase")
+ {}
+ ~PolyDiamondBase() {}
+ std::string getClassName() const {
+ return name_;
+ }
private:
- std::string str;
+ std::string name_;
+};
+
+class PolyDiamondDerived: public PolyDiamondBase {
+public:
+ PolyDiamondDerived()
+ : PolyDiamondBase(),
+ name_("PolyDiamondDerived")
+ {}
+
+ std::string getClassName() const {
+ return name_;
+ }
+private:
+ std::string name_;
+};
+
+class PolyDiamondSiblingDerived: public PolyDiamondBase {
+public:
+ PolyDiamondSiblingDerived()
+ : PolyDiamondBase(),
+ name_("PolyDiamondSiblingDerived")
+ {}
+
+ std::string getClassName() const {
+ return name_;
+ }
+private:
+ std::string name_;
+};
+
+class PolyDiamondMultiplyDerived: public PolyDiamondDerived, public PolyDiamondSiblingDerived {
+public:
+ PolyDiamondMultiplyDerived()
+ : PolyDiamondDerived(), PolyDiamondSiblingDerived(),
+ name_("PolyDiamondMultiplyDerived")
+ {}
+
+ std::string getClassName() const {
+ return name_;
+ }
+private:
+ std::string name_;
+};
+
+// End Inheritance Hierarchy Class Definitions
+
+std::map<std::string, int> embind_test_get_string_int_map() {
+ std::map<std::string, int> m;
+
+ m["one"] = 1;
+ m["two"] = 2;
+
+ return m;
+};
+
+struct Vector {
+ Vector() = delete;
+
+ Vector(float x_, float y_, float z_, float w_)
+ : x(x_)
+ , y(y_)
+ , z(z_)
+ , w(w_)
+ {}
+
+ float x, y, z, w;
+
+ float& operator[](int i) {
+ return (&x)[i];
+ }
+
+ const float& operator[](int i) const {
+ return (&x)[i];
+ }
+
+ float getY() const {
+ return y;
+ }
+ void setY(float _y) {
+ y = _y;
+ }
+};
+
+struct DummyDataToTestPointerAdjustment {
+ std::string dummy;
+};
+
+struct TupleVector : DummyDataToTestPointerAdjustment, Vector {
+ TupleVector(): Vector(0, 0, 0, 0) {}
+ TupleVector(float x, float y, float z, float w): Vector(x, y, z, w) {}
};
-struct TupleVector {
- float x, y, z;
+struct StructVector : DummyDataToTestPointerAdjustment, Vector {
+ StructVector(): Vector(0, 0, 0, 0) {}
+ StructVector(float x, float y, float z, float w): Vector(x, y, z, w) {}
};
-float readTupleVectorZ(const TupleVector& v) {
+float readVectorZ(const Vector& v) {
return v.z;
}
-void writeTupleVectorZ(TupleVector& v, float z) {
+void writeVectorZ(Vector& v, float z) {
v.z = z;
}
struct TupleVectorTuple {
- TupleVector v;
+ TupleVector v = TupleVector(0, 0, 0, 0);
};
TupleVector emval_test_return_TupleVector() {
- TupleVector cv;
- cv.x = 1;
- cv.y = 2;
- cv.z = 3;
- return cv;
+ return TupleVector(1, 2, 3, 4);
}
TupleVector emval_test_take_and_return_TupleVector(TupleVector v) {
@@ -167,16 +808,8 @@ TupleVectorTuple emval_test_return_TupleVectorTuple() { return cvt;
}
-struct StructVector {
- float x, y, z;
-};
-
StructVector emval_test_return_StructVector() {
- StructVector v;
- v.x = 1;
- v.y = 2;
- v.z = 3;
- return v;
+ return StructVector(1, 2, 3, 4);
}
StructVector emval_test_take_and_return_StructVector(StructVector v) {
@@ -187,6 +820,11 @@ struct CustomStruct { CustomStruct()
: field(10)
{}
+
+ const int& getField() const {
+ return field;
+ }
+
int field;
};
@@ -210,34 +848,645 @@ EnumClass emval_test_take_and_return_EnumClass(EnumClass e) { return e;
}
-class Interface {
+void emval_test_call_function(val v, int i, float f, TupleVector tv, StructVector sv) {
+ v(i, f, tv, sv);
+}
+
+std::unique_ptr<ValHolder> emval_test_return_unique_ptr() {
+ return std::unique_ptr<ValHolder>(new ValHolder(val::object()));
+}
+
+std::shared_ptr<ValHolder> emval_test_return_shared_ptr() {
+ return std::shared_ptr<ValHolder>(new ValHolder(val::object()));
+}
+
+std::shared_ptr<ValHolder> emval_test_return_empty_shared_ptr() {
+ return std::shared_ptr<ValHolder>();
+}
+
+bool emval_test_is_shared_ptr_null(std::shared_ptr<ValHolder> p) {
+ return !p;
+}
+
+static SmallClass smallClass;
+static BigClass bigClass;
+
+SmallClass embind_test_return_small_class_instance() {
+ return smallClass;
+}
+
+BigClass embind_test_return_big_class_instance() {
+ return bigClass;
+}
+
+int embind_test_accept_small_class_instance(SmallClass c) {
+ return c.member;
+}
+
+int embind_test_accept_big_class_instance(BigClass c) {
+ return c.member;
+}
+
+// Begin Inheritance Hierarchy Test Wrappers
+
+Base* embind_test_return_raw_base_ptr() {
+ return new Base();
+}
+
+Base* embind_test_return_raw_derived_ptr_as_base() {
+ return new Derived();
+}
+
+Base* embind_test_return_raw_sibling_derived_ptr_as_base() {
+ return new SiblingDerived();
+}
+
+PolyBase* embind_test_return_raw_polymorphic_derived_ptr_as_base() {
+ return new PolyDerived();
+}
+
+PolyBase* embind_test_return_raw_polymorphic_sibling_derived_ptr_as_base() {
+ return new PolySiblingDerived();
+}
+
+PolyBase* embind_test_return_raw_polymorphic_multiply_derived_ptr_as_base() {
+ return new PolyMultiplyDerived();
+}
+
+PolySecondBase* embind_test_return_raw_polymorphic_multiply_derived_ptr_as_second_base() {
+ return new PolyMultiplyDerived();
+}
+
+PolyBase* embind_test_return_raw_polymorphic_derived_four_times_not_bound_as_base() {
+ return new PolyDerivedFourTimesNotBound();
+}
+
+std::shared_ptr<Base> embind_test_return_smart_base_ptr() {
+ return std::shared_ptr<Base>(new Base());
+}
+
+std::shared_ptr<PolyBase> embind_test_return_smart_polymorphic_base_ptr() {
+ return std::shared_ptr<PolyBase>(new PolyBase("PolyBase"));
+}
+
+std::shared_ptr<Derived> embind_test_return_smart_derived_ptr() {
+ return std::shared_ptr<Derived>(new Derived());
+}
+
+std::shared_ptr<SiblingDerived> embind_test_return_smart_sibling_derived_ptr() {
+ return std::shared_ptr<SiblingDerived>(new SiblingDerived());
+}
+
+std::shared_ptr<MultiplyDerived> embind_test_return_smart_multiply_derived_ptr() {
+ return std::shared_ptr<MultiplyDerived>(new MultiplyDerived());
+}
+
+std::shared_ptr<DerivedThrice> embind_test_return_smart_derived_thrice_ptr() {
+ return std::shared_ptr<DerivedThrice>(new DerivedThrice());
+}
+
+std::shared_ptr<PolyDerived> embind_test_return_smart_polymorphic_derived_ptr() {
+ return std::shared_ptr<PolyDerived>(new PolyDerived());
+}
+
+std::shared_ptr<PolySiblingDerived> embind_test_return_smart_polymorphic_sibling_derived_ptr() {
+ return std::shared_ptr<PolySiblingDerived>(new PolySiblingDerived());
+}
+
+std::shared_ptr<PolyMultiplyDerived> embind_test_return_smart_polymorphic_multiply_derived_ptr() {
+ return std::shared_ptr<PolyMultiplyDerived>(new PolyMultiplyDerived());
+}
+
+std::shared_ptr<PolyBase> embind_test_return_poly_derived_twice_without_smart_pointer_as_poly_base() {
+ return std::shared_ptr<PolyBase>(new PolyDerivedTwiceWithoutSmartPointer());
+}
+
+std::shared_ptr<PolyDerivedThrice> embind_test_return_smart_poly_derived_thrice_ptr() {
+ return std::shared_ptr<PolyDerivedThrice>(new PolyDerivedThrice());
+}
+
+std::shared_ptr<PolyBase> embind_test_return_smart_derived_ptr_as_base() {
+ return std::shared_ptr<PolyBase>(new PolyDerived());
+}
+
+val embind_test_return_smart_derived_ptr_as_val() {
+ return val(std::shared_ptr<PolyBase>(new PolyDerived()));
+}
+
+std::shared_ptr<PolyBase> embind_test_return_smart_polymorphic_derived_ptr_as_base() {
+ return std::shared_ptr<PolyBase>(new PolyDerived());
+}
+
+std::shared_ptr<PolyBase> embind_test_return_smart_polymorphic_sibling_derived_ptr_as_base() {
+ return std::shared_ptr<PolyBase>(new PolySiblingDerived());
+}
+
+std::string embind_test_get_class_name_via_base_ptr(Base *p) {
+ return p->getClassName();
+}
+
+std::string embind_test_get_class_name_via_second_base_ptr(SecondBase *p) {
+ return p->getClassName();
+}
+
+std::string embind_test_get_class_name_via_polymorphic_base_ptr(PolyBase *p) {
+ return p->getClassName();
+}
+
+std::string embind_test_get_class_name_via_polymorphic_second_base_ptr(PolySecondBase *p) {
+ return p->getClassName();
+}
+
+std::string embind_test_get_class_name_via_smart_base_ptr(std::shared_ptr<Base> p) {
+ return p->getClassName();
+}
+
+std::string embind_test_get_class_name_via_reference_to_smart_base_ptr(std::shared_ptr<Base>& p) {
+ return p->getClassName();
+}
+
+std::string embind_test_get_class_name_via_smart_second_base_ptr(std::shared_ptr<SecondBase> p) {
+ return p->getClassName();
+}
+
+std::string embind_test_get_class_name_via_smart_polymorphic_base_ptr(std::shared_ptr<PolyBase> p) {
+ return p->getClassName();
+}
+
+std::string embind_test_get_virtual_class_name_via_smart_polymorphic_base_ptr(std::shared_ptr<PolyBase> p) {
+ return p->virtualGetClassName();
+}
+
+std::string embind_test_get_class_name_via_smart_polymorphic_second_base_ptr(std::shared_ptr<PolySecondBase> p) {
+ return p->getClassName();
+}
+
+void embind_modify_smart_pointer_passed_by_reference(std::shared_ptr<Base>& p) {
+ p = std::shared_ptr<Base>(new Base());
+ p->name = "Changed";
+}
+
+void embind_attempt_to_modify_smart_pointer_when_passed_by_value(std::shared_ptr<Base> p) {
+ p = std::shared_ptr<Base>(new Base());
+ p->name = "Changed";
+}
+
+static std::shared_ptr<Base> savedBasePointer;
+
+void embind_save_smart_base_pointer(std::shared_ptr<Base> p) {
+ savedBasePointer = p;
+}
+
+// End Inheritance Hierarchy Test Wrappers
+
+std::vector<int> emval_test_return_vector() {
+ int myints[] = { 10, 20, 30 };
+ return std::vector<int>(myints, myints + sizeof(myints) / sizeof(int));
+}
+
+std::vector<std::vector<int> > emval_test_return_vector_of_vectors() {
+ int myints1[] = { 10, 20, 30 };
+ int myints2[] = { 40, 50, 60 };
+ std::vector<int> vec1(myints1, myints1 + sizeof(myints1) / sizeof(int));
+ std::vector<int> vec2(myints2, myints2 + sizeof(myints2) / sizeof(int));
+ std::vector<std::vector<int>>vec3;
+ vec3.emplace_back(vec1);
+ vec3.emplace_back(vec2);
+ return vec3;
+}
+
+std::vector<std::shared_ptr<StringHolder>> emval_test_return_shared_ptr_vector() {
+ std::vector<std::shared_ptr<StringHolder>> sharedStrVector;
+ sharedStrVector.push_back(std::shared_ptr<StringHolder>(new StringHolder("string #1")));
+ sharedStrVector.push_back(std::shared_ptr<StringHolder>(new StringHolder("string #2")));
+
+ return sharedStrVector;
+}
+
+void test_string_with_vec(const std::string& p1, std::vector<std::string>& v1) {
+ // THIS DOES NOT WORK -- need to get as val and then call vecFromJSArray
+ printf("%s\n", p1.c_str());
+}
+
+val embind_test_new_Object() {
+ return val::global("Object").new_();
+}
+
+val embind_test_new_factory(val factory, val argument) {
+ return factory.new_(10, std::string("hello"), argument);
+}
+
+class AbstractClass {
public:
- virtual int method() = 0;
- virtual TupleInStruct method2(const TupleInStruct& arg1, float arg2) = 0;
- virtual void method3() = 0;
+ virtual ~AbstractClass() {}
+ virtual std::string abstractMethod() const = 0;
+ virtual std::string optionalMethod(std::string s) const {
+ return "optional" + s;
+ }
+};
+
+EMSCRIPTEN_SYMBOL(optionalMethod);
+
+class AbstractClassWrapper : public wrapper<AbstractClass> {
+public:
+ EMSCRIPTEN_WRAPPER(AbstractClassWrapper);
+
+ std::string abstractMethod() const {
+ return call<std::string>("abstractMethod");
+ }
+ std::string optionalMethod(std::string s) const {
+ return optional_call<std::string>(optionalMethod_symbol, [&] {
+ return AbstractClass::optionalMethod(s);
+ }, s);
+ }
+};
+
+class ConcreteClass : public AbstractClass {
+ std::string abstractMethod() const {
+ return "from concrete";
+ }
};
-int emval_test_call_method(Interface& i) {
- return i.method();
+std::shared_ptr<AbstractClass> getAbstractClass() {
+ return std::make_shared<ConcreteClass>();
}
-TupleInStruct emval_test_call_method2(Interface& i, const TupleInStruct& arg1, float arg2) {
- return i.method2(arg1, arg2);
+std::string callAbstractMethod(AbstractClass& ac) {
+ return ac.abstractMethod();
}
-void emval_test_call_method3(Interface& i) {
- i.method3();
+std::string callOptionalMethod(AbstractClass& ac, std::string s) {
+ return ac.optionalMethod(s);
}
-void emval_test_call_function(val v, int i, float f, TupleVector tv, StructVector sv) {
- v(i, f, tv, sv);
+class HasExternalConstructor {
+public:
+ HasExternalConstructor(const std::string& str)
+ : m(str)
+ {}
+
+ std::string getString() const {
+ return m;
+ }
+
+ std::string m;
+};
+
+HasExternalConstructor* createHasExternalConstructor(const std::string& str) {
+ return new HasExternalConstructor(str);
}
-EMSCRIPTEN_BINDINGS(([]() {
- function("mallinfo", &emval_test_mallinfo);
+template<typename T>
+class CustomSmartPtr {
+public:
+ CustomSmartPtr()
+ : CustomSmartPtr(nullptr)
+ {
+ std::fill(d_, d_ + N_, Valid);
+ }
+
+ explicit CustomSmartPtr(T* t)
+ : ptr_(t)
+ {
+ std::fill(d_, d_ + N_, Valid);
+ }
+
+ CustomSmartPtr(const CustomSmartPtr& other)
+ : ptr_(other.ptr_)
+ {
+ other.verify();
+ std::fill(d_, d_ + N_, Valid);
+ if (ptr_) {
+ ++(ptr_->refcount);
+ }
+ }
+
+ ~CustomSmartPtr() {
+ verify();
+ std::fill(d_, d_ + N_, Deleted);
+
+ if (ptr_ && --ptr_->refcount == 0) {
+ delete ptr_;
+ }
+ }
+
+ T* get_raw() const {
+ return ptr_;
+ }
+
+private:
+ void verify() const {
+ for (size_t i = 0; i < N_; ++i) {
+ if (d_[i] != Valid) {
+ abort();
+ }
+ }
+ }
+
+ enum {
+ Valid = 255,
+ Deleted = 127,
+ };
+ static constexpr size_t N_ = 1000000;
+ unsigned char d_[N_];
+ T* ptr_;
+
+ CustomSmartPtr& operator=(const CustomSmartPtr&) = delete;
+};
+
+class HeldBySmartPtr {
+public:
+ HeldBySmartPtr(int i, const std::string& s)
+ : i(i)
+ , s(s)
+ {}
+
+ static CustomSmartPtr<HeldBySmartPtr> newCustomPtr(int i, const std::string& s) {
+ return CustomSmartPtr<HeldBySmartPtr>(new HeldBySmartPtr(i, s));
+ }
+
+ int refcount = 1;
+ int i;
+ std::string s;
+};
+
+HeldBySmartPtr takesHeldBySmartPtr(HeldBySmartPtr p) {
+ return p;
+}
+std::shared_ptr<HeldBySmartPtr> takesHeldBySmartPtrSharedPtr(std::shared_ptr<HeldBySmartPtr> p) {
+ return p;
+}
+
+namespace emscripten {
+ template<typename T>
+ struct smart_ptr_trait<CustomSmartPtr<T>> {
+ typedef T element_type;
+
+ static sharing_policy get_sharing_policy() {
+ return sharing_policy::NONE;
+ }
+ static T* get(const CustomSmartPtr<T>& p) {
+ return p.get_raw();
+ }
+
+ static CustomSmartPtr<T> share(const CustomSmartPtr<T>& r, T* ptr) {
+ ++ptr->refcount; // implement an adopt API?
+ return CustomSmartPtr<T>(ptr);
+ }
+ };
+}
+
+typedef CustomSmartPtr<class HeldByCustomSmartPtr> HeldByCustomSmartPtrPtr;
+
+class HeldByCustomSmartPtr {
+public:
+ HeldByCustomSmartPtr(int i, const std::string& s)
+ : i(i)
+ , s(s)
+ {}
+
+ static HeldByCustomSmartPtrPtr create(int i, const std::string& s) {
+ return HeldByCustomSmartPtrPtr(new HeldByCustomSmartPtr(i, s));
+ }
+
+ static std::shared_ptr<HeldByCustomSmartPtr> createSharedPtr(int i, const std::string& s) {
+ return std::make_shared<HeldByCustomSmartPtr>(i, s);
+ };
+
+ int refcount = 1;
+ int i;
+ std::string s;
+};
+
+HeldByCustomSmartPtr* passThroughRawPtr(HeldByCustomSmartPtr* p) {
+ return p;
+}
+HeldByCustomSmartPtrPtr passThroughCustomSmartPtr(HeldByCustomSmartPtrPtr p) {
+ return p;
+}
+
+struct Base1 {
+public:
+ Base1(): field1("Base1") {}
+ std::string field1;
+
+ std::string getField() const {
+ return field1;
+ }
+};
+
+struct Base2 {
+public:
+ Base2(): field2("Base2") {}
+ std::string field2;
+
+ std::string getField() const {
+ return field2;
+ }
+};
+
+struct HasTwoBases : public Base1, public Base2 {
+};
+
+val get_module_property(const std::string& s) {
+ return val::module_property(s.c_str());
+}
+
+std::string char_to_string(char ch) {
+ char str[256];
+ sprintf(str, "%d", (int)ch);
+ return str;
+}
+
+std::string signed_char_to_string(signed char ch) {
+ char str[256];
+ sprintf(str, "%hhd", ch);
+ return str;
+}
+
+std::string unsigned_char_to_string(unsigned char ch) {
+ char str[256];
+ sprintf(str, "%hhu", ch);
+ return str;
+}
+
+std::string short_to_string(short val) {
+ char str[256];
+ sprintf(str, "%hd", val);
+ return str;
+}
+
+std::string unsigned_short_to_string(unsigned short val) {
+ char str[256];
+ sprintf(str, "%hu", val);
+ return str;
+}
+
+std::string int_to_string(int val) {
+ char str[256];
+ sprintf(str, "%d", val);
+ return str;
+}
+
+std::string unsigned_int_to_string(unsigned int val) {
+ char str[256];
+ sprintf(str, "%u", val);
+ return str;
+}
+
+std::string long_to_string(long val) {
+ char str[256];
+ sprintf(str, "%ld", val);
+ return str;
+}
+
+std::string unsigned_long_to_string(unsigned long val) {
+ char str[256];
+ sprintf(str, "%lu", val);
+ return str;
+}
+
+class MultipleCtors {
+public:
+ int value;
+
+ MultipleCtors(int i) {
+ value = 1;
+ assert(i == 10);
+ }
+ MultipleCtors(int i, int j) {
+ value = 2;
+ assert(i == 20);
+ assert(j == 20);
+ }
+ MultipleCtors(int i, int j, int k) {
+ value = 3;
+ assert(i == 30);
+ assert(j == 30);
+ assert(k == 30);
+ }
+
+ int WhichCtorCalled() const {
+ return value;
+ }
+};
+
+class MultipleOverloads {
+public:
+ MultipleOverloads() {}
+
+ int value;
+ static int staticValue;
+
+ int Func(int i) {
+ assert(i == 10);
+ value = 1;
+ return 1;
+ }
+ int Func(int i, int j) {
+ assert(i == 20);
+ assert(j == 20);
+ value = 2;
+ return 2;
+ }
+
+ int WhichFuncCalled() const {
+ return value;
+ }
+
+ static int StaticFunc(int i) {
+ assert(i == 10);
+ staticValue = 1;
+ return 1;
+ }
+ static int StaticFunc(int i, int j) {
+ assert(i == 20);
+ assert(j == 20);
+ staticValue = 2;
+ return 2;
+ }
+
+ static int WhichStaticFuncCalled() {
+ return staticValue;
+ }
+};
+
+class MultipleOverloadsDerived : public MultipleOverloads {
+public:
+ MultipleOverloadsDerived() {}
+
+ int Func(int i, int j, int k) {
+ assert(i == 30);
+ assert(j == 30);
+ assert(k == 30);
+ value = 3;
+ return 3;
+ }
+ int Func(int i, int j, int k, int l) {
+ assert(i == 40);
+ assert(j == 40);
+ assert(k == 40);
+ assert(l == 40);
+ value = 4;
+ return 4;
+ }
+
+ static int StaticFunc(int i, int j, int k) {
+ assert(i == 30);
+ assert(j == 30);
+ assert(k == 30);
+ staticValue = 3;
+ return 3;
+ }
+ static int StaticFunc(int i, int j, int k, int l) {
+ assert(i == 40);
+ assert(j == 40);
+ assert(k == 40);
+ assert(l == 40);
+ staticValue = 4;
+ return 4;
+ }
+};
+
+int overloaded_function(int i)
+{
+ assert(i == 10);
+ return 1;
+}
+
+int overloaded_function(int i, int j)
+{
+ assert(i == 20);
+ assert(j == 20);
+ return 2;
+}
+
+EMSCRIPTEN_BINDINGS(constants) {
+ constant("INT_CONSTANT", 10);
+ constant("STRING_CONSTANT", std::string("some string"));
+
+ TupleVector tv(1, 2, 3, 4);
+ constant("VALUE_TUPLE_CONSTANT", tv);
+
+ StructVector sv(1, 2, 3, 4);
+ constant("VALUE_STRUCT_CONSTANT", sv);
+}
+
+EMSCRIPTEN_BINDINGS(tests) {
+ register_vector<int>("IntegerVector");
+ register_vector<char>("CharVector");
+ register_vector<unsigned>("VectorUnsigned");
+ register_vector<unsigned char>("VectorUnsignedChar");
+ register_vector<std::string>("StringVector");
+ register_vector<emscripten::val>("EmValVector");
+ register_vector<float>("FloatVector");
+ register_vector<std::vector<int>>("IntegerVectorVector");
+
+ function("mallinfo", &emval_test_mallinfo);
function("emval_test_new_integer", &emval_test_new_integer);
function("emval_test_new_string", &emval_test_new_string);
+ function("emval_test_get_string_from_val", &emval_test_get_string_from_val);
function("emval_test_new_object", &emval_test_new_object);
function("emval_test_passthrough_unsigned", &emval_test_passthrough_unsigned);
function("emval_test_passthrough", &emval_test_passthrough);
@@ -247,19 +1496,23 @@ EMSCRIPTEN_BINDINGS(([]() { function("emval_test_as_unsigned", &emval_test_as_unsigned);
function("emval_test_get_length", &emval_test_get_length);
function("emval_test_add", &emval_test_add);
+ function("const_ref_adder", &const_ref_adder);
function("emval_test_sum", &emval_test_sum);
+ function("get_non_ascii_string", &get_non_ascii_string);
+ function("get_non_ascii_wstring", &get_non_ascii_wstring);
//function("emval_test_take_and_return_const_char_star", &emval_test_take_and_return_const_char_star);
function("emval_test_take_and_return_std_string", &emval_test_take_and_return_std_string);
function("emval_test_take_and_return_std_string_const_ref", &emval_test_take_and_return_std_string_const_ref);
+ function("take_and_return_std_wstring", &take_and_return_std_wstring);
//function("emval_test_take_and_return_CustomStruct", &emval_test_take_and_return_CustomStruct);
value_tuple<TupleVector>("TupleVector")
.element(&TupleVector::x)
- .element(&TupleVector::y)
- //.element(&TupleVector::z)
- .element(&readTupleVectorZ, &writeTupleVectorZ)
+ .element(&Vector::getY, &Vector::setY)
+ .element(&readVectorZ, &writeVectorZ)
+ .element(index<3>())
;
function("emval_test_return_TupleVector", &emval_test_return_TupleVector);
@@ -273,8 +1526,9 @@ EMSCRIPTEN_BINDINGS(([]() { value_struct<StructVector>("StructVector")
.field("x", &StructVector::x)
- .field("y", &StructVector::y)
- .field("z", &StructVector::z)
+ .field("y", &Vector::getY, &Vector::setY)
+ .field("z", &readVectorZ, &writeVectorZ)
+ .field("w", index<3>())
;
function("emval_test_return_StructVector", &emval_test_return_StructVector);
@@ -287,24 +1541,296 @@ EMSCRIPTEN_BINDINGS(([]() { function("emval_test_take_and_return_TupleInStruct", &emval_test_take_and_return_TupleInStruct);
class_<ValHolder>("ValHolder")
+ .smart_ptr<std::shared_ptr<ValHolder>>()
.constructor<val>()
- .method("getVal", &ValHolder::getVal)
- .method("setVal", &ValHolder::setVal)
- .method("returnIntPlusFive", &ValHolder::returnIntPlusFive)
- .classmethod("some_class_method", &ValHolder::some_class_method)
+ .function("getVal", &ValHolder::getVal)
+ .function("getValNonConst", &ValHolder::getValNonConst)
+ .function("getConstVal", &ValHolder::getConstVal)
+ .function("getValConstRef", &ValHolder::getValConstRef)
+ .function("setVal", &ValHolder::setVal)
+ .property("val", &ValHolder::getVal, &ValHolder::setVal)
+ .property("val_readonly", &ValHolder::getVal)
+ .class_function("makeConst", &ValHolder::makeConst, allow_raw_pointer<ret_val>())
+ .class_function("makeValHolder", &ValHolder::makeValHolder)
+ .class_function("some_class_method", &ValHolder::some_class_method)
+ .class_function("set_via_raw_pointer",
+ &ValHolder::set_via_raw_pointer,
+ allow_raw_pointer<arg<0>>())
+ .class_function("get_via_raw_pointer",
+ &ValHolder::get_via_raw_pointer,
+ allow_raw_pointer<arg<0>>())
+ .class_function("transfer_via_raw_pointer",
+ &ValHolder::transfer_via_raw_pointer,
+ allow_raw_pointers())
+
+ // non-member method
+ .function("setEmpty", &emval_test_set_ValHolder_to_empty_object)
+ .function("getValNonMember", &ValHolder::getValNonMember)
;
+
function("emval_test_return_ValHolder", &emval_test_return_ValHolder);
function("emval_test_set_ValHolder_to_empty_object", &emval_test_set_ValHolder_to_empty_object);
+ class_<std::function<std::string(std::string)>>("StringFunctorString")
+ .constructor<>()
+ .function("opcall", &std::function<std::string(std::string)>::operator())
+ ;
+
+ function("emval_test_get_function_ptr", &emval_test_get_function_ptr);
+ function("emval_test_take_and_call_functor", &emval_test_take_and_call_functor);
+
class_<StringHolder>("StringHolder")
+ .smart_ptr<std::shared_ptr<StringHolder>>()
.constructor<std::string>()
- .method("set", &StringHolder::set)
- .method("get", &StringHolder::get)
+ .function("set", &StringHolder::set)
+ .function("get", &StringHolder::get)
+ .function("get_const_ref", &StringHolder::get_const_ref)
+ ;
+
+ class_<SharedPtrHolder>("SharedPtrHolder")
+ .constructor<>()
+ .function("get", &SharedPtrHolder::get)
+ .function("set", &SharedPtrHolder::set)
+ ;
+
+ class_<SmallClass>("SmallClass")
+ .constructor<>()
+ .property("member", &SmallClass::member)
+ ;
+
+ class_<BigClass>("BigClass")
+ .constructor<>()
+ .property("member", &BigClass::member)
+ .property("otherMember", &BigClass::otherMember)
+ .property("yetAnotherMember", &BigClass::yetAnotherMember)
+ .function("getMember", &BigClass::getMember)
+ ;
+
+ class_<ParentClass>("ParentClass")
+ .constructor<>()
+ .function("getBigClass", &ParentClass::getBigClass)
+ ;
+
+ class_<TemplateClass<int>>("IntTemplateClass")
+ .constructor<int, int, int>()
+ .function("getMember", &TemplateClass<int>::getMember)
+ ;
+
+ class_<ContainsTemplatedMemberClass>("ContainsTemplatedMemberClass")
+ .constructor<>()
+ .function("getTestTemplate", &ContainsTemplatedMemberClass::getTestTemplate)
+ ;
+
+ // register Derived before Base as a test that it's possible to
+ // register base classes afterwards
+ class_<Derived, base<Base>>("Derived")
+ .smart_ptr<std::shared_ptr<Derived>>()
+ .constructor<>()
+ .function("getClassName", &Derived::getClassName)
+ .function("getMember", &Derived::getMember)
+ .function("setMember", &Derived::setMember)
+ .property("member", &Derived::member)
+ ;
+
+ class_<Base>("Base")
+ .smart_ptr<std::shared_ptr<Base>>()
+ .constructor<>()
+ .function("getClassName", &Base::getClassName)
+ .function("getClassNameFromBase", &Base::getClassNameFromBase)
+ .function("getClassNameNotAvailableInDerivedClasses", &Base::getClassNameNotAvailableInDerivedClasses)
+ .function("getMember", &Base::getMember)
+ .function("setMember", &Base::setMember)
+ .function("getBaseMember", &Base::getBaseMember)
+ .function("setBaseMember", &Base::setBaseMember)
+ .property("member", &Base::member)
+ .property("baseMember", &Base::baseMember)
+ ;
+
+ class_<SecondBase>("SecondBase")
+ .smart_ptr<std::shared_ptr<SecondBase>>()
+ .constructor<>()
+ .function("getClassName", &SecondBase::getClassName)
+ .function("getClassNameFromSecondBase", &SecondBase::getClassNameFromSecondBase)
+ .function("getClassNameNotAvailableInDerivedClasses", &SecondBase::getClassNameNotAvailableInDerivedClasses)
+ .function("getMember", &SecondBase::getMember)
+ .function("setMember", &SecondBase::setMember)
+ .function("getSecondBaseMember", &SecondBase::getSecondBaseMember)
+ .function("setSecondBaseMember", &SecondBase::setSecondBaseMember)
+ .property("member", &SecondBase::member)
+ .property("secondBaseMember", &SecondBase::secondBaseMember)
+ ;
+
+
+ class_<DerivedHolder>("DerivedHolder")
+ .constructor<>()
+ .function("newDerived", &DerivedHolder::newDerived)
+ .function("deleteDerived", &DerivedHolder::deleteDerived)
+ .function("getDerived", &DerivedHolder::getDerived)
+ .function("getDerivedClassName", &DerivedHolder::getDerivedClassName)
+ ;
+
+ class_<SiblingDerived>("SiblingDerived")
+ .smart_ptr<std::shared_ptr<SiblingDerived>>()
+ .constructor<>()
+ .function("getClassName", &SiblingDerived::getClassName)
+ ;
+
+ class_<MultiplyDerived, base<Base>>("MultiplyDerived")
+ .smart_ptr<std::shared_ptr<MultiplyDerived>>()
+ .constructor<>()
+ .function("getClassName", &MultiplyDerived::getClassName)
+ .class_function("getInstanceCount", &MultiplyDerived::getInstanceCount)
+ ;
+
+ class_<DerivedTwice, base<Derived> >("DerivedTwice")
+ .constructor<>()
+ .function("getClassName", &DerivedTwice::getClassName)
+ ;
+
+ class_<DerivedThrice, base<Derived> >("DerivedThrice")
+ .smart_ptr<std::shared_ptr<DerivedThrice>>()
+ .constructor<>()
+ .function("getClassName", &DerivedThrice::getClassName)
+ ;
+
+ class_<PolyBase>("PolyBase")
+ .smart_ptr<std::shared_ptr<PolyBase>>()
+ .constructor<>()
+ .function("virtualGetClassName", &PolyBase::virtualGetClassName)
+ .function("getClassName", &PolyBase::getClassName)
+ ;
+
+ class_<PolySecondBase>("PolySecondBase")
+ .smart_ptr<std::shared_ptr<PolySecondBase>>()
+ .constructor<>()
+ .function("getClassName", &PolySecondBase::getClassName)
+ ;
+
+ class_<PolyDerived, base<PolyBase>>("PolyDerived")
+ .smart_ptr<std::shared_ptr<PolyDerived>>()
+ .constructor<>()
+ .function("virtualGetClassName", &PolyDerived::virtualGetClassName)
+ .function("getClassName", &PolyDerived::getClassName)
+ .class_function("setPtrDerived", &PolyDerived::setPtrDerived)
+ .class_function("releasePtr", &PolyDerived::releasePtr)
+ .class_function("getPtrClassName", &PolyDerived::getPtrClassName)
+ .class_function("getPtr", &PolyDerived::getPtr)
+ ;
+// static void setPtrDerived() {
+// ptr = std::shared_ptr<PolyDerived>(new PolyDerived());
+// }
+//
+// static std::string getPtrClassName() {
+// return ptr->getClassName();
+// }
+//
+// static std::shared_ptr<PolyBase> getPtr() {
+// return ptr;
+// }
+
+ class_<PolySiblingDerived, base<PolyBase>>("PolySiblingDerived")
+ .smart_ptr<std::shared_ptr<PolySiblingDerived>>()
+ .constructor<>()
+ .function("getClassName", &PolySiblingDerived::getClassName)
+ ;
+
+ class_<PolyMultiplyDerived, base<PolyBase>>("PolyMultiplyDerived")
+ .smart_ptr<std::shared_ptr<PolyMultiplyDerived>>()
+ .constructor<>()
+ .function("getClassName", &PolyMultiplyDerived::getClassName)
+ ;
+
+ class_<PolyDerivedThrice, base<PolyDerived>>("PolyDerivedThrice")
+ .smart_ptr<std::shared_ptr<PolyDerivedThrice>>()
+ .constructor<>()
+ .function("getClassName", &PolyDerivedThrice::getClassName)
+ ;
+
+ class_<PolyDiamondBase>("PolyDiamondBase")
+ .smart_ptr<std::shared_ptr<PolyDiamondBase>>()
+ .constructor<>()
+ .function("getClassName", &PolyDiamondBase::getClassName)
+ ;
+
+ class_<PolyDiamondDerived>("PolyDiamondDerived")
+ .smart_ptr<std::shared_ptr<PolyDiamondDerived>>()
+ .constructor<>()
+ .function("getClassName", &PolyDiamondDerived::getClassName)
+ ;
+
+ class_<PolyDiamondSiblingDerived>("PolyDiamondSiblingDerived")
+ .smart_ptr<std::shared_ptr<PolyDiamondSiblingDerived>>()
+ .constructor<>()
+ .function("getClassName", &PolyDiamondSiblingDerived::getClassName)
+ ;
+
+ class_<PolyDiamondMultiplyDerived>("PolyDiamondMultiplyDerived")
+ .smart_ptr<std::shared_ptr<PolyDiamondMultiplyDerived>>()
+ .constructor<>()
+ .function("getClassName", &PolyDiamondMultiplyDerived::getClassName)
+ ;
+
+ function("embind_test_return_small_class_instance", &embind_test_return_small_class_instance);
+ function("embind_test_return_big_class_instance", &embind_test_return_big_class_instance);
+ function("embind_test_accept_small_class_instance", &embind_test_accept_small_class_instance);
+ function("embind_test_accept_big_class_instance", &embind_test_accept_big_class_instance);
+
+ function("embind_test_return_raw_base_ptr", embind_test_return_raw_base_ptr, allow_raw_pointer<ret_val>());
+ function("embind_test_return_raw_derived_ptr_as_base", embind_test_return_raw_derived_ptr_as_base, allow_raw_pointer<ret_val>());
+ function("embind_test_return_raw_sibling_derived_ptr_as_base", embind_test_return_raw_sibling_derived_ptr_as_base, allow_raw_pointer<ret_val>());
+ function("embind_test_return_raw_polymorphic_derived_ptr_as_base", embind_test_return_raw_polymorphic_derived_ptr_as_base, allow_raw_pointer<ret_val>());
+ function("embind_test_return_raw_polymorphic_sibling_derived_ptr_as_base", embind_test_return_raw_polymorphic_sibling_derived_ptr_as_base, allow_raw_pointer<ret_val>());
+ function("embind_test_return_raw_polymorphic_multiply_derived_ptr_as_base", embind_test_return_raw_polymorphic_multiply_derived_ptr_as_base, allow_raw_pointer<ret_val>());
+ function("embind_test_return_raw_polymorphic_multiply_derived_ptr_as_second_base", embind_test_return_raw_polymorphic_multiply_derived_ptr_as_second_base, allow_raw_pointer<ret_val>());
+ function("embind_test_return_raw_polymorphic_derived_four_times_not_bound_as_base", embind_test_return_raw_polymorphic_derived_four_times_not_bound_as_base, allow_raw_pointer<ret_val>());
+ function("embind_test_return_smart_derived_ptr", embind_test_return_smart_derived_ptr);
+ function("embind_test_return_smart_sibling_derived_ptr", embind_test_return_smart_sibling_derived_ptr);
+ function("embind_test_return_smart_multiply_derived_ptr", embind_test_return_smart_multiply_derived_ptr);
+ function("embind_test_return_smart_derived_thrice_ptr", embind_test_return_smart_derived_thrice_ptr);
+ function("embind_test_return_smart_base_ptr", embind_test_return_smart_base_ptr);
+ function("embind_test_return_smart_polymorphic_base_ptr", embind_test_return_smart_polymorphic_base_ptr);
+ function("embind_test_return_smart_polymorphic_derived_ptr", embind_test_return_smart_polymorphic_derived_ptr);
+ function("embind_test_return_smart_polymorphic_sibling_derived_ptr", embind_test_return_smart_polymorphic_sibling_derived_ptr);
+ function("embind_test_return_smart_polymorphic_multiply_derived_ptr", embind_test_return_smart_polymorphic_multiply_derived_ptr);
+ function("embind_test_return_poly_derived_twice_without_smart_pointer_as_poly_base", embind_test_return_poly_derived_twice_without_smart_pointer_as_poly_base);
+ function("embind_test_return_smart_poly_derived_thrice_ptr", embind_test_return_smart_poly_derived_thrice_ptr);
+ function("embind_test_return_smart_derived_ptr_as_base", embind_test_return_smart_derived_ptr_as_base);
+ function("embind_test_return_smart_derived_ptr_as_val", embind_test_return_smart_derived_ptr_as_val);
+ function("embind_test_return_smart_polymorphic_derived_ptr_as_base", embind_test_return_smart_polymorphic_derived_ptr_as_base);
+ function("embind_test_return_smart_polymorphic_sibling_derived_ptr_as_base", embind_test_return_smart_polymorphic_sibling_derived_ptr_as_base);
+ function("embind_test_get_class_name_via_base_ptr", embind_test_get_class_name_via_base_ptr, allow_raw_pointer<arg<0>>());
+ function("embind_test_get_class_name_via_second_base_ptr", embind_test_get_class_name_via_second_base_ptr, allow_raw_pointer<arg<0>>());
+ function("embind_test_get_class_name_via_polymorphic_base_ptr", embind_test_get_class_name_via_polymorphic_base_ptr, allow_raw_pointer<arg<0>>());
+ function("embind_test_get_class_name_via_polymorphic_second_base_ptr", embind_test_get_class_name_via_polymorphic_second_base_ptr, allow_raw_pointer<arg<0>>());
+ // todo: allow_raw_pointer should fail earlier if argument is not a pointer
+ function("embind_test_get_class_name_via_smart_base_ptr", embind_test_get_class_name_via_smart_base_ptr);
+ function("embind_test_get_class_name_via_reference_to_smart_base_ptr", embind_test_get_class_name_via_reference_to_smart_base_ptr);
+ function("embind_test_get_class_name_via_smart_second_base_ptr", embind_test_get_class_name_via_smart_second_base_ptr);
+ function("embind_test_get_class_name_via_smart_polymorphic_base_ptr", embind_test_get_class_name_via_smart_polymorphic_base_ptr);
+ function("embind_test_get_virtual_class_name_via_smart_polymorphic_base_ptr", embind_test_get_virtual_class_name_via_smart_polymorphic_base_ptr);
+ function("embind_test_get_class_name_via_smart_polymorphic_second_base_ptr", embind_test_get_class_name_via_smart_polymorphic_second_base_ptr);
+ function("embind_modify_smart_pointer_passed_by_reference", embind_modify_smart_pointer_passed_by_reference);
+ function("embind_attempt_to_modify_smart_pointer_when_passed_by_value", embind_attempt_to_modify_smart_pointer_when_passed_by_value);
+ function("embind_save_smart_base_pointer", embind_save_smart_base_pointer);
+
+ class_<Base1>("Base1")
+ .constructor()
+ .function("getField", &Base1::getField)
+ ;
+
+ class_<Base2>("Base2")
+ .function("getField", &Base2::getField)
+ .property("field", &Base2::field2)
+ ;
+
+ class_<HasTwoBases, base<Base2>>("HasTwoBases")
+ .constructor()
;
class_<CustomStruct>("CustomStruct")
.constructor<>()
- .field("field", &CustomStruct::field)
+ .property("field", &CustomStruct::field)
+ .function("getField", &CustomStruct::getField)
;
enum_<Enum>("Enum")
@@ -319,22 +1845,270 @@ EMSCRIPTEN_BINDINGS(([]() { ;
function("emval_test_take_and_return_EnumClass", &emval_test_take_and_return_EnumClass);
- class InterfaceWrapper : public wrapper<Interface> {
- int method() {
- return call<int>("method");
- }
- TupleInStruct method2(const TupleInStruct& arg1, float arg2) {
- return call<TupleInStruct>("method2", arg1, arg2);
- }
- void method3() {
- return call<void>("method3");
- }
- };
- interface<InterfaceWrapper>("Interface")
+ function("emval_test_call_function", &emval_test_call_function);
+
+ function("emval_test_return_unique_ptr", &emval_test_return_unique_ptr);
+
+ function("emval_test_return_shared_ptr", &emval_test_return_shared_ptr);
+ function("emval_test_return_empty_shared_ptr", &emval_test_return_empty_shared_ptr);
+ function("emval_test_is_shared_ptr_null", &emval_test_is_shared_ptr_null);
+
+ function("emval_test_return_vector", &emval_test_return_vector);
+ function("emval_test_return_vector_of_vectors", &emval_test_return_vector_of_vectors);
+
+ register_vector<std::shared_ptr<StringHolder>>("SharedPtrVector");
+ function("emval_test_return_shared_ptr_vector", &emval_test_return_shared_ptr_vector);
+
+ function("get_module_property", &get_module_property);
+
+ register_vector<StringHolder>("StringHolderVector");
+ class_<VectorHolder>("VectorHolder")
+ .constructor<>()
+ .function("get", &VectorHolder::get)
+ .function("set", &VectorHolder::set)
;
- function("emval_test_call_method", &emval_test_call_method);
- function("emval_test_call_method2", &emval_test_call_method2);
- function("emval_test_call_method3", &emval_test_call_method3);
- function("emval_test_call_function", &emval_test_call_function);
-}));
+ function("test_string_with_vec", &test_string_with_vec);
+
+ register_map<std::string, int>("StringIntMap");
+ function("embind_test_get_string_int_map", embind_test_get_string_int_map);
+
+ function("embind_test_new_Object", &embind_test_new_Object);
+ function("embind_test_new_factory", &embind_test_new_factory);
+
+ class_<AbstractClass>("AbstractClass")
+ .smart_ptr<std::shared_ptr<AbstractClass>>()
+ .allow_subclass<AbstractClassWrapper>()
+ .function("abstractMethod", &AbstractClass::abstractMethod)
+ .function("optionalMethod", &AbstractClass::optionalMethod)
+ ;
+
+ function("getAbstractClass", &getAbstractClass);
+ function("callAbstractMethod", &callAbstractMethod);
+ function("callOptionalMethod", &callOptionalMethod);
+
+ class_<HasExternalConstructor>("HasExternalConstructor")
+ .constructor(&createHasExternalConstructor)
+ .function("getString", &HasExternalConstructor::getString)
+ ;
+
+ auto HeldBySmartPtr_class = class_<HeldBySmartPtr>("HeldBySmartPtr");
+ HeldBySmartPtr_class
+ .smart_ptr<CustomSmartPtr<HeldBySmartPtr>>()
+ .smart_ptr_constructor(&std::make_shared<HeldBySmartPtr, int, std::string>)
+ .class_function("newCustomPtr", HeldBySmartPtr::newCustomPtr)
+ .function("returnThis", &takesHeldBySmartPtrSharedPtr)
+ .property("i", &HeldBySmartPtr::i)
+ .property("s", &HeldBySmartPtr::s)
+ ;
+ function("takesHeldBySmartPtr", &takesHeldBySmartPtr);
+ function("takesHeldBySmartPtrSharedPtr", &takesHeldBySmartPtrSharedPtr);
+
+ class_<HeldByCustomSmartPtr>("HeldByCustomSmartPtr")
+ .smart_ptr<std::shared_ptr<HeldByCustomSmartPtr>>()
+ .smart_ptr_constructor(&HeldByCustomSmartPtr::create)
+ .class_function("createSharedPtr", &HeldByCustomSmartPtr::createSharedPtr)
+ .property("i", &HeldByCustomSmartPtr::i)
+ .property("s", &HeldByCustomSmartPtr::s)
+ ;
+
+ function("passThroughRawPtr", &passThroughRawPtr, allow_raw_pointers());
+ function("passThroughCustomSmartPtr", &passThroughCustomSmartPtr);
+
+ function("char_to_string", &char_to_string);
+ function("signed_char_to_string", &signed_char_to_string);
+ function("unsigned_char_to_string", &unsigned_char_to_string);
+ function("short_to_string", &short_to_string);
+ function("unsigned_short_to_string", &unsigned_short_to_string);
+ function("int_to_string", &int_to_string);
+ function("unsigned_int_to_string", &unsigned_int_to_string);
+ function("long_to_string", &long_to_string);
+ function("unsigned_long_to_string", &unsigned_long_to_string);
+
+ function("overloaded_function", select_overload<int(int)>(&overloaded_function));
+ function("overloaded_function", select_overload<int(int, int)>(&overloaded_function));
+
+ class_<MultipleCtors>("MultipleCtors")
+ .constructor<int>()
+ .constructor<int, int>()
+ .constructor<int, int, int>()
+ .function("WhichCtorCalled", &MultipleCtors::WhichCtorCalled);
+
+ class_<MultipleOverloads>("MultipleOverloads")
+ .constructor<>()
+ .function("Func", select_overload<int(int)>(&MultipleOverloads::Func))
+ .function("Func", select_overload<int(int, int)>(&MultipleOverloads::Func))
+ .function("WhichFuncCalled", &MultipleOverloads::WhichFuncCalled)
+ .class_function("StaticFunc", select_overload<int(int)>(&MultipleOverloads::StaticFunc))
+ .class_function("StaticFunc", select_overload<int(int,int)>(&MultipleOverloads::StaticFunc))
+ .class_function("WhichStaticFuncCalled", &MultipleOverloads::WhichStaticFuncCalled)
+ ;
+
+ class_<MultipleOverloadsDerived, base<MultipleOverloads> >("MultipleOverloadsDerived")
+ .constructor<>()
+ .function("Func", select_overload<int(int,int,int)>(&MultipleOverloadsDerived::Func))
+ .function("Func", select_overload<int(int,int,int,int)>(&MultipleOverloadsDerived::Func))
+ .class_function("StaticFunc", select_overload<int(int,int,int)>(&MultipleOverloadsDerived::StaticFunc))
+ .class_function("StaticFunc", select_overload<int(int,int,int,int)>(&MultipleOverloadsDerived::StaticFunc))
+ ;
+}
+
+// tests for out-of-order registration
+
+class SecondElement {
+};
+
+class FirstElement {
+};
+
+struct OrderedTuple {
+ FirstElement first;
+ SecondElement second;
+};
+
+struct OrderedStruct {
+ FirstElement first;
+ SecondElement second;
+};
+
+OrderedTuple getOrderedTuple() {
+ return OrderedTuple();
+}
+
+OrderedStruct getOrderedStruct() {
+ return OrderedStruct();
+}
+
+EMSCRIPTEN_BINDINGS(order) {
+ value_tuple<OrderedTuple>("OrderedTuple")
+ .element(&OrderedTuple::first)
+ .element(&OrderedTuple::second)
+ ;
+
+ value_struct<OrderedStruct>("OrderedStruct")
+ .field("first", &OrderedStruct::first)
+ .field("second", &OrderedStruct::second)
+ ;
+
+ class_<SecondElement>("SecondElement")
+ ;
+
+ class_<FirstElement>("FirstElement")
+ ;
+
+ function("getOrderedTuple", &getOrderedTuple);
+ function("getOrderedStruct", &getOrderedStruct);
+}
+
+// tests for unbound types
+
+template<typename T>
+T passThrough(T t) {
+ return t;
+}
+
+struct UnboundClass {
+};
+
+struct HasUnboundBase : public UnboundClass {
+ static void noop() {
+ }
+};
+
+HasUnboundBase getHasUnboundBase(HasUnboundBase f) {
+ return f;
+}
+
+struct HasConstructorUsingUnboundArgument {
+ HasConstructorUsingUnboundArgument(UnboundClass) {
+ }
+};
+
+struct SecondUnboundClass {
+};
+
+struct HasConstructorUsingUnboundArgumentAndUnboundBase : public SecondUnboundClass {
+ HasConstructorUsingUnboundArgumentAndUnboundBase(UnboundClass) {
+ }
+};
+
+struct BoundClass {
+ UnboundClass method(UnboundClass t) {
+ return t;
+ }
+
+ static UnboundClass classfunction(UnboundClass t) {
+ return t;
+ }
+
+ UnboundClass property;
+};
+
+EMSCRIPTEN_BINDINGS(incomplete) {
+ function("getUnboundClass", &passThrough<UnboundClass>);
+
+ class_<HasUnboundBase, base<UnboundClass>>("HasUnboundBase")
+ .class_function("noop", &HasUnboundBase::noop)
+ ;
+ function("getHasUnboundBase", &passThrough<HasUnboundBase>);
+
+ class_<HasConstructorUsingUnboundArgument>("HasConstructorUsingUnboundArgument")
+ .constructor<UnboundClass>()
+ ;
+
+ class_<HasConstructorUsingUnboundArgumentAndUnboundBase, base<SecondUnboundClass>>("HasConstructorUsingUnboundArgumentAndUnboundBase")
+ .constructor<UnboundClass>()
+ ;
+
+ class_<BoundClass>("BoundClass")
+ .constructor<>()
+ .function("method", &BoundClass::method)
+ .class_function("classfunction", &BoundClass::classfunction)
+ .property("property", &BoundClass::property)
+ ;
+}
+
+class Noncopyable {
+ Noncopyable(const Noncopyable&) = delete;
+ Noncopyable& operator=(const Noncopyable&) = delete;
+
+public:
+ Noncopyable() {}
+ Noncopyable(Noncopyable&& other) {
+ other.valid = false;
+ }
+
+ std::string method() const {
+ return "foo";
+ }
+
+ bool valid = true;
+};
+
+Noncopyable getNoncopyable() {
+ return Noncopyable();
+}
+
+EMSCRIPTEN_BINDINGS(noncopyable) {
+ class_<Noncopyable>("Noncopyable")
+ .constructor<>()
+ .function("method", &Noncopyable::method)
+ ;
+
+ function("getNoncopyable", &getNoncopyable);
+}
+
+struct HasReadOnlyProperty {
+ HasReadOnlyProperty(int i)
+ : i(i)
+ {}
+
+ const int i;
+};
+
+EMSCRIPTEN_BINDINGS(read_only_properties) {
+ class_<HasReadOnlyProperty>("HasReadOnlyProperty")
+ .constructor<int>()
+ .property("i", &HasReadOnlyProperty::i)
+ ;
+}
|