/tests/embind/embind_test.cpp

http://github.com/kripken/emscripten · C++ · 3036 lines · 2424 code · 569 blank · 43 comment · 48 complexity · db543af386d4783d9824abe8caca9ffc MD5 · raw file

  1. // Copyright 2012 The Emscripten Authors. All rights reserved.
  2. // Emscripten is available under two separate licenses, the MIT license and the
  3. // University of Illinois/NCSA Open Source License. Both these licenses can be
  4. // found in the LICENSE file.
  5. #include <string>
  6. #include <malloc.h>
  7. #include <functional>
  8. #include <emscripten/bind.h>
  9. using namespace emscripten;
  10. val emval_test_mallinfo() {
  11. const auto& i = mallinfo();
  12. val rv(val::object());
  13. rv.set("arena", val(i.arena));
  14. rv.set("ordblks", val(i.ordblks));
  15. rv.set("smblks", val(i.smblks));
  16. rv.set("hblks", val(i.hblks));
  17. rv.set("usmblks", val(i.usmblks));
  18. rv.set("fsmblks", val(i.fsmblks));
  19. rv.set("uordblks", val(i.uordblks));
  20. rv.set("fordblks", val(i.fordblks));
  21. rv.set("keepcost", val(i.keepcost));
  22. return rv;
  23. }
  24. val emval_test_new_integer() {
  25. return val(15);
  26. }
  27. val emval_test_new_string() {
  28. return val("Hello everyone");
  29. }
  30. std::string emval_test_get_string_from_val(val v) {
  31. return v["key"].as<std::string>();
  32. }
  33. val emval_test_new_object() {
  34. val rv(val::object());
  35. rv.set("foo", val("bar"));
  36. rv.set("baz", val(1));
  37. return rv;
  38. }
  39. struct DummyForPointer {
  40. int value;
  41. DummyForPointer(const int v) : value(v) {}
  42. };
  43. static DummyForPointer emval_pointer_dummy(42);
  44. val emval_test_instance_pointer() {
  45. DummyForPointer* p = &emval_pointer_dummy;
  46. return val(p);
  47. }
  48. int emval_test_value_from_instance_pointer(val v) {
  49. DummyForPointer * p = v.as<DummyForPointer *>(allow_raw_pointers());
  50. return p->value;
  51. }
  52. unsigned emval_test_passthrough_unsigned(unsigned v) {
  53. return v;
  54. }
  55. val emval_test_passthrough(val v) {
  56. return v;
  57. }
  58. void emval_test_return_void() {
  59. }
  60. bool emval_test_not(bool b) {
  61. return !b;
  62. }
  63. bool emval_test_is_true(val v) {
  64. return v.isTrue();
  65. }
  66. bool emval_test_is_false(val v) {
  67. return v.isFalse();
  68. }
  69. bool emval_test_is_null(val v) {
  70. return v.isNull();
  71. }
  72. bool emval_test_is_undefined(val v) {
  73. return v.isUndefined();
  74. }
  75. bool emval_test_equals(val v1,val v2) {
  76. return v1.equals(v2);
  77. }
  78. bool emval_test_strictly_equals(val v1, val v2) {
  79. return v1.strictlyEquals(v2);
  80. }
  81. unsigned emval_test_as_unsigned(val v) {
  82. return v.as<unsigned>();
  83. }
  84. unsigned emval_test_get_length(val v) {
  85. return v["length"].as<unsigned>();
  86. }
  87. 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) {
  88. return c + sc + uc + ss + us + si + ui + sl + ul + f + d;
  89. }
  90. float const_ref_adder(const int& i, const float& f) {
  91. return i + f;
  92. }
  93. unsigned emval_test_sum(val v) {
  94. unsigned length = v["length"].as<unsigned>();
  95. double rv = 0;
  96. for (unsigned i = 0; i < length; ++i) {
  97. rv += v[i].as<double>();
  98. }
  99. return rv;
  100. }
  101. std::string get_non_ascii_string(bool embindStdStringUTF8Support) {
  102. if(embindStdStringUTF8Support) {
  103. //ASCII
  104. std::string testString{"aei"};
  105. //Latin-1 Supplement
  106. testString += "\u00E1\u00E9\u00ED";
  107. //Greek
  108. testString += "\u03B1\u03B5\u03B9";
  109. //Cyrillic
  110. testString += "\u0416\u041B\u0424";
  111. //CJK
  112. testString += "\u5F9E\u7345\u5B50";
  113. //Euro sign
  114. testString += "\u20AC";
  115. return testString;
  116. } else {
  117. char c[128 + 1];
  118. c[128] = 0;
  119. for (int i = 0; i < 128; ++i) {
  120. c[i] = 128 + i;
  121. }
  122. return c;
  123. }
  124. }
  125. std::wstring get_non_ascii_wstring() {
  126. std::wstring ws(4, 0);
  127. ws[0] = 10;
  128. ws[1] = 1234;
  129. ws[2] = 2345;
  130. ws[3] = 65535;
  131. return ws;
  132. }
  133. std::u16string get_non_ascii_u16string() {
  134. std::u16string u16s(4, 0);
  135. u16s[0] = 10;
  136. u16s[1] = 1234;
  137. u16s[2] = 2345;
  138. u16s[3] = 65535;
  139. return u16s;
  140. }
  141. std::u32string get_non_ascii_u32string() {
  142. std::u32string u32s(5, 0);
  143. u32s[0] = 10;
  144. u32s[1] = 1234;
  145. u32s[2] = 2345;
  146. u32s[3] = 128513;
  147. u32s[4] = 128640;
  148. return u32s;
  149. }
  150. std::wstring get_literal_wstring() {
  151. return L"get_literal_wstring";
  152. }
  153. std::u16string get_literal_u16string() {
  154. return u"get_literal_u16string";
  155. }
  156. std::u32string get_literal_u32string() {
  157. return U"get_literal_u32string";
  158. }
  159. void force_memory_growth() {
  160. val module = val::global("Module");
  161. std::size_t heap_size = module["HEAPU8"]["byteLength"].as<size_t>();
  162. free(malloc(heap_size + 1));
  163. }
  164. std::string emval_test_take_and_return_const_char_star(const char* str) {
  165. return str;
  166. }
  167. std::string emval_test_take_and_return_std_string(std::string str) {
  168. return str;
  169. }
  170. std::string emval_test_take_and_return_std_string_const_ref(const std::string& str) {
  171. return str;
  172. }
  173. std::basic_string<unsigned char> emval_test_take_and_return_std_basic_string_unsigned_char(std::basic_string<unsigned char> str) {
  174. return str;
  175. }
  176. std::wstring take_and_return_std_wstring(std::wstring str) {
  177. return str;
  178. }
  179. std::u16string take_and_return_std_u16string(std::u16string str) {
  180. return str;
  181. }
  182. std::u32string take_and_return_std_u32string(std::u32string str) {
  183. return str;
  184. }
  185. std::function<std::string (std::string)> emval_test_get_function_ptr() {
  186. return emval_test_take_and_return_std_string;
  187. }
  188. std::string emval_test_take_and_call_functor(std::function<std::string(std::string)> func) {
  189. return func("asdf");
  190. }
  191. class ValHolder {
  192. public:
  193. ValHolder(val v)
  194. : v_(v)
  195. {}
  196. val getVal() const {
  197. return v_;
  198. }
  199. val getValNonConst() {
  200. return v_;
  201. }
  202. const val getConstVal() const {
  203. return v_;
  204. }
  205. const val& getValConstRef() const {
  206. return v_;
  207. }
  208. void setVal(val v) {
  209. this->v_ = v;
  210. }
  211. static int some_class_method(int i) {
  212. return i;
  213. }
  214. static const ValHolder* makeConst(val v) {
  215. return new ValHolder(v);
  216. }
  217. static ValHolder makeValHolder(val v) {
  218. return ValHolder(v);
  219. }
  220. static void set_via_raw_pointer(ValHolder* vh, val v) {
  221. vh->setVal(v);
  222. }
  223. static val get_via_raw_pointer(const ValHolder* vh) {
  224. return vh->getVal();
  225. }
  226. static void transfer_via_raw_pointer(ValHolder* target, const ValHolder* source) {
  227. target->setVal(source->getVal());
  228. }
  229. static val getValNonMember(const ValHolder& target) {
  230. return target.getVal();
  231. }
  232. private:
  233. val v_;
  234. };
  235. ValHolder emval_test_return_ValHolder() {
  236. return val::object();
  237. }
  238. val valholder_get_value_mixin(const ValHolder& target) {
  239. return target.getVal();
  240. }
  241. void valholder_set_value_mixin(ValHolder& target, const val& value) {
  242. target.setVal(value);
  243. }
  244. void emval_test_set_ValHolder_to_empty_object(ValHolder& vh) {
  245. vh.setVal(val::object());
  246. }
  247. class StringHolder {
  248. public:
  249. StringHolder(const std::string& s)
  250. : str_(s)
  251. {}
  252. void set(const std::string& s) {
  253. str_ = s;
  254. }
  255. std::string get() const {
  256. return str_;
  257. }
  258. std::string& get_ref() {
  259. return str_;
  260. }
  261. const std::string& get_const_ref() const {
  262. return str_;
  263. }
  264. private:
  265. std::string str_;
  266. };
  267. class SharedPtrHolder {
  268. public:
  269. SharedPtrHolder()
  270. : ptr_(new StringHolder("a string"))
  271. {}
  272. std::shared_ptr<StringHolder> get() const {
  273. return ptr_;
  274. }
  275. void set(std::shared_ptr<StringHolder> p) {
  276. ptr_ = p;
  277. }
  278. private:
  279. std::shared_ptr<StringHolder> ptr_;
  280. };
  281. class VectorHolder {
  282. public:
  283. VectorHolder() {
  284. v_.push_back(StringHolder("string #1"));
  285. v_.push_back(StringHolder("string #2"));
  286. }
  287. std::vector<StringHolder> get() const {
  288. return v_;
  289. }
  290. void set(std::vector<StringHolder> vec) {
  291. v_ = vec;
  292. }
  293. private:
  294. std::vector<StringHolder> v_;
  295. };
  296. class SmallClass {
  297. public:
  298. SmallClass(): member(7) {};
  299. int member;
  300. };
  301. class BigClass {
  302. public:
  303. BigClass(): member(11) {};
  304. int member;
  305. int otherMember;
  306. int yetAnotherMember;
  307. int getMember() {
  308. return member;
  309. }
  310. };
  311. class ParentClass {
  312. public:
  313. ParentClass(): bigClass() {};
  314. BigClass bigClass;
  315. const BigClass& getBigClass() {
  316. return bigClass;
  317. };
  318. };
  319. template<typename T>
  320. class TemplateClass {
  321. public:
  322. TemplateClass(T a, T b, T c) {
  323. members[0] = a;
  324. members[1] = b;
  325. members[2] = c;
  326. };
  327. const T getMember(int n) {
  328. return members[n];
  329. }
  330. protected:
  331. T members[3];
  332. };
  333. class ContainsTemplatedMemberClass {
  334. public:
  335. ContainsTemplatedMemberClass(): testTemplate(86, 87, 88) {};
  336. TemplateClass<int> testTemplate;
  337. const TemplateClass<int>& getTestTemplate() {
  338. return testTemplate;
  339. };
  340. };
  341. // Begin Inheritance Hierarchy Class Definitions
  342. class Base {
  343. public:
  344. Base(): name("Base"),
  345. member(0),
  346. baseMember(0)
  347. {}
  348. std::string getClassName() const {
  349. return name;
  350. }
  351. std::string getClassNameFromBase() const {
  352. return name;
  353. }
  354. std::string getClassNameNotAvailableInDerivedClasses() {
  355. // but wait -- if you act now we will throw in a SECOND base class method ABSOLUTELY FREE!!
  356. return name;
  357. }
  358. void setMember(int value) {
  359. member = value;
  360. }
  361. int getMember() {
  362. return member;
  363. }
  364. void setBaseMember(int value) {
  365. baseMember = value;
  366. }
  367. int getBaseMember() {
  368. return baseMember;
  369. }
  370. std::string name;
  371. int member;
  372. int baseMember;
  373. };
  374. class SecondBase {
  375. public:
  376. SecondBase()
  377. : name("SecondBase"),
  378. member(0),
  379. secondBaseMember(0)
  380. {}
  381. std::string getClassName() const {
  382. return name;
  383. }
  384. std::string getClassNameNotAvailableInDerivedClasses() {
  385. return name;
  386. }
  387. std::string getClassNameFromSecondBase() const {
  388. return name;
  389. }
  390. void setMember(int value) {
  391. member = value;
  392. }
  393. int getMember() {
  394. return member;
  395. }
  396. void setSecondBaseMember(int value) {
  397. secondBaseMember = value;
  398. }
  399. int getSecondBaseMember() {
  400. return secondBaseMember;
  401. }
  402. std::string name;
  403. int member;
  404. int secondBaseMember;
  405. };
  406. class Derived : public Base{
  407. public:
  408. Derived()
  409. : Base()
  410. , member(0)
  411. , name_("Derived")
  412. {}
  413. std::string getClassName() const {
  414. return name_;
  415. }
  416. void setMember(int value) {
  417. member = value;
  418. }
  419. int getMember() {
  420. return member;
  421. }
  422. int member;
  423. private:
  424. std::string name_;
  425. };
  426. class DerivedHolder {
  427. public:
  428. DerivedHolder() {
  429. derived_.reset();
  430. }
  431. void newDerived() {
  432. deleteDerived();
  433. derived_ = std::shared_ptr<Derived>(new Derived());
  434. }
  435. void deleteDerived() {
  436. derived_.reset();
  437. }
  438. std::shared_ptr<Derived> getDerived() {
  439. return derived_;
  440. }
  441. std::string getDerivedClassName() {
  442. return derived_->getClassName();
  443. }
  444. private:
  445. std::shared_ptr<Derived> derived_;
  446. };
  447. class SiblingDerived : public Base {
  448. public:
  449. SiblingDerived()
  450. : Base(),
  451. name_("SiblingDerived")
  452. {}
  453. std::string getClassName() const {
  454. return name_;
  455. }
  456. private:
  457. std::string name_;
  458. };
  459. class MultiplyDerived : public Base, public SecondBase {
  460. public:
  461. MultiplyDerived()
  462. : Base(), SecondBase(),
  463. name_("MultiplyDerived")
  464. { instanceCount_ ++; }
  465. ~MultiplyDerived()
  466. { instanceCount_ --; }
  467. std::string getClassName() const {
  468. return name_;
  469. }
  470. static int getInstanceCount() {
  471. return instanceCount_;
  472. }
  473. private:
  474. std::string name_;
  475. static int instanceCount_;
  476. };
  477. int MultiplyDerived::instanceCount_ = 0;
  478. class DerivedTwice : public Derived {
  479. public:
  480. DerivedTwice()
  481. : Derived(),
  482. name_("DerivedTwice")
  483. {}
  484. std::string getClassName() const {
  485. return name_;
  486. }
  487. private:
  488. std::string name_;
  489. };
  490. class DerivedTwiceNotBound : public Derived {
  491. public:
  492. DerivedTwiceNotBound()
  493. : Derived(),
  494. name_("DerivedTwiceNotBound")
  495. {}
  496. std::string getClassName() const {
  497. return name_;
  498. }
  499. private:
  500. std::string name_;
  501. };
  502. class DerivedThrice: public DerivedTwiceNotBound {
  503. public:
  504. DerivedThrice()
  505. : DerivedTwiceNotBound(),
  506. name_("DerivedThrice")
  507. {}
  508. std::string getClassName() const {
  509. return name_;
  510. }
  511. private:
  512. std::string name_;
  513. };
  514. class DerivedFourTimesNotBound: public DerivedThrice {
  515. public:
  516. DerivedFourTimesNotBound()
  517. : DerivedThrice(),
  518. name_("DerivedFourTimesNotBound")
  519. {}
  520. std::string getClassName() const {
  521. return name_;
  522. }
  523. private:
  524. std::string name_;
  525. };
  526. class PolyBase {
  527. public:
  528. PolyBase(const std::string& s)
  529. : str_(s),
  530. name_("PolyBase")
  531. {}
  532. PolyBase(): name_("PolyBase") {}
  533. virtual ~PolyBase() {}
  534. virtual std::string virtualGetClassName() const {
  535. return name_;
  536. }
  537. std::string getClassName() const {
  538. return name_;
  539. }
  540. private:
  541. std::string str_;
  542. std::string name_;
  543. };
  544. class PolySecondBase {
  545. public:
  546. PolySecondBase(): name_("PolySecondBase")
  547. {}
  548. virtual ~PolySecondBase() {}
  549. std::string getClassName() const {
  550. return name_;
  551. }
  552. private:
  553. std::string name_;
  554. };
  555. class PolyDerived : public PolyBase{
  556. public:
  557. PolyDerived()
  558. : PolyBase("PolyDerived"),
  559. name_("PolyDerived")
  560. {}
  561. std::string virtualGetClassName() const {
  562. return name_;
  563. }
  564. std::string getClassName() const {
  565. return name_;
  566. }
  567. static void setPtrDerived() {
  568. ptr_ = std::shared_ptr<PolyDerived>(new PolyDerived());
  569. }
  570. static void releasePtr() {
  571. ptr_.reset();
  572. }
  573. static std::string getPtrClassName() {
  574. return ptr_->getClassName();
  575. }
  576. static std::shared_ptr<PolyBase> getPtr() {
  577. return ptr_;
  578. }
  579. private:
  580. std::string name_;
  581. static std::shared_ptr<PolyBase> ptr_;
  582. };
  583. std::shared_ptr<PolyBase> PolyDerived::ptr_;
  584. class PolySiblingDerived : public PolyBase {
  585. public:
  586. PolySiblingDerived()
  587. : PolyBase(),
  588. name_("PolySiblingDerived")
  589. {}
  590. std::string getClassName() const {
  591. return name_;
  592. }
  593. private:
  594. std::string name_;
  595. };
  596. class PolyMultiplyDerived : public PolyBase, public PolySecondBase {
  597. public:
  598. PolyMultiplyDerived()
  599. : PolyBase(), PolySecondBase(),
  600. name_("PolyMultiplyDerived")
  601. {}
  602. std::string getClassName() const {
  603. return name_;
  604. }
  605. private:
  606. std::string name_;
  607. };
  608. class PolyDerivedTwiceWithoutSmartPointer: public PolyDerived {
  609. public:
  610. PolyDerivedTwiceWithoutSmartPointer()
  611. : PolyDerived(),
  612. name_("PolyDerivedTwiceWithoutSmartPointer")
  613. {}
  614. std::string getClassName() const {
  615. return name_;
  616. }
  617. private:
  618. std::string name_;
  619. };
  620. class PolyDerivedTwiceNotBound : public PolyDerived {
  621. public:
  622. PolyDerivedTwiceNotBound()
  623. : PolyDerived(),
  624. name_("PolyDerivedTwiceNotBound")
  625. {}
  626. std::string getClassName() const {
  627. return name_;
  628. }
  629. private:
  630. std::string name_;
  631. };
  632. class PolyDerivedThrice: public PolyDerivedTwiceNotBound {
  633. public:
  634. PolyDerivedThrice()
  635. : PolyDerivedTwiceNotBound(),
  636. name_("PolyDerivedThrice")
  637. {}
  638. std::string getClassName() const {
  639. return name_;
  640. }
  641. private:
  642. std::string name_;
  643. };
  644. class PolyDerivedFourTimesNotBound: public PolyDerivedThrice {
  645. public:
  646. PolyDerivedFourTimesNotBound()
  647. : PolyDerivedThrice(),
  648. name_("PolyDerivedFourTimesNotBound")
  649. {}
  650. std::string getClassName() const {
  651. return name_;
  652. }
  653. private:
  654. std::string name_;
  655. };
  656. class PolyDiamondBase {
  657. public:
  658. PolyDiamondBase():
  659. name_("PolyBase")
  660. {}
  661. ~PolyDiamondBase() {}
  662. std::string getClassName() const {
  663. return name_;
  664. }
  665. private:
  666. std::string name_;
  667. };
  668. class PolyDiamondDerived: public PolyDiamondBase {
  669. public:
  670. PolyDiamondDerived()
  671. : PolyDiamondBase(),
  672. name_("PolyDiamondDerived")
  673. {}
  674. std::string getClassName() const {
  675. return name_;
  676. }
  677. private:
  678. std::string name_;
  679. };
  680. class PolyDiamondSiblingDerived: public PolyDiamondBase {
  681. public:
  682. PolyDiamondSiblingDerived()
  683. : PolyDiamondBase(),
  684. name_("PolyDiamondSiblingDerived")
  685. {}
  686. std::string getClassName() const {
  687. return name_;
  688. }
  689. private:
  690. std::string name_;
  691. };
  692. class PolyDiamondMultiplyDerived: public PolyDiamondDerived, public PolyDiamondSiblingDerived {
  693. public:
  694. PolyDiamondMultiplyDerived()
  695. : PolyDiamondDerived(), PolyDiamondSiblingDerived(),
  696. name_("PolyDiamondMultiplyDerived")
  697. {}
  698. std::string getClassName() const {
  699. return name_;
  700. }
  701. private:
  702. std::string name_;
  703. };
  704. // End Inheritance Hierarchy Class Definitions
  705. std::map<std::string, int> embind_test_get_string_int_map() {
  706. std::map<std::string, int> m;
  707. m["one"] = 1;
  708. m["two"] = 2;
  709. return m;
  710. };
  711. struct Vector {
  712. Vector() = delete;
  713. Vector(float x_, float y_, float z_, float w_)
  714. : x(x_)
  715. , y(y_)
  716. , z(z_)
  717. , w(w_)
  718. {}
  719. float x, y, z, w;
  720. float& operator[](int i) {
  721. return (&x)[i];
  722. }
  723. const float& operator[](int i) const {
  724. return (&x)[i];
  725. }
  726. float getY() const {
  727. return y;
  728. }
  729. void setY(float _y) {
  730. y = _y;
  731. }
  732. };
  733. struct DummyDataToTestPointerAdjustment {
  734. std::string dummy;
  735. };
  736. struct TupleVector : DummyDataToTestPointerAdjustment, Vector {
  737. TupleVector(): Vector(0, 0, 0, 0) {}
  738. TupleVector(float x, float y, float z, float w): Vector(x, y, z, w) {}
  739. };
  740. struct StructVector : DummyDataToTestPointerAdjustment, Vector {
  741. StructVector(): Vector(0, 0, 0, 0) {}
  742. StructVector(float x, float y, float z, float w): Vector(x, y, z, w) {}
  743. };
  744. float readVectorZ(const Vector& v) {
  745. return v.z;
  746. }
  747. void writeVectorZ(Vector& v, float z) {
  748. v.z = z;
  749. }
  750. struct TupleVectorTuple {
  751. TupleVector v = TupleVector(0, 0, 0, 0);
  752. };
  753. TupleVector emval_test_return_TupleVector() {
  754. return TupleVector(1, 2, 3, 4);
  755. }
  756. TupleVector emval_test_take_and_return_TupleVector(TupleVector v) {
  757. return v;
  758. }
  759. TupleVectorTuple emval_test_return_TupleVectorTuple() {
  760. TupleVectorTuple cvt;
  761. cvt.v = emval_test_return_TupleVector();
  762. return cvt;
  763. }
  764. StructVector emval_test_return_StructVector() {
  765. return StructVector(1, 2, 3, 4);
  766. }
  767. StructVector emval_test_take_and_return_StructVector(StructVector v) {
  768. return v;
  769. }
  770. struct CustomStruct {
  771. CustomStruct()
  772. : field(10)
  773. {}
  774. const int& getField() const {
  775. return field;
  776. }
  777. int field;
  778. };
  779. struct TupleInStruct {
  780. TupleVector field;
  781. };
  782. TupleInStruct emval_test_take_and_return_TupleInStruct(TupleInStruct cs) {
  783. return cs;
  784. }
  785. struct NestedStruct {
  786. int x;
  787. int y;
  788. };
  789. struct ArrayInStruct {
  790. int field1[2];
  791. NestedStruct field2[2];
  792. };
  793. ArrayInStruct emval_test_take_and_return_ArrayInStruct(ArrayInStruct cs) {
  794. return cs;
  795. }
  796. enum Enum { ONE, TWO };
  797. Enum emval_test_take_and_return_Enum(Enum e) {
  798. return e;
  799. }
  800. enum class EnumClass : char { ONE, TWO };
  801. EnumClass emval_test_take_and_return_EnumClass(EnumClass e) {
  802. return e;
  803. }
  804. void emval_test_call_function(val v, int i, float f, TupleVector tv, StructVector sv) {
  805. v(i, f, tv, sv);
  806. }
  807. class UniquePtrToConstructor {
  808. public:
  809. UniquePtrToConstructor(std::unique_ptr<int> p)
  810. : value(*p)
  811. {}
  812. int getValue() const {
  813. return value;
  814. }
  815. private:
  816. int value;
  817. };
  818. std::unique_ptr<int> embind_test_return_unique_ptr(int v) {
  819. return std::unique_ptr<int>(new int(v));
  820. }
  821. UniquePtrToConstructor* embind_test_construct_class_with_unique_ptr(int v) {
  822. return new UniquePtrToConstructor(embind_test_return_unique_ptr(v));
  823. }
  824. int embind_test_accept_unique_ptr(std::unique_ptr<int> p) {
  825. return *p.get();
  826. }
  827. std::unique_ptr<ValHolder> emval_test_return_unique_ptr() {
  828. return std::unique_ptr<ValHolder>(new ValHolder(val::object()));
  829. }
  830. class UniquePtrLifetimeMock {
  831. public:
  832. UniquePtrLifetimeMock(val l) : logger(l) {
  833. logger(std::string("(constructor)"));
  834. }
  835. ~UniquePtrLifetimeMock() {
  836. logger(std::string("(destructor)"));
  837. }
  838. private:
  839. val logger;
  840. };
  841. std::unique_ptr<UniquePtrLifetimeMock> emval_test_return_unique_ptr_lifetime(val logger) {
  842. return std::unique_ptr<UniquePtrLifetimeMock>(new UniquePtrLifetimeMock(logger));
  843. }
  844. std::shared_ptr<ValHolder> emval_test_return_shared_ptr() {
  845. return std::shared_ptr<ValHolder>(new ValHolder(val::object()));
  846. }
  847. std::shared_ptr<ValHolder> emval_test_return_empty_shared_ptr() {
  848. return std::shared_ptr<ValHolder>();
  849. }
  850. bool emval_test_is_shared_ptr_null(std::shared_ptr<ValHolder> p) {
  851. return !p;
  852. }
  853. static SmallClass smallClass;
  854. static BigClass bigClass;
  855. SmallClass embind_test_return_small_class_instance() {
  856. return smallClass;
  857. }
  858. BigClass embind_test_return_big_class_instance() {
  859. return bigClass;
  860. }
  861. int embind_test_accept_small_class_instance(SmallClass c) {
  862. return c.member;
  863. }
  864. int embind_test_accept_big_class_instance(BigClass c) {
  865. return c.member;
  866. }
  867. // Begin Inheritance Hierarchy Test Wrappers
  868. Base* embind_test_return_raw_base_ptr() {
  869. return new Base();
  870. }
  871. Base* embind_test_return_raw_derived_ptr_as_base() {
  872. return new Derived();
  873. }
  874. Base* embind_test_return_raw_sibling_derived_ptr_as_base() {
  875. return new SiblingDerived();
  876. }
  877. PolyBase* embind_test_return_raw_polymorphic_derived_ptr_as_base() {
  878. return new PolyDerived();
  879. }
  880. PolyBase* embind_test_return_raw_polymorphic_sibling_derived_ptr_as_base() {
  881. return new PolySiblingDerived();
  882. }
  883. PolyBase* embind_test_return_raw_polymorphic_multiply_derived_ptr_as_base() {
  884. return new PolyMultiplyDerived();
  885. }
  886. PolySecondBase* embind_test_return_raw_polymorphic_multiply_derived_ptr_as_second_base() {
  887. return new PolyMultiplyDerived();
  888. }
  889. PolyBase* embind_test_return_raw_polymorphic_derived_four_times_not_bound_as_base() {
  890. return new PolyDerivedFourTimesNotBound();
  891. }
  892. std::shared_ptr<Base> embind_test_return_smart_base_ptr() {
  893. return std::shared_ptr<Base>(new Base());
  894. }
  895. std::shared_ptr<PolyBase> embind_test_return_smart_polymorphic_base_ptr() {
  896. return std::shared_ptr<PolyBase>(new PolyBase("PolyBase"));
  897. }
  898. std::shared_ptr<Derived> embind_test_return_smart_derived_ptr() {
  899. return std::shared_ptr<Derived>(new Derived());
  900. }
  901. std::shared_ptr<SiblingDerived> embind_test_return_smart_sibling_derived_ptr() {
  902. return std::shared_ptr<SiblingDerived>(new SiblingDerived());
  903. }
  904. std::shared_ptr<MultiplyDerived> embind_test_return_smart_multiply_derived_ptr() {
  905. return std::shared_ptr<MultiplyDerived>(new MultiplyDerived());
  906. }
  907. std::shared_ptr<DerivedThrice> embind_test_return_smart_derived_thrice_ptr() {
  908. return std::shared_ptr<DerivedThrice>(new DerivedThrice());
  909. }
  910. std::shared_ptr<PolyDerived> embind_test_return_smart_polymorphic_derived_ptr() {
  911. return std::shared_ptr<PolyDerived>(new PolyDerived());
  912. }
  913. std::shared_ptr<PolySiblingDerived> embind_test_return_smart_polymorphic_sibling_derived_ptr() {
  914. return std::shared_ptr<PolySiblingDerived>(new PolySiblingDerived());
  915. }
  916. std::shared_ptr<PolyMultiplyDerived> embind_test_return_smart_polymorphic_multiply_derived_ptr() {
  917. return std::shared_ptr<PolyMultiplyDerived>(new PolyMultiplyDerived());
  918. }
  919. std::shared_ptr<PolyBase> embind_test_return_poly_derived_twice_without_smart_pointer_as_poly_base() {
  920. return std::shared_ptr<PolyBase>(new PolyDerivedTwiceWithoutSmartPointer());
  921. }
  922. std::shared_ptr<PolyDerivedThrice> embind_test_return_smart_poly_derived_thrice_ptr() {
  923. return std::shared_ptr<PolyDerivedThrice>(new PolyDerivedThrice());
  924. }
  925. std::shared_ptr<PolyBase> embind_test_return_smart_derived_ptr_as_base() {
  926. return std::shared_ptr<PolyBase>(new PolyDerived());
  927. }
  928. val embind_test_return_smart_derived_ptr_as_val() {
  929. return val(std::shared_ptr<PolyBase>(new PolyDerived()));
  930. }
  931. std::shared_ptr<PolyBase> embind_test_return_smart_polymorphic_derived_ptr_as_base() {
  932. return std::shared_ptr<PolyBase>(new PolyDerived());
  933. }
  934. std::shared_ptr<PolyBase> embind_test_return_smart_polymorphic_sibling_derived_ptr_as_base() {
  935. return std::shared_ptr<PolyBase>(new PolySiblingDerived());
  936. }
  937. std::string embind_test_get_class_name_via_base_ptr(Base *p) {
  938. return p->getClassName();
  939. }
  940. std::string embind_test_get_class_name_via_second_base_ptr(SecondBase *p) {
  941. return p->getClassName();
  942. }
  943. std::string embind_test_get_class_name_via_polymorphic_base_ptr(PolyBase *p) {
  944. return p->getClassName();
  945. }
  946. std::string embind_test_get_class_name_via_polymorphic_second_base_ptr(PolySecondBase *p) {
  947. return p->getClassName();
  948. }
  949. std::string embind_test_get_class_name_via_smart_base_ptr(std::shared_ptr<Base> p) {
  950. return p->getClassName();
  951. }
  952. std::string embind_test_get_class_name_via_reference_to_smart_base_ptr(std::shared_ptr<Base>& p) {
  953. return p->getClassName();
  954. }
  955. std::string embind_test_get_class_name_via_smart_second_base_ptr(std::shared_ptr<SecondBase> p) {
  956. return p->getClassName();
  957. }
  958. std::string embind_test_get_class_name_via_smart_polymorphic_base_ptr(std::shared_ptr<PolyBase> p) {
  959. return p->getClassName();
  960. }
  961. std::string embind_test_get_virtual_class_name_via_smart_polymorphic_base_ptr(std::shared_ptr<PolyBase> p) {
  962. return p->virtualGetClassName();
  963. }
  964. std::string embind_test_get_class_name_via_smart_polymorphic_second_base_ptr(std::shared_ptr<PolySecondBase> p) {
  965. return p->getClassName();
  966. }
  967. void embind_modify_smart_pointer_passed_by_reference(std::shared_ptr<Base>& p) {
  968. p = std::shared_ptr<Base>(new Base());
  969. p->name = "Changed";
  970. }
  971. void embind_attempt_to_modify_smart_pointer_when_passed_by_value(std::shared_ptr<Base> p) {
  972. p = std::shared_ptr<Base>(new Base());
  973. p->name = "Changed";
  974. }
  975. static std::shared_ptr<Base> savedBasePointer;
  976. void embind_save_smart_base_pointer(std::shared_ptr<Base> p) {
  977. savedBasePointer = p;
  978. }
  979. // End Inheritance Hierarchy Test Wrappers
  980. std::vector<int> emval_test_return_vector() {
  981. int myints[] = { 10, 20, 30 };
  982. return std::vector<int>(myints, myints + sizeof(myints) / sizeof(int));
  983. }
  984. std::vector<std::vector<int> > emval_test_return_vector_of_vectors() {
  985. int myints1[] = { 10, 20, 30 };
  986. int myints2[] = { 40, 50, 60 };
  987. std::vector<int> vec1(myints1, myints1 + sizeof(myints1) / sizeof(int));
  988. std::vector<int> vec2(myints2, myints2 + sizeof(myints2) / sizeof(int));
  989. std::vector<std::vector<int>>vec3;
  990. vec3.emplace_back(vec1);
  991. vec3.emplace_back(vec2);
  992. return vec3;
  993. }
  994. std::vector<std::shared_ptr<StringHolder>> emval_test_return_shared_ptr_vector() {
  995. std::vector<std::shared_ptr<StringHolder>> sharedStrVector;
  996. sharedStrVector.push_back(std::shared_ptr<StringHolder>(new StringHolder("string #1")));
  997. sharedStrVector.push_back(std::shared_ptr<StringHolder>(new StringHolder("string #2")));
  998. return sharedStrVector;
  999. }
  1000. void test_string_with_vec(const std::string& p1, std::vector<std::string>& v1) {
  1001. // THIS DOES NOT WORK -- need to get as val and then call vecFromJSArray
  1002. printf("%s\n", p1.c_str());
  1003. }
  1004. val embind_test_getglobal() {
  1005. return val::global();
  1006. }
  1007. val embind_test_new_Object() {
  1008. return val::global("Object").new_();
  1009. }
  1010. val embind_test_new_factory(val factory, val argument) {
  1011. return factory.new_(10, std::string("hello"), argument);
  1012. }
  1013. class AbstractClass {
  1014. public:
  1015. virtual ~AbstractClass() {}
  1016. virtual std::string abstractMethod() const = 0;
  1017. virtual std::string optionalMethod(std::string s) const {
  1018. return "optional" + s;
  1019. }
  1020. virtual std::shared_ptr<Derived> returnsSharedPtr() = 0;
  1021. virtual void differentArguments(int i, double d, unsigned char f, double q, std::string) = 0;
  1022. std::string concreteMethod() const {
  1023. return "concrete";
  1024. }
  1025. virtual void passShared(const std::shared_ptr<Derived>&) {
  1026. }
  1027. virtual void passVal(const val& v) {
  1028. }
  1029. };
  1030. EMSCRIPTEN_SYMBOL(optionalMethod);
  1031. class AbstractClassWrapper : public wrapper<AbstractClass> {
  1032. public:
  1033. EMSCRIPTEN_WRAPPER(AbstractClassWrapper);
  1034. std::string abstractMethod() const override {
  1035. return call<std::string>("abstractMethod");
  1036. }
  1037. std::string optionalMethod(std::string s) const override {
  1038. return call<std::string>("optionalMethod", s);
  1039. }
  1040. std::shared_ptr<Derived> returnsSharedPtr() override {
  1041. return call<std::shared_ptr<Derived> >("returnsSharedPtr");
  1042. }
  1043. void differentArguments(int i, double d, unsigned char f, double q, std::string s) override {
  1044. return call<void>("differentArguments", i, d, f, q, s);
  1045. }
  1046. virtual void passShared(const std::shared_ptr<Derived>& p) override {
  1047. return call<void>("passShared", p);
  1048. }
  1049. virtual void passVal(const val& v) override {
  1050. return call<void>("passVal", v);
  1051. }
  1052. };
  1053. class ConcreteClass : public AbstractClass {
  1054. std::string abstractMethod() const {
  1055. return "from concrete";
  1056. }
  1057. void differentArguments(int i, double d, unsigned char f, double q, std::string s) {
  1058. }
  1059. std::shared_ptr<Derived> returnsSharedPtr() {
  1060. return std::shared_ptr<Derived>();
  1061. }
  1062. };
  1063. std::shared_ptr<AbstractClass> getAbstractClass() {
  1064. return std::make_shared<ConcreteClass>();
  1065. }
  1066. std::string callAbstractMethod(AbstractClass& ac) {
  1067. return ac.abstractMethod();
  1068. }
  1069. std::string callOptionalMethod(AbstractClass& ac, std::string s) {
  1070. return ac.optionalMethod(s);
  1071. }
  1072. void callReturnsSharedPtrMethod(AbstractClass& ac) {
  1073. std::shared_ptr<Derived> sp = ac.returnsSharedPtr();
  1074. // unused: sp
  1075. }
  1076. void callDifferentArguments(AbstractClass& ac, int i, double d, unsigned char f, double q, std::string s) {
  1077. return ac.differentArguments(i, d, f, q, s);
  1078. }
  1079. struct AbstractClassWithConstructor {
  1080. explicit AbstractClassWithConstructor(std::string s)
  1081. : s(s)
  1082. {}
  1083. virtual ~AbstractClassWithConstructor() {};
  1084. virtual std::string abstractMethod() = 0;
  1085. std::string concreteMethod() {
  1086. return s;
  1087. }
  1088. std::string s;
  1089. };
  1090. struct AbstractClassWithConstructorWrapper : public wrapper<AbstractClassWithConstructor> {
  1091. EMSCRIPTEN_WRAPPER(AbstractClassWithConstructorWrapper);
  1092. virtual std::string abstractMethod() override {
  1093. return call<std::string>("abstractMethod");
  1094. }
  1095. };
  1096. std::string callAbstractMethod2(AbstractClassWithConstructor& ac) {
  1097. return ac.abstractMethod();
  1098. }
  1099. struct HeldAbstractClass : public PolyBase, public PolySecondBase {
  1100. virtual void method() = 0;
  1101. };
  1102. struct HeldAbstractClassWrapper : wrapper<HeldAbstractClass> {
  1103. EMSCRIPTEN_WRAPPER(HeldAbstractClassWrapper);
  1104. virtual void method() override {
  1105. return call<void>("method");
  1106. }
  1107. };
  1108. std::shared_ptr<PolySecondBase> passHeldAbstractClass(std::shared_ptr<HeldAbstractClass> p) {
  1109. return p;
  1110. }
  1111. void passShared(AbstractClass& ac) {
  1112. auto p = std::make_shared<Derived>();
  1113. ac.passShared(p);
  1114. }
  1115. void passVal(AbstractClass& ac, val v) {
  1116. return ac.passVal(v);
  1117. }
  1118. EMSCRIPTEN_BINDINGS(interface_tests) {
  1119. class_<AbstractClass>("AbstractClass")
  1120. .smart_ptr<std::shared_ptr<AbstractClass>>("shared_ptr<AbstractClass>")
  1121. .allow_subclass<AbstractClassWrapper>("AbstractClassWrapper")
  1122. .function("abstractMethod", &AbstractClass::abstractMethod, pure_virtual())
  1123. // The optional_override is necessary because, otherwise, the C++ compiler
  1124. // cannot deduce the signature of the lambda function.
  1125. .function("optionalMethod", optional_override(
  1126. [](AbstractClass& this_, const std::string& s) {
  1127. return this_.AbstractClass::optionalMethod(s);
  1128. }
  1129. ))
  1130. .function("concreteMethod", &AbstractClass::concreteMethod)
  1131. .function("passShared", select_overload<void(AbstractClass&, const std::shared_ptr<Derived>&)>([](AbstractClass& self, const std::shared_ptr<Derived>& derived) {
  1132. self.AbstractClass::passShared(derived);
  1133. }))
  1134. .function("passVal", select_overload<void(AbstractClass&, const val&)>([](AbstractClass& self, const val& v) {
  1135. self.AbstractClass::passVal(v);
  1136. }))
  1137. ;
  1138. function("getAbstractClass", &getAbstractClass);
  1139. function("callAbstractMethod", &callAbstractMethod);
  1140. function("callOptionalMethod", &callOptionalMethod);
  1141. function("callReturnsSharedPtrMethod", &callReturnsSharedPtrMethod);
  1142. function("callDifferentArguments", &callDifferentArguments);
  1143. function("passShared", &passShared);
  1144. function("passVal", &passVal);
  1145. class_<AbstractClassWithConstructor>("AbstractClassWithConstructor")
  1146. .allow_subclass<AbstractClassWithConstructorWrapper>("AbstractClassWithConstructorWrapper", constructor<std::string>())
  1147. .function("abstractMethod", &AbstractClassWithConstructor::abstractMethod, pure_virtual())
  1148. .function("concreteMethod", &AbstractClassWithConstructor::concreteMethod)
  1149. ;
  1150. function("callAbstractMethod2", &callAbstractMethod2);
  1151. class_<HeldAbstractClass, base<PolySecondBase>>("HeldAbstractClass")
  1152. .smart_ptr<std::shared_ptr<HeldAbstractClass>>("shared_ptr<HeldAbstractClass>")
  1153. .allow_subclass<HeldAbstractClassWrapper, std::shared_ptr<HeldAbstractClassWrapper>>("HeldAbstractClassWrapper", "HeldAbstractClassWrapperPtr")
  1154. .function("method", &HeldAbstractClass::method, pure_virtual())
  1155. ;
  1156. function("passHeldAbstractClass", &passHeldAbstractClass);
  1157. }
  1158. template<typename T, size_t sizeOfArray>
  1159. constexpr size_t getElementCount(T (&)[sizeOfArray]) {
  1160. return sizeOfArray;
  1161. }
  1162. static void callWithMemoryView(val v) {
  1163. // static so the JS test can read the memory after callTakeMemoryView runs
  1164. static unsigned char data[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
  1165. v(typed_memory_view(getElementCount(data), data));
  1166. static float f[] = { 1.5f, 2.5f, 3.5f, 4.5f };
  1167. v(typed_memory_view(getElementCount(f), f));
  1168. static short s[] = { 1000, 100, 10, 1 };
  1169. v(typed_memory_view(getElementCount(s), s));
  1170. }
  1171. EMSCRIPTEN_BINDINGS(memory_view_tests) {
  1172. function("callWithMemoryView", &callWithMemoryView);
  1173. }
  1174. class HasExternalConstructor {
  1175. public:
  1176. HasExternalConstructor(const std::string& str)
  1177. : m(str)
  1178. {}
  1179. std::string getString() const {
  1180. return m;
  1181. }
  1182. std::string m;
  1183. };
  1184. HasExternalConstructor* createHasExternalConstructor(const std::string& str) {
  1185. return new HasExternalConstructor(str);
  1186. }
  1187. template<typename T>
  1188. class CustomSmartPtr {
  1189. public:
  1190. CustomSmartPtr()
  1191. : CustomSmartPtr(nullptr)
  1192. {
  1193. std::fill(d_, d_ + N_, Valid);
  1194. }
  1195. explicit CustomSmartPtr(T* t)
  1196. : ptr_(t)
  1197. {
  1198. std::fill(d_, d_ + N_, Valid);
  1199. }
  1200. CustomSmartPtr(const CustomSmartPtr& other)
  1201. : ptr_(other.ptr_)
  1202. {
  1203. other.verify();
  1204. std::fill(d_, d_ + N_, Valid);
  1205. if (ptr_) {
  1206. ++(ptr_->refcount);
  1207. }
  1208. }
  1209. ~CustomSmartPtr() {
  1210. verify();
  1211. std::fill(d_, d_ + N_, Deleted);
  1212. if (ptr_ && --ptr_->refcount == 0) {
  1213. delete ptr_;
  1214. }
  1215. }
  1216. T* get_raw() const {
  1217. return ptr_;
  1218. }
  1219. private:
  1220. void verify() const {
  1221. for (size_t i = 0; i < N_; ++i) {
  1222. if (d_[i] != Valid) {
  1223. abort();
  1224. }
  1225. }
  1226. }
  1227. enum {
  1228. Valid = 255,
  1229. Deleted = 127,
  1230. };
  1231. static constexpr size_t N_ = 1000000;
  1232. unsigned char d_[N_];
  1233. T* ptr_;
  1234. CustomSmartPtr& operator=(const CustomSmartPtr&) = delete;
  1235. };
  1236. class HeldBySmartPtr {
  1237. public:
  1238. HeldBySmartPtr(int i, const std::string& s)
  1239. : i(i)
  1240. , s(s)
  1241. {}
  1242. static CustomSmartPtr<HeldBySmartPtr> newCustomPtr(int i, const std::string& s) {
  1243. return CustomSmartPtr<HeldBySmartPtr>(new HeldBySmartPtr(i, s));
  1244. }
  1245. int refcount = 1;
  1246. int i;
  1247. std::string s;
  1248. };
  1249. HeldBySmartPtr takesHeldBySmartPtr(HeldBySmartPtr p) {
  1250. return p;
  1251. }
  1252. std::shared_ptr<HeldBySmartPtr> takesHeldBySmartPtrSharedPtr(std::shared_ptr<HeldBySmartPtr> p) {
  1253. return p;
  1254. }
  1255. namespace emscripten {
  1256. template<typename T>
  1257. struct smart_ptr_trait<CustomSmartPtr<T>> {
  1258. typedef CustomSmartPtr<T> pointer_type;
  1259. typedef T element_type;
  1260. static sharing_policy get_sharing_policy() {
  1261. return sharing_policy::NONE;
  1262. }
  1263. static T* get(const CustomSmartPtr<T>& p) {
  1264. return p.get_raw();
  1265. }
  1266. static CustomSmartPtr<T> share(const CustomSmartPtr<T>& r, T* ptr) {
  1267. ++ptr->refcount; // implement an adopt API?
  1268. return CustomSmartPtr<T>(ptr);
  1269. }
  1270. static pointer_type* construct_null() {
  1271. return new pointer_type;
  1272. }
  1273. };
  1274. }
  1275. typedef CustomSmartPtr<class HeldByCustomSmartPtr> HeldByCustomSmartPtrPtr;
  1276. class HeldByCustomSmartPtr {
  1277. public:
  1278. HeldByCustomSmartPtr(int i, const std::string& s)
  1279. : i(i)
  1280. , s(s)
  1281. {}
  1282. static HeldByCustomSmartPtrPtr create(int i, const std::string& s) {
  1283. return HeldByCustomSmartPtrPtr(new HeldByCustomSmartPtr(i, s));
  1284. }
  1285. static std::shared_ptr<HeldByCustomSmartPtr> createSharedPtr(int i, const std::string& s) {
  1286. return std::make_shared<HeldByCustomSmartPtr>(i, s);
  1287. };
  1288. int refcount = 1;
  1289. int i;
  1290. std::string s;
  1291. };
  1292. HeldByCustomSmartPtr* passThroughRawPtr(HeldByCustomSmartPtr* p) {
  1293. return p;
  1294. }
  1295. HeldByCustomSmartPtrPtr passThroughCustomSmartPtr(HeldByCustomSmartPtrPtr p) {
  1296. return p;
  1297. }
  1298. struct Base1 {
  1299. public:
  1300. Base1(): field1("Base1") {}
  1301. std::string field1;
  1302. std::string getField() const {
  1303. return field1;
  1304. }
  1305. };
  1306. struct Base2 {
  1307. public:
  1308. Base2(): field2("Base2") {}
  1309. std::string field2;
  1310. std::string getField() const {
  1311. return field2;
  1312. }
  1313. };
  1314. struct HasTwoBases : public Base1, public Base2 {
  1315. };
  1316. val get_module_property(const std::string& s) {
  1317. return val::module_property(s.c_str());
  1318. }
  1319. std::string char_to_string(char ch) {
  1320. char str[256];
  1321. sprintf(str, "%d", (int)ch);
  1322. return str;
  1323. }
  1324. std::string signed_char_to_string(signed char ch) {
  1325. char str[256];
  1326. sprintf(str, "%hhd", ch);
  1327. return str;
  1328. }
  1329. std::string unsigned_char_to_string(unsigned char ch) {
  1330. char str[256];
  1331. sprintf(str, "%hhu", ch);
  1332. return str;
  1333. }
  1334. std::string short_to_string(short val) {
  1335. char str[256];
  1336. sprintf(str, "%hd", val);
  1337. return str;
  1338. }
  1339. std::string unsigned_short_to_string(unsigned short val) {
  1340. char str[256];
  1341. sprintf(str, "%hu", val);
  1342. return str;
  1343. }
  1344. std::string int_to_string(int val) {
  1345. char str[256];
  1346. sprintf(str, "%d", val);
  1347. return str;
  1348. }
  1349. std::string unsigned_int_to_string(unsigned int val) {
  1350. char str[256];
  1351. sprintf(str, "%u", val);
  1352. return str;
  1353. }
  1354. std::string long_to_string(long val) {
  1355. char str[256];
  1356. sprintf(str, "%ld", val);
  1357. return str;
  1358. }
  1359. std::string unsigned_long_to_string(unsigned long val) {
  1360. char str[256];
  1361. sprintf(str, "%lu", val);
  1362. return str;
  1363. }
  1364. //test loading unsigned value from memory
  1365. static unsigned char uchar;
  1366. void store_unsigned_char(unsigned char arg) {
  1367. uchar = arg;
  1368. }
  1369. unsigned char load_unsigned_char() {
  1370. return uchar;
  1371. }
  1372. static unsigned short ushort;
  1373. void store_unsigned_short(unsigned short arg) {
  1374. ushort = arg;
  1375. }
  1376. unsigned short load_unsigned_short() {
  1377. return ushort;
  1378. }
  1379. static unsigned int uint;
  1380. void store_unsigned_int(unsigned int arg) {
  1381. uint = arg;
  1382. }
  1383. unsigned int load_unsigned_int() {
  1384. return uint;
  1385. }
  1386. static unsigned long ulong;
  1387. void store_unsigned_long(unsigned long arg) {
  1388. ulong = arg;
  1389. }
  1390. unsigned long load_unsigned_long() {
  1391. return ulong;
  1392. }
  1393. template <int I>
  1394. class ConstructFromFunctor {
  1395. public:
  1396. ConstructFromFunctor(const val& v, int a)
  1397. : v_(v), a_(a)
  1398. {}
  1399. val getVal() const {
  1400. return v_;
  1401. }
  1402. int getA() const {
  1403. return a_;
  1404. }
  1405. private:
  1406. val v_;
  1407. int a_;
  1408. };
  1409. template <int I>
  1410. ConstructFromFunctor<I> construct_from_functor_mixin(const val& v, int i)
  1411. {
  1412. return {v, i};
  1413. }
  1414. EMSCRIPTEN_BINDINGS(tests) {
  1415. register_vector<int>("IntegerVector");
  1416. register_vector<char>("CharVector");
  1417. register_vector<unsigned>("VectorUnsigned");
  1418. register_vector<unsigned char>("VectorUnsignedChar");
  1419. register_vector<std::string>("StringVector");
  1420. register_vector<emscripten::val>("EmValVector");
  1421. register_vector<float>("FloatVector");
  1422. register_vector<std::vector<int>>("IntegerVectorVector");
  1423. class_<DummyForPointer>("DummyForPointer");
  1424. function("mallinfo", &emval_test_mallinfo);
  1425. function("emval_test_new_integer", &emval_test_new_integer);
  1426. function("emval_test_new_string", &emval_test_new_string);
  1427. function("emval_test_get_string_from_val", &emval_test_get_string_from_val);
  1428. function("emval_test_new_object", &emval_test_new_object);
  1429. function("emval_test_instance_pointer", &emval_test_instance_pointer);
  1430. function("emval_test_value_from_instance_pointer", &emval_test_value_from_instance_pointer);
  1431. function("emval_test_passthrough_unsigned", &emval_test_passthrough_unsigned);
  1432. function("emval_test_passthrough", &emval_test_passthrough);
  1433. function("emval_test_return_void", &emval_test_return_void);
  1434. function("emval_test_not", &emval_test_not);
  1435. function("emval_test_is_true", &emval_test_is_true);
  1436. function("emval_test_is_false", &emval_test_is_false);
  1437. function("emval_test_is_null", &emval_test_is_null);
  1438. function("emval_test_is_undefined", &emval_test_is_undefined);
  1439. function("emval_test_equals", &emval_test_equals);
  1440. function("emval_test_strictly_equals", &emval_test_strictly_equals);
  1441. function("emval_test_as_unsigned", &emval_test_as_unsigned);
  1442. function("emval_test_get_length", &emval_test_get_length);
  1443. function("emval_test_add", &emval_test_add);
  1444. function("const_ref_adder", &const_ref_adder);
  1445. function("emval_test_sum", &emval_test_sum);
  1446. function("get_non_ascii_string", &get_non_ascii_string);
  1447. function("get_non_ascii_wstring", &get_non_ascii_wstring);
  1448. function("get_literal_wstring", &get_literal_wstring);
  1449. function("force_memory_growth", &force_memory_growth);
  1450. //function("emval_test_take_and_return_const_char_star", &emval_test_take_and_return_const_char_star);
  1451. function("emval_test_take_and_return_std_string", &emval_test_take_and_return_std_string);
  1452. function("emval_test_take_and_return_std_string_const_ref", &emval_test_take_and_return_std_string_const_ref);
  1453. function("emval_test_take_and_return_std_basic_string_unsigned_char", &emval_test_take_and_return_std_basic_string_unsigned_char);
  1454. function("take_and_return_std_wstring", &take_and_return_std_wstring);
  1455. function("take_and_return_std_u16string", &take_and_return_std_u16string);
  1456. function("take_and_return_std_u32string", &take_and_return_std_u32string);
  1457. function("get_non_ascii_u16string", &get_non_ascii_u16string);
  1458. function("get_non_ascii_u32string", &get_non_ascii_u32string);
  1459. function("get_literal_u16string", &get_literal_u16string);
  1460. function("get_literal_u32string", &get_literal_u32string);
  1461. //function("emval_test_take_and_return_CustomStruct", &emval_test_take_and_return_CustomStruct);
  1462. value_array<TupleVector>("TupleVector")
  1463. .element(&TupleVector::x)
  1464. .element(&Vector::getY, &Vector::setY)
  1465. .element(&readVectorZ, &writeVectorZ)
  1466. .element(emscripten::index<3>())
  1467. ;
  1468. function("emval_test_return_TupleVector", &emval_test_return_TupleVector);
  1469. function("emval_test_take_and_return_TupleVector", &emval_test_take_and_return_TupleVector);
  1470. value_array<TupleVectorTuple>("TupleVectorTuple")
  1471. .element(&TupleVectorTuple::v)
  1472. ;
  1473. function("emval_test_return_TupleVectorTuple", &emval_test_return_TupleVectorTuple);
  1474. value_object<StructVector>("StructVector")
  1475. .field("x", &StructVector::x)
  1476. .field("y", &Vector::getY, &Vector::setY)
  1477. .field("z", &readVectorZ, &writeVectorZ)
  1478. .field("w", emscripten::index<3>())
  1479. ;
  1480. function("emval_test_return_StructVector", &emval_test_return_StructVector);
  1481. function("emval_test_take_and_return_StructVector", &emval_test_take_and_return_StructVector);
  1482. value_object<TupleInStruct>("TupleInStruct")
  1483. .field("field", &TupleInStruct::field)
  1484. ;
  1485. function("emval_test_take_and_return_TupleInStruct", &emval_test_take_and_return_TupleInStruct);
  1486. value_array<std::array<int, 2>>("array_int_2")
  1487. .element(emscripten::index<0>())
  1488. .element(emscripten::index<1>())
  1489. ;
  1490. value_array<std::array<NestedStruct, 2>>("array_NestedStruct_2")
  1491. .element(emscripten::index<0>())
  1492. .element(emscripten::index<1>())
  1493. ;
  1494. value_object<NestedStruct>("NestedStruct")
  1495. .field("x", &NestedStruct::x)
  1496. .field("y", &NestedStruct::y)
  1497. ;
  1498. value_object<ArrayInStruct>("ArrayInStruct")
  1499. .field("field1", &ArrayInStruct::field1)
  1500. .field("field2", &ArrayInStruct::field2)
  1501. ;
  1502. function("emval_test_take_and_return_ArrayInStruct", &emval_test_take_and_return_ArrayInStruct);
  1503. using namespace std::placeholders;
  1504. class_<ConstructFromFunctor<1>>("ConstructFromStdFunction")
  1505. .constructor(std::function<ConstructFromFunctor<1>(const val&, int)>(&construct_from_functor_mixin<1>))
  1506. .function("getVal", &ConstructFromFunctor<1>::getVal)
  1507. .function("getA", &ConstructFromFunctor<1>::getA)
  1508. ;
  1509. class_<ConstructFromFunctor<2>>("ConstructFromFunctionObject")
  1510. .constructor<ConstructFromFunctor<2>(const val&, int)>(std::bind(&construct_from_functor_mixin<2>, _1, _2))
  1511. .function("getVal", &ConstructFromFunctor<2>::getVal)
  1512. .function("getA", &ConstructFromFunctor<2>::getA)
  1513. ;
  1514. class_<ValHolder>("ValHolder")
  1515. .smart_ptr<std::shared_ptr<ValHolder>>("std::shared_ptr<ValHolder>")
  1516. .constructor<val>()
  1517. .function("getVal", &ValHolder::getVal)
  1518. .function("getValNonConst", &ValHolder::getValNonConst)
  1519. .function("getConstVal", &ValHolder::getConstVal)
  1520. .function("getValConstRef", &ValHolder::getValConstRef)
  1521. .function("setVal", &ValHolder::setVal)
  1522. .function("getValFunction", std::function<val(const ValHolder&)>(&valholder_get_value_mixin))
  1523. .function("setValFunction", std::function<void(ValHolder&, const val&)>(&valholder_set_value_mixin))
  1524. .function<val(const ValHolder&)>("getValFunctor", std::bind(&valholder_get_value_mixin, _1))
  1525. .function<void(ValHolder&, const val&)>("setValFunctor", std::bind(&valholder_set_value_mixin, _1, _2))
  1526. .property("val", &ValHolder::getVal, &ValHolder::setVal)
  1527. .property("val_readonly", &ValHolder::getVal)
  1528. .property("readonly_function_val", std::function<val(const ValHolder&)>(&valholder_get_value_mixin))
  1529. .property("function_val", std::function<val(const ValHolder&)>(&valholder_get_value_mixin),
  1530. std::function<void(ValHolder&, const val&)>(&valholder_set_value_mixin))
  1531. .property<val>("readonly_functor_val", std::bind(&valholder_get_value_mixin, _1))
  1532. .property<val>("functor_val", std::bind(&valholder_get_value_mixin, _1),
  1533. std::bind(&valholder_set_value_mixin, _1, _2))
  1534. .class_function("makeConst", &ValHolder::makeConst, allow_raw_pointer<ret_val>())
  1535. .class_function("makeValHolder", &ValHolder::makeValHolder)
  1536. .class_function("some_class_method", &ValHolder::some_class_method)
  1537. .class_function("set_via_raw_pointer",
  1538. &ValHolder::set_via_raw_pointer,
  1539. allow_raw_pointer<arg<0>>())
  1540. .class_function("get_via_raw_pointer",
  1541. &ValHolder::get_via_raw_pointer,
  1542. allow_raw_pointer<arg<0>>())
  1543. .class_function("transfer_via_raw_pointer",
  1544. &ValHolder::transfer_via_raw_pointer,
  1545. allow_raw_pointers())
  1546. // non-member method
  1547. .function("setEmpty", &emval_test_set_ValHolder_to_empty_object)
  1548. .function("getValNonMember", &ValHolder::getValNonMember)
  1549. ;
  1550. function("emval_test_return_ValHolder", &emval_test_return_ValHolder);
  1551. function("emval_test_set_ValHolder_to_empty_object", &emval_test_set_ValHolder_to_empty_object);
  1552. class_<std::function<std::string(std::string)>>("StringFunctorString")
  1553. .constructor<>()
  1554. .function("opcall", &std::function<std::string(std::string)>::operator())
  1555. ;
  1556. function("emval_test_get_function_ptr", &emval_test_get_function_ptr);
  1557. function("emval_test_take_and_call_functor", &emval_test_take_and_call_functor);
  1558. class_<StringHolder>("StringHolder")
  1559. .smart_ptr<std::shared_ptr<StringHolder>>("shared_ptr<StringHolder>")
  1560. .constructor<std::string>()
  1561. .function("set", &StringHolder::set)
  1562. .function("get", &StringHolder::get)
  1563. .function("get_const_ref", &StringHolder::get_const_ref)
  1564. ;
  1565. class_<SharedPtrHolder>("SharedPtrHolder")
  1566. .constructor<>()
  1567. .function("get", &SharedPtrHolder::get)
  1568. .function("set", &SharedPtrHolder::set)
  1569. ;
  1570. class_<SmallClass>("SmallClass")
  1571. .constructor<>()
  1572. .property("member", &SmallClass::member)
  1573. ;
  1574. class_<BigClass>("BigClass")
  1575. .constructor<>()
  1576. .property("member", &BigClass::member)
  1577. .property("otherMember", &BigClass::otherMember)
  1578. .property("yetAnotherMember", &BigClass::yetAnotherMember)
  1579. .function("getMember", &BigClass::getMember)
  1580. ;
  1581. class_<ParentClass>("ParentClass")
  1582. .constructor<>()
  1583. .function("getBigClass", &ParentClass::getBigClass)
  1584. ;
  1585. class_<TemplateClass<int>>("IntTemplateClass")
  1586. .constructor<int, int, int>()
  1587. .function("getMember", &TemplateClass<int>::getMember)
  1588. ;
  1589. class_<ContainsTemplatedMemberClass>("ContainsTemplatedMemberClass")
  1590. .constructor<>()
  1591. .function("getTestTemplate", &ContainsTemplatedMemberClass::getTestTemplate)
  1592. ;
  1593. // register Derived before Base as a test that it's possible to
  1594. // register base classes afterwards
  1595. class_<Derived, base<Base>>("Derived")
  1596. .smart_ptr<std::shared_ptr<Derived>>("shared_ptr<Derived>")
  1597. .constructor<>()
  1598. .function("getClassName", &Derived::getClassName)
  1599. .function("getMember", &Derived::getMember)
  1600. .function("setMember", &Derived::setMember)
  1601. .property("member", &Derived::member)
  1602. ;
  1603. class_<Base>("Base")
  1604. .smart_ptr<std::shared_ptr<Base>>("shared_ptr<Base")
  1605. .constructor<>()
  1606. .function("getClassName", &Base::getClassName)
  1607. .function("getClassNameFromBase", &Base::getClassNameFromBase)
  1608. .function("getClassNameNotAvailableInDerivedClasses", &Base::getClassNameNotAvailableInDerivedClasses)
  1609. .function("getMember", &Base::getMember)
  1610. .function("setMember", &Base::setMember)
  1611. .function("getBaseMember", &Base::getBaseMember)
  1612. .function("setBaseMember", &Base::setBaseMember)
  1613. .property("member", &Base::member)
  1614. .property("baseMember", &Base::baseMember)
  1615. ;
  1616. class_<SecondBase>("SecondBase")
  1617. .smart_ptr<std::shared_ptr<SecondBase>>("shared_ptr<SecondBase>")
  1618. .constructor<>()
  1619. .function("getClassName", &SecondBase::getClassName)
  1620. .function("getClassNameFromSecondBase", &SecondBase::getClassNameFromSecondBase)
  1621. .function("getClassNameNotAvailableInDerivedClasses", &SecondBase::getClassNameNotAvailableInDerivedClasses)
  1622. .function("getMember", &SecondBase::getMember)
  1623. .function("setMember", &SecondBase::setMember)
  1624. .function("getSecondBaseMember", &SecondBase::getSecondBaseMember)
  1625. .function("setSecondBaseMember", &SecondBase::setSecondBaseMember)
  1626. .property("member", &SecondBase::member)
  1627. .property("secondBaseMember", &SecondBase::secondBaseMember)
  1628. ;
  1629. class_<DerivedHolder>("DerivedHolder")
  1630. .constructor<>()
  1631. .function("newDerived", &DerivedHolder::newDerived)
  1632. .function("deleteDerived", &DerivedHolder::deleteDerived)
  1633. .function("getDerived", &DerivedHolder::getDerived)
  1634. .function("getDerivedClassName", &DerivedHolder::getDerivedClassName)
  1635. ;
  1636. class_<SiblingDerived>("SiblingDerived")
  1637. .smart_ptr<std::shared_ptr<SiblingDerived>>("shared_ptr<SiblingDerived>")
  1638. .constructor<>()
  1639. .function("getClassName", &SiblingDerived::getClassName)
  1640. ;
  1641. class_<MultiplyDerived, base<Base>>("MultiplyDerived")
  1642. .smart_ptr<std::shared_ptr<MultiplyDerived>>("shared_ptr<MultiplyDerived>")
  1643. .constructor<>()
  1644. .function("getClassName", &MultiplyDerived::getClassName)
  1645. .class_function("getInstanceCount", &MultiplyDerived::getInstanceCount)
  1646. ;
  1647. class_<DerivedTwice, base<Derived> >("DerivedTwice")
  1648. .constructor<>()
  1649. .function("getClassName", &DerivedTwice::getClassName)
  1650. ;
  1651. class_<DerivedThrice, base<Derived> >("DerivedThrice")
  1652. .smart_ptr<std::shared_ptr<DerivedThrice>>("shared_ptr<DerivedThrice>")
  1653. .constructor<>()
  1654. .function("getClassName", &DerivedThrice::getClassName)
  1655. ;
  1656. class_<PolyBase>("PolyBase")
  1657. .smart_ptr<std::shared_ptr<PolyBase>>("shared_ptr<PolyBase>")
  1658. .constructor<>()
  1659. .function("virtualGetClassName", &PolyBase::virtualGetClassName)
  1660. .function("getClassName", &PolyBase::getClassName)
  1661. ;
  1662. class_<PolySecondBase>("PolySecondBase")
  1663. .smart_ptr<std::shared_ptr<PolySecondBase>>("shared_ptr<PolySecondBase>")
  1664. .constructor<>()
  1665. .function("getClassName", &PolySecondBase::getClassName)
  1666. ;
  1667. class_<PolyDerived, base<PolyBase>>("PolyDerived")
  1668. .smart_ptr<std::shared_ptr<PolyDerived>>("shared_ptr<PolyDerived>")
  1669. .constructor<>()
  1670. .function("virtualGetClassName", &PolyDerived::virtualGetClassName)
  1671. .function("getClassName", &PolyDerived::getClassName)
  1672. .class_function("setPtrDerived", &PolyDerived::setPtrDerived)
  1673. .class_function("releasePtr", &PolyDerived::releasePtr)
  1674. .class_function("getPtrClassName", &PolyDerived::getPtrClassName)
  1675. .class_function("getPtr", &PolyDerived::getPtr)
  1676. ;
  1677. // static void setPtrDerived() {
  1678. // ptr = std::shared_ptr<PolyDerived>(new PolyDerived());
  1679. // }
  1680. //
  1681. // static std::string getPtrClassName() {
  1682. // return ptr->getClassName();
  1683. // }
  1684. //
  1685. // static std::shared_ptr<PolyBase> getPtr() {
  1686. // return ptr;
  1687. // }
  1688. class_<PolySiblingDerived, base<PolyBase>>("PolySiblingDerived")
  1689. .smart_ptr<std::shared_ptr<PolySiblingDerived>>("shared_ptr<PolySiblingDerived>")
  1690. .constructor<>()
  1691. .function("getClassName", &PolySiblingDerived::getClassName)
  1692. ;
  1693. class_<PolyMultiplyDerived, base<PolyBase>>("PolyMultiplyDerived")
  1694. .smart_ptr<std::shared_ptr<PolyMultiplyDerived>>("shared_ptr<PolyMultiplyDerived>")
  1695. .constructor<>()
  1696. .function("getClassName", &PolyMultiplyDerived::getClassName)
  1697. ;
  1698. class_<PolyDerivedThrice, base<PolyDerived>>("PolyDerivedThrice")
  1699. .smart_ptr<std::shared_ptr<PolyDerivedThrice>>("shared_ptr<PolyDerivedThrice>")
  1700. .constructor<>()
  1701. .function("getClassName", &PolyDerivedThrice::getClassName)
  1702. ;
  1703. class_<PolyDiamondBase>("PolyDiamondBase")
  1704. .smart_ptr<std::shared_ptr<PolyDiamondBase>>("shared_ptr<PolyDiamondBase>")
  1705. .constructor<>()
  1706. .function("getClassName", &PolyDiamondBase::getClassName)
  1707. ;
  1708. class_<PolyDiamondDerived>("PolyDiamondDerived")
  1709. .smart_ptr<std::shared_ptr<PolyDiamondDerived>>("shared_ptr<PolyDiamondDerived>")
  1710. .constructor<>()
  1711. .function("getClassName", &PolyDiamondDerived::getClassName)
  1712. ;
  1713. class_<PolyDiamondSiblingDerived>("PolyDiamondSiblingDerived")
  1714. .smart_ptr<std::shared_ptr<PolyDiamondSiblingDerived>>("shared_ptr<PolyDiamondSiblingDerived>")
  1715. .constructor<>()
  1716. .function("getClassName", &PolyDiamondSiblingDerived::getClassName)
  1717. ;
  1718. class_<PolyDiamondMultiplyDerived>("PolyDiamondMultiplyDerived")
  1719. .smart_ptr<std::shared_ptr<PolyDiamondMultiplyDerived>>("shared_ptr<PolyDiamondMultiplyDerived>")
  1720. .constructor<>()
  1721. .function("getClassName", &PolyDiamondMultiplyDerived::getClassName)
  1722. ;
  1723. function("embind_test_return_small_class_instance", &embind_test_return_small_class_instance);
  1724. function("embind_test_return_big_class_instance", &embind_test_return_big_class_instance);
  1725. function("embind_test_accept_small_class_instance", &embind_test_accept_small_class_instance);
  1726. function("embind_test_accept_big_class_instance", &embind_test_accept_big_class_instance);
  1727. class_<UniquePtrToConstructor>("UniquePtrToConstructor")
  1728. .constructor<std::unique_ptr<int>>()
  1729. .function("getValue", &UniquePtrToConstructor::getValue)
  1730. ;
  1731. function("embind_test_construct_class_with_unique_ptr", embind_test_construct_class_with_unique_ptr, allow_raw_pointer<ret_val>());
  1732. function("embind_test_return_unique_ptr", embind_test_return_unique_ptr);
  1733. function("embind_test_accept_unique_ptr", embind_test_accept_unique_ptr);
  1734. function("embind_test_return_raw_base_ptr", embind_test_return_raw_base_ptr, allow_raw_pointer<ret_val>());
  1735. function("embind_test_return_raw_derived_ptr_as_base", embind_test_return_raw_derived_ptr_as_base, allow_raw_pointer<ret_val>());
  1736. function("embind_test_return_raw_sibling_derived_ptr_as_base", embind_test_return_raw_sibling_derived_ptr_as_base, allow_raw_pointer<ret_val>());
  1737. function("embind_test_return_raw_polymorphic_derived_ptr_as_base", embind_test_return_raw_polymorphic_derived_ptr_as_base, allow_raw_pointer<ret_val>());
  1738. 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>());
  1739. 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>());
  1740. 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>());
  1741. 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>());
  1742. function("embind_test_return_smart_derived_ptr", embind_test_return_smart_derived_ptr);
  1743. function("embind_test_return_smart_sibling_derived_ptr", embind_test_return_smart_sibling_derived_ptr);
  1744. function("embind_test_return_smart_multiply_derived_ptr", embind_test_return_smart_multiply_derived_ptr);
  1745. function("embind_test_return_smart_derived_thrice_ptr", embind_test_return_smart_derived_thrice_ptr);
  1746. function("embind_test_return_smart_base_ptr", embind_test_return_smart_base_ptr);
  1747. function("embind_test_return_smart_polymorphic_base_ptr", embind_test_return_smart_polymorphic_base_ptr);
  1748. function("embind_test_return_smart_polymorphic_derived_ptr", embind_test_return_smart_polymorphic_derived_ptr);
  1749. function("embind_test_return_smart_polymorphic_sibling_derived_ptr", embind_test_return_smart_polymorphic_sibling_derived_ptr);
  1750. function("embind_test_return_smart_polymorphic_multiply_derived_ptr", embind_test_return_smart_polymorphic_multiply_derived_ptr);
  1751. 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);
  1752. function("embind_test_return_smart_poly_derived_thrice_ptr", embind_test_return_smart_poly_derived_thrice_ptr);
  1753. function("embind_test_return_smart_derived_ptr_as_base", embind_test_return_smart_derived_ptr_as_base);
  1754. function("embind_test_return_smart_derived_ptr_as_val", embind_test_return_smart_derived_ptr_as_val);
  1755. function("embind_test_return_smart_polymorphic_derived_ptr_as_base", embind_test_return_smart_polymorphic_derived_ptr_as_base);
  1756. function("embind_test_return_smart_polymorphic_sibling_derived_ptr_as_base", embind_test_return_smart_polymorphic_sibling_derived_ptr_as_base);
  1757. function("embind_test_get_class_name_via_base_ptr", embind_test_get_class_name_via_base_ptr, allow_raw_pointer<arg<0>>());
  1758. function("embind_test_get_class_name_via_second_base_ptr", embind_test_get_class_name_via_second_base_ptr, allow_raw_pointer<arg<0>>());
  1759. function("embind_test_get_class_name_via_polymorphic_base_ptr", embind_test_get_class_name_via_polymorphic_base_ptr, allow_raw_pointer<arg<0>>());
  1760. 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>>());
  1761. // todo: allow_raw_pointer should fail earlier if argument is not a pointer
  1762. function("embind_test_get_class_name_via_smart_base_ptr", embind_test_get_class_name_via_smart_base_ptr);
  1763. function("embind_test_get_class_name_via_reference_to_smart_base_ptr", embind_test_get_class_name_via_reference_to_smart_base_ptr);
  1764. function("embind_test_get_class_name_via_smart_second_base_ptr", embind_test_get_class_name_via_smart_second_base_ptr);
  1765. function("embind_test_get_class_name_via_smart_polymorphic_base_ptr", embind_test_get_class_name_via_smart_polymorphic_base_ptr);
  1766. function("embind_test_get_virtual_class_name_via_smart_polymorphic_base_ptr", embind_test_get_virtual_class_name_via_smart_polymorphic_base_ptr);
  1767. function("embind_test_get_class_name_via_smart_polymorphic_second_base_ptr", embind_test_get_class_name_via_smart_polymorphic_second_base_ptr);
  1768. function("embind_modify_smart_pointer_passed_by_reference", embind_modify_smart_pointer_passed_by_reference);
  1769. function("embind_attempt_to_modify_smart_pointer_when_passed_by_value", embind_attempt_to_modify_smart_pointer_when_passed_by_value);
  1770. function("embind_save_smart_base_pointer", embind_save_smart_base_pointer);
  1771. class_<Base1>("Base1")
  1772. .constructor()
  1773. .function("getField", &Base1::getField)
  1774. ;
  1775. class_<Base2>("Base2")
  1776. .function("getField", &Base2::getField)
  1777. .property("field", &Base2::field2)
  1778. ;
  1779. class_<HasTwoBases, base<Base2>>("HasTwoBases")
  1780. .constructor()
  1781. ;
  1782. class_<CustomStruct>("CustomStruct")
  1783. .constructor<>()
  1784. .property("field", &CustomStruct::field)
  1785. .function("getField", &CustomStruct::getField)
  1786. ;
  1787. enum_<Enum>("Enum")
  1788. .value("ONE", ONE)
  1789. .value("TWO", TWO)
  1790. ;
  1791. function("emval_test_take_and_return_Enum", &emval_test_take_and_return_Enum);
  1792. enum_<EnumClass>("EnumClass")
  1793. .value("ONE", EnumClass::ONE)
  1794. .value("TWO", EnumClass::TWO)
  1795. ;
  1796. function("emval_test_take_and_return_EnumClass", &emval_test_take_and_return_EnumClass);
  1797. function("emval_test_call_function", &emval_test_call_function);
  1798. function("emval_test_return_unique_ptr", &emval_test_return_unique_ptr);
  1799. class_<UniquePtrLifetimeMock>("UniquePtrLifetimeMock");
  1800. function("emval_test_return_unique_ptr_lifetime", &emval_test_return_unique_ptr_lifetime);
  1801. function("emval_test_return_shared_ptr", &emval_test_return_shared_ptr);
  1802. function("emval_test_return_empty_shared_ptr", &emval_test_return_empty_shared_ptr);
  1803. function("emval_test_is_shared_ptr_null", &emval_test_is_shared_ptr_null);
  1804. function("emval_test_return_vector", &emval_test_return_vector);
  1805. function("emval_test_return_vector_of_vectors", &emval_test_return_vector_of_vectors);
  1806. register_vector<std::shared_ptr<StringHolder>>("SharedPtrVector");
  1807. function("emval_test_return_shared_ptr_vector", &emval_test_return_shared_ptr_vector);
  1808. function("get_module_property", &get_module_property);
  1809. register_vector<StringHolder>("StringHolderVector");
  1810. class_<VectorHolder>("VectorHolder")
  1811. .constructor<>()
  1812. .function("get", &VectorHolder::get)
  1813. .function("set", &VectorHolder::set)
  1814. ;
  1815. function("test_string_with_vec", &test_string_with_vec);
  1816. register_map<std::string, int>("StringIntMap");
  1817. function("embind_test_get_string_int_map", embind_test_get_string_int_map);
  1818. function("embind_test_getglobal", &embind_test_getglobal);
  1819. function("embind_test_new_Object", &embind_test_new_Object);
  1820. function("embind_test_new_factory", &embind_test_new_factory);
  1821. class_<HasExternalConstructor>("HasExternalConstructor")
  1822. .constructor(&createHasExternalConstructor)
  1823. .function("getString", &HasExternalConstructor::getString)
  1824. ;
  1825. auto HeldBySmartPtr_class = class_<HeldBySmartPtr>("HeldBySmartPtr");
  1826. HeldBySmartPtr_class
  1827. .smart_ptr<CustomSmartPtr<HeldBySmartPtr>>("CustomSmartPtr<HeldBySmartPtr>")
  1828. .smart_ptr_constructor("shared_ptr<HeldbySmartPtr>", &std::make_shared<HeldBySmartPtr, int, std::string>)
  1829. .class_function("newCustomPtr", HeldBySmartPtr::newCustomPtr)
  1830. .function("returnThis", &takesHeldBySmartPtrSharedPtr)
  1831. .property("i", &HeldBySmartPtr::i)
  1832. .property("s", &HeldBySmartPtr::s)
  1833. ;
  1834. function("takesHeldBySmartPtr", &takesHeldBySmartPtr);
  1835. function("takesHeldBySmartPtrSharedPtr", &takesHeldBySmartPtrSharedPtr);
  1836. class_<HeldByCustomSmartPtr>("HeldByCustomSmartPtr")
  1837. .smart_ptr<std::shared_ptr<HeldByCustomSmartPtr>>("shared_ptr<HeldByCustomSmartPtr>")
  1838. .smart_ptr_constructor("CustomSmartPtr<HeldByCustomSmartPtr>", &HeldByCustomSmartPtr::create)
  1839. .class_function("createSharedPtr", &HeldByCustomSmartPtr::createSharedPtr)
  1840. .property("i", &HeldByCustomSmartPtr::i)
  1841. .property("s", &HeldByCustomSmartPtr::s)
  1842. ;
  1843. function("passThroughRawPtr", &passThroughRawPtr, allow_raw_pointers());
  1844. function("passThroughCustomSmartPtr", &passThroughCustomSmartPtr);
  1845. function("char_to_string", &char_to_string);
  1846. function("signed_char_to_string", &signed_char_to_string);
  1847. function("unsigned_char_to_string", &unsigned_char_to_string);
  1848. function("short_to_string", &short_to_string);
  1849. function("unsigned_short_to_string", &unsigned_short_to_string);
  1850. function("int_to_string", &int_to_string);
  1851. function("unsigned_int_to_string", &unsigned_int_to_string);
  1852. function("long_to_string", &long_to_string);
  1853. function("unsigned_long_to_string", &unsigned_long_to_string);
  1854. function("store_unsigned_char", &store_unsigned_char);
  1855. function("load_unsigned_char", &load_unsigned_char);
  1856. function("store_unsigned_short", &store_unsigned_short);
  1857. function("load_unsigned_short", &load_unsigned_short);
  1858. function("store_unsigned_int", &store_unsigned_int);
  1859. function("load_unsigned_int", &load_unsigned_int);
  1860. function("store_unsigned_long", &store_unsigned_long);
  1861. function("load_unsigned_long", &load_unsigned_long);
  1862. }
  1863. int overloaded_function(int i) {
  1864. assert(i == 10);
  1865. return 1;
  1866. }
  1867. int overloaded_function(int i, int j) {
  1868. assert(i == 20);
  1869. assert(j == 20);
  1870. return 2;
  1871. }
  1872. class MultipleCtors {
  1873. public:
  1874. int value = 0;
  1875. MultipleCtors(int i) {
  1876. value = 1;
  1877. assert(i == 10);
  1878. }
  1879. MultipleCtors(int i, int j) {
  1880. value = 2;
  1881. assert(i == 20);
  1882. assert(j == 20);
  1883. }
  1884. MultipleCtors(int i, int j, int k) {
  1885. value = 3;
  1886. assert(i == 30);
  1887. assert(j == 30);
  1888. assert(k == 30);
  1889. }
  1890. int WhichCtorCalled() const {
  1891. return value;
  1892. }
  1893. };
  1894. class MultipleSmartCtors {
  1895. public:
  1896. int value = 0;
  1897. MultipleSmartCtors(int i) {
  1898. value = 1;
  1899. assert(i == 10);
  1900. }
  1901. MultipleSmartCtors(int i, int j) {
  1902. value = 2;
  1903. assert(i == 20);
  1904. assert(j == 20);
  1905. }
  1906. int WhichCtorCalled() const {
  1907. return value;
  1908. }
  1909. };
  1910. class MultipleOverloads {
  1911. public:
  1912. MultipleOverloads() {}
  1913. int value;
  1914. static int staticValue;
  1915. int Func(int i) {
  1916. assert(i == 10);
  1917. value = 1;
  1918. return 1;
  1919. }
  1920. int Func(int i, int j) {
  1921. assert(i == 20);
  1922. assert(j == 20);
  1923. value = 2;
  1924. return 2;
  1925. }
  1926. int WhichFuncCalled() const {
  1927. return value;
  1928. }
  1929. static int StaticFunc(int i) {
  1930. assert(i == 10);
  1931. staticValue = 1;
  1932. return 1;
  1933. }
  1934. static int StaticFunc(int i, int j) {
  1935. assert(i == 20);
  1936. assert(j == 20);
  1937. staticValue = 2;
  1938. return 2;
  1939. }
  1940. static int WhichStaticFuncCalled() {
  1941. return staticValue;
  1942. }
  1943. };
  1944. int MultipleOverloads::staticValue = 0;
  1945. class MultipleOverloadsDerived : public MultipleOverloads {
  1946. public:
  1947. MultipleOverloadsDerived() {}
  1948. int Func(int i, int j, int k) {
  1949. assert(i == 30);
  1950. assert(j == 30);
  1951. assert(k == 30);
  1952. value = 3;
  1953. return 3;
  1954. }
  1955. int Func(int i, int j, int k, int l) {
  1956. assert(i == 40);
  1957. assert(j == 40);
  1958. assert(k == 40);
  1959. assert(l == 40);
  1960. value = 4;
  1961. return 4;
  1962. }
  1963. static int StaticFunc(int i, int j, int k) {
  1964. assert(i == 30);
  1965. assert(j == 30);
  1966. assert(k == 30);
  1967. staticValue = 3;
  1968. return 3;
  1969. }
  1970. static int StaticFunc(int i, int j, int k, int l) {
  1971. assert(i == 40);
  1972. assert(j == 40);
  1973. assert(k == 40);
  1974. assert(l == 40);
  1975. staticValue = 4;
  1976. return 4;
  1977. }
  1978. };
  1979. struct MultipleAccessors {
  1980. int getConst() {
  1981. return 1;
  1982. }
  1983. int getConst() const {
  1984. return 2;
  1985. }
  1986. int getConst(int i) const {
  1987. return i;
  1988. }
  1989. };
  1990. struct ConstAndNonConst {
  1991. void method(int) {
  1992. }
  1993. int method() const {
  1994. return 10;
  1995. }
  1996. };
  1997. class DummyForOverloads {};
  1998. class MultipleOverloadsDependingOnDummy {
  1999. public:
  2000. DummyForOverloads dummy() {
  2001. return DummyForOverloads();
  2002. }
  2003. DummyForOverloads dummy(DummyForOverloads d) {
  2004. return d;
  2005. }
  2006. static DummyForOverloads staticDummy() {
  2007. return DummyForOverloads();
  2008. }
  2009. static DummyForOverloads staticDummy(DummyForOverloads d) {
  2010. return d;
  2011. }
  2012. };
  2013. DummyForOverloads getDummy() {
  2014. return DummyForOverloads();
  2015. }
  2016. DummyForOverloads getDummy(DummyForOverloads d) {
  2017. return d;
  2018. }
  2019. EMSCRIPTEN_BINDINGS(overloads) {
  2020. function("overloaded_function", select_overload<int(int)>(&overloaded_function));
  2021. function("overloaded_function", select_overload<int(int, int)>(&overloaded_function));
  2022. class_<MultipleCtors>("MultipleCtors")
  2023. .constructor<int>()
  2024. .constructor<int, int>()
  2025. .constructor<int, int, int>()
  2026. .function("WhichCtorCalled", &MultipleCtors::WhichCtorCalled)
  2027. ;
  2028. class_<MultipleSmartCtors>("MultipleSmartCtors")
  2029. .smart_ptr<std::shared_ptr<MultipleSmartCtors>>("shared_ptr<MultipleSmartCtors>")
  2030. .constructor(&std::make_shared<MultipleSmartCtors, int>)
  2031. .constructor(&std::make_shared<MultipleSmartCtors, int, int>)
  2032. .function("WhichCtorCalled", &MultipleSmartCtors::WhichCtorCalled)
  2033. ;
  2034. class_<MultipleOverloads>("MultipleOverloads")
  2035. .constructor<>()
  2036. .function("Func", select_overload<int(int)>(&MultipleOverloads::Func))
  2037. .function("Func", select_overload<int(int, int)>(&MultipleOverloads::Func))
  2038. .function("WhichFuncCalled", &MultipleOverloads::WhichFuncCalled)
  2039. .class_function("StaticFunc", select_overload<int(int)>(&MultipleOverloads::StaticFunc))
  2040. .class_function("StaticFunc", select_overload<int(int,int)>(&MultipleOverloads::StaticFunc))
  2041. .class_function("WhichStaticFuncCalled", &MultipleOverloads::WhichStaticFuncCalled)
  2042. ;
  2043. class_<MultipleOverloadsDerived, base<MultipleOverloads> >("MultipleOverloadsDerived")
  2044. .constructor<>()
  2045. .function("Func", select_overload<int(int,int,int)>(&MultipleOverloadsDerived::Func))
  2046. .function("Func", select_overload<int(int,int,int,int)>(&MultipleOverloadsDerived::Func))
  2047. .class_function("StaticFunc", select_overload<int(int,int,int)>(&MultipleOverloadsDerived::StaticFunc))
  2048. .class_function("StaticFunc", select_overload<int(int,int,int,int)>(&MultipleOverloadsDerived::StaticFunc))
  2049. ;
  2050. class_<MultipleAccessors>("MultipleAccessors")
  2051. .function("getConst", select_overload<int(int)const>(&MultipleAccessors::getConst))
  2052. ;
  2053. class_<ConstAndNonConst>("ConstAndNonConst")
  2054. .function("method", select_const(&ConstAndNonConst::method))
  2055. ;
  2056. class_<DummyForOverloads>("DummyForOverloads").constructor();
  2057. class_<MultipleOverloadsDependingOnDummy>("MultipleOverloadsDependingOnDummy")
  2058. .constructor()
  2059. .function("dummy", select_overload<DummyForOverloads()>(&MultipleOverloadsDependingOnDummy::dummy))
  2060. .function("dummy", select_overload<DummyForOverloads(DummyForOverloads)>(&MultipleOverloadsDependingOnDummy::dummy))
  2061. .class_function("staticDummy", select_overload<DummyForOverloads()>(&MultipleOverloadsDependingOnDummy::staticDummy))
  2062. .class_function("staticDummy", select_overload<DummyForOverloads(DummyForOverloads)>(&MultipleOverloadsDependingOnDummy::staticDummy))
  2063. ;
  2064. function("getDummy", select_overload<DummyForOverloads(void)>(&getDummy));
  2065. function("getDummy", select_overload<DummyForOverloads(DummyForOverloads)>(&getDummy));
  2066. }
  2067. // tests for out-of-order registration
  2068. class SecondElement {
  2069. };
  2070. class FirstElement {
  2071. };
  2072. struct OrderedTuple {
  2073. FirstElement first;
  2074. SecondElement second;
  2075. };
  2076. struct OrderedStruct {
  2077. FirstElement first;
  2078. SecondElement second;
  2079. };
  2080. OrderedTuple getOrderedTuple() {
  2081. return OrderedTuple();
  2082. }
  2083. OrderedStruct getOrderedStruct() {
  2084. return OrderedStruct();
  2085. }
  2086. EMSCRIPTEN_BINDINGS(order) {
  2087. value_array<OrderedTuple>("OrderedTuple")
  2088. .element(&OrderedTuple::first)
  2089. .element(&OrderedTuple::second)
  2090. ;
  2091. value_object<OrderedStruct>("OrderedStruct")
  2092. .field("first", &OrderedStruct::first)
  2093. .field("second", &OrderedStruct::second)
  2094. ;
  2095. class_<SecondElement>("SecondElement")
  2096. ;
  2097. class_<FirstElement>("FirstElement")
  2098. ;
  2099. function("getOrderedTuple", &getOrderedTuple);
  2100. function("getOrderedStruct", &getOrderedStruct);
  2101. }
  2102. // tests for unbound types
  2103. template<typename T>
  2104. T passThrough(T t) {
  2105. return t;
  2106. }
  2107. struct UnboundClass {
  2108. };
  2109. struct HasUnboundBase : public UnboundClass {
  2110. static void noop() {
  2111. }
  2112. };
  2113. HasUnboundBase getHasUnboundBase(HasUnboundBase f) {
  2114. return f;
  2115. }
  2116. struct HasConstructorUsingUnboundArgument {
  2117. HasConstructorUsingUnboundArgument(UnboundClass) {
  2118. }
  2119. };
  2120. struct SecondUnboundClass {
  2121. };
  2122. struct HasConstructorUsingUnboundArgumentAndUnboundBase : public SecondUnboundClass {
  2123. HasConstructorUsingUnboundArgumentAndUnboundBase(UnboundClass) {
  2124. }
  2125. };
  2126. struct BoundClass {
  2127. UnboundClass method(UnboundClass t) {
  2128. return t;
  2129. }
  2130. static UnboundClass classfunction(UnboundClass t) {
  2131. return t;
  2132. }
  2133. UnboundClass property;
  2134. };
  2135. EMSCRIPTEN_BINDINGS(incomplete) {
  2136. constant("hasUnboundTypeNames", emscripten::has_unbound_type_names);
  2137. function("getUnboundClass", &passThrough<UnboundClass>);
  2138. class_<HasUnboundBase, base<UnboundClass>>("HasUnboundBase")
  2139. .class_function("noop", &HasUnboundBase::noop)
  2140. ;
  2141. function("getHasUnboundBase", &passThrough<HasUnboundBase>);
  2142. class_<HasConstructorUsingUnboundArgument>("HasConstructorUsingUnboundArgument")
  2143. .constructor<UnboundClass>()
  2144. ;
  2145. class_<HasConstructorUsingUnboundArgumentAndUnboundBase, base<SecondUnboundClass>>("HasConstructorUsingUnboundArgumentAndUnboundBase")
  2146. .constructor<UnboundClass>()
  2147. ;
  2148. class_<BoundClass>("BoundClass")
  2149. .constructor<>()
  2150. .function("method", &BoundClass::method)
  2151. .class_function("classfunction", &BoundClass::classfunction)
  2152. .property("property", &BoundClass::property)
  2153. ;
  2154. }
  2155. class Noncopyable {
  2156. Noncopyable(const Noncopyable&) = delete;
  2157. Noncopyable& operator=(const Noncopyable&) = delete;
  2158. public:
  2159. Noncopyable() {}
  2160. Noncopyable(Noncopyable&& other) {
  2161. other.valid = false;
  2162. }
  2163. std::string method() const {
  2164. return "foo";
  2165. }
  2166. bool valid = true;
  2167. };
  2168. Noncopyable getNoncopyable() {
  2169. return Noncopyable();
  2170. }
  2171. EMSCRIPTEN_BINDINGS(noncopyable) {
  2172. class_<Noncopyable>("Noncopyable")
  2173. .constructor<>()
  2174. .function("method", &Noncopyable::method)
  2175. ;
  2176. function("getNoncopyable", &getNoncopyable);
  2177. }
  2178. struct HasReadOnlyProperty {
  2179. HasReadOnlyProperty(int i)
  2180. : i(i)
  2181. {}
  2182. const int i;
  2183. };
  2184. EMSCRIPTEN_BINDINGS(read_only_properties) {
  2185. class_<HasReadOnlyProperty>("HasReadOnlyProperty")
  2186. .constructor<int>()
  2187. .property("i", &HasReadOnlyProperty::i)
  2188. ;
  2189. }
  2190. struct StaticConstIntStruct {
  2191. static const int STATIC_CONST_INTEGER_VALUE_1;
  2192. static const int STATIC_CONST_INTEGER_VALUE_1000;
  2193. };
  2194. const int StaticConstIntStruct::STATIC_CONST_INTEGER_VALUE_1 = 1;
  2195. const int StaticConstIntStruct::STATIC_CONST_INTEGER_VALUE_1000 = 1000;
  2196. EMSCRIPTEN_BINDINGS(constants) {
  2197. constant("INT_CONSTANT", 10);
  2198. constant("STATIC_CONST_INTEGER_VALUE_1", StaticConstIntStruct::STATIC_CONST_INTEGER_VALUE_1);
  2199. constant("STATIC_CONST_INTEGER_VALUE_1000", StaticConstIntStruct::STATIC_CONST_INTEGER_VALUE_1000);
  2200. constant("STRING_CONSTANT", std::string("some string"));
  2201. TupleVector tv(1, 2, 3, 4);
  2202. constant("VALUE_ARRAY_CONSTANT", tv);
  2203. StructVector sv(1, 2, 3, 4);
  2204. constant("VALUE_OBJECT_CONSTANT", sv);
  2205. }
  2206. class DerivedWithOffset : public DummyDataToTestPointerAdjustment, public Base {
  2207. };
  2208. std::shared_ptr<Base> return_Base_from_DerivedWithOffset(std::shared_ptr<DerivedWithOffset> ptr) {
  2209. return ptr;
  2210. }
  2211. EMSCRIPTEN_BINDINGS(with_adjustment) {
  2212. class_<DerivedWithOffset, base<Base>>("DerivedWithOffset")
  2213. .smart_ptr_constructor("shared_ptr<DerivedWithOffset>", &std::make_shared<DerivedWithOffset>)
  2214. ;
  2215. function("return_Base_from_DerivedWithOffset", &return_Base_from_DerivedWithOffset);
  2216. }
  2217. void clear_StringHolder(StringHolder& sh) {
  2218. sh.set("");
  2219. }
  2220. EMSCRIPTEN_BINDINGS(references) {
  2221. function("clear_StringHolder", &clear_StringHolder);
  2222. }
  2223. StringHolder return_StringHolder_copy(val func) {
  2224. return func.as<StringHolder>();
  2225. }
  2226. StringHolder call_StringHolder_func(val func) {
  2227. return func().as<StringHolder>();
  2228. }
  2229. EMSCRIPTEN_BINDINGS(return_values) {
  2230. function("return_StringHolder_copy", &return_StringHolder_copy);
  2231. function("call_StringHolder_func", &call_StringHolder_func);
  2232. }
  2233. struct Mixin {
  2234. int get10() const {
  2235. return 10;
  2236. }
  2237. };
  2238. template<typename ClassBinding>
  2239. const ClassBinding& registerMixin(const ClassBinding& binding) {
  2240. // need a wrapper for implicit conversion from DerivedWithMixin to Mixin
  2241. struct Local {
  2242. static int get10(const typename ClassBinding::class_type& self) {
  2243. return self.get10();
  2244. }
  2245. };
  2246. return binding
  2247. .function("get10", &Local::get10)
  2248. ;
  2249. }
  2250. class DerivedWithMixin : public Base, public Mixin {
  2251. };
  2252. EMSCRIPTEN_BINDINGS(mixins) {
  2253. registerMixin(
  2254. class_<DerivedWithMixin, base<Base>>("DerivedWithMixin")
  2255. .constructor<>()
  2256. );
  2257. }
  2258. template<typename T>
  2259. T val_as(const val& v) {
  2260. return v.as<T>();
  2261. }
  2262. EMSCRIPTEN_BINDINGS(val_as) {
  2263. function("val_as_bool", &val_as<bool>);
  2264. function("val_as_char", &val_as<char>);
  2265. function("val_as_short", &val_as<short>);
  2266. function("val_as_int", &val_as<int>);
  2267. function("val_as_long", &val_as<long>);
  2268. function("val_as_float", &val_as<float>);
  2269. function("val_as_double", &val_as<double>);
  2270. function("val_as_string", &val_as<std::string>);
  2271. function("val_as_wstring", &val_as<std::wstring>);
  2272. function("val_as_val", &val_as<val>);
  2273. function("val_as_value_object", &val_as<StructVector>);
  2274. function("val_as_value_array", &val_as<TupleVector>);
  2275. function("val_as_enum", &val_as<Enum>);
  2276. // memory_view is always JS -> C++
  2277. //function("val_as_memory_view", &val_as<memory_view>);
  2278. }
  2279. val construct_with_6(val factory) {
  2280. unsigned char a1 = 6;
  2281. double a2 = -12.5;
  2282. std::string a3("a3");
  2283. StructVector a4(1, 2, 3, 4);
  2284. EnumClass a5 = EnumClass::TWO;
  2285. TupleVector a6(-1, -2, -3, -4);
  2286. return factory.new_(a1, a2, a3, a4, a5, a6);
  2287. }
  2288. val construct_with_memory_view(val factory) {
  2289. static const char data[11] = "0123456789";
  2290. return factory.new_(
  2291. std::string("before"),
  2292. typed_memory_view(10, data),
  2293. std::string("after"));
  2294. }
  2295. val construct_with_ints_and_float(val factory) {
  2296. return factory.new_(65537, 4.0f, 65538);
  2297. }
  2298. val construct_with_arguments_before_and_after_memory_growth() {
  2299. auto out = val::array();
  2300. out.set(0, val::global("Uint8Array").new_(5));
  2301. force_memory_growth();
  2302. out.set(1, val::global("Uint8Array").new_(5));
  2303. return out;
  2304. }
  2305. EMSCRIPTEN_BINDINGS(val_new_) {
  2306. function("construct_with_6_arguments", &construct_with_6);
  2307. function("construct_with_memory_view", &construct_with_memory_view);
  2308. function("construct_with_ints_and_float", &construct_with_ints_and_float);
  2309. function(
  2310. "construct_with_arguments_before_and_after_memory_growth",
  2311. &construct_with_arguments_before_and_after_memory_growth);
  2312. }
  2313. template <typename T>
  2314. class intrusive_ptr {
  2315. public:
  2316. typedef T element_type;
  2317. intrusive_ptr(std::nullptr_t = nullptr)
  2318. : px(nullptr)
  2319. {}
  2320. template <typename U>
  2321. explicit intrusive_ptr(U* px)
  2322. : px(px)
  2323. {
  2324. addRef(px);
  2325. }
  2326. intrusive_ptr(const intrusive_ptr& that)
  2327. : px(that.px)
  2328. {
  2329. addRef(px);
  2330. }
  2331. template<typename U>
  2332. intrusive_ptr(const intrusive_ptr<U>& that)
  2333. : px(that.get())
  2334. {
  2335. addRef(px);
  2336. }
  2337. intrusive_ptr& operator=(const intrusive_ptr& that) {
  2338. reset(that.get());
  2339. return *this;
  2340. }
  2341. intrusive_ptr& operator=(intrusive_ptr&& that) {
  2342. release(px);
  2343. px = that.px;
  2344. that.px = 0;
  2345. return *this;
  2346. }
  2347. template<typename U>
  2348. intrusive_ptr& operator=(const intrusive_ptr<U>& that) {
  2349. reset(that.get());
  2350. return *this;
  2351. }
  2352. template<typename U>
  2353. intrusive_ptr& operator=(intrusive_ptr<U>&& that) {
  2354. release(px);
  2355. px = that.px;
  2356. that.px = 0;
  2357. return *this;
  2358. }
  2359. ~intrusive_ptr() {
  2360. release(px);
  2361. }
  2362. void reset(T* nx = nullptr) {
  2363. addRef(nx);
  2364. release(px);
  2365. px = nx;
  2366. }
  2367. T* get() const {
  2368. return px;
  2369. }
  2370. T& operator*() const {
  2371. return *px;
  2372. }
  2373. T* operator->() const {
  2374. return px;
  2375. }
  2376. explicit operator bool() const {
  2377. return px != nullptr;
  2378. }
  2379. void swap(intrusive_ptr& rhs) {
  2380. std::swap(px, rhs.px);
  2381. }
  2382. private:
  2383. void addRef(T* px) {
  2384. if (px) {
  2385. ++px->referenceCount;
  2386. }
  2387. }
  2388. void release(T* px) {
  2389. if (px && --px->referenceCount == 0) {
  2390. delete px;
  2391. }
  2392. }
  2393. T* px;
  2394. template<typename U>
  2395. friend class intrusive_ptr;
  2396. };
  2397. namespace emscripten {
  2398. template<typename T>
  2399. struct smart_ptr_trait<intrusive_ptr<T>> {
  2400. typedef intrusive_ptr<T> pointer_type;
  2401. typedef T element_type;
  2402. static sharing_policy get_sharing_policy() {
  2403. return sharing_policy::INTRUSIVE;
  2404. }
  2405. static T* get(const intrusive_ptr<T>& p) {
  2406. return p.get();
  2407. }
  2408. static intrusive_ptr<T> share(const intrusive_ptr<T>& r, T* ptr) {
  2409. return intrusive_ptr<T>(ptr);
  2410. }
  2411. static pointer_type* construct_null() {
  2412. return new pointer_type;
  2413. }
  2414. };
  2415. }
  2416. template<typename T>
  2417. intrusive_ptr<T> make_intrusive_ptr() {
  2418. return intrusive_ptr<T>(new T);
  2419. }
  2420. struct IntrusiveClass {
  2421. virtual ~IntrusiveClass() {}
  2422. long referenceCount = 0;
  2423. };
  2424. struct IntrusiveClassWrapper : public wrapper<IntrusiveClass> {
  2425. EMSCRIPTEN_WRAPPER(IntrusiveClassWrapper);
  2426. };
  2427. template<typename T>
  2428. struct Holder {
  2429. void set(const T& v) {
  2430. value = v;
  2431. }
  2432. const T& get() const {
  2433. return value;
  2434. }
  2435. T value;
  2436. };
  2437. EMSCRIPTEN_BINDINGS(intrusive_pointers) {
  2438. class_<IntrusiveClass>("IntrusiveClass")
  2439. .smart_ptr_constructor("intrusive_ptr<IntrusiveClass>", &make_intrusive_ptr<IntrusiveClass>)
  2440. .allow_subclass<IntrusiveClassWrapper, intrusive_ptr<IntrusiveClassWrapper>>("IntrusiveClassWrapper", "IntrusiveClassWrapperPtr")
  2441. ;
  2442. typedef Holder<intrusive_ptr<IntrusiveClass>> IntrusiveClassHolder;
  2443. class_<IntrusiveClassHolder>("IntrusiveClassHolder")
  2444. .constructor<>()
  2445. .function("set", &IntrusiveClassHolder::set)
  2446. .function("get", &IntrusiveClassHolder::get)
  2447. ;
  2448. function("passThroughIntrusiveClass", &passThrough<intrusive_ptr<IntrusiveClass>>);
  2449. }
  2450. std::string getTypeOfVal(const val& v) {
  2451. return v.typeOf().as<std::string>();
  2452. }
  2453. EMSCRIPTEN_BINDINGS(typeOf) {
  2454. function("getTypeOfVal", &getTypeOfVal);
  2455. }
  2456. struct HasStaticMember {
  2457. static const int c;
  2458. static int v;
  2459. };
  2460. const int HasStaticMember::c = 10;
  2461. int HasStaticMember::v = 20;
  2462. EMSCRIPTEN_BINDINGS(static_member) {
  2463. class_<HasStaticMember>("HasStaticMember")
  2464. .class_property("c", &HasStaticMember::c)
  2465. .class_property("v", &HasStaticMember::v)
  2466. ;
  2467. }