blob: 3561b8a1e95f5d0f7ebce7cbe3a5e91e395fb589 [file] [log] [blame] [edit]
#include <string>
#include <malloc.h>
#include <functional>
#include <emscripten/bind.h>
using namespace emscripten;
val emval_test_mallinfo() {
const auto& i = mallinfo();
val rv(val::object());
rv.set("arena", val(i.arena));
rv.set("ordblks", val(i.ordblks));
rv.set("smblks", val(i.smblks));
rv.set("hblks", val(i.hblks));
rv.set("usmblks", val(i.usmblks));
rv.set("fsmblks", val(i.fsmblks));
rv.set("uordblks", val(i.uordblks));
rv.set("fordblks", val(i.fordblks));
rv.set("keepcost", val(i.keepcost));
return rv;
}
val emval_test_new_integer() {
return val(15);
}
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"));
rv.set("baz", val(1));
return rv;
}
unsigned emval_test_passthrough_unsigned(unsigned v) {
return v;
}
val emval_test_passthrough(val v) {
return v;
}
void emval_test_return_void() {
}
bool emval_test_not(bool b) {
return !b;
}
unsigned emval_test_as_unsigned(val v) {
return v.as<unsigned>();
}
unsigned emval_test_get_length(val v) {
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["length"].as<unsigned>();
double rv = 0;
for (unsigned i = 0; i < length; ++i) {
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;
}
std::string emval_test_take_and_return_std_string(std::string str) {
return str;
}
std::string emval_test_take_and_return_std_string_const_ref(const std::string& str) {
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)
{}
val getVal() const {
return v_;
}
val getValNonConst() {
return v_;
}
const val getConstVal() const {
return v_;
}
const val& getValConstRef() const {
return v_;
}
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_;
};
ValHolder emval_test_return_ValHolder() {
return val::object();
}
void emval_test_set_ValHolder_to_empty_object(ValHolder& vh) {
vh.setVal(val::object());
}
class StringHolder {
public:
StringHolder(const std::string& s)
: str_(s)
{}
void set(const std::string& s) {
str_ = s;
}
std::string get() const {
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 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 StructVector : DummyDataToTestPointerAdjustment, Vector {
StructVector(): Vector(0, 0, 0, 0) {}
StructVector(float x, float y, float z, float w): Vector(x, y, z, w) {}
};
float readVectorZ(const Vector& v) {
return v.z;
}
void writeVectorZ(Vector& v, float z) {
v.z = z;
}
struct TupleVectorTuple {
TupleVector v = TupleVector(0, 0, 0, 0);
};
TupleVector emval_test_return_TupleVector() {
return TupleVector(1, 2, 3, 4);
}
TupleVector emval_test_take_and_return_TupleVector(TupleVector v) {
return v;
}
TupleVectorTuple emval_test_return_TupleVectorTuple() {
TupleVectorTuple cvt;
cvt.v = emval_test_return_TupleVector();
return cvt;
}
StructVector emval_test_return_StructVector() {
return StructVector(1, 2, 3, 4);
}
StructVector emval_test_take_and_return_StructVector(StructVector v) {
return v;
}
struct CustomStruct {
CustomStruct()
: field(10)
{}
const int& getField() const {
return field;
}
int field;
};
struct TupleInStruct {
TupleVector field;
};
TupleInStruct emval_test_take_and_return_TupleInStruct(TupleInStruct cs) {
return cs;
}
enum Enum { ONE, TWO };
Enum emval_test_take_and_return_Enum(Enum e) {
return e;
}
enum class EnumClass { ONE, TWO };
EnumClass emval_test_take_and_return_EnumClass(EnumClass e) {
return e;
}
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 ~AbstractClass() {}
virtual std::string abstractMethod() const = 0;
virtual std::string optionalMethod(std::string s) const {
return "optional" + s;
}
virtual std::shared_ptr<Derived> returnsSharedPtr() = 0;
virtual void differentArguments(int i, double d, unsigned char f, double q, std::string) = 0;
};
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);
}
std::shared_ptr<Derived> returnsSharedPtr() {
return call<std::shared_ptr<Derived> >("returnsSharedPtr");
}
void differentArguments(int i, double d, unsigned char f, double q, std::string s) {
return call<void>("differentArguments", i, d, f, q, s);
}
};
class ConcreteClass : public AbstractClass {
std::string abstractMethod() const {
return "from concrete";
}
void differentArguments(int i, double d, unsigned char f, double q, std::string s) {
}
std::shared_ptr<Derived> returnsSharedPtr() {
return std::shared_ptr<Derived>();
}
};
std::shared_ptr<AbstractClass> getAbstractClass() {
return std::make_shared<ConcreteClass>();
}
std::string callAbstractMethod(AbstractClass& ac) {
return ac.abstractMethod();
}
std::string callOptionalMethod(AbstractClass& ac, std::string s) {
return ac.optionalMethod(s);
}
void callReturnsSharedPtrMethod(AbstractClass& ac) {
std::shared_ptr<Derived> sp = ac.returnsSharedPtr();
// unused: sp
}
void callDifferentArguments(AbstractClass& ac, int i, double d, unsigned char f, double q, std::string s) {
return ac.differentArguments(i, d, f, q, s);
}
EMSCRIPTEN_BINDINGS(interface_tests) {
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);
function("callReturnsSharedPtrMethod", &callReturnsSharedPtrMethod);
function("callDifferentArguments", &callDifferentArguments);
}
template<typename T, size_t sizeOfArray>
constexpr size_t getElementCount(T (&)[sizeOfArray]) {
return sizeOfArray;
}
static void callWithMemoryView(val v) {
// static so the JS test can read the memory after callTakeMemoryView runs
static unsigned char data[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
v(memory_view(getElementCount(data), data));
static float f[] = { 1.5f, 2.5f, 3.5f, 4.5f };
v(typed_memory_view(getElementCount(f), f));
static short s[] = { 1000, 100, 10, 1 };
v(typed_memory_view(getElementCount(s), s));
}
EMSCRIPTEN_BINDINGS(memory_view_tests) {
function("callWithMemoryView", &callWithMemoryView);
}
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);
}
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;
}
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);
function("emval_test_return_void", &emval_test_return_void);
function("emval_test_not", &emval_test_not);
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(&Vector::getY, &Vector::setY)
.element(&readVectorZ, &writeVectorZ)
.element(index<3>())
;
function("emval_test_return_TupleVector", &emval_test_return_TupleVector);
function("emval_test_take_and_return_TupleVector", &emval_test_take_and_return_TupleVector);
value_tuple<TupleVectorTuple>("TupleVectorTuple")
.element(&TupleVectorTuple::v)
;
function("emval_test_return_TupleVectorTuple", &emval_test_return_TupleVectorTuple);
value_struct<StructVector>("StructVector")
.field("x", &StructVector::x)
.field("y", &Vector::getY, &Vector::setY)
.field("z", &readVectorZ, &writeVectorZ)
.field("w", index<3>())
;
function("emval_test_return_StructVector", &emval_test_return_StructVector);
function("emval_test_take_and_return_StructVector", &emval_test_take_and_return_StructVector);
value_struct<TupleInStruct>("TupleInStruct")
.field("field", &TupleInStruct::field)
;
function("emval_test_take_and_return_TupleInStruct", &emval_test_take_and_return_TupleInStruct);
class_<ValHolder>("ValHolder")
.smart_ptr<std::shared_ptr<ValHolder>>()
.constructor<val>()
.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>()
.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<>()
.property("field", &CustomStruct::field)
.function("getField", &CustomStruct::getField)
;
enum_<Enum>("Enum")
.value("ONE", ONE)
.value("TWO", TWO)
;
function("emval_test_take_and_return_Enum", &emval_test_take_and_return_Enum);
enum_<EnumClass>("EnumClass")
.value("ONE", EnumClass::ONE)
.value("TWO", EnumClass::TWO)
;
function("emval_test_take_and_return_EnumClass", &emval_test_take_and_return_EnumClass);
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("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_<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);
}
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;
}
class MultipleCtors {
public:
int value = 0;
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 MultipleSmartCtors {
public:
int value = 0;
MultipleSmartCtors(int i) {
value = 1;
assert(i == 10);
}
MultipleSmartCtors(int i, int j) {
value = 2;
assert(i == 20);
assert(j == 20);
}
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;
}
};
struct MultipleAccessors {
int getConst() {
return 1;
}
int getConst() const {
return 2;
}
int getConst(int i) const {
return i;
}
};
struct ConstAndNonConst {
void method(int) {
}
int method() const {
return 10;
}
};
EMSCRIPTEN_BINDINGS(overloads) {
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_<MultipleSmartCtors>("MultipleSmartCtors")
.smart_ptr<std::shared_ptr<MultipleSmartCtors>>()
.constructor(&std::make_shared<MultipleSmartCtors, int>)
.constructor(&std::make_shared<MultipleSmartCtors, int, int>)
.function("WhichCtorCalled", &MultipleSmartCtors::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))
;
class_<MultipleAccessors>("MultipleAccessors")
.function("getConst", select_overload<int(int)const>(&MultipleAccessors::getConst))
;
class_<ConstAndNonConst>("ConstAndNonConst")
.function("method", select_const(&ConstAndNonConst::method))
;
}
// 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)
;
}
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);
}
class DerivedWithOffset : public DummyDataToTestPointerAdjustment, public Base {
};
std::shared_ptr<Base> return_Base_from_DerivedWithOffset(std::shared_ptr<DerivedWithOffset> ptr) {
return ptr;
}
EMSCRIPTEN_BINDINGS(with_adjustment) {
class_<DerivedWithOffset, base<Base>>("DerivedWithOffset")
.smart_ptr_constructor(&std::make_shared<DerivedWithOffset>)
;
function("return_Base_from_DerivedWithOffset", &return_Base_from_DerivedWithOffset);
}