Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/test/embind/embind_test.cpp
6170 views
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
6
#include <emscripten/bind.h>
7
#include <emscripten/em_asm.h>
8
#include <emscripten/heap.h>
9
#include <functional>
10
#include <malloc.h>
11
#include <string>
12
13
#if __cplusplus >= 201703L
14
#include <optional>
15
#endif
16
17
using namespace emscripten;
18
19
val emval_test_mallinfo() {
20
const auto& i = mallinfo();
21
val rv(val::object());
22
rv.set("arena", val(i.arena));
23
rv.set("ordblks", val(i.ordblks));
24
rv.set("smblks", val(i.smblks));
25
rv.set("hblks", val(i.hblks));
26
rv.set("usmblks", val(i.usmblks));
27
rv.set("fsmblks", val(i.fsmblks));
28
rv.set("uordblks", val(i.uordblks));
29
rv.set("fordblks", val(i.fordblks));
30
rv.set("keepcost", val(i.keepcost));
31
return rv;
32
}
33
34
val emval_test_new_integer() {
35
return val(15);
36
}
37
38
val emval_test_new_string() {
39
return val("Hello everyone");
40
}
41
42
std::string emval_test_get_string_from_val(val v) {
43
return v["key"].as<std::string>();
44
}
45
46
val emval_test_new_object() {
47
val rv(val::object());
48
rv.set("foo", val("bar"));
49
rv.set("baz", val(1));
50
return rv;
51
}
52
53
struct DummyForPointer {
54
int value;
55
DummyForPointer(const int v) : value(v) {}
56
};
57
58
static DummyForPointer emval_pointer_dummy(42);
59
60
val emval_test_instance_pointer() {
61
DummyForPointer* p = &emval_pointer_dummy;
62
return val(p, allow_raw_pointers());
63
}
64
65
int emval_test_value_from_instance_pointer(val v) {
66
DummyForPointer* p = v.as<DummyForPointer*>(allow_raw_pointers());
67
return p->value;
68
}
69
70
unsigned emval_test_passthrough_unsigned(unsigned v) {
71
return v;
72
}
73
74
val emval_test_passthrough(val v) {
75
return v;
76
}
77
78
void emval_test_return_void() {
79
}
80
81
bool emval_test_not(bool b) {
82
return !b;
83
}
84
85
bool emval_test_is_true(val v) {
86
return v.isTrue();
87
}
88
89
bool emval_test_is_false(val v) {
90
return v.isFalse();
91
}
92
93
bool emval_test_is_null(val v) {
94
return v.isNull();
95
}
96
97
bool emval_test_is_undefined(val v) {
98
return v.isUndefined();
99
}
100
101
bool emval_test_equals(val v1, val v2) {
102
return v1.equals(v2);
103
}
104
105
bool emval_test_strictly_equals(val v1, val v2) {
106
return v1.strictlyEquals(v2);
107
}
108
109
unsigned emval_test_as_unsigned(val v) {
110
return v.as<unsigned>();
111
}
112
113
unsigned emval_test_get_length(val v) {
114
return v["length"].as<unsigned>();
115
}
116
117
double emval_test_add(char c,
118
signed char sc,
119
unsigned char uc,
120
signed short ss,
121
unsigned short us,
122
signed int si,
123
unsigned int ui,
124
signed long sl,
125
unsigned long ul,
126
float f,
127
double d) {
128
return c + sc + uc + ss + us + si + ui + sl + ul + f + d;
129
}
130
131
float const_ref_adder(const int& i, const float& f) {
132
return i + f;
133
}
134
135
unsigned emval_test_sum(val v) {
136
unsigned length = v["length"].as<unsigned>();
137
double rv = 0;
138
for (unsigned i = 0; i < length; ++i) {
139
rv += v[i].as<double>();
140
}
141
return rv;
142
}
143
144
struct DestructorCounter {
145
static int count;
146
~DestructorCounter() {
147
count++;
148
};
149
};
150
151
int DestructorCounter::count = 0;
152
153
void emval_test_callback_arg_lifetime(val callback) {
154
DestructorCounter dc;
155
int destructorCount = DestructorCounter::count;
156
callback(dc);
157
assert(destructorCount == DestructorCounter::count);
158
}
159
160
std::string get_non_ascii_string(bool embindStdStringUTF8Support) {
161
if (embindStdStringUTF8Support) {
162
// ASCII
163
std::string testString{"aei"};
164
// Latin-1 Supplement
165
testString += "\u00E1\u00E9\u00ED";
166
// Greek
167
testString += "\u03B1\u03B5\u03B9";
168
// Cyrillic
169
testString += "\u0416\u041B\u0424";
170
// CJK
171
testString += "\u5F9E\u7345\u5B50";
172
// Euro sign
173
testString += "\u20AC";
174
return testString;
175
} else {
176
char c[128 + 1];
177
c[128] = 0;
178
for (int i = 0; i < 128; ++i) {
179
c[i] = 128 + i;
180
}
181
return c;
182
}
183
}
184
185
std::wstring get_non_ascii_wstring() {
186
std::wstring ws(4, 0);
187
ws[0] = 10;
188
ws[1] = 1234;
189
ws[2] = 2345;
190
ws[3] = 65535;
191
return ws;
192
}
193
194
std::u16string get_non_ascii_u16string() {
195
std::u16string u16s(4, 0);
196
u16s[0] = 10;
197
u16s[1] = 1234;
198
u16s[2] = 2345;
199
u16s[3] = 65535;
200
return u16s;
201
}
202
203
std::u32string get_non_ascii_u32string() {
204
std::u32string u32s(5, 0);
205
u32s[0] = 10;
206
u32s[1] = 1234;
207
u32s[2] = 2345;
208
u32s[3] = 128513;
209
u32s[4] = 128640;
210
return u32s;
211
}
212
213
std::wstring get_literal_wstring() {
214
return L"get_literal_wstring";
215
}
216
217
std::u16string get_literal_u16string() {
218
return u"get_literal_u16string";
219
}
220
221
std::u32string get_literal_u32string() {
222
return U"get_literal_u32string";
223
}
224
225
void force_memory_growth() {
226
std::size_t old_size = emscripten_get_heap_size();
227
EM_ASM({"globalThis.oldheap = HEAP8;"});
228
assert(val::global("oldheap")["byteLength"].as<size_t>() == old_size);
229
emscripten_resize_heap(old_size + EMSCRIPTEN_PAGE_SIZE);
230
assert(emscripten_get_heap_size() > old_size);
231
// HEAP8 on the module should now be rebound, and our oldheap should be
232
// detached
233
assert(val::module_property("HEAP8")["byteLength"].as<size_t>() > old_size);
234
assert(val::global("oldheap")["byteLength"].as<size_t>() == 0);
235
}
236
237
std::string emval_test_take_and_return_const_char_star(const char* str) {
238
return str;
239
}
240
241
std::string emval_test_take_and_return_std_string(std::string str) {
242
return str;
243
}
244
245
std::string emval_test_take_and_return_std_string_const_ref(const std::string& str) {
246
return str;
247
}
248
249
std::wstring take_and_return_std_wstring(std::wstring str) {
250
return str;
251
}
252
253
std::u16string take_and_return_std_u16string(std::u16string str) {
254
return str;
255
}
256
257
std::u32string take_and_return_std_u32string(std::u32string str) {
258
return str;
259
}
260
261
std::function<std::string(std::string)> emval_test_get_function_ptr() {
262
return emval_test_take_and_return_std_string;
263
}
264
265
std::string emval_test_take_and_call_functor(std::function<std::string(std::string)> func) {
266
return func("asdf");
267
}
268
269
class ValHolder {
270
public:
271
ValHolder(val v) : v_(v) {}
272
273
val getVal() const {
274
return v_;
275
}
276
277
val getValNonConst() {
278
return v_;
279
}
280
281
const val getConstVal() const {
282
return v_;
283
}
284
285
const val& getValConstRef() const {
286
return v_;
287
}
288
289
void setVal(val v) {
290
this->v_ = v;
291
}
292
293
static int some_class_method(int i) {
294
return i;
295
}
296
297
static const ValHolder* makeConst(val v) {
298
return new ValHolder(v);
299
}
300
301
static ValHolder makeValHolder(val v) {
302
return ValHolder(v);
303
}
304
305
static void set_via_raw_pointer(ValHolder* vh, val v) {
306
vh->setVal(v);
307
}
308
309
static val get_via_raw_pointer(const ValHolder* vh) {
310
return vh->getVal();
311
}
312
313
static void transfer_via_raw_pointer(ValHolder* target,
314
const ValHolder* source) {
315
target->setVal(source->getVal());
316
}
317
318
static val getValNonMember(const ValHolder& target) {
319
return target.getVal();
320
}
321
322
private:
323
val v_;
324
};
325
326
ValHolder emval_test_return_ValHolder() {
327
return val::object();
328
}
329
330
ValHolder valholder_from_sum(int x, int y) {
331
return val(x+y);
332
}
333
334
val valholder_get_value_mixin(const ValHolder& target) {
335
return target.getVal();
336
}
337
338
ValHolder* valholder_get_this_ptr(ValHolder& target) {
339
return &target;
340
}
341
342
void valholder_set_value_mixin(ValHolder& target, const val& value) {
343
target.setVal(value);
344
}
345
346
void emval_test_set_ValHolder_to_empty_object(ValHolder& vh) {
347
vh.setVal(val::object());
348
}
349
350
class StringHolder {
351
public:
352
StringHolder(const std::string& s) : str_(s) {}
353
354
void set(const std::string& s) {
355
str_ = s;
356
}
357
358
std::string get() const {
359
return str_;
360
}
361
362
std::string& get_ref() {
363
return str_;
364
}
365
366
const std::string& get_const_ref() const {
367
return str_;
368
}
369
370
private:
371
std::string str_;
372
};
373
374
class SharedPtrHolder {
375
public:
376
SharedPtrHolder() : ptr_(new StringHolder("a string")) {}
377
378
std::shared_ptr<StringHolder> get() const {
379
return ptr_;
380
}
381
382
void set(std::shared_ptr<StringHolder> p) {
383
ptr_ = p;
384
}
385
386
private:
387
std::shared_ptr<StringHolder> ptr_;
388
};
389
390
class VectorHolder {
391
public:
392
VectorHolder() {
393
v_.push_back(StringHolder("string #1"));
394
v_.push_back(StringHolder("string #2"));
395
}
396
397
std::vector<StringHolder> get() const {
398
return v_;
399
}
400
401
void set(std::vector<StringHolder> vec) {
402
v_ = vec;
403
}
404
405
private:
406
std::vector<StringHolder> v_;
407
};
408
409
class SmallClass {
410
public:
411
SmallClass() : member(7){};
412
int member;
413
};
414
415
class BigClass {
416
public:
417
BigClass() : member(11){};
418
int member;
419
int otherMember;
420
int yetAnotherMember;
421
422
int getMember() {
423
return member;
424
}
425
};
426
427
class NoExceptClass {
428
public:
429
int getValue() noexcept {
430
return 42;
431
}
432
int getValueConst() const noexcept {
433
return 43;
434
}
435
int getX() const noexcept { return x; }
436
void setX(int x_) noexcept { x = x_; }
437
438
private:
439
int x;
440
};
441
442
void embind_test_no_except_function(NoExceptClass&) noexcept {}
443
444
class ParentClass {
445
public:
446
ParentClass() : bigClass(){};
447
448
BigClass bigClass;
449
450
const BigClass& getBigClass() {
451
return bigClass;
452
};
453
};
454
455
template<typename T> class TemplateClass {
456
public:
457
TemplateClass(T a, T b, T c) {
458
members[0] = a;
459
members[1] = b;
460
members[2] = c;
461
};
462
463
const T getMember(int n) {
464
return members[n];
465
}
466
467
protected:
468
T members[3];
469
};
470
471
class ContainsTemplatedMemberClass {
472
public:
473
ContainsTemplatedMemberClass() : testTemplate(86, 87, 88){};
474
475
TemplateClass<int> testTemplate;
476
477
const TemplateClass<int>& getTestTemplate() {
478
return testTemplate;
479
};
480
};
481
482
class SymbolNameClass {
483
public:
484
std::string iterator() {
485
return "Iterator";
486
}
487
488
static std::string species() {
489
return "Species";
490
}
491
};
492
493
// Begin Inheritance Hierarchy Class Definitions
494
495
class Base {
496
public:
497
Base() : name("Base"), member(0), baseMember(0) {}
498
499
std::string getClassName() const {
500
return name;
501
}
502
std::string getClassNameFromBase() const {
503
return name;
504
}
505
std::string getClassNameNotAvailableInDerivedClasses() {
506
// but wait -- if you act now we will throw in a SECOND base class method
507
// ABSOLUTELY FREE!!
508
return name;
509
}
510
void setMember(int value) {
511
member = value;
512
}
513
int getMember() {
514
return member;
515
}
516
void setBaseMember(int value) {
517
baseMember = value;
518
}
519
int getBaseMember() {
520
return baseMember;
521
}
522
static std::string classFunction() {
523
return "Base";
524
};
525
std::string name;
526
int member;
527
int baseMember;
528
};
529
530
class SecondBase {
531
public:
532
SecondBase() : name("SecondBase"), member(0), secondBaseMember(0) {}
533
534
std::string getClassName() const {
535
return name;
536
}
537
std::string getClassNameNotAvailableInDerivedClasses() {
538
return name;
539
}
540
std::string getClassNameFromSecondBase() const {
541
return name;
542
}
543
void setMember(int value) {
544
member = value;
545
}
546
int getMember() {
547
return member;
548
}
549
void setSecondBaseMember(int value) {
550
secondBaseMember = value;
551
}
552
int getSecondBaseMember() {
553
return secondBaseMember;
554
}
555
std::string name;
556
int member;
557
int secondBaseMember;
558
};
559
560
class Derived : public Base {
561
public:
562
Derived() : Base(), member(0), name_("Derived") {
563
}
564
565
std::string getClassName() const {
566
return name_;
567
}
568
void setMember(int value) {
569
member = value;
570
}
571
int getMember() {
572
return member;
573
}
574
static std::string classFunction() {
575
return "Derived";
576
}
577
int member;
578
579
private:
580
std::string name_;
581
};
582
583
class DerivedHolder {
584
public:
585
DerivedHolder() {
586
derived_.reset();
587
}
588
void newDerived() {
589
deleteDerived();
590
derived_ = std::shared_ptr<Derived>(new Derived());
591
}
592
void deleteDerived() {
593
derived_.reset();
594
}
595
std::shared_ptr<Derived> getDerived() {
596
return derived_;
597
}
598
std::string getDerivedClassName() {
599
return derived_->getClassName();
600
}
601
602
private:
603
std::shared_ptr<Derived> derived_;
604
};
605
606
class SiblingDerived : public Base {
607
public:
608
SiblingDerived() : Base(), name_("SiblingDerived") {}
609
610
std::string getClassName() const {
611
return name_;
612
}
613
614
private:
615
std::string name_;
616
};
617
618
class MultiplyDerived : public Base, public SecondBase {
619
public:
620
MultiplyDerived() : Base(), SecondBase(), name_("MultiplyDerived") {
621
instanceCount_++;
622
}
623
624
~MultiplyDerived() {
625
instanceCount_--;
626
}
627
628
std::string getClassName() const {
629
return name_;
630
}
631
632
static int getInstanceCount() {
633
return instanceCount_;
634
}
635
636
private:
637
std::string name_;
638
static int instanceCount_;
639
};
640
int MultiplyDerived::instanceCount_ = 0;
641
642
class DerivedTwice : public Derived {
643
public:
644
DerivedTwice() : Derived(), name_("DerivedTwice") {
645
}
646
647
std::string getClassName() const {
648
return name_;
649
}
650
651
private:
652
std::string name_;
653
};
654
655
class DerivedTwiceNotBound : public Derived {
656
public:
657
DerivedTwiceNotBound() : Derived(), name_("DerivedTwiceNotBound") {}
658
659
std::string getClassName() const {
660
return name_;
661
}
662
663
private:
664
std::string name_;
665
};
666
667
class DerivedThrice : public DerivedTwiceNotBound {
668
public:
669
DerivedThrice() : DerivedTwiceNotBound(), name_("DerivedThrice") {}
670
671
std::string getClassName() const {
672
return name_;
673
}
674
675
private:
676
std::string name_;
677
};
678
679
class DerivedFourTimesNotBound : public DerivedThrice {
680
public:
681
DerivedFourTimesNotBound() : DerivedThrice(), name_("DerivedFourTimesNotBound") {}
682
683
std::string getClassName() const {
684
return name_;
685
}
686
687
private:
688
std::string name_;
689
};
690
691
class PolyBase {
692
public:
693
PolyBase(const std::string& s) : str_(s), name_("PolyBase") {}
694
695
PolyBase() : name_("PolyBase") {}
696
697
virtual ~PolyBase() {
698
}
699
700
virtual std::string virtualGetClassName() const {
701
return name_;
702
}
703
704
std::string getClassName() const {
705
return name_;
706
}
707
708
private:
709
std::string str_;
710
std::string name_;
711
};
712
713
class PolySecondBase {
714
public:
715
PolySecondBase() : name_("PolySecondBase") {}
716
717
virtual ~PolySecondBase() {}
718
719
std::string getClassName() const {
720
return name_;
721
}
722
723
private:
724
std::string name_;
725
};
726
727
class PolyDerived : public PolyBase {
728
public:
729
PolyDerived() : PolyBase("PolyDerived"), name_("PolyDerived") {}
730
731
std::string virtualGetClassName() const {
732
return name_;
733
}
734
735
std::string getClassName() const {
736
return name_;
737
}
738
739
static void setPtrDerived() {
740
ptr_ = std::shared_ptr<PolyDerived>(new PolyDerived());
741
}
742
743
static void releasePtr() {
744
ptr_.reset();
745
}
746
747
static std::string getPtrClassName() {
748
return ptr_->getClassName();
749
}
750
751
static std::shared_ptr<PolyBase> getPtr() {
752
return ptr_;
753
}
754
755
private:
756
std::string name_;
757
static std::shared_ptr<PolyBase> ptr_;
758
};
759
std::shared_ptr<PolyBase> PolyDerived::ptr_;
760
761
class PolySiblingDerived : public PolyBase {
762
public:
763
PolySiblingDerived() : PolyBase(), name_("PolySiblingDerived") {}
764
765
std::string getClassName() const {
766
return name_;
767
}
768
769
private:
770
std::string name_;
771
};
772
773
class PolyMultiplyDerived : public PolyBase, public PolySecondBase {
774
public:
775
PolyMultiplyDerived() : PolyBase(), PolySecondBase(), name_("PolyMultiplyDerived") {}
776
777
std::string getClassName() const {
778
return name_;
779
}
780
781
private:
782
std::string name_;
783
};
784
785
class PolyDerivedTwiceWithoutSmartPointer : public PolyDerived {
786
public:
787
PolyDerivedTwiceWithoutSmartPointer() : PolyDerived(), name_("PolyDerivedTwiceWithoutSmartPointer") {}
788
789
std::string getClassName() const {
790
return name_;
791
}
792
793
private:
794
std::string name_;
795
};
796
797
class PolyDerivedTwiceNotBound : public PolyDerived {
798
public:
799
PolyDerivedTwiceNotBound() : PolyDerived(), name_("PolyDerivedTwiceNotBound") {}
800
801
std::string getClassName() const {
802
return name_;
803
}
804
805
private:
806
std::string name_;
807
};
808
809
class PolyDerivedThrice : public PolyDerivedTwiceNotBound {
810
public:
811
PolyDerivedThrice() : PolyDerivedTwiceNotBound(), name_("PolyDerivedThrice") {}
812
813
std::string getClassName() const {
814
return name_;
815
}
816
817
private:
818
std::string name_;
819
};
820
821
class PolyDerivedFourTimesNotBound : public PolyDerivedThrice {
822
public:
823
PolyDerivedFourTimesNotBound() : PolyDerivedThrice(), name_("PolyDerivedFourTimesNotBound") {}
824
825
std::string getClassName() const {
826
return name_;
827
}
828
829
private:
830
std::string name_;
831
};
832
833
class PolyDiamondBase {
834
public:
835
PolyDiamondBase() : name_("PolyBase") {}
836
~PolyDiamondBase() {}
837
838
std::string getClassName() const {
839
return name_;
840
}
841
842
private:
843
std::string name_;
844
};
845
846
class PolyDiamondDerived : public PolyDiamondBase {
847
public:
848
PolyDiamondDerived() : PolyDiamondBase(), name_("PolyDiamondDerived") {}
849
850
std::string getClassName() const {
851
return name_;
852
}
853
854
private:
855
std::string name_;
856
};
857
858
class PolyDiamondSiblingDerived : public PolyDiamondBase {
859
public:
860
PolyDiamondSiblingDerived() : PolyDiamondBase(), name_("PolyDiamondSiblingDerived") {}
861
862
std::string getClassName() const {
863
return name_;
864
}
865
866
private:
867
std::string name_;
868
};
869
870
class PolyDiamondMultiplyDerived : public PolyDiamondDerived,
871
public PolyDiamondSiblingDerived {
872
public:
873
PolyDiamondMultiplyDerived()
874
: PolyDiamondDerived(), PolyDiamondSiblingDerived(),
875
name_("PolyDiamondMultiplyDerived") {}
876
877
std::string getClassName() const {
878
return name_;
879
}
880
881
private:
882
std::string name_;
883
};
884
885
// End Inheritance Hierarchy Class Definitions
886
887
std::map<std::string, int> embind_test_get_string_int_map() {
888
std::map<std::string, int> m;
889
890
m["one"] = 1;
891
m["two"] = 2;
892
893
return m;
894
};
895
896
std::map<int, std::string, std::greater<int>> embind_test_get_int_string_greater_map() {
897
std::map<int, std::string, std::greater<int>> m;
898
899
m[1] = "one";
900
m[2] = "two";
901
902
return m;
903
}
904
905
struct Vector {
906
Vector() = delete;
907
908
Vector(float x_, float y_, float z_, float w_) : x(x_), y(y_), z(z_), w(w_) {}
909
910
float x, y, z, w;
911
912
float& operator[](int i) {
913
return (&x)[i];
914
}
915
916
const float& operator[](int i) const {
917
return (&x)[i];
918
}
919
920
float getY() const {
921
return y;
922
}
923
void setY(float _y) {
924
y = _y;
925
}
926
};
927
928
struct DummyDataToTestPointerAdjustment {
929
std::string dummy;
930
};
931
932
struct TupleVector : DummyDataToTestPointerAdjustment, Vector {
933
TupleVector() : Vector(0, 0, 0, 0) {}
934
TupleVector(float x, float y, float z, float w) : Vector(x, y, z, w) {}
935
};
936
937
struct StructVector : DummyDataToTestPointerAdjustment, Vector {
938
StructVector() : Vector(0, 0, 0, 0) {}
939
StructVector(float x, float y, float z, float w) : Vector(x, y, z, w) {}
940
};
941
942
float readVectorZ(const Vector& v) {
943
return v.z;
944
}
945
946
void writeVectorZ(Vector& v, float z) {
947
v.z = z;
948
}
949
950
struct TupleVectorTuple {
951
TupleVector v = TupleVector(0, 0, 0, 0);
952
};
953
954
TupleVector emval_test_return_TupleVector() {
955
return TupleVector(1, 2, 3, 4);
956
}
957
958
TupleVector emval_test_take_and_return_TupleVector(TupleVector v) {
959
return v;
960
}
961
962
TupleVectorTuple emval_test_return_TupleVectorTuple() {
963
TupleVectorTuple cvt;
964
cvt.v = emval_test_return_TupleVector();
965
return cvt;
966
}
967
968
StructVector emval_test_return_StructVector() {
969
return StructVector(1, 2, 3, 4);
970
}
971
972
StructVector emval_test_take_and_return_StructVector(StructVector v) {
973
return v;
974
}
975
976
struct CustomStruct {
977
CustomStruct() : field(10) {
978
}
979
980
const int& getField() const {
981
return field;
982
}
983
984
int field;
985
};
986
987
struct TupleInStruct {
988
TupleVector field;
989
};
990
991
TupleInStruct emval_test_take_and_return_TupleInStruct(TupleInStruct cs) {
992
return cs;
993
}
994
995
struct NestedStruct {
996
int x;
997
int y;
998
};
999
struct ArrayInStruct {
1000
int field1[2];
1001
NestedStruct field2[2];
1002
};
1003
ArrayInStruct emval_test_take_and_return_ArrayInStruct(ArrayInStruct cs) {
1004
return cs;
1005
}
1006
1007
enum Enum { ONE, TWO };
1008
1009
Enum emval_test_take_and_return_Enum(Enum e) {
1010
return e;
1011
}
1012
1013
enum class EnumClass : char { ONE, TWO };
1014
1015
EnumClass emval_test_take_and_return_EnumClass(EnumClass e) {
1016
return e;
1017
}
1018
1019
enum class EnumNum { ONE, TWO };
1020
1021
EnumNum emval_test_take_and_return_EnumNum(EnumNum e) {
1022
return e;
1023
}
1024
1025
enum class EnumStr { ONE, TWO };
1026
1027
EnumStr emval_test_take_and_return_EnumStr(EnumStr e) {
1028
return e;
1029
}
1030
1031
void emval_test_call_function(val v, int i, float f, TupleVector tv, StructVector sv) {
1032
v(i, f, tv, sv);
1033
}
1034
1035
struct CharWrapper {
1036
CharWrapper(char v) {
1037
value = v;
1038
};
1039
1040
char getValue() {
1041
return value;
1042
}
1043
1044
char value;
1045
};
1046
1047
class UniquePtrToConstructor {
1048
public:
1049
UniquePtrToConstructor(std::unique_ptr<CharWrapper> p)
1050
: value((*p).getValue()) {
1051
}
1052
1053
char getValue() const {
1054
return value;
1055
}
1056
1057
private:
1058
char value;
1059
};
1060
1061
std::unique_ptr<CharWrapper> embind_test_return_unique_ptr(char v) {
1062
return std::unique_ptr<CharWrapper>(new CharWrapper(v));
1063
}
1064
1065
UniquePtrToConstructor* embind_test_construct_class_with_unique_ptr(char v) {
1066
return new UniquePtrToConstructor(embind_test_return_unique_ptr(v));
1067
}
1068
1069
char embind_test_accept_unique_ptr(std::unique_ptr<CharWrapper> p) {
1070
return (*p.get()).getValue();
1071
}
1072
1073
std::unique_ptr<ValHolder> emval_test_return_unique_ptr() {
1074
return std::unique_ptr<ValHolder>(new ValHolder(val::object()));
1075
}
1076
1077
class UniquePtrLifetimeMock {
1078
public:
1079
UniquePtrLifetimeMock(val l) : logger(l) {
1080
logger(std::string("(constructor)"));
1081
}
1082
~UniquePtrLifetimeMock() {
1083
logger(std::string("(destructor)"));
1084
}
1085
1086
private:
1087
val logger;
1088
};
1089
1090
std::unique_ptr<UniquePtrLifetimeMock> emval_test_return_unique_ptr_lifetime(val logger) {
1091
return std::unique_ptr<UniquePtrLifetimeMock>(new UniquePtrLifetimeMock(logger));
1092
}
1093
1094
std::shared_ptr<ValHolder> emval_test_return_shared_ptr() {
1095
return std::shared_ptr<ValHolder>(new ValHolder(val::object()));
1096
}
1097
1098
std::shared_ptr<ValHolder> emval_test_return_empty_shared_ptr() {
1099
return std::shared_ptr<ValHolder>();
1100
}
1101
1102
bool emval_test_is_shared_ptr_null(std::shared_ptr<ValHolder> p) {
1103
return !p;
1104
}
1105
1106
static SmallClass smallClass;
1107
static BigClass bigClass;
1108
1109
SmallClass embind_test_return_small_class_instance() {
1110
return smallClass;
1111
}
1112
1113
BigClass embind_test_return_big_class_instance() {
1114
return bigClass;
1115
}
1116
1117
int embind_test_accept_small_class_instance(SmallClass c) {
1118
return c.member;
1119
}
1120
1121
int embind_test_accept_big_class_instance(BigClass c) {
1122
return c.member;
1123
}
1124
1125
// Begin Inheritance Hierarchy Test Wrappers
1126
1127
Base* embind_test_return_raw_base_ptr() {
1128
return new Base();
1129
}
1130
1131
Base* embind_test_return_raw_derived_ptr_as_base() {
1132
return new Derived();
1133
}
1134
1135
Base* embind_test_return_raw_sibling_derived_ptr_as_base() {
1136
return new SiblingDerived();
1137
}
1138
1139
PolyBase* embind_test_return_raw_polymorphic_derived_ptr_as_base() {
1140
return new PolyDerived();
1141
}
1142
1143
PolyBase* embind_test_return_raw_polymorphic_sibling_derived_ptr_as_base() {
1144
return new PolySiblingDerived();
1145
}
1146
1147
PolyBase* embind_test_return_raw_polymorphic_multiply_derived_ptr_as_base() {
1148
return new PolyMultiplyDerived();
1149
}
1150
1151
PolySecondBase* embind_test_return_raw_polymorphic_multiply_derived_ptr_as_second_base() {
1152
return new PolyMultiplyDerived();
1153
}
1154
1155
PolyBase* embind_test_return_raw_polymorphic_derived_four_times_not_bound_as_base() {
1156
return new PolyDerivedFourTimesNotBound();
1157
}
1158
1159
std::shared_ptr<Base> embind_test_return_smart_base_ptr() {
1160
return std::shared_ptr<Base>(new Base());
1161
}
1162
1163
std::shared_ptr<PolyBase> embind_test_return_smart_polymorphic_base_ptr() {
1164
return std::shared_ptr<PolyBase>(new PolyBase("PolyBase"));
1165
}
1166
1167
std::shared_ptr<Derived> embind_test_return_smart_derived_ptr() {
1168
return std::shared_ptr<Derived>(new Derived());
1169
}
1170
1171
std::shared_ptr<SiblingDerived> embind_test_return_smart_sibling_derived_ptr() {
1172
return std::shared_ptr<SiblingDerived>(new SiblingDerived());
1173
}
1174
1175
std::shared_ptr<MultiplyDerived> embind_test_return_smart_multiply_derived_ptr() {
1176
return std::shared_ptr<MultiplyDerived>(new MultiplyDerived());
1177
}
1178
1179
std::shared_ptr<DerivedThrice> embind_test_return_smart_derived_thrice_ptr() {
1180
return std::shared_ptr<DerivedThrice>(new DerivedThrice());
1181
}
1182
1183
std::shared_ptr<PolyDerived> embind_test_return_smart_polymorphic_derived_ptr() {
1184
return std::shared_ptr<PolyDerived>(new PolyDerived());
1185
}
1186
1187
std::shared_ptr<PolySiblingDerived> embind_test_return_smart_polymorphic_sibling_derived_ptr() {
1188
return std::shared_ptr<PolySiblingDerived>(new PolySiblingDerived());
1189
}
1190
1191
std::shared_ptr<PolyMultiplyDerived> embind_test_return_smart_polymorphic_multiply_derived_ptr() {
1192
return std::shared_ptr<PolyMultiplyDerived>(new PolyMultiplyDerived());
1193
}
1194
1195
std::shared_ptr<PolyBase> embind_test_return_poly_derived_twice_without_smart_pointer_as_poly_base() {
1196
return std::shared_ptr<PolyBase>(new PolyDerivedTwiceWithoutSmartPointer());
1197
}
1198
1199
std::shared_ptr<PolyDerivedThrice> embind_test_return_smart_poly_derived_thrice_ptr() {
1200
return std::shared_ptr<PolyDerivedThrice>(new PolyDerivedThrice());
1201
}
1202
1203
std::shared_ptr<PolyBase> embind_test_return_smart_derived_ptr_as_base() {
1204
return std::shared_ptr<PolyBase>(new PolyDerived());
1205
}
1206
1207
val embind_test_return_smart_derived_ptr_as_val() {
1208
return val(std::shared_ptr<PolyBase>(new PolyDerived()));
1209
}
1210
1211
std::shared_ptr<PolyBase> embind_test_return_smart_polymorphic_derived_ptr_as_base() {
1212
return std::shared_ptr<PolyBase>(new PolyDerived());
1213
}
1214
1215
std::shared_ptr<PolyBase> embind_test_return_smart_polymorphic_sibling_derived_ptr_as_base() {
1216
return std::shared_ptr<PolyBase>(new PolySiblingDerived());
1217
}
1218
1219
std::string embind_test_get_class_name_via_base_ptr(Base* p) {
1220
return p->getClassName();
1221
}
1222
1223
std::string embind_test_get_class_name_via_second_base_ptr(SecondBase* p) {
1224
return p->getClassName();
1225
}
1226
1227
std::string embind_test_get_class_name_via_polymorphic_base_ptr(PolyBase* p) {
1228
return p->getClassName();
1229
}
1230
1231
std::string embind_test_get_class_name_via_polymorphic_second_base_ptr(PolySecondBase* p) {
1232
return p->getClassName();
1233
}
1234
1235
std::string embind_test_get_class_name_via_smart_base_ptr(std::shared_ptr<Base> p) {
1236
return p->getClassName();
1237
}
1238
1239
std::string embind_test_get_class_name_via_reference_to_smart_base_ptr(std::shared_ptr<Base>& p) {
1240
return p->getClassName();
1241
}
1242
1243
std::string embind_test_get_class_name_via_smart_second_base_ptr(std::shared_ptr<SecondBase> p) {
1244
return p->getClassName();
1245
}
1246
1247
std::string embind_test_get_class_name_via_smart_polymorphic_base_ptr(std::shared_ptr<PolyBase> p) {
1248
return p->getClassName();
1249
}
1250
1251
std::string embind_test_get_virtual_class_name_via_smart_polymorphic_base_ptr(std::shared_ptr<PolyBase> p) {
1252
return p->virtualGetClassName();
1253
}
1254
1255
std::string embind_test_get_class_name_via_smart_polymorphic_second_base_ptr(std::shared_ptr<PolySecondBase> p) {
1256
return p->getClassName();
1257
}
1258
1259
void embind_modify_smart_pointer_passed_by_reference(std::shared_ptr<Base>& p) {
1260
p = std::shared_ptr<Base>(new Base());
1261
p->name = "Changed";
1262
}
1263
1264
void embind_attempt_to_modify_smart_pointer_when_passed_by_value(std::shared_ptr<Base> p) {
1265
p = std::shared_ptr<Base>(new Base());
1266
p->name = "Changed";
1267
}
1268
1269
static std::shared_ptr<Base> savedBasePointer;
1270
1271
void embind_save_smart_base_pointer(std::shared_ptr<Base> p) {
1272
savedBasePointer = p;
1273
}
1274
1275
// End Inheritance Hierarchy Test Wrappers
1276
1277
std::vector<int> emval_test_return_vector() {
1278
int myints[] = {10, 20, 30};
1279
return std::vector<int>(myints, myints + sizeof(myints) / sizeof(int));
1280
}
1281
1282
std::vector<std::vector<int>> emval_test_return_vector_of_vectors() {
1283
int myints1[] = {10, 20, 30};
1284
int myints2[] = {40, 50, 60};
1285
std::vector<int> vec1(myints1, myints1 + sizeof(myints1) / sizeof(int));
1286
std::vector<int> vec2(myints2, myints2 + sizeof(myints2) / sizeof(int));
1287
std::vector<std::vector<int>> vec3;
1288
vec3.emplace_back(vec1);
1289
vec3.emplace_back(vec2);
1290
return vec3;
1291
}
1292
1293
std::vector<std::shared_ptr<StringHolder>> emval_test_return_shared_ptr_vector() {
1294
std::vector<std::shared_ptr<StringHolder>> sharedStrVector;
1295
sharedStrVector.push_back(std::shared_ptr<StringHolder>(new StringHolder("string #1")));
1296
sharedStrVector.push_back(std::shared_ptr<StringHolder>(new StringHolder("string #2")));
1297
1298
return sharedStrVector;
1299
}
1300
1301
std::vector<SmallClass*> emval_test_return_vector_pointers() {
1302
std::vector<SmallClass*> vec;
1303
vec.push_back(new SmallClass());
1304
return vec;
1305
}
1306
1307
class CustomIterable {
1308
public:
1309
CustomIterable() : values_({1, 2, 3}) {}
1310
1311
unsigned int count() const {
1312
return values_.size();
1313
}
1314
1315
int at(unsigned int index) const {
1316
return values_[index];
1317
}
1318
1319
private:
1320
std::vector<int> values_;
1321
};
1322
1323
class CustomIterableSizeT {
1324
public:
1325
CustomIterableSizeT() : values_({10, 20, 30}) {}
1326
1327
size_t count() const {
1328
return values_.size();
1329
}
1330
1331
int at(size_t index) const {
1332
return values_[index];
1333
}
1334
1335
private:
1336
std::vector<int> values_;
1337
};
1338
1339
void test_string_with_vec(const std::string& p1, std::vector<std::string>& v1) {
1340
// THIS DOES NOT WORK -- need to get as val and then call vecFromJSArray
1341
printf("%s\n", p1.c_str());
1342
}
1343
1344
#if __cplusplus >= 201703L
1345
std::optional<int> embind_test_return_optional_int(bool create) {
1346
if (create) {
1347
return 42;
1348
}
1349
return {};
1350
}
1351
std::optional<float> embind_test_return_optional_float(bool create) {
1352
if (create) {
1353
return 4.2;
1354
}
1355
return {};
1356
}
1357
std::optional<std::string> embind_test_return_optional_string(bool create) {
1358
if (create) {
1359
return "hello";
1360
}
1361
return {};
1362
}
1363
std::optional<SmallClass> embind_test_return_optional_small_class(bool create) {
1364
if (create) {
1365
return SmallClass();
1366
}
1367
return {};
1368
}
1369
std::optional<SmallClass*>
1370
embind_test_return_optional_small_class_pointer(bool create) {
1371
if (create) {
1372
return new SmallClass();
1373
}
1374
return {};
1375
}
1376
1377
int embind_test_optional_int_arg(std::optional<int> arg) {
1378
if (arg) {
1379
return *arg;
1380
}
1381
return -1;
1382
}
1383
float embind_test_optional_float_arg(std::optional<float> arg) {
1384
if (arg) {
1385
return *arg;
1386
}
1387
return -1.1;
1388
}
1389
std::string embind_test_optional_string_arg(std::optional<std::string> arg) {
1390
if (arg) {
1391
return *arg;
1392
}
1393
return "no value";
1394
}
1395
1396
int embind_test_optional_small_class_arg(std::optional<SmallClass> arg) {
1397
if (arg) {
1398
return arg->member;
1399
}
1400
return -1;
1401
}
1402
void embind_test_optional_multiple_arg(int arg1,
1403
std::optional<int> arg2,
1404
std::optional<int> arg3) {
1405
}
1406
1407
struct StructWithOptionalProperty {
1408
int x;
1409
std::optional<int> y;
1410
};
1411
void embind_test_optional_property(const StructWithOptionalProperty &arg) {
1412
}
1413
#endif
1414
1415
val embind_test_getglobal() {
1416
return val::global();
1417
}
1418
1419
val embind_test_new_Object() {
1420
return val::global("Object").new_();
1421
}
1422
1423
val embind_test_new_factory(val factory, val argument) {
1424
return factory.new_(10, std::string("hello"), argument);
1425
}
1426
1427
class AbstractClass {
1428
public:
1429
virtual ~AbstractClass() {}
1430
virtual std::string abstractMethod() const = 0;
1431
virtual std::string optionalMethod(std::string s) const {
1432
return "optional" + s;
1433
}
1434
1435
virtual std::shared_ptr<Derived> returnsSharedPtr() = 0;
1436
virtual void differentArguments(
1437
int i, double d, unsigned char f, double q, std::string) = 0;
1438
1439
std::string concreteMethod() const {
1440
return "concrete";
1441
}
1442
1443
virtual void passShared(const std::shared_ptr<Derived>&) {
1444
}
1445
1446
virtual void passVal(const val& v) {
1447
}
1448
};
1449
1450
EMSCRIPTEN_SYMBOL(optionalMethod);
1451
1452
class AbstractClassWrapper : public wrapper<AbstractClass> {
1453
public:
1454
EMSCRIPTEN_WRAPPER(AbstractClassWrapper);
1455
1456
std::string abstractMethod() const override {
1457
return call<std::string>("abstractMethod");
1458
}
1459
1460
std::string optionalMethod(std::string s) const override {
1461
return call<std::string>("optionalMethod", s);
1462
}
1463
1464
std::shared_ptr<Derived> returnsSharedPtr() override {
1465
return call<std::shared_ptr<Derived>>("returnsSharedPtr");
1466
}
1467
1468
void differentArguments(int i, double d, unsigned char f, double q, std::string s) override {
1469
return call<void>("differentArguments", i, d, f, q, s);
1470
}
1471
1472
virtual void passShared(const std::shared_ptr<Derived>& p) override {
1473
return call<void>("passShared", p);
1474
}
1475
1476
virtual void passVal(const val& v) override {
1477
return call<void>("passVal", v);
1478
}
1479
};
1480
1481
class ConcreteClass : public AbstractClass {
1482
std::string abstractMethod() const {
1483
return "from concrete";
1484
}
1485
1486
void differentArguments(
1487
int i, double d, unsigned char f, double q, std::string s) {
1488
}
1489
1490
std::shared_ptr<Derived> returnsSharedPtr() {
1491
return std::shared_ptr<Derived>();
1492
}
1493
};
1494
1495
std::shared_ptr<AbstractClass> getAbstractClass() {
1496
return std::make_shared<ConcreteClass>();
1497
}
1498
1499
std::string callAbstractMethod(AbstractClass& ac) {
1500
return ac.abstractMethod();
1501
}
1502
1503
std::string callOptionalMethod(AbstractClass& ac, std::string s) {
1504
return ac.optionalMethod(s);
1505
}
1506
1507
void callReturnsSharedPtrMethod(AbstractClass& ac) {
1508
std::shared_ptr<Derived> sp = ac.returnsSharedPtr();
1509
// unused: sp
1510
}
1511
1512
void callDifferentArguments(AbstractClass& ac,
1513
int i,
1514
double d,
1515
unsigned char f,
1516
double q,
1517
std::string s) {
1518
return ac.differentArguments(i, d, f, q, s);
1519
}
1520
1521
struct AbstractClassWithConstructor {
1522
explicit AbstractClassWithConstructor(std::string s) : s(s) {}
1523
1524
virtual ~AbstractClassWithConstructor(){};
1525
1526
virtual std::string abstractMethod() = 0;
1527
std::string concreteMethod() {
1528
return s;
1529
}
1530
1531
std::string s;
1532
};
1533
1534
struct AbstractClassWithConstructorWrapper
1535
: public wrapper<AbstractClassWithConstructor> {
1536
EMSCRIPTEN_WRAPPER(AbstractClassWithConstructorWrapper);
1537
1538
virtual std::string abstractMethod() override {
1539
return call<std::string>("abstractMethod");
1540
}
1541
};
1542
1543
std::string callAbstractMethod2(AbstractClassWithConstructor& ac) {
1544
return ac.abstractMethod();
1545
}
1546
1547
struct HeldAbstractClass : public PolyBase, public PolySecondBase {
1548
virtual void method() = 0;
1549
};
1550
struct HeldAbstractClassWrapper : wrapper<HeldAbstractClass> {
1551
EMSCRIPTEN_WRAPPER(HeldAbstractClassWrapper);
1552
1553
virtual void method() override {
1554
return call<void>("method");
1555
}
1556
};
1557
1558
std::shared_ptr<PolySecondBase> passHeldAbstractClass(std::shared_ptr<HeldAbstractClass> p) {
1559
return p;
1560
}
1561
1562
void passShared(AbstractClass& ac) {
1563
auto p = std::make_shared<Derived>();
1564
ac.passShared(p);
1565
}
1566
1567
void passVal(AbstractClass& ac, val v) {
1568
return ac.passVal(v);
1569
}
1570
1571
EMSCRIPTEN_BINDINGS(interface_tests) {
1572
class_<AbstractClass>("AbstractClass")
1573
.smart_ptr<std::shared_ptr<AbstractClass>>("shared_ptr<AbstractClass>")
1574
.allow_subclass<AbstractClassWrapper>("AbstractClassWrapper")
1575
.function("abstractMethod", &AbstractClass::abstractMethod, pure_virtual())
1576
// The optional_override is necessary because, otherwise, the C++ compiler
1577
// cannot deduce the signature of the lambda function.
1578
.function("optionalMethod", optional_override(
1579
[](AbstractClass& this_, const std::string& s) {
1580
return this_.AbstractClass::optionalMethod(s);
1581
}
1582
))
1583
.function("concreteMethod", &AbstractClass::concreteMethod)
1584
.function("passShared", select_overload<void(AbstractClass&, const std::shared_ptr<Derived>&)>([](AbstractClass& self, const std::shared_ptr<Derived>& derived) {
1585
self.AbstractClass::passShared(derived);
1586
}))
1587
.function("passVal", select_overload<void(AbstractClass&, const val&)>([](AbstractClass& self, const val& v) {
1588
self.AbstractClass::passVal(v);
1589
}))
1590
;
1591
1592
function("getAbstractClass", &getAbstractClass);
1593
function("callAbstractMethod", &callAbstractMethod);
1594
function("callOptionalMethod", &callOptionalMethod);
1595
function("callReturnsSharedPtrMethod", &callReturnsSharedPtrMethod);
1596
function("callDifferentArguments", &callDifferentArguments);
1597
function("passShared", &passShared);
1598
function("passVal", &passVal);
1599
1600
class_<AbstractClassWithConstructor>("AbstractClassWithConstructor")
1601
.allow_subclass<AbstractClassWithConstructorWrapper>("AbstractClassWithConstructorWrapper", constructor<std::string>())
1602
.function("abstractMethod", &AbstractClassWithConstructor::abstractMethod, pure_virtual())
1603
.function("concreteMethod", &AbstractClassWithConstructor::concreteMethod)
1604
;
1605
function("callAbstractMethod2", &callAbstractMethod2);
1606
1607
class_<HeldAbstractClass, base<PolySecondBase>>("HeldAbstractClass")
1608
.smart_ptr<std::shared_ptr<HeldAbstractClass>>("shared_ptr<HeldAbstractClass>")
1609
.allow_subclass<HeldAbstractClassWrapper, std::shared_ptr<HeldAbstractClassWrapper>>("HeldAbstractClassWrapper", "HeldAbstractClassWrapperPtr")
1610
.function("method", &HeldAbstractClass::method, pure_virtual())
1611
;
1612
function("passHeldAbstractClass", &passHeldAbstractClass);
1613
}
1614
1615
template<typename T, size_t sizeOfArray>
1616
constexpr size_t getElementCount(T (&)[sizeOfArray]) {
1617
return sizeOfArray;
1618
}
1619
1620
static void callWithMemoryView(val v) {
1621
// static so the JS test can read the memory after callTakeMemoryView runs
1622
static unsigned char data[] = {0, 1, 2, 3, 4, 5, 6, 7};
1623
v(typed_memory_view(getElementCount(data), data));
1624
static float f[] = {1.5f, 2.5f, 3.5f, 4.5f};
1625
v(typed_memory_view(getElementCount(f), f));
1626
static short s[] = {1000, 100, 10, 1};
1627
v(typed_memory_view(getElementCount(s), s));
1628
}
1629
1630
EMSCRIPTEN_BINDINGS(memory_view_tests) {
1631
function("callWithMemoryView", &callWithMemoryView);
1632
}
1633
1634
class HasExternalConstructor {
1635
public:
1636
HasExternalConstructor(const std::string& str) : m(str) {}
1637
1638
std::string getString() const {
1639
return m;
1640
}
1641
1642
std::string m;
1643
};
1644
1645
HasExternalConstructor* createHasExternalConstructor(const std::string& str) {
1646
return new HasExternalConstructor(str);
1647
}
1648
1649
class HasExternalConstructorNoCopy {
1650
private:
1651
HasExternalConstructorNoCopy(int i) : m(i) {
1652
}
1653
int m;
1654
1655
public:
1656
HasExternalConstructorNoCopy(HasExternalConstructorNoCopy&) = delete;
1657
HasExternalConstructorNoCopy(HasExternalConstructorNoCopy&&) = default;
1658
int getInt() {
1659
return m;
1660
}
1661
static HasExternalConstructorNoCopy create(int i) {
1662
HasExternalConstructorNoCopy obj(i);
1663
return obj;
1664
}
1665
};
1666
1667
template<typename T> class CustomSmartPtr {
1668
public:
1669
CustomSmartPtr() : CustomSmartPtr(nullptr) {
1670
std::fill(d_, d_ + N_, Valid);
1671
}
1672
1673
explicit CustomSmartPtr(T* t) : ptr_(t) {
1674
std::fill(d_, d_ + N_, Valid);
1675
}
1676
1677
CustomSmartPtr(const CustomSmartPtr& other) : ptr_(other.ptr_) {
1678
other.verify();
1679
std::fill(d_, d_ + N_, Valid);
1680
if (ptr_) {
1681
++(ptr_->refcount);
1682
}
1683
}
1684
1685
~CustomSmartPtr() {
1686
verify();
1687
std::fill(d_, d_ + N_, Deleted);
1688
1689
if (ptr_ && --ptr_->refcount == 0) {
1690
delete ptr_;
1691
}
1692
}
1693
1694
T* get_raw() const {
1695
return ptr_;
1696
}
1697
1698
private:
1699
void verify() const {
1700
for (size_t i = 0; i < N_; ++i) {
1701
if (d_[i] != Valid) {
1702
abort();
1703
}
1704
}
1705
}
1706
1707
enum {
1708
Valid = 255,
1709
Deleted = 127,
1710
};
1711
static constexpr size_t N_ = 1000000;
1712
unsigned char d_[N_];
1713
T* ptr_;
1714
1715
CustomSmartPtr& operator=(const CustomSmartPtr&) = delete;
1716
};
1717
1718
class HeldBySmartPtr {
1719
public:
1720
HeldBySmartPtr(int i, const std::string& s) : i(i), s(s) {
1721
}
1722
1723
static CustomSmartPtr<HeldBySmartPtr> newCustomPtr(int i,
1724
const std::string& s) {
1725
return CustomSmartPtr<HeldBySmartPtr>(new HeldBySmartPtr(i, s));
1726
}
1727
1728
int refcount = 1;
1729
int i;
1730
std::string s;
1731
};
1732
1733
HeldBySmartPtr takesHeldBySmartPtr(HeldBySmartPtr p) {
1734
return p;
1735
}
1736
std::shared_ptr<HeldBySmartPtr>
1737
takesHeldBySmartPtrSharedPtr(std::shared_ptr<HeldBySmartPtr> p) {
1738
return p;
1739
}
1740
1741
namespace emscripten {
1742
template<typename T> struct smart_ptr_trait<CustomSmartPtr<T>> {
1743
typedef CustomSmartPtr<T> pointer_type;
1744
typedef T element_type;
1745
1746
static sharing_policy get_sharing_policy() {
1747
return sharing_policy::NONE;
1748
}
1749
1750
static T* get(const CustomSmartPtr<T>& p) {
1751
return p.get_raw();
1752
}
1753
1754
static CustomSmartPtr<T> share(const CustomSmartPtr<T>& r, T* ptr) {
1755
++ptr->refcount; // implement an adopt API?
1756
return CustomSmartPtr<T>(ptr);
1757
}
1758
1759
static pointer_type* construct_null() {
1760
return new pointer_type;
1761
}
1762
};
1763
} // namespace emscripten
1764
1765
typedef CustomSmartPtr<class HeldByCustomSmartPtr> HeldByCustomSmartPtrPtr;
1766
1767
class HeldByCustomSmartPtr {
1768
public:
1769
HeldByCustomSmartPtr(int i, const std::string& s) : i(i), s(s) {}
1770
1771
static HeldByCustomSmartPtrPtr create(int i, const std::string& s) {
1772
return HeldByCustomSmartPtrPtr(new HeldByCustomSmartPtr(i, s));
1773
}
1774
1775
static std::shared_ptr<HeldByCustomSmartPtr>
1776
createSharedPtr(int i, const std::string& s) {
1777
return std::make_shared<HeldByCustomSmartPtr>(i, s);
1778
};
1779
1780
int refcount = 1;
1781
int i;
1782
std::string s;
1783
};
1784
1785
HeldByCustomSmartPtr* passThroughRawPtr(HeldByCustomSmartPtr* p) {
1786
return p;
1787
}
1788
HeldByCustomSmartPtrPtr passThroughCustomSmartPtr(HeldByCustomSmartPtrPtr p) {
1789
return p;
1790
}
1791
1792
struct Base1 {
1793
public:
1794
Base1() : field1("Base1") {}
1795
std::string field1;
1796
1797
std::string getField() const {
1798
return field1;
1799
}
1800
};
1801
1802
struct Base2 {
1803
public:
1804
Base2() : field2("Base2") {}
1805
std::string field2;
1806
1807
std::string getField() const {
1808
return field2;
1809
}
1810
};
1811
1812
struct HasTwoBases : public Base1, public Base2 {};
1813
1814
val get_module_property(const std::string& s) {
1815
return val::module_property(s.c_str());
1816
}
1817
1818
std::string char_to_string(char ch) {
1819
char str[256];
1820
sprintf(str, "%d", (int)ch);
1821
return str;
1822
}
1823
1824
std::string signed_char_to_string(signed char ch) {
1825
char str[256];
1826
sprintf(str, "%hhd", ch);
1827
return str;
1828
}
1829
1830
std::string unsigned_char_to_string(unsigned char ch) {
1831
char str[256];
1832
sprintf(str, "%hhu", ch);
1833
return str;
1834
}
1835
1836
std::string short_to_string(short val) {
1837
char str[256];
1838
sprintf(str, "%hd", val);
1839
return str;
1840
}
1841
1842
std::string unsigned_short_to_string(unsigned short val) {
1843
char str[256];
1844
sprintf(str, "%hu", val);
1845
return str;
1846
}
1847
1848
std::string int_to_string(int val) {
1849
char str[256];
1850
sprintf(str, "%d", val);
1851
return str;
1852
}
1853
1854
std::string unsigned_int_to_string(unsigned int val) {
1855
char str[256];
1856
sprintf(str, "%u", val);
1857
return str;
1858
}
1859
1860
std::string long_to_string(long val) {
1861
char str[256];
1862
sprintf(str, "%ld", val);
1863
return str;
1864
}
1865
1866
std::string unsigned_long_to_string(unsigned long val) {
1867
char str[256];
1868
sprintf(str, "%lu", val);
1869
return str;
1870
}
1871
1872
// test loading unsigned value from memory
1873
static unsigned char uchar;
1874
void store_unsigned_char(unsigned char arg) {
1875
uchar = arg;
1876
}
1877
1878
unsigned char load_unsigned_char() {
1879
return uchar;
1880
}
1881
1882
static unsigned short ushort;
1883
void store_unsigned_short(unsigned short arg) {
1884
ushort = arg;
1885
}
1886
1887
unsigned short load_unsigned_short() {
1888
return ushort;
1889
}
1890
1891
static unsigned int uint;
1892
void store_unsigned_int(unsigned int arg) {
1893
uint = arg;
1894
}
1895
1896
unsigned int load_unsigned_int() {
1897
return uint;
1898
}
1899
1900
static unsigned long ulong;
1901
void store_unsigned_long(unsigned long arg) {
1902
ulong = arg;
1903
}
1904
1905
unsigned long load_unsigned_long() {
1906
return ulong;
1907
}
1908
1909
template<int I> class ConstructFromFunctor {
1910
public:
1911
ConstructFromFunctor(const val& v, int a) : v_(v), a_(a) {
1912
}
1913
1914
val getVal() const {
1915
return v_;
1916
}
1917
1918
int getA() const {
1919
return a_;
1920
}
1921
1922
private:
1923
val v_;
1924
int a_;
1925
};
1926
1927
template<int I>
1928
ConstructFromFunctor<I> construct_from_functor_mixin(const val& v, int i) {
1929
return {v, i};
1930
}
1931
1932
EMSCRIPTEN_BINDINGS(tests) {
1933
register_vector<int>("IntegerVector");
1934
register_vector<char>("CharVector");
1935
register_vector<unsigned>("VectorUnsigned");
1936
register_vector<unsigned char>("VectorUnsignedChar");
1937
register_vector<std::string>("StringVector");
1938
register_vector<emscripten::val>("EmValVector");
1939
register_vector<float>("FloatVector");
1940
register_vector<std::vector<int>>("IntegerVectorVector");
1941
register_vector<SmallClass*>("SmallClassPointerVector");
1942
1943
class_<CustomIterable>("CustomIterable")
1944
.constructor<>()
1945
.function("count", &CustomIterable::count)
1946
.function("at", &CustomIterable::at)
1947
.iterable<int>("count", "at");
1948
1949
class_<CustomIterableSizeT>("CustomIterableSizeT")
1950
.constructor<>()
1951
.function("count", &CustomIterableSizeT::count)
1952
.function("at", &CustomIterableSizeT::at)
1953
.iterable<int>("count", "at");
1954
1955
class_<DummyForPointer>("DummyForPointer");
1956
1957
function("mallinfo", &emval_test_mallinfo);
1958
function("emval_test_new_integer", &emval_test_new_integer);
1959
function("emval_test_new_string", &emval_test_new_string);
1960
function("emval_test_get_string_from_val", &emval_test_get_string_from_val);
1961
function("emval_test_new_object", &emval_test_new_object);
1962
function("emval_test_instance_pointer", &emval_test_instance_pointer);
1963
function("emval_test_value_from_instance_pointer", &emval_test_value_from_instance_pointer);
1964
function("emval_test_passthrough_unsigned", &emval_test_passthrough_unsigned);
1965
function("emval_test_passthrough", &emval_test_passthrough);
1966
function("emval_test_return_void", &emval_test_return_void);
1967
function("emval_test_not", &emval_test_not);
1968
1969
function("emval_test_is_true", &emval_test_is_true);
1970
function("emval_test_is_false", &emval_test_is_false);
1971
function("emval_test_is_null", &emval_test_is_null);
1972
function("emval_test_is_undefined", &emval_test_is_undefined);
1973
function("emval_test_equals", &emval_test_equals);
1974
function("emval_test_strictly_equals", &emval_test_strictly_equals);
1975
1976
function("emval_test_as_unsigned", &emval_test_as_unsigned);
1977
function("emval_test_get_length", &emval_test_get_length);
1978
function("emval_test_add", &emval_test_add);
1979
function("const_ref_adder", &const_ref_adder);
1980
function("emval_test_sum", &emval_test_sum);
1981
1982
class_<DestructorCounter>("DestructorCounter");
1983
function("emval_test_callback_arg_lifetime", &emval_test_callback_arg_lifetime);
1984
1985
function("get_non_ascii_string", &get_non_ascii_string);
1986
function("get_non_ascii_wstring", &get_non_ascii_wstring);
1987
function("get_literal_wstring", &get_literal_wstring);
1988
function("force_memory_growth", &force_memory_growth);
1989
1990
//function("emval_test_take_and_return_const_char_star", &emval_test_take_and_return_const_char_star);
1991
function("emval_test_take_and_return_std_string", &emval_test_take_and_return_std_string);
1992
function("emval_test_take_and_return_std_string_const_ref", &emval_test_take_and_return_std_string_const_ref);
1993
function("take_and_return_std_wstring", &take_and_return_std_wstring);
1994
function("take_and_return_std_u16string", &take_and_return_std_u16string);
1995
function("take_and_return_std_u32string", &take_and_return_std_u32string);
1996
function("get_non_ascii_u16string", &get_non_ascii_u16string);
1997
function("get_non_ascii_u32string", &get_non_ascii_u32string);
1998
function("get_literal_u16string", &get_literal_u16string);
1999
function("get_literal_u32string", &get_literal_u32string);
2000
2001
//function("emval_test_take_and_return_CustomStruct", &emval_test_take_and_return_CustomStruct);
2002
2003
value_array<TupleVector>("TupleVector")
2004
.element(&TupleVector::x)
2005
.element(&Vector::getY, &Vector::setY)
2006
.element(&readVectorZ, &writeVectorZ)
2007
.element(emscripten::index<3>())
2008
;
2009
2010
function("emval_test_return_TupleVector", &emval_test_return_TupleVector);
2011
function("emval_test_take_and_return_TupleVector", &emval_test_take_and_return_TupleVector);
2012
2013
value_array<TupleVectorTuple>("TupleVectorTuple")
2014
.element(&TupleVectorTuple::v)
2015
;
2016
2017
function("emval_test_return_TupleVectorTuple", &emval_test_return_TupleVectorTuple);
2018
2019
value_object<StructVector>("StructVector")
2020
.field("x", &StructVector::x)
2021
.field("y", &Vector::getY, &Vector::setY)
2022
.field("z", &readVectorZ, &writeVectorZ)
2023
.field("w", emscripten::index<3>())
2024
;
2025
2026
function("emval_test_return_StructVector", &emval_test_return_StructVector);
2027
function("emval_test_take_and_return_StructVector", &emval_test_take_and_return_StructVector);
2028
2029
value_object<TupleInStruct>("TupleInStruct")
2030
.field("field", &TupleInStruct::field)
2031
;
2032
2033
function("emval_test_take_and_return_TupleInStruct", &emval_test_take_and_return_TupleInStruct);
2034
2035
2036
value_array<std::array<int, 2>>("array_int_2")
2037
.element(emscripten::index<0>())
2038
.element(emscripten::index<1>())
2039
;
2040
value_array<std::array<NestedStruct, 2>>("array_NestedStruct_2")
2041
.element(emscripten::index<0>())
2042
.element(emscripten::index<1>())
2043
;
2044
value_object<NestedStruct>("NestedStruct")
2045
.field("x", &NestedStruct::x)
2046
.field("y", &NestedStruct::y)
2047
;
2048
2049
value_object<ArrayInStruct>("ArrayInStruct")
2050
.field("field1", &ArrayInStruct::field1)
2051
.field("field2", &ArrayInStruct::field2)
2052
;
2053
function("emval_test_take_and_return_ArrayInStruct", &emval_test_take_and_return_ArrayInStruct);
2054
2055
using namespace std::placeholders;
2056
2057
class_<ConstructFromFunctor<1>>("ConstructFromStdFunction")
2058
.constructor(std::function<ConstructFromFunctor<1>(const val&, int)>(&construct_from_functor_mixin<1>))
2059
.function("getVal", &ConstructFromFunctor<1>::getVal)
2060
.function("getA", &ConstructFromFunctor<1>::getA)
2061
;
2062
2063
class_<ConstructFromFunctor<2>>("ConstructFromFunctionObject")
2064
.constructor<ConstructFromFunctor<2>(const val&, int)>(std::bind(&construct_from_functor_mixin<2>, _1, _2))
2065
.function("getVal", &ConstructFromFunctor<2>::getVal)
2066
.function("getA", &ConstructFromFunctor<2>::getA)
2067
;
2068
2069
class_<ValHolder>("ValHolder")
2070
.smart_ptr<std::shared_ptr<ValHolder>>("std::shared_ptr<ValHolder>")
2071
.constructor<val>()
2072
.constructor<ValHolder(int, int)>(&valholder_from_sum, allow_raw_pointers()) // custom signature with policy
2073
.function("getVal", &ValHolder::getVal)
2074
.function("getValNonConst", &ValHolder::getValNonConst)
2075
.function("getConstVal", &ValHolder::getConstVal)
2076
.function("getValConstRef", &ValHolder::getValConstRef)
2077
.function("setVal", &ValHolder::setVal)
2078
.function("getValFunction", std::function<val(const ValHolder&)>(&valholder_get_value_mixin))
2079
.function("setValFunction", std::function<void(ValHolder&, const val&)>(&valholder_set_value_mixin))
2080
.function<ValHolder*(ValHolder&)>("getThisPointer", std::function<ValHolder*(ValHolder&)>(&valholder_get_this_ptr), allow_raw_pointer<ret_val>())
2081
.function<val(const ValHolder&)>("getValFunctor", std::bind(&valholder_get_value_mixin, _1))
2082
.function<void(ValHolder&, const val&)>("setValFunctor", std::bind(&valholder_set_value_mixin, _1, _2))
2083
.property("val", &ValHolder::getVal, &ValHolder::setVal)
2084
.property("val_readonly", &ValHolder::getVal)
2085
.property("readonly_function_val", std::function<val(const ValHolder&)>(&valholder_get_value_mixin))
2086
.property("function_val", std::function<val(const ValHolder&)>(&valholder_get_value_mixin),
2087
std::function<void(ValHolder&, const val&)>(&valholder_set_value_mixin))
2088
.property<val>("readonly_functor_val", std::bind(&valholder_get_value_mixin, _1))
2089
.property<val>("functor_val", std::bind(&valholder_get_value_mixin, _1),
2090
std::bind(&valholder_set_value_mixin, _1, _2))
2091
.class_function("makeConst", &ValHolder::makeConst, allow_raw_pointer<ret_val>())
2092
.class_function("makeValHolder", &ValHolder::makeValHolder)
2093
.class_function("some_class_method", &ValHolder::some_class_method)
2094
.class_function("set_via_raw_pointer",
2095
&ValHolder::set_via_raw_pointer,
2096
allow_raw_pointer<arg<0>>())
2097
.class_function("get_via_raw_pointer",
2098
&ValHolder::get_via_raw_pointer,
2099
allow_raw_pointer<arg<0>>())
2100
.class_function("transfer_via_raw_pointer",
2101
&ValHolder::transfer_via_raw_pointer,
2102
allow_raw_pointers())
2103
2104
// non-member method
2105
.function("setEmpty", &emval_test_set_ValHolder_to_empty_object)
2106
.function("getValNonMember", &ValHolder::getValNonMember)
2107
;
2108
2109
function("emval_test_return_ValHolder", &emval_test_return_ValHolder);
2110
function("emval_test_set_ValHolder_to_empty_object", &emval_test_set_ValHolder_to_empty_object);
2111
2112
class_<std::function<std::string(std::string)>>("StringFunctorString")
2113
.constructor<>()
2114
.function("opcall", &std::function<std::string(std::string)>::operator())
2115
;
2116
2117
function("emval_test_get_function_ptr", &emval_test_get_function_ptr);
2118
function("emval_test_take_and_call_functor", &emval_test_take_and_call_functor);
2119
2120
class_<StringHolder>("StringHolder")
2121
.smart_ptr<std::shared_ptr<StringHolder>>("shared_ptr<StringHolder>")
2122
.constructor<std::string>()
2123
.function("set", &StringHolder::set)
2124
.function("get", &StringHolder::get)
2125
.function("get_const_ref", &StringHolder::get_const_ref)
2126
;
2127
2128
class_<SharedPtrHolder>("SharedPtrHolder")
2129
.constructor<>()
2130
.function("get", &SharedPtrHolder::get)
2131
.function("set", &SharedPtrHolder::set)
2132
;
2133
2134
class_<SmallClass>("SmallClass")
2135
.constructor<>()
2136
.property("member", &SmallClass::member)
2137
;
2138
2139
class_<BigClass>("BigClass")
2140
.constructor<>()
2141
.property("member", &BigClass::member)
2142
.property("otherMember", &BigClass::otherMember)
2143
.property("yetAnotherMember", &BigClass::yetAnotherMember)
2144
.function("getMember", &BigClass::getMember)
2145
;
2146
2147
class_<ParentClass>("ParentClass")
2148
.constructor<>()
2149
.function("getBigClass", &ParentClass::getBigClass)
2150
;
2151
2152
class_<TemplateClass<int>>("IntTemplateClass")
2153
.constructor<int, int, int>()
2154
.function("getMember", &TemplateClass<int>::getMember)
2155
;
2156
2157
class_<NoExceptClass>("NoExceptClass")
2158
.function("embind_test_no_except_function", &embind_test_no_except_function)
2159
.function("getValue", &NoExceptClass::getValue)
2160
.function("getValueConst", &NoExceptClass::getValueConst)
2161
.property("x", &NoExceptClass::getX, &NoExceptClass::setX);
2162
2163
class_<ContainsTemplatedMemberClass>("ContainsTemplatedMemberClass")
2164
.constructor<>()
2165
.function("getTestTemplate", &ContainsTemplatedMemberClass::getTestTemplate)
2166
;
2167
2168
class_<SymbolNameClass>("SymbolNameClass")
2169
.constructor<>()
2170
.function("@@iterator", &SymbolNameClass::iterator)
2171
.class_function("@@species", &SymbolNameClass::species)
2172
;
2173
2174
// register Derived before Base as a test that it's possible to
2175
// register base classes afterwards
2176
class_<Derived, base<Base>>("Derived")
2177
.smart_ptr<std::shared_ptr<Derived>>("shared_ptr<Derived>")
2178
.constructor<>()
2179
.function("getClassName", &Derived::getClassName)
2180
.function("getMember", &Derived::getMember)
2181
.function("setMember", &Derived::setMember)
2182
.property("member", &Derived::member)
2183
.class_function("classFunction", &Derived::classFunction)
2184
;
2185
2186
class_<Base>("Base")
2187
.smart_ptr<std::shared_ptr<Base>>("shared_ptr<Base")
2188
.constructor<>()
2189
.function("getClassName", &Base::getClassName)
2190
.function("getClassNameFromBase", &Base::getClassNameFromBase)
2191
.function("getClassNameNotAvailableInDerivedClasses", &Base::getClassNameNotAvailableInDerivedClasses)
2192
.function("getMember", &Base::getMember)
2193
.function("setMember", &Base::setMember)
2194
.function("getBaseMember", &Base::getBaseMember)
2195
.function("setBaseMember", &Base::setBaseMember)
2196
.property("member", &Base::member)
2197
.property("baseMember", &Base::baseMember)
2198
.class_function("classFunction", &Base::classFunction)
2199
;
2200
2201
class_<SecondBase>("SecondBase")
2202
.smart_ptr<std::shared_ptr<SecondBase>>("shared_ptr<SecondBase>")
2203
.constructor<>()
2204
.function("getClassName", &SecondBase::getClassName)
2205
.function("getClassNameFromSecondBase", &SecondBase::getClassNameFromSecondBase)
2206
.function("getClassNameNotAvailableInDerivedClasses", &SecondBase::getClassNameNotAvailableInDerivedClasses)
2207
.function("getMember", &SecondBase::getMember)
2208
.function("setMember", &SecondBase::setMember)
2209
.function("getSecondBaseMember", &SecondBase::getSecondBaseMember)
2210
.function("setSecondBaseMember", &SecondBase::setSecondBaseMember)
2211
.property("member", &SecondBase::member)
2212
.property("secondBaseMember", &SecondBase::secondBaseMember)
2213
;
2214
2215
2216
class_<DerivedHolder>("DerivedHolder")
2217
.constructor<>()
2218
.function("newDerived", &DerivedHolder::newDerived)
2219
.function("deleteDerived", &DerivedHolder::deleteDerived)
2220
.function("getDerived", &DerivedHolder::getDerived)
2221
.function("getDerivedClassName", &DerivedHolder::getDerivedClassName)
2222
;
2223
2224
class_<SiblingDerived>("SiblingDerived")
2225
.smart_ptr<std::shared_ptr<SiblingDerived>>("shared_ptr<SiblingDerived>")
2226
.constructor<>()
2227
.function("getClassName", &SiblingDerived::getClassName)
2228
;
2229
2230
class_<MultiplyDerived, base<Base>>("MultiplyDerived")
2231
.smart_ptr<std::shared_ptr<MultiplyDerived>>("shared_ptr<MultiplyDerived>")
2232
.constructor<>()
2233
.function("getClassName", &MultiplyDerived::getClassName)
2234
.class_function("getInstanceCount", &MultiplyDerived::getInstanceCount)
2235
;
2236
2237
class_<DerivedTwice, base<Derived> >("DerivedTwice")
2238
.constructor<>()
2239
.function("getClassName", &DerivedTwice::getClassName)
2240
;
2241
2242
class_<DerivedThrice, base<Derived> >("DerivedThrice")
2243
.smart_ptr<std::shared_ptr<DerivedThrice>>("shared_ptr<DerivedThrice>")
2244
.constructor<>()
2245
.function("getClassName", &DerivedThrice::getClassName)
2246
;
2247
2248
class_<PolyBase>("PolyBase")
2249
.smart_ptr<std::shared_ptr<PolyBase>>("shared_ptr<PolyBase>")
2250
.constructor<>()
2251
.function("virtualGetClassName", &PolyBase::virtualGetClassName)
2252
.function("getClassName", &PolyBase::getClassName)
2253
;
2254
2255
class_<PolySecondBase>("PolySecondBase")
2256
.smart_ptr<std::shared_ptr<PolySecondBase>>("shared_ptr<PolySecondBase>")
2257
.constructor<>()
2258
.function("getClassName", &PolySecondBase::getClassName)
2259
;
2260
2261
class_<PolyDerived, base<PolyBase>>("PolyDerived")
2262
.smart_ptr<std::shared_ptr<PolyDerived>>("shared_ptr<PolyDerived>")
2263
.constructor<>()
2264
.function("virtualGetClassName", &PolyDerived::virtualGetClassName)
2265
.function("getClassName", &PolyDerived::getClassName)
2266
.class_function("setPtrDerived", &PolyDerived::setPtrDerived)
2267
.class_function("releasePtr", &PolyDerived::releasePtr)
2268
.class_function("getPtrClassName", &PolyDerived::getPtrClassName)
2269
.class_function("getPtr", &PolyDerived::getPtr)
2270
;
2271
// static void setPtrDerived() {
2272
// ptr = std::shared_ptr<PolyDerived>(new PolyDerived());
2273
// }
2274
//
2275
// static std::string getPtrClassName() {
2276
// return ptr->getClassName();
2277
// }
2278
//
2279
// static std::shared_ptr<PolyBase> getPtr() {
2280
// return ptr;
2281
// }
2282
2283
class_<PolySiblingDerived, base<PolyBase>>("PolySiblingDerived")
2284
.smart_ptr<std::shared_ptr<PolySiblingDerived>>("shared_ptr<PolySiblingDerived>")
2285
.constructor<>()
2286
.function("getClassName", &PolySiblingDerived::getClassName)
2287
;
2288
2289
class_<PolyMultiplyDerived, base<PolyBase>>("PolyMultiplyDerived")
2290
.smart_ptr<std::shared_ptr<PolyMultiplyDerived>>("shared_ptr<PolyMultiplyDerived>")
2291
.constructor<>()
2292
.function("getClassName", &PolyMultiplyDerived::getClassName)
2293
;
2294
2295
class_<PolyDerivedThrice, base<PolyDerived>>("PolyDerivedThrice")
2296
.smart_ptr<std::shared_ptr<PolyDerivedThrice>>("shared_ptr<PolyDerivedThrice>")
2297
.constructor<>()
2298
.function("getClassName", &PolyDerivedThrice::getClassName)
2299
;
2300
2301
class_<PolyDiamondBase>("PolyDiamondBase")
2302
.smart_ptr<std::shared_ptr<PolyDiamondBase>>("shared_ptr<PolyDiamondBase>")
2303
.constructor<>()
2304
.function("getClassName", &PolyDiamondBase::getClassName)
2305
;
2306
2307
class_<PolyDiamondDerived>("PolyDiamondDerived")
2308
.smart_ptr<std::shared_ptr<PolyDiamondDerived>>("shared_ptr<PolyDiamondDerived>")
2309
.constructor<>()
2310
.function("getClassName", &PolyDiamondDerived::getClassName)
2311
;
2312
2313
class_<PolyDiamondSiblingDerived>("PolyDiamondSiblingDerived")
2314
.smart_ptr<std::shared_ptr<PolyDiamondSiblingDerived>>("shared_ptr<PolyDiamondSiblingDerived>")
2315
.constructor<>()
2316
.function("getClassName", &PolyDiamondSiblingDerived::getClassName)
2317
;
2318
2319
class_<PolyDiamondMultiplyDerived>("PolyDiamondMultiplyDerived")
2320
.smart_ptr<std::shared_ptr<PolyDiamondMultiplyDerived>>("shared_ptr<PolyDiamondMultiplyDerived>")
2321
.constructor<>()
2322
.function("getClassName", &PolyDiamondMultiplyDerived::getClassName)
2323
;
2324
2325
function("embind_test_return_small_class_instance", &embind_test_return_small_class_instance);
2326
function("embind_test_return_big_class_instance", &embind_test_return_big_class_instance);
2327
function("embind_test_accept_small_class_instance", &embind_test_accept_small_class_instance);
2328
function("embind_test_accept_big_class_instance", &embind_test_accept_big_class_instance);
2329
2330
class_<UniquePtrToConstructor>("UniquePtrToConstructor")
2331
.function("getValue", &UniquePtrToConstructor::getValue)
2332
;
2333
class_<CharWrapper>("CharWrapper");
2334
2335
function("embind_test_construct_class_with_unique_ptr", embind_test_construct_class_with_unique_ptr, allow_raw_pointer<ret_val>());
2336
function("embind_test_return_unique_ptr", embind_test_return_unique_ptr);
2337
function("embind_test_accept_unique_ptr", embind_test_accept_unique_ptr);
2338
2339
function("embind_test_return_raw_base_ptr", embind_test_return_raw_base_ptr, allow_raw_pointer<ret_val>());
2340
function("embind_test_return_raw_derived_ptr_as_base", embind_test_return_raw_derived_ptr_as_base, allow_raw_pointer<ret_val>());
2341
function("embind_test_return_raw_sibling_derived_ptr_as_base", embind_test_return_raw_sibling_derived_ptr_as_base, allow_raw_pointer<ret_val>());
2342
function("embind_test_return_raw_polymorphic_derived_ptr_as_base", embind_test_return_raw_polymorphic_derived_ptr_as_base, allow_raw_pointer<ret_val>());
2343
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>());
2344
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>());
2345
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>());
2346
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>());
2347
function("embind_test_return_smart_derived_ptr", embind_test_return_smart_derived_ptr);
2348
function("embind_test_return_smart_sibling_derived_ptr", embind_test_return_smart_sibling_derived_ptr);
2349
function("embind_test_return_smart_multiply_derived_ptr", embind_test_return_smart_multiply_derived_ptr);
2350
function("embind_test_return_smart_derived_thrice_ptr", embind_test_return_smart_derived_thrice_ptr);
2351
function("embind_test_return_smart_base_ptr", embind_test_return_smart_base_ptr);
2352
function("embind_test_return_smart_polymorphic_base_ptr", embind_test_return_smart_polymorphic_base_ptr);
2353
function("embind_test_return_smart_polymorphic_derived_ptr", embind_test_return_smart_polymorphic_derived_ptr);
2354
function("embind_test_return_smart_polymorphic_sibling_derived_ptr", embind_test_return_smart_polymorphic_sibling_derived_ptr);
2355
function("embind_test_return_smart_polymorphic_multiply_derived_ptr", embind_test_return_smart_polymorphic_multiply_derived_ptr);
2356
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);
2357
function("embind_test_return_smart_poly_derived_thrice_ptr", embind_test_return_smart_poly_derived_thrice_ptr);
2358
function("embind_test_return_smart_derived_ptr_as_base", embind_test_return_smart_derived_ptr_as_base);
2359
function("embind_test_return_smart_derived_ptr_as_val", embind_test_return_smart_derived_ptr_as_val);
2360
function("embind_test_return_smart_polymorphic_derived_ptr_as_base", embind_test_return_smart_polymorphic_derived_ptr_as_base);
2361
function("embind_test_return_smart_polymorphic_sibling_derived_ptr_as_base", embind_test_return_smart_polymorphic_sibling_derived_ptr_as_base);
2362
function("embind_test_get_class_name_via_base_ptr", embind_test_get_class_name_via_base_ptr, allow_raw_pointer<arg<0>>());
2363
function("embind_test_get_class_name_via_second_base_ptr", embind_test_get_class_name_via_second_base_ptr, allow_raw_pointer<arg<0>>());
2364
function("embind_test_get_class_name_via_polymorphic_base_ptr", embind_test_get_class_name_via_polymorphic_base_ptr, allow_raw_pointer<arg<0>>());
2365
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>>());
2366
// todo: allow_raw_pointer should fail earlier if argument is not a pointer
2367
function("embind_test_get_class_name_via_smart_base_ptr", embind_test_get_class_name_via_smart_base_ptr);
2368
function("embind_test_get_class_name_via_reference_to_smart_base_ptr", embind_test_get_class_name_via_reference_to_smart_base_ptr);
2369
function("embind_test_get_class_name_via_smart_second_base_ptr", embind_test_get_class_name_via_smart_second_base_ptr);
2370
function("embind_test_get_class_name_via_smart_polymorphic_base_ptr", embind_test_get_class_name_via_smart_polymorphic_base_ptr);
2371
function("embind_test_get_virtual_class_name_via_smart_polymorphic_base_ptr", embind_test_get_virtual_class_name_via_smart_polymorphic_base_ptr);
2372
function("embind_test_get_class_name_via_smart_polymorphic_second_base_ptr", embind_test_get_class_name_via_smart_polymorphic_second_base_ptr);
2373
function("embind_modify_smart_pointer_passed_by_reference", embind_modify_smart_pointer_passed_by_reference);
2374
function("embind_attempt_to_modify_smart_pointer_when_passed_by_value", embind_attempt_to_modify_smart_pointer_when_passed_by_value);
2375
function("embind_save_smart_base_pointer", embind_save_smart_base_pointer);
2376
2377
class_<Base1>("Base1")
2378
.constructor()
2379
.function("getField", &Base1::getField)
2380
;
2381
2382
class_<Base2>("Base2")
2383
.function("getField", &Base2::getField)
2384
.property("field", &Base2::field2)
2385
;
2386
2387
class_<HasTwoBases, base<Base2>>("HasTwoBases")
2388
.constructor()
2389
;
2390
2391
class_<CustomStruct>("CustomStruct")
2392
.constructor<>()
2393
.property("field", &CustomStruct::field)
2394
.function("getField", &CustomStruct::getField)
2395
;
2396
2397
enum_<Enum>("Enum")
2398
.value("ONE", ONE)
2399
.value("TWO", TWO)
2400
;
2401
function("emval_test_take_and_return_Enum", &emval_test_take_and_return_Enum);
2402
2403
enum_<EnumClass>("EnumClass")
2404
.value("ONE", EnumClass::ONE)
2405
.value("TWO", EnumClass::TWO)
2406
;
2407
function("emval_test_take_and_return_EnumClass", &emval_test_take_and_return_EnumClass);
2408
2409
enum_<EnumNum>("EnumNum", enum_value_type::number)
2410
.value("ONE", EnumNum::ONE)
2411
.value("TWO", EnumNum::TWO)
2412
;
2413
function("emval_test_take_and_return_EnumNum", &emval_test_take_and_return_EnumNum);
2414
2415
2416
enum_<EnumStr>("EnumStr", enum_value_type::string)
2417
.value("ONE", EnumStr::ONE)
2418
.value("TWO", EnumStr::TWO)
2419
;
2420
function("emval_test_take_and_return_EnumStr", &emval_test_take_and_return_EnumStr);
2421
2422
function("emval_test_call_function", &emval_test_call_function);
2423
2424
function("emval_test_return_unique_ptr", &emval_test_return_unique_ptr);
2425
2426
class_<UniquePtrLifetimeMock>("UniquePtrLifetimeMock");
2427
function("emval_test_return_unique_ptr_lifetime", &emval_test_return_unique_ptr_lifetime);
2428
2429
function("emval_test_return_shared_ptr", &emval_test_return_shared_ptr);
2430
function("emval_test_return_empty_shared_ptr", &emval_test_return_empty_shared_ptr);
2431
function("emval_test_is_shared_ptr_null", &emval_test_is_shared_ptr_null);
2432
2433
function("emval_test_return_vector", &emval_test_return_vector);
2434
function("emval_test_return_vector_of_vectors", &emval_test_return_vector_of_vectors);
2435
function("emval_test_return_vector_pointers", &emval_test_return_vector_pointers);
2436
2437
register_vector<std::shared_ptr<StringHolder>>("SharedPtrVector");
2438
function("emval_test_return_shared_ptr_vector", &emval_test_return_shared_ptr_vector);
2439
2440
function("get_module_property", &get_module_property);
2441
2442
register_vector<StringHolder>("StringHolderVector");
2443
class_<VectorHolder>("VectorHolder")
2444
.constructor<>()
2445
.function("get", &VectorHolder::get)
2446
.function("set", &VectorHolder::set)
2447
;
2448
2449
function("test_string_with_vec", &test_string_with_vec);
2450
2451
#if __cplusplus >= 201703L
2452
register_optional<int>();
2453
register_optional<float>();
2454
register_optional<SmallClass>();
2455
register_optional<SmallClass*>();
2456
register_optional<std::string>();
2457
function("embind_test_return_optional_int", &embind_test_return_optional_int);
2458
function("embind_test_return_optional_float", &embind_test_return_optional_float);
2459
function("embind_test_return_optional_small_class", &embind_test_return_optional_small_class);
2460
function("embind_test_return_optional_small_class_pointer", &embind_test_return_optional_small_class_pointer);
2461
function("embind_test_return_optional_string", &embind_test_return_optional_string);
2462
function("embind_test_optional_int_arg", &embind_test_optional_int_arg);
2463
function("embind_test_optional_float_arg", &embind_test_optional_float_arg);
2464
function("embind_test_optional_string_arg", &embind_test_optional_string_arg);
2465
function("embind_test_optional_small_class_arg", &embind_test_optional_small_class_arg);
2466
function("embind_test_optional_multiple_arg", &embind_test_optional_multiple_arg);
2467
value_object<StructWithOptionalProperty>("StructWithOptionalProperty")
2468
.field("x", &StructWithOptionalProperty::x)
2469
.field("y", &StructWithOptionalProperty::y)
2470
;
2471
function("embind_test_optional_property", &embind_test_optional_property);
2472
#endif
2473
2474
register_map<std::string, int>("StringIntMap");
2475
function("embind_test_get_string_int_map", embind_test_get_string_int_map);
2476
2477
register_map<int, std::string, std::greater<int>>("IntStringMapGreater");
2478
function("embind_test_get_int_string_greater_map", embind_test_get_int_string_greater_map);
2479
2480
function("embind_test_getglobal", &embind_test_getglobal);
2481
2482
function("embind_test_new_Object", &embind_test_new_Object);
2483
function("embind_test_new_factory", &embind_test_new_factory);
2484
2485
class_<HasExternalConstructor>("HasExternalConstructor")
2486
.constructor(&createHasExternalConstructor)
2487
.function("getString", &HasExternalConstructor::getString)
2488
;
2489
2490
class_<HasExternalConstructorNoCopy>("HasExternalConstructorNoCopy")
2491
.constructor(&HasExternalConstructorNoCopy::create)
2492
.function("getInt", &HasExternalConstructorNoCopy::getInt)
2493
;
2494
2495
auto HeldBySmartPtr_class = class_<HeldBySmartPtr>("HeldBySmartPtr");
2496
HeldBySmartPtr_class
2497
.smart_ptr<CustomSmartPtr<HeldBySmartPtr>>("CustomSmartPtr<HeldBySmartPtr>")
2498
.smart_ptr_constructor("shared_ptr<HeldbySmartPtr>", &std::make_shared<HeldBySmartPtr, int, std::string>)
2499
.class_function("newCustomPtr", HeldBySmartPtr::newCustomPtr)
2500
.function("returnThis", &takesHeldBySmartPtrSharedPtr)
2501
.property("i", &HeldBySmartPtr::i)
2502
.property("s", &HeldBySmartPtr::s)
2503
;
2504
function("takesHeldBySmartPtr", &takesHeldBySmartPtr);
2505
function("takesHeldBySmartPtrSharedPtr", &takesHeldBySmartPtrSharedPtr);
2506
2507
class_<HeldByCustomSmartPtr>("HeldByCustomSmartPtr")
2508
.smart_ptr<std::shared_ptr<HeldByCustomSmartPtr>>("shared_ptr<HeldByCustomSmartPtr>")
2509
.smart_ptr_constructor("CustomSmartPtr<HeldByCustomSmartPtr>", &HeldByCustomSmartPtr::create)
2510
.class_function("createSharedPtr", &HeldByCustomSmartPtr::createSharedPtr)
2511
.property("i", &HeldByCustomSmartPtr::i)
2512
.property("s", &HeldByCustomSmartPtr::s)
2513
;
2514
2515
function("passThroughRawPtr", &passThroughRawPtr, allow_raw_pointers());
2516
function("passThroughCustomSmartPtr", &passThroughCustomSmartPtr);
2517
2518
function("char_to_string", &char_to_string);
2519
function("signed_char_to_string", &signed_char_to_string);
2520
function("unsigned_char_to_string", &unsigned_char_to_string);
2521
function("short_to_string", &short_to_string);
2522
function("unsigned_short_to_string", &unsigned_short_to_string);
2523
function("int_to_string", &int_to_string);
2524
function("unsigned_int_to_string", &unsigned_int_to_string);
2525
function("long_to_string", &long_to_string);
2526
function("unsigned_long_to_string", &unsigned_long_to_string);
2527
2528
function("store_unsigned_char", &store_unsigned_char);
2529
function("load_unsigned_char", &load_unsigned_char);
2530
function("store_unsigned_short", &store_unsigned_short);
2531
function("load_unsigned_short", &load_unsigned_short);
2532
function("store_unsigned_int", &store_unsigned_int);
2533
function("load_unsigned_int", &load_unsigned_int);
2534
function("store_unsigned_long", &store_unsigned_long);
2535
function("load_unsigned_long", &load_unsigned_long);
2536
}
2537
2538
int overloaded_function(int i) {
2539
assert(i == 10);
2540
return 1;
2541
}
2542
2543
int overloaded_function(int i, int j) {
2544
assert(i == 20);
2545
assert(j == 20);
2546
return 2;
2547
}
2548
2549
class MultipleCtors {
2550
public:
2551
int value = 0;
2552
2553
MultipleCtors(int i) {
2554
value = 1;
2555
assert(i == 10);
2556
}
2557
MultipleCtors(int i, int j) {
2558
value = 2;
2559
assert(i == 20);
2560
assert(j == 20);
2561
}
2562
MultipleCtors(int i, int j, int k) {
2563
value = 3;
2564
assert(i == 30);
2565
assert(j == 30);
2566
assert(k == 30);
2567
}
2568
2569
int WhichCtorCalled() const {
2570
return value;
2571
}
2572
};
2573
2574
class MultipleSmartCtors {
2575
public:
2576
int value = 0;
2577
2578
MultipleSmartCtors(int i) {
2579
value = 1;
2580
assert(i == 10);
2581
}
2582
MultipleSmartCtors(int i, int j) {
2583
value = 2;
2584
assert(i == 20);
2585
assert(j == 20);
2586
}
2587
2588
int WhichCtorCalled() const {
2589
return value;
2590
}
2591
};
2592
2593
class MultipleOverloads {
2594
public:
2595
MultipleOverloads() {}
2596
2597
int value;
2598
static int staticValue;
2599
2600
int Func(int i) {
2601
assert(i == 10);
2602
value = 1;
2603
return 1;
2604
}
2605
int Func(int i, int j) {
2606
assert(i == 20);
2607
assert(j == 20);
2608
value = 2;
2609
return 2;
2610
}
2611
2612
int WhichFuncCalled() const {
2613
return value;
2614
}
2615
2616
static int StaticFunc(int i) {
2617
assert(i == 10);
2618
staticValue = 1;
2619
return 1;
2620
}
2621
static int StaticFunc(int i, int j) {
2622
assert(i == 20);
2623
assert(j == 20);
2624
staticValue = 2;
2625
return 2;
2626
}
2627
2628
static int WhichStaticFuncCalled() {
2629
return staticValue;
2630
}
2631
};
2632
2633
int MultipleOverloads::staticValue = 0;
2634
2635
class MultipleOverloadsDerived : public MultipleOverloads {
2636
public:
2637
MultipleOverloadsDerived() {
2638
}
2639
2640
int Func(int i, int j, int k) {
2641
assert(i == 30);
2642
assert(j == 30);
2643
assert(k == 30);
2644
value = 3;
2645
return 3;
2646
}
2647
int Func(int i, int j, int k, int l) {
2648
assert(i == 40);
2649
assert(j == 40);
2650
assert(k == 40);
2651
assert(l == 40);
2652
value = 4;
2653
return 4;
2654
}
2655
2656
static int StaticFunc(int i, int j, int k) {
2657
assert(i == 30);
2658
assert(j == 30);
2659
assert(k == 30);
2660
staticValue = 3;
2661
return 3;
2662
}
2663
static int StaticFunc(int i, int j, int k, int l) {
2664
assert(i == 40);
2665
assert(j == 40);
2666
assert(k == 40);
2667
assert(l == 40);
2668
staticValue = 4;
2669
return 4;
2670
}
2671
};
2672
2673
struct MultipleAccessors {
2674
int getConst() {
2675
return 1;
2676
}
2677
int getConst() const {
2678
return 2;
2679
}
2680
int getConst(int i) const {
2681
return i;
2682
}
2683
};
2684
2685
struct ConstAndNonConst {
2686
void method(int) {
2687
}
2688
2689
int method() const {
2690
return 10;
2691
}
2692
};
2693
2694
class DummyForOverloads {};
2695
2696
class MultipleOverloadsDependingOnDummy {
2697
public:
2698
DummyForOverloads dummy() {
2699
return DummyForOverloads();
2700
}
2701
2702
DummyForOverloads dummy(DummyForOverloads d) {
2703
return d;
2704
}
2705
2706
static DummyForOverloads staticDummy() {
2707
return DummyForOverloads();
2708
}
2709
2710
static DummyForOverloads staticDummy(DummyForOverloads d) {
2711
return d;
2712
}
2713
};
2714
2715
DummyForOverloads getDummy() {
2716
return DummyForOverloads();
2717
}
2718
2719
DummyForOverloads getDummy(DummyForOverloads d) {
2720
return d;
2721
}
2722
2723
EMSCRIPTEN_BINDINGS(overloads) {
2724
function("overloaded_function", select_overload<int(int)>(&overloaded_function));
2725
function("overloaded_function", select_overload<int(int, int)>(&overloaded_function));
2726
2727
class_<MultipleCtors>("MultipleCtors")
2728
.constructor<int>()
2729
.constructor<int, int>()
2730
.constructor<int, int, int>()
2731
.function("WhichCtorCalled", &MultipleCtors::WhichCtorCalled)
2732
;
2733
2734
class_<MultipleSmartCtors>("MultipleSmartCtors")
2735
.smart_ptr<std::shared_ptr<MultipleSmartCtors>>("shared_ptr<MultipleSmartCtors>")
2736
.constructor(&std::make_shared<MultipleSmartCtors, int>)
2737
.constructor(&std::make_shared<MultipleSmartCtors, int, int>)
2738
.function("WhichCtorCalled", &MultipleSmartCtors::WhichCtorCalled)
2739
;
2740
2741
class_<MultipleOverloads>("MultipleOverloads")
2742
.constructor<>()
2743
.function("Func", select_overload<int(int)>(&MultipleOverloads::Func))
2744
.function("Func", select_overload<int(int, int)>(&MultipleOverloads::Func))
2745
.function("WhichFuncCalled", &MultipleOverloads::WhichFuncCalled)
2746
.class_function("StaticFunc", select_overload<int(int)>(&MultipleOverloads::StaticFunc))
2747
.class_function("StaticFunc", select_overload<int(int,int)>(&MultipleOverloads::StaticFunc))
2748
.class_function("WhichStaticFuncCalled", &MultipleOverloads::WhichStaticFuncCalled)
2749
;
2750
2751
class_<MultipleOverloadsDerived, base<MultipleOverloads> >("MultipleOverloadsDerived")
2752
.constructor<>()
2753
.function("Func", select_overload<int(int,int,int)>(&MultipleOverloadsDerived::Func))
2754
.function("Func", select_overload<int(int,int,int,int)>(&MultipleOverloadsDerived::Func))
2755
.class_function("StaticFunc", select_overload<int(int,int,int)>(&MultipleOverloadsDerived::StaticFunc))
2756
.class_function("StaticFunc", select_overload<int(int,int,int,int)>(&MultipleOverloadsDerived::StaticFunc))
2757
;
2758
2759
class_<MultipleAccessors>("MultipleAccessors")
2760
.function("getConst", select_overload<int(int)const>(&MultipleAccessors::getConst))
2761
;
2762
2763
class_<ConstAndNonConst>("ConstAndNonConst")
2764
.function("method", select_const(&ConstAndNonConst::method))
2765
;
2766
2767
class_<DummyForOverloads>("DummyForOverloads").constructor();
2768
2769
class_<MultipleOverloadsDependingOnDummy>("MultipleOverloadsDependingOnDummy")
2770
.constructor()
2771
.function("dummy", select_overload<DummyForOverloads()>(&MultipleOverloadsDependingOnDummy::dummy))
2772
.function("dummy", select_overload<DummyForOverloads(DummyForOverloads)>(&MultipleOverloadsDependingOnDummy::dummy))
2773
.class_function("staticDummy", select_overload<DummyForOverloads()>(&MultipleOverloadsDependingOnDummy::staticDummy))
2774
.class_function("staticDummy", select_overload<DummyForOverloads(DummyForOverloads)>(&MultipleOverloadsDependingOnDummy::staticDummy))
2775
;
2776
2777
function("getDummy", select_overload<DummyForOverloads(void)>(&getDummy));
2778
function("getDummy", select_overload<DummyForOverloads(DummyForOverloads)>(&getDummy));
2779
}
2780
2781
// tests for out-of-order registration
2782
2783
class SecondElement {};
2784
2785
class FirstElement {};
2786
2787
struct OrderedTuple {
2788
FirstElement first;
2789
SecondElement second;
2790
};
2791
2792
struct OrderedStruct {
2793
FirstElement first;
2794
SecondElement second;
2795
};
2796
2797
OrderedTuple getOrderedTuple() {
2798
return OrderedTuple();
2799
}
2800
2801
OrderedStruct getOrderedStruct() {
2802
return OrderedStruct();
2803
}
2804
2805
EMSCRIPTEN_BINDINGS(order) {
2806
value_array<OrderedTuple>("OrderedTuple")
2807
.element(&OrderedTuple::first)
2808
.element(&OrderedTuple::second)
2809
;
2810
2811
value_object<OrderedStruct>("OrderedStruct")
2812
.field("first", &OrderedStruct::first)
2813
.field("second", &OrderedStruct::second)
2814
;
2815
2816
class_<SecondElement>("SecondElement")
2817
;
2818
2819
class_<FirstElement>("FirstElement")
2820
;
2821
2822
function("getOrderedTuple", &getOrderedTuple);
2823
function("getOrderedStruct", &getOrderedStruct);
2824
}
2825
2826
// tests for unbound types
2827
2828
template<typename T> T passThrough(T t) {
2829
return t;
2830
}
2831
2832
struct UnboundClass {};
2833
2834
struct HasUnboundBase : public UnboundClass {
2835
static void noop() {
2836
}
2837
};
2838
2839
HasUnboundBase getHasUnboundBase(HasUnboundBase f) {
2840
return f;
2841
}
2842
2843
struct HasConstructorUsingUnboundArgument {
2844
HasConstructorUsingUnboundArgument(UnboundClass) {
2845
}
2846
};
2847
2848
struct SecondUnboundClass {};
2849
2850
struct HasConstructorUsingUnboundArgumentAndUnboundBase
2851
: public SecondUnboundClass {
2852
HasConstructorUsingUnboundArgumentAndUnboundBase(UnboundClass) {
2853
}
2854
};
2855
2856
struct BoundClass {
2857
UnboundClass method(UnboundClass t) {
2858
return t;
2859
}
2860
2861
static UnboundClass classfunction(UnboundClass t) {
2862
return t;
2863
}
2864
2865
UnboundClass property;
2866
};
2867
2868
#ifndef SKIP_UNBOUND_TYPES
2869
EMSCRIPTEN_BINDINGS(incomplete) {
2870
constant("hasUnboundTypeNames", emscripten::has_unbound_type_names);
2871
2872
function("getUnboundClass", &passThrough<UnboundClass>);
2873
2874
class_<HasUnboundBase, base<UnboundClass>>("HasUnboundBase")
2875
.class_function("noop", &HasUnboundBase::noop)
2876
;
2877
function("getHasUnboundBase", &passThrough<HasUnboundBase>);
2878
2879
class_<HasConstructorUsingUnboundArgument>("HasConstructorUsingUnboundArgument")
2880
.constructor<UnboundClass>()
2881
;
2882
2883
class_<HasConstructorUsingUnboundArgumentAndUnboundBase, base<SecondUnboundClass>>("HasConstructorUsingUnboundArgumentAndUnboundBase")
2884
.constructor<UnboundClass>()
2885
;
2886
2887
class_<BoundClass>("BoundClass")
2888
.constructor<>()
2889
.function("method", &BoundClass::method)
2890
.class_function("classfunction", &BoundClass::classfunction)
2891
.property("property", &BoundClass::property)
2892
;
2893
}
2894
#endif
2895
2896
class Noncopyable {
2897
Noncopyable(const Noncopyable&) = delete;
2898
Noncopyable& operator=(const Noncopyable&) = delete;
2899
2900
public:
2901
Noncopyable() {
2902
}
2903
Noncopyable(Noncopyable&& other) {
2904
other.valid = false;
2905
}
2906
2907
std::string method() const {
2908
return "foo";
2909
}
2910
2911
bool valid = true;
2912
};
2913
2914
Noncopyable getNoncopyable() {
2915
return Noncopyable();
2916
}
2917
2918
EMSCRIPTEN_BINDINGS(noncopyable) {
2919
class_<Noncopyable>("Noncopyable")
2920
.constructor<>()
2921
.function("method", &Noncopyable::method)
2922
;
2923
2924
function("getNoncopyable", &getNoncopyable, return_value_policy::take_ownership());
2925
}
2926
2927
struct HasReadOnlyProperty {
2928
HasReadOnlyProperty(int i) : i(i) {
2929
}
2930
2931
const int i;
2932
};
2933
2934
EMSCRIPTEN_BINDINGS(read_only_properties) {
2935
class_<HasReadOnlyProperty>("HasReadOnlyProperty")
2936
.constructor<int>()
2937
.property("i", &HasReadOnlyProperty::i)
2938
;
2939
}
2940
2941
struct StaticConstIntStruct {
2942
static const int STATIC_CONST_INTEGER_VALUE_1;
2943
static const int STATIC_CONST_INTEGER_VALUE_1000;
2944
};
2945
2946
const int StaticConstIntStruct::STATIC_CONST_INTEGER_VALUE_1 = 1;
2947
const int StaticConstIntStruct::STATIC_CONST_INTEGER_VALUE_1000 = 1000;
2948
2949
EMSCRIPTEN_BINDINGS(constants) {
2950
constant("INT_CONSTANT", 10);
2951
2952
constant("STATIC_CONST_INTEGER_VALUE_1", StaticConstIntStruct::STATIC_CONST_INTEGER_VALUE_1);
2953
constant("STATIC_CONST_INTEGER_VALUE_1000", StaticConstIntStruct::STATIC_CONST_INTEGER_VALUE_1000);
2954
2955
constant("STRING_CONSTANT", std::string("some string"));
2956
2957
TupleVector tv(1, 2, 3, 4);
2958
constant("VALUE_ARRAY_CONSTANT", tv);
2959
2960
StructVector sv(1, 2, 3, 4);
2961
constant("VALUE_OBJECT_CONSTANT", sv);
2962
}
2963
2964
class DerivedWithOffset : public DummyDataToTestPointerAdjustment,
2965
public Base {};
2966
2967
std::shared_ptr<Base>
2968
return_Base_from_DerivedWithOffset(std::shared_ptr<DerivedWithOffset> ptr) {
2969
return ptr;
2970
}
2971
2972
EMSCRIPTEN_BINDINGS(with_adjustment) {
2973
class_<DerivedWithOffset, base<Base>>("DerivedWithOffset")
2974
.smart_ptr_constructor("shared_ptr<DerivedWithOffset>", &std::make_shared<DerivedWithOffset>)
2975
;
2976
2977
function("return_Base_from_DerivedWithOffset", &return_Base_from_DerivedWithOffset);
2978
}
2979
2980
void clear_StringHolder(StringHolder& sh) {
2981
sh.set("");
2982
}
2983
2984
EMSCRIPTEN_BINDINGS(references) {
2985
function("clear_StringHolder", &clear_StringHolder);
2986
}
2987
2988
StringHolder return_StringHolder_copy(val func) {
2989
return func.as<StringHolder>();
2990
}
2991
2992
StringHolder call_StringHolder_func(val func) {
2993
return func().as<StringHolder>();
2994
}
2995
2996
EMSCRIPTEN_BINDINGS(return_values) {
2997
function("return_StringHolder_copy", &return_StringHolder_copy);
2998
function("call_StringHolder_func", &call_StringHolder_func);
2999
}
3000
3001
struct Mixin {
3002
int get10() const {
3003
return 10;
3004
}
3005
};
3006
3007
template<typename ClassBinding>
3008
const ClassBinding& registerMixin(const ClassBinding& binding) {
3009
// need a wrapper for implicit conversion from DerivedWithMixin to Mixin
3010
struct Local {
3011
static int get10(const typename ClassBinding::class_type& self) {
3012
return self.get10();
3013
}
3014
};
3015
3016
return binding
3017
.function("get10", &Local::get10)
3018
;
3019
}
3020
3021
class DerivedWithMixin : public Base, public Mixin {
3022
};
3023
3024
EMSCRIPTEN_BINDINGS(mixins) {
3025
registerMixin(
3026
class_<DerivedWithMixin, base<Base>>("DerivedWithMixin")
3027
.constructor<>()
3028
);
3029
}
3030
3031
template<typename T> T val_as(const val& v) {
3032
return v.as<T>();
3033
}
3034
3035
EMSCRIPTEN_BINDINGS(val_as) {
3036
function("val_as_bool", &val_as<bool>);
3037
function("val_as_char", &val_as<char>);
3038
function("val_as_short", &val_as<short>);
3039
function("val_as_int", &val_as<int>);
3040
function("val_as_long", &val_as<long>);
3041
3042
function("val_as_float", &val_as<float>);
3043
function("val_as_double", &val_as<double>);
3044
3045
function("val_as_string", &val_as<std::string>);
3046
function("val_as_wstring", &val_as<std::wstring>);
3047
function("val_as_val", &val_as<val>);
3048
3049
function("val_as_value_object", &val_as<StructVector>);
3050
function("val_as_value_array", &val_as<TupleVector>);
3051
3052
function("val_as_enum", &val_as<Enum>);
3053
3054
// memory_view is always JS -> C++
3055
// function("val_as_memory_view", &val_as<memory_view>);
3056
}
3057
3058
val construct_with_6(val factory) {
3059
unsigned char a1 = 6;
3060
double a2 = -12.5;
3061
std::string a3("a3");
3062
StructVector a4(1, 2, 3, 4);
3063
EnumClass a5 = EnumClass::TWO;
3064
TupleVector a6(-1, -2, -3, -4);
3065
return factory.new_(a1, a2, a3, a4, a5, a6);
3066
}
3067
3068
val construct_with_memory_view(val factory) {
3069
static const char data[11] = "0123456789";
3070
return factory.new_(
3071
std::string("before"), typed_memory_view(10, data), std::string("after"));
3072
}
3073
3074
val construct_with_ints_and_float(val factory) {
3075
return factory.new_(65537, 4.0f, 65538);
3076
}
3077
3078
val construct_with_arguments_before_and_after_memory_growth() {
3079
auto out = val::array();
3080
out.set(0, val::global("Uint8Array").new_(5));
3081
force_memory_growth();
3082
out.set(1, val::global("Uint8Array").new_(5));
3083
return out;
3084
}
3085
3086
EMSCRIPTEN_BINDINGS(val_new_) {
3087
function("construct_with_6_arguments", &construct_with_6);
3088
function("construct_with_memory_view", &construct_with_memory_view);
3089
function("construct_with_ints_and_float", &construct_with_ints_and_float);
3090
function("construct_with_arguments_before_and_after_memory_growth",
3091
&construct_with_arguments_before_and_after_memory_growth);
3092
}
3093
3094
template<typename T> class intrusive_ptr {
3095
public:
3096
typedef T element_type;
3097
3098
intrusive_ptr(std::nullptr_t = nullptr) : px(nullptr) {
3099
}
3100
3101
template<typename U> explicit intrusive_ptr(U* px) : px(px) {
3102
addRef(px);
3103
}
3104
3105
intrusive_ptr(const intrusive_ptr& that) : px(that.px) {
3106
addRef(px);
3107
}
3108
3109
template<typename U>
3110
intrusive_ptr(const intrusive_ptr<U>& that) : px(that.get()) {
3111
addRef(px);
3112
}
3113
3114
intrusive_ptr& operator=(const intrusive_ptr& that) {
3115
reset(that.get());
3116
return *this;
3117
}
3118
3119
intrusive_ptr& operator=(intrusive_ptr&& that) {
3120
release(px);
3121
px = that.px;
3122
that.px = 0;
3123
return *this;
3124
}
3125
3126
template<typename U> intrusive_ptr& operator=(const intrusive_ptr<U>& that) {
3127
reset(that.get());
3128
return *this;
3129
}
3130
3131
template<typename U> intrusive_ptr& operator=(intrusive_ptr<U>&& that) {
3132
release(px);
3133
px = that.px;
3134
that.px = 0;
3135
return *this;
3136
}
3137
3138
~intrusive_ptr() {
3139
release(px);
3140
}
3141
3142
void reset(T* nx = nullptr) {
3143
addRef(nx);
3144
release(px);
3145
px = nx;
3146
}
3147
3148
T* get() const {
3149
return px;
3150
}
3151
3152
T& operator*() const {
3153
return *px;
3154
}
3155
3156
T* operator->() const {
3157
return px;
3158
}
3159
3160
explicit operator bool() const {
3161
return px != nullptr;
3162
}
3163
3164
void swap(intrusive_ptr& rhs) {
3165
std::swap(px, rhs.px);
3166
}
3167
3168
private:
3169
void addRef(T* px) {
3170
if (px) {
3171
++px->referenceCount;
3172
}
3173
}
3174
3175
void release(T* px) {
3176
if (px && --px->referenceCount == 0) {
3177
delete px;
3178
}
3179
}
3180
3181
T* px;
3182
3183
template<typename U> friend class intrusive_ptr;
3184
};
3185
3186
namespace emscripten {
3187
template<typename T> struct smart_ptr_trait<intrusive_ptr<T>> {
3188
typedef intrusive_ptr<T> pointer_type;
3189
typedef T element_type;
3190
3191
static sharing_policy get_sharing_policy() {
3192
return sharing_policy::INTRUSIVE;
3193
}
3194
3195
static T* get(const intrusive_ptr<T>& p) {
3196
return p.get();
3197
}
3198
3199
static intrusive_ptr<T> share(const intrusive_ptr<T>& r, T* ptr) {
3200
return intrusive_ptr<T>(ptr);
3201
}
3202
3203
static pointer_type* construct_null() {
3204
return new pointer_type;
3205
}
3206
};
3207
} // namespace emscripten
3208
3209
template<typename T> intrusive_ptr<T> make_intrusive_ptr() {
3210
return intrusive_ptr<T>(new T);
3211
}
3212
3213
struct IntrusiveClass {
3214
virtual ~IntrusiveClass() {}
3215
long referenceCount = 0;
3216
};
3217
3218
struct IntrusiveClassWrapper : public wrapper<IntrusiveClass> {
3219
EMSCRIPTEN_WRAPPER(IntrusiveClassWrapper);
3220
};
3221
3222
template<typename T> struct Holder {
3223
void set(const T& v) {
3224
value = v;
3225
}
3226
const T& get() const {
3227
return value;
3228
}
3229
T value;
3230
};
3231
3232
EMSCRIPTEN_BINDINGS(intrusive_pointers) {
3233
class_<IntrusiveClass>("IntrusiveClass")
3234
.smart_ptr_constructor("intrusive_ptr<IntrusiveClass>", &make_intrusive_ptr<IntrusiveClass>)
3235
.allow_subclass<IntrusiveClassWrapper, intrusive_ptr<IntrusiveClassWrapper>>("IntrusiveClassWrapper", "IntrusiveClassWrapperPtr")
3236
;
3237
3238
typedef Holder<intrusive_ptr<IntrusiveClass>> IntrusiveClassHolder;
3239
class_<IntrusiveClassHolder>("IntrusiveClassHolder")
3240
.constructor<>()
3241
.function("set", &IntrusiveClassHolder::set)
3242
.function("get", &IntrusiveClassHolder::get)
3243
;
3244
3245
function("passThroughIntrusiveClass", &passThrough<intrusive_ptr<IntrusiveClass>>);
3246
}
3247
3248
std::string getTypeOfVal(const val& v) {
3249
return v.typeOf().as<std::string>();
3250
}
3251
3252
EMSCRIPTEN_BINDINGS(typeOf) {
3253
function("getTypeOfVal", &getTypeOfVal);
3254
}
3255
3256
struct HasStaticMember {
3257
static const int c;
3258
static int v;
3259
};
3260
3261
const int HasStaticMember::c = 10;
3262
int HasStaticMember::v = 20;
3263
3264
EMSCRIPTEN_BINDINGS(static_member) {
3265
class_<HasStaticMember>("HasStaticMember")
3266
.class_property("c", &HasStaticMember::c)
3267
.class_property("v", &HasStaticMember::v)
3268
;
3269
}
3270
3271