Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/test/embind/embind_test.cpp
4150 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
void emval_test_call_function(val v, int i, float f, TupleVector tv, StructVector sv) {
1020
v(i, f, tv, sv);
1021
}
1022
1023
struct CharWrapper {
1024
CharWrapper(char v) {
1025
value = v;
1026
};
1027
1028
char getValue() {
1029
return value;
1030
}
1031
1032
char value;
1033
};
1034
1035
class UniquePtrToConstructor {
1036
public:
1037
UniquePtrToConstructor(std::unique_ptr<CharWrapper> p)
1038
: value((*p).getValue()) {
1039
}
1040
1041
char getValue() const {
1042
return value;
1043
}
1044
1045
private:
1046
char value;
1047
};
1048
1049
std::unique_ptr<CharWrapper> embind_test_return_unique_ptr(char v) {
1050
return std::unique_ptr<CharWrapper>(new CharWrapper(v));
1051
}
1052
1053
UniquePtrToConstructor* embind_test_construct_class_with_unique_ptr(char v) {
1054
return new UniquePtrToConstructor(embind_test_return_unique_ptr(v));
1055
}
1056
1057
char embind_test_accept_unique_ptr(std::unique_ptr<CharWrapper> p) {
1058
return (*p.get()).getValue();
1059
}
1060
1061
std::unique_ptr<ValHolder> emval_test_return_unique_ptr() {
1062
return std::unique_ptr<ValHolder>(new ValHolder(val::object()));
1063
}
1064
1065
class UniquePtrLifetimeMock {
1066
public:
1067
UniquePtrLifetimeMock(val l) : logger(l) {
1068
logger(std::string("(constructor)"));
1069
}
1070
~UniquePtrLifetimeMock() {
1071
logger(std::string("(destructor)"));
1072
}
1073
1074
private:
1075
val logger;
1076
};
1077
1078
std::unique_ptr<UniquePtrLifetimeMock> emval_test_return_unique_ptr_lifetime(val logger) {
1079
return std::unique_ptr<UniquePtrLifetimeMock>(new UniquePtrLifetimeMock(logger));
1080
}
1081
1082
std::shared_ptr<ValHolder> emval_test_return_shared_ptr() {
1083
return std::shared_ptr<ValHolder>(new ValHolder(val::object()));
1084
}
1085
1086
std::shared_ptr<ValHolder> emval_test_return_empty_shared_ptr() {
1087
return std::shared_ptr<ValHolder>();
1088
}
1089
1090
bool emval_test_is_shared_ptr_null(std::shared_ptr<ValHolder> p) {
1091
return !p;
1092
}
1093
1094
static SmallClass smallClass;
1095
static BigClass bigClass;
1096
1097
SmallClass embind_test_return_small_class_instance() {
1098
return smallClass;
1099
}
1100
1101
BigClass embind_test_return_big_class_instance() {
1102
return bigClass;
1103
}
1104
1105
int embind_test_accept_small_class_instance(SmallClass c) {
1106
return c.member;
1107
}
1108
1109
int embind_test_accept_big_class_instance(BigClass c) {
1110
return c.member;
1111
}
1112
1113
// Begin Inheritance Hierarchy Test Wrappers
1114
1115
Base* embind_test_return_raw_base_ptr() {
1116
return new Base();
1117
}
1118
1119
Base* embind_test_return_raw_derived_ptr_as_base() {
1120
return new Derived();
1121
}
1122
1123
Base* embind_test_return_raw_sibling_derived_ptr_as_base() {
1124
return new SiblingDerived();
1125
}
1126
1127
PolyBase* embind_test_return_raw_polymorphic_derived_ptr_as_base() {
1128
return new PolyDerived();
1129
}
1130
1131
PolyBase* embind_test_return_raw_polymorphic_sibling_derived_ptr_as_base() {
1132
return new PolySiblingDerived();
1133
}
1134
1135
PolyBase* embind_test_return_raw_polymorphic_multiply_derived_ptr_as_base() {
1136
return new PolyMultiplyDerived();
1137
}
1138
1139
PolySecondBase* embind_test_return_raw_polymorphic_multiply_derived_ptr_as_second_base() {
1140
return new PolyMultiplyDerived();
1141
}
1142
1143
PolyBase* embind_test_return_raw_polymorphic_derived_four_times_not_bound_as_base() {
1144
return new PolyDerivedFourTimesNotBound();
1145
}
1146
1147
std::shared_ptr<Base> embind_test_return_smart_base_ptr() {
1148
return std::shared_ptr<Base>(new Base());
1149
}
1150
1151
std::shared_ptr<PolyBase> embind_test_return_smart_polymorphic_base_ptr() {
1152
return std::shared_ptr<PolyBase>(new PolyBase("PolyBase"));
1153
}
1154
1155
std::shared_ptr<Derived> embind_test_return_smart_derived_ptr() {
1156
return std::shared_ptr<Derived>(new Derived());
1157
}
1158
1159
std::shared_ptr<SiblingDerived> embind_test_return_smart_sibling_derived_ptr() {
1160
return std::shared_ptr<SiblingDerived>(new SiblingDerived());
1161
}
1162
1163
std::shared_ptr<MultiplyDerived> embind_test_return_smart_multiply_derived_ptr() {
1164
return std::shared_ptr<MultiplyDerived>(new MultiplyDerived());
1165
}
1166
1167
std::shared_ptr<DerivedThrice> embind_test_return_smart_derived_thrice_ptr() {
1168
return std::shared_ptr<DerivedThrice>(new DerivedThrice());
1169
}
1170
1171
std::shared_ptr<PolyDerived> embind_test_return_smart_polymorphic_derived_ptr() {
1172
return std::shared_ptr<PolyDerived>(new PolyDerived());
1173
}
1174
1175
std::shared_ptr<PolySiblingDerived> embind_test_return_smart_polymorphic_sibling_derived_ptr() {
1176
return std::shared_ptr<PolySiblingDerived>(new PolySiblingDerived());
1177
}
1178
1179
std::shared_ptr<PolyMultiplyDerived> embind_test_return_smart_polymorphic_multiply_derived_ptr() {
1180
return std::shared_ptr<PolyMultiplyDerived>(new PolyMultiplyDerived());
1181
}
1182
1183
std::shared_ptr<PolyBase> embind_test_return_poly_derived_twice_without_smart_pointer_as_poly_base() {
1184
return std::shared_ptr<PolyBase>(new PolyDerivedTwiceWithoutSmartPointer());
1185
}
1186
1187
std::shared_ptr<PolyDerivedThrice> embind_test_return_smart_poly_derived_thrice_ptr() {
1188
return std::shared_ptr<PolyDerivedThrice>(new PolyDerivedThrice());
1189
}
1190
1191
std::shared_ptr<PolyBase> embind_test_return_smart_derived_ptr_as_base() {
1192
return std::shared_ptr<PolyBase>(new PolyDerived());
1193
}
1194
1195
val embind_test_return_smart_derived_ptr_as_val() {
1196
return val(std::shared_ptr<PolyBase>(new PolyDerived()));
1197
}
1198
1199
std::shared_ptr<PolyBase> embind_test_return_smart_polymorphic_derived_ptr_as_base() {
1200
return std::shared_ptr<PolyBase>(new PolyDerived());
1201
}
1202
1203
std::shared_ptr<PolyBase> embind_test_return_smart_polymorphic_sibling_derived_ptr_as_base() {
1204
return std::shared_ptr<PolyBase>(new PolySiblingDerived());
1205
}
1206
1207
std::string embind_test_get_class_name_via_base_ptr(Base* p) {
1208
return p->getClassName();
1209
}
1210
1211
std::string embind_test_get_class_name_via_second_base_ptr(SecondBase* p) {
1212
return p->getClassName();
1213
}
1214
1215
std::string embind_test_get_class_name_via_polymorphic_base_ptr(PolyBase* p) {
1216
return p->getClassName();
1217
}
1218
1219
std::string embind_test_get_class_name_via_polymorphic_second_base_ptr(PolySecondBase* p) {
1220
return p->getClassName();
1221
}
1222
1223
std::string embind_test_get_class_name_via_smart_base_ptr(std::shared_ptr<Base> p) {
1224
return p->getClassName();
1225
}
1226
1227
std::string embind_test_get_class_name_via_reference_to_smart_base_ptr(std::shared_ptr<Base>& p) {
1228
return p->getClassName();
1229
}
1230
1231
std::string embind_test_get_class_name_via_smart_second_base_ptr(std::shared_ptr<SecondBase> p) {
1232
return p->getClassName();
1233
}
1234
1235
std::string embind_test_get_class_name_via_smart_polymorphic_base_ptr(std::shared_ptr<PolyBase> p) {
1236
return p->getClassName();
1237
}
1238
1239
std::string embind_test_get_virtual_class_name_via_smart_polymorphic_base_ptr(std::shared_ptr<PolyBase> p) {
1240
return p->virtualGetClassName();
1241
}
1242
1243
std::string embind_test_get_class_name_via_smart_polymorphic_second_base_ptr(std::shared_ptr<PolySecondBase> p) {
1244
return p->getClassName();
1245
}
1246
1247
void embind_modify_smart_pointer_passed_by_reference(std::shared_ptr<Base>& p) {
1248
p = std::shared_ptr<Base>(new Base());
1249
p->name = "Changed";
1250
}
1251
1252
void embind_attempt_to_modify_smart_pointer_when_passed_by_value(std::shared_ptr<Base> p) {
1253
p = std::shared_ptr<Base>(new Base());
1254
p->name = "Changed";
1255
}
1256
1257
static std::shared_ptr<Base> savedBasePointer;
1258
1259
void embind_save_smart_base_pointer(std::shared_ptr<Base> p) {
1260
savedBasePointer = p;
1261
}
1262
1263
// End Inheritance Hierarchy Test Wrappers
1264
1265
std::vector<int> emval_test_return_vector() {
1266
int myints[] = {10, 20, 30};
1267
return std::vector<int>(myints, myints + sizeof(myints) / sizeof(int));
1268
}
1269
1270
std::vector<std::vector<int>> emval_test_return_vector_of_vectors() {
1271
int myints1[] = {10, 20, 30};
1272
int myints2[] = {40, 50, 60};
1273
std::vector<int> vec1(myints1, myints1 + sizeof(myints1) / sizeof(int));
1274
std::vector<int> vec2(myints2, myints2 + sizeof(myints2) / sizeof(int));
1275
std::vector<std::vector<int>> vec3;
1276
vec3.emplace_back(vec1);
1277
vec3.emplace_back(vec2);
1278
return vec3;
1279
}
1280
1281
std::vector<std::shared_ptr<StringHolder>> emval_test_return_shared_ptr_vector() {
1282
std::vector<std::shared_ptr<StringHolder>> sharedStrVector;
1283
sharedStrVector.push_back(std::shared_ptr<StringHolder>(new StringHolder("string #1")));
1284
sharedStrVector.push_back(std::shared_ptr<StringHolder>(new StringHolder("string #2")));
1285
1286
return sharedStrVector;
1287
}
1288
1289
std::vector<SmallClass*> emval_test_return_vector_pointers() {
1290
std::vector<SmallClass*> vec;
1291
vec.push_back(new SmallClass());
1292
return vec;
1293
}
1294
1295
void test_string_with_vec(const std::string& p1, std::vector<std::string>& v1) {
1296
// THIS DOES NOT WORK -- need to get as val and then call vecFromJSArray
1297
printf("%s\n", p1.c_str());
1298
}
1299
1300
#if __cplusplus >= 201703L
1301
std::optional<int> embind_test_return_optional_int(bool create) {
1302
if (create) {
1303
return 42;
1304
}
1305
return {};
1306
}
1307
std::optional<float> embind_test_return_optional_float(bool create) {
1308
if (create) {
1309
return 4.2;
1310
}
1311
return {};
1312
}
1313
std::optional<std::string> embind_test_return_optional_string(bool create) {
1314
if (create) {
1315
return "hello";
1316
}
1317
return {};
1318
}
1319
std::optional<SmallClass> embind_test_return_optional_small_class(bool create) {
1320
if (create) {
1321
return SmallClass();
1322
}
1323
return {};
1324
}
1325
std::optional<SmallClass*>
1326
embind_test_return_optional_small_class_pointer(bool create) {
1327
if (create) {
1328
return new SmallClass();
1329
}
1330
return {};
1331
}
1332
1333
int embind_test_optional_int_arg(std::optional<int> arg) {
1334
if (arg) {
1335
return *arg;
1336
}
1337
return -1;
1338
}
1339
float embind_test_optional_float_arg(std::optional<float> arg) {
1340
if (arg) {
1341
return *arg;
1342
}
1343
return -1.1;
1344
}
1345
std::string embind_test_optional_string_arg(std::optional<std::string> arg) {
1346
if (arg) {
1347
return *arg;
1348
}
1349
return "no value";
1350
}
1351
1352
int embind_test_optional_small_class_arg(std::optional<SmallClass> arg) {
1353
if (arg) {
1354
return arg->member;
1355
}
1356
return -1;
1357
}
1358
void embind_test_optional_multiple_arg(int arg1,
1359
std::optional<int> arg2,
1360
std::optional<int> arg3) {
1361
}
1362
1363
struct StructWithOptionalProperty {
1364
int x;
1365
std::optional<int> y;
1366
};
1367
void embind_test_optional_property(const StructWithOptionalProperty &arg) {
1368
}
1369
#endif
1370
1371
val embind_test_getglobal() {
1372
return val::global();
1373
}
1374
1375
val embind_test_new_Object() {
1376
return val::global("Object").new_();
1377
}
1378
1379
val embind_test_new_factory(val factory, val argument) {
1380
return factory.new_(10, std::string("hello"), argument);
1381
}
1382
1383
class AbstractClass {
1384
public:
1385
virtual ~AbstractClass() {}
1386
virtual std::string abstractMethod() const = 0;
1387
virtual std::string optionalMethod(std::string s) const {
1388
return "optional" + s;
1389
}
1390
1391
virtual std::shared_ptr<Derived> returnsSharedPtr() = 0;
1392
virtual void differentArguments(
1393
int i, double d, unsigned char f, double q, std::string) = 0;
1394
1395
std::string concreteMethod() const {
1396
return "concrete";
1397
}
1398
1399
virtual void passShared(const std::shared_ptr<Derived>&) {
1400
}
1401
1402
virtual void passVal(const val& v) {
1403
}
1404
};
1405
1406
EMSCRIPTEN_SYMBOL(optionalMethod);
1407
1408
class AbstractClassWrapper : public wrapper<AbstractClass> {
1409
public:
1410
EMSCRIPTEN_WRAPPER(AbstractClassWrapper);
1411
1412
std::string abstractMethod() const override {
1413
return call<std::string>("abstractMethod");
1414
}
1415
1416
std::string optionalMethod(std::string s) const override {
1417
return call<std::string>("optionalMethod", s);
1418
}
1419
1420
std::shared_ptr<Derived> returnsSharedPtr() override {
1421
return call<std::shared_ptr<Derived>>("returnsSharedPtr");
1422
}
1423
1424
void differentArguments(int i, double d, unsigned char f, double q, std::string s) override {
1425
return call<void>("differentArguments", i, d, f, q, s);
1426
}
1427
1428
virtual void passShared(const std::shared_ptr<Derived>& p) override {
1429
return call<void>("passShared", p);
1430
}
1431
1432
virtual void passVal(const val& v) override {
1433
return call<void>("passVal", v);
1434
}
1435
};
1436
1437
class ConcreteClass : public AbstractClass {
1438
std::string abstractMethod() const {
1439
return "from concrete";
1440
}
1441
1442
void differentArguments(
1443
int i, double d, unsigned char f, double q, std::string s) {
1444
}
1445
1446
std::shared_ptr<Derived> returnsSharedPtr() {
1447
return std::shared_ptr<Derived>();
1448
}
1449
};
1450
1451
std::shared_ptr<AbstractClass> getAbstractClass() {
1452
return std::make_shared<ConcreteClass>();
1453
}
1454
1455
std::string callAbstractMethod(AbstractClass& ac) {
1456
return ac.abstractMethod();
1457
}
1458
1459
std::string callOptionalMethod(AbstractClass& ac, std::string s) {
1460
return ac.optionalMethod(s);
1461
}
1462
1463
void callReturnsSharedPtrMethod(AbstractClass& ac) {
1464
std::shared_ptr<Derived> sp = ac.returnsSharedPtr();
1465
// unused: sp
1466
}
1467
1468
void callDifferentArguments(AbstractClass& ac,
1469
int i,
1470
double d,
1471
unsigned char f,
1472
double q,
1473
std::string s) {
1474
return ac.differentArguments(i, d, f, q, s);
1475
}
1476
1477
struct AbstractClassWithConstructor {
1478
explicit AbstractClassWithConstructor(std::string s) : s(s) {}
1479
1480
virtual ~AbstractClassWithConstructor(){};
1481
1482
virtual std::string abstractMethod() = 0;
1483
std::string concreteMethod() {
1484
return s;
1485
}
1486
1487
std::string s;
1488
};
1489
1490
struct AbstractClassWithConstructorWrapper
1491
: public wrapper<AbstractClassWithConstructor> {
1492
EMSCRIPTEN_WRAPPER(AbstractClassWithConstructorWrapper);
1493
1494
virtual std::string abstractMethod() override {
1495
return call<std::string>("abstractMethod");
1496
}
1497
};
1498
1499
std::string callAbstractMethod2(AbstractClassWithConstructor& ac) {
1500
return ac.abstractMethod();
1501
}
1502
1503
struct HeldAbstractClass : public PolyBase, public PolySecondBase {
1504
virtual void method() = 0;
1505
};
1506
struct HeldAbstractClassWrapper : wrapper<HeldAbstractClass> {
1507
EMSCRIPTEN_WRAPPER(HeldAbstractClassWrapper);
1508
1509
virtual void method() override {
1510
return call<void>("method");
1511
}
1512
};
1513
1514
std::shared_ptr<PolySecondBase> passHeldAbstractClass(std::shared_ptr<HeldAbstractClass> p) {
1515
return p;
1516
}
1517
1518
void passShared(AbstractClass& ac) {
1519
auto p = std::make_shared<Derived>();
1520
ac.passShared(p);
1521
}
1522
1523
void passVal(AbstractClass& ac, val v) {
1524
return ac.passVal(v);
1525
}
1526
1527
EMSCRIPTEN_BINDINGS(interface_tests) {
1528
class_<AbstractClass>("AbstractClass")
1529
.smart_ptr<std::shared_ptr<AbstractClass>>("shared_ptr<AbstractClass>")
1530
.allow_subclass<AbstractClassWrapper>("AbstractClassWrapper")
1531
.function("abstractMethod", &AbstractClass::abstractMethod, pure_virtual())
1532
// The optional_override is necessary because, otherwise, the C++ compiler
1533
// cannot deduce the signature of the lambda function.
1534
.function("optionalMethod", optional_override(
1535
[](AbstractClass& this_, const std::string& s) {
1536
return this_.AbstractClass::optionalMethod(s);
1537
}
1538
))
1539
.function("concreteMethod", &AbstractClass::concreteMethod)
1540
.function("passShared", select_overload<void(AbstractClass&, const std::shared_ptr<Derived>&)>([](AbstractClass& self, const std::shared_ptr<Derived>& derived) {
1541
self.AbstractClass::passShared(derived);
1542
}))
1543
.function("passVal", select_overload<void(AbstractClass&, const val&)>([](AbstractClass& self, const val& v) {
1544
self.AbstractClass::passVal(v);
1545
}))
1546
;
1547
1548
function("getAbstractClass", &getAbstractClass);
1549
function("callAbstractMethod", &callAbstractMethod);
1550
function("callOptionalMethod", &callOptionalMethod);
1551
function("callReturnsSharedPtrMethod", &callReturnsSharedPtrMethod);
1552
function("callDifferentArguments", &callDifferentArguments);
1553
function("passShared", &passShared);
1554
function("passVal", &passVal);
1555
1556
class_<AbstractClassWithConstructor>("AbstractClassWithConstructor")
1557
.allow_subclass<AbstractClassWithConstructorWrapper>("AbstractClassWithConstructorWrapper", constructor<std::string>())
1558
.function("abstractMethod", &AbstractClassWithConstructor::abstractMethod, pure_virtual())
1559
.function("concreteMethod", &AbstractClassWithConstructor::concreteMethod)
1560
;
1561
function("callAbstractMethod2", &callAbstractMethod2);
1562
1563
class_<HeldAbstractClass, base<PolySecondBase>>("HeldAbstractClass")
1564
.smart_ptr<std::shared_ptr<HeldAbstractClass>>("shared_ptr<HeldAbstractClass>")
1565
.allow_subclass<HeldAbstractClassWrapper, std::shared_ptr<HeldAbstractClassWrapper>>("HeldAbstractClassWrapper", "HeldAbstractClassWrapperPtr")
1566
.function("method", &HeldAbstractClass::method, pure_virtual())
1567
;
1568
function("passHeldAbstractClass", &passHeldAbstractClass);
1569
}
1570
1571
template<typename T, size_t sizeOfArray>
1572
constexpr size_t getElementCount(T (&)[sizeOfArray]) {
1573
return sizeOfArray;
1574
}
1575
1576
static void callWithMemoryView(val v) {
1577
// static so the JS test can read the memory after callTakeMemoryView runs
1578
static unsigned char data[] = {0, 1, 2, 3, 4, 5, 6, 7};
1579
v(typed_memory_view(getElementCount(data), data));
1580
static float f[] = {1.5f, 2.5f, 3.5f, 4.5f};
1581
v(typed_memory_view(getElementCount(f), f));
1582
static short s[] = {1000, 100, 10, 1};
1583
v(typed_memory_view(getElementCount(s), s));
1584
}
1585
1586
EMSCRIPTEN_BINDINGS(memory_view_tests) {
1587
function("callWithMemoryView", &callWithMemoryView);
1588
}
1589
1590
class HasExternalConstructor {
1591
public:
1592
HasExternalConstructor(const std::string& str) : m(str) {}
1593
1594
std::string getString() const {
1595
return m;
1596
}
1597
1598
std::string m;
1599
};
1600
1601
HasExternalConstructor* createHasExternalConstructor(const std::string& str) {
1602
return new HasExternalConstructor(str);
1603
}
1604
1605
class HasExternalConstructorNoCopy {
1606
private:
1607
HasExternalConstructorNoCopy(int i) : m(i) {
1608
}
1609
int m;
1610
1611
public:
1612
HasExternalConstructorNoCopy(HasExternalConstructorNoCopy&) = delete;
1613
HasExternalConstructorNoCopy(HasExternalConstructorNoCopy&&) = default;
1614
int getInt() {
1615
return m;
1616
}
1617
static HasExternalConstructorNoCopy create(int i) {
1618
HasExternalConstructorNoCopy obj(i);
1619
return obj;
1620
}
1621
};
1622
1623
template<typename T> class CustomSmartPtr {
1624
public:
1625
CustomSmartPtr() : CustomSmartPtr(nullptr) {
1626
std::fill(d_, d_ + N_, Valid);
1627
}
1628
1629
explicit CustomSmartPtr(T* t) : ptr_(t) {
1630
std::fill(d_, d_ + N_, Valid);
1631
}
1632
1633
CustomSmartPtr(const CustomSmartPtr& other) : ptr_(other.ptr_) {
1634
other.verify();
1635
std::fill(d_, d_ + N_, Valid);
1636
if (ptr_) {
1637
++(ptr_->refcount);
1638
}
1639
}
1640
1641
~CustomSmartPtr() {
1642
verify();
1643
std::fill(d_, d_ + N_, Deleted);
1644
1645
if (ptr_ && --ptr_->refcount == 0) {
1646
delete ptr_;
1647
}
1648
}
1649
1650
T* get_raw() const {
1651
return ptr_;
1652
}
1653
1654
private:
1655
void verify() const {
1656
for (size_t i = 0; i < N_; ++i) {
1657
if (d_[i] != Valid) {
1658
abort();
1659
}
1660
}
1661
}
1662
1663
enum {
1664
Valid = 255,
1665
Deleted = 127,
1666
};
1667
static constexpr size_t N_ = 1000000;
1668
unsigned char d_[N_];
1669
T* ptr_;
1670
1671
CustomSmartPtr& operator=(const CustomSmartPtr&) = delete;
1672
};
1673
1674
class HeldBySmartPtr {
1675
public:
1676
HeldBySmartPtr(int i, const std::string& s) : i(i), s(s) {
1677
}
1678
1679
static CustomSmartPtr<HeldBySmartPtr> newCustomPtr(int i,
1680
const std::string& s) {
1681
return CustomSmartPtr<HeldBySmartPtr>(new HeldBySmartPtr(i, s));
1682
}
1683
1684
int refcount = 1;
1685
int i;
1686
std::string s;
1687
};
1688
1689
HeldBySmartPtr takesHeldBySmartPtr(HeldBySmartPtr p) {
1690
return p;
1691
}
1692
std::shared_ptr<HeldBySmartPtr>
1693
takesHeldBySmartPtrSharedPtr(std::shared_ptr<HeldBySmartPtr> p) {
1694
return p;
1695
}
1696
1697
namespace emscripten {
1698
template<typename T> struct smart_ptr_trait<CustomSmartPtr<T>> {
1699
typedef CustomSmartPtr<T> pointer_type;
1700
typedef T element_type;
1701
1702
static sharing_policy get_sharing_policy() {
1703
return sharing_policy::NONE;
1704
}
1705
1706
static T* get(const CustomSmartPtr<T>& p) {
1707
return p.get_raw();
1708
}
1709
1710
static CustomSmartPtr<T> share(const CustomSmartPtr<T>& r, T* ptr) {
1711
++ptr->refcount; // implement an adopt API?
1712
return CustomSmartPtr<T>(ptr);
1713
}
1714
1715
static pointer_type* construct_null() {
1716
return new pointer_type;
1717
}
1718
};
1719
} // namespace emscripten
1720
1721
typedef CustomSmartPtr<class HeldByCustomSmartPtr> HeldByCustomSmartPtrPtr;
1722
1723
class HeldByCustomSmartPtr {
1724
public:
1725
HeldByCustomSmartPtr(int i, const std::string& s) : i(i), s(s) {}
1726
1727
static HeldByCustomSmartPtrPtr create(int i, const std::string& s) {
1728
return HeldByCustomSmartPtrPtr(new HeldByCustomSmartPtr(i, s));
1729
}
1730
1731
static std::shared_ptr<HeldByCustomSmartPtr>
1732
createSharedPtr(int i, const std::string& s) {
1733
return std::make_shared<HeldByCustomSmartPtr>(i, s);
1734
};
1735
1736
int refcount = 1;
1737
int i;
1738
std::string s;
1739
};
1740
1741
HeldByCustomSmartPtr* passThroughRawPtr(HeldByCustomSmartPtr* p) {
1742
return p;
1743
}
1744
HeldByCustomSmartPtrPtr passThroughCustomSmartPtr(HeldByCustomSmartPtrPtr p) {
1745
return p;
1746
}
1747
1748
struct Base1 {
1749
public:
1750
Base1() : field1("Base1") {}
1751
std::string field1;
1752
1753
std::string getField() const {
1754
return field1;
1755
}
1756
};
1757
1758
struct Base2 {
1759
public:
1760
Base2() : field2("Base2") {}
1761
std::string field2;
1762
1763
std::string getField() const {
1764
return field2;
1765
}
1766
};
1767
1768
struct HasTwoBases : public Base1, public Base2 {};
1769
1770
val get_module_property(const std::string& s) {
1771
return val::module_property(s.c_str());
1772
}
1773
1774
std::string char_to_string(char ch) {
1775
char str[256];
1776
sprintf(str, "%d", (int)ch);
1777
return str;
1778
}
1779
1780
std::string signed_char_to_string(signed char ch) {
1781
char str[256];
1782
sprintf(str, "%hhd", ch);
1783
return str;
1784
}
1785
1786
std::string unsigned_char_to_string(unsigned char ch) {
1787
char str[256];
1788
sprintf(str, "%hhu", ch);
1789
return str;
1790
}
1791
1792
std::string short_to_string(short val) {
1793
char str[256];
1794
sprintf(str, "%hd", val);
1795
return str;
1796
}
1797
1798
std::string unsigned_short_to_string(unsigned short val) {
1799
char str[256];
1800
sprintf(str, "%hu", val);
1801
return str;
1802
}
1803
1804
std::string int_to_string(int val) {
1805
char str[256];
1806
sprintf(str, "%d", val);
1807
return str;
1808
}
1809
1810
std::string unsigned_int_to_string(unsigned int val) {
1811
char str[256];
1812
sprintf(str, "%u", val);
1813
return str;
1814
}
1815
1816
std::string long_to_string(long val) {
1817
char str[256];
1818
sprintf(str, "%ld", val);
1819
return str;
1820
}
1821
1822
std::string unsigned_long_to_string(unsigned long val) {
1823
char str[256];
1824
sprintf(str, "%lu", val);
1825
return str;
1826
}
1827
1828
// test loading unsigned value from memory
1829
static unsigned char uchar;
1830
void store_unsigned_char(unsigned char arg) {
1831
uchar = arg;
1832
}
1833
1834
unsigned char load_unsigned_char() {
1835
return uchar;
1836
}
1837
1838
static unsigned short ushort;
1839
void store_unsigned_short(unsigned short arg) {
1840
ushort = arg;
1841
}
1842
1843
unsigned short load_unsigned_short() {
1844
return ushort;
1845
}
1846
1847
static unsigned int uint;
1848
void store_unsigned_int(unsigned int arg) {
1849
uint = arg;
1850
}
1851
1852
unsigned int load_unsigned_int() {
1853
return uint;
1854
}
1855
1856
static unsigned long ulong;
1857
void store_unsigned_long(unsigned long arg) {
1858
ulong = arg;
1859
}
1860
1861
unsigned long load_unsigned_long() {
1862
return ulong;
1863
}
1864
1865
template<int I> class ConstructFromFunctor {
1866
public:
1867
ConstructFromFunctor(const val& v, int a) : v_(v), a_(a) {
1868
}
1869
1870
val getVal() const {
1871
return v_;
1872
}
1873
1874
int getA() const {
1875
return a_;
1876
}
1877
1878
private:
1879
val v_;
1880
int a_;
1881
};
1882
1883
template<int I>
1884
ConstructFromFunctor<I> construct_from_functor_mixin(const val& v, int i) {
1885
return {v, i};
1886
}
1887
1888
EMSCRIPTEN_BINDINGS(tests) {
1889
register_vector<int>("IntegerVector");
1890
register_vector<char>("CharVector");
1891
register_vector<unsigned>("VectorUnsigned");
1892
register_vector<unsigned char>("VectorUnsignedChar");
1893
register_vector<std::string>("StringVector");
1894
register_vector<emscripten::val>("EmValVector");
1895
register_vector<float>("FloatVector");
1896
register_vector<std::vector<int>>("IntegerVectorVector");
1897
register_vector<SmallClass*>("SmallClassPointerVector");
1898
1899
class_<DummyForPointer>("DummyForPointer");
1900
1901
function("mallinfo", &emval_test_mallinfo);
1902
function("emval_test_new_integer", &emval_test_new_integer);
1903
function("emval_test_new_string", &emval_test_new_string);
1904
function("emval_test_get_string_from_val", &emval_test_get_string_from_val);
1905
function("emval_test_new_object", &emval_test_new_object);
1906
function("emval_test_instance_pointer", &emval_test_instance_pointer);
1907
function("emval_test_value_from_instance_pointer", &emval_test_value_from_instance_pointer);
1908
function("emval_test_passthrough_unsigned", &emval_test_passthrough_unsigned);
1909
function("emval_test_passthrough", &emval_test_passthrough);
1910
function("emval_test_return_void", &emval_test_return_void);
1911
function("emval_test_not", &emval_test_not);
1912
1913
function("emval_test_is_true", &emval_test_is_true);
1914
function("emval_test_is_false", &emval_test_is_false);
1915
function("emval_test_is_null", &emval_test_is_null);
1916
function("emval_test_is_undefined", &emval_test_is_undefined);
1917
function("emval_test_equals", &emval_test_equals);
1918
function("emval_test_strictly_equals", &emval_test_strictly_equals);
1919
1920
function("emval_test_as_unsigned", &emval_test_as_unsigned);
1921
function("emval_test_get_length", &emval_test_get_length);
1922
function("emval_test_add", &emval_test_add);
1923
function("const_ref_adder", &const_ref_adder);
1924
function("emval_test_sum", &emval_test_sum);
1925
1926
class_<DestructorCounter>("DestructorCounter");
1927
function("emval_test_callback_arg_lifetime", &emval_test_callback_arg_lifetime);
1928
1929
function("get_non_ascii_string", &get_non_ascii_string);
1930
function("get_non_ascii_wstring", &get_non_ascii_wstring);
1931
function("get_literal_wstring", &get_literal_wstring);
1932
function("force_memory_growth", &force_memory_growth);
1933
1934
//function("emval_test_take_and_return_const_char_star", &emval_test_take_and_return_const_char_star);
1935
function("emval_test_take_and_return_std_string", &emval_test_take_and_return_std_string);
1936
function("emval_test_take_and_return_std_string_const_ref", &emval_test_take_and_return_std_string_const_ref);
1937
function("take_and_return_std_wstring", &take_and_return_std_wstring);
1938
function("take_and_return_std_u16string", &take_and_return_std_u16string);
1939
function("take_and_return_std_u32string", &take_and_return_std_u32string);
1940
function("get_non_ascii_u16string", &get_non_ascii_u16string);
1941
function("get_non_ascii_u32string", &get_non_ascii_u32string);
1942
function("get_literal_u16string", &get_literal_u16string);
1943
function("get_literal_u32string", &get_literal_u32string);
1944
1945
//function("emval_test_take_and_return_CustomStruct", &emval_test_take_and_return_CustomStruct);
1946
1947
value_array<TupleVector>("TupleVector")
1948
.element(&TupleVector::x)
1949
.element(&Vector::getY, &Vector::setY)
1950
.element(&readVectorZ, &writeVectorZ)
1951
.element(emscripten::index<3>())
1952
;
1953
1954
function("emval_test_return_TupleVector", &emval_test_return_TupleVector);
1955
function("emval_test_take_and_return_TupleVector", &emval_test_take_and_return_TupleVector);
1956
1957
value_array<TupleVectorTuple>("TupleVectorTuple")
1958
.element(&TupleVectorTuple::v)
1959
;
1960
1961
function("emval_test_return_TupleVectorTuple", &emval_test_return_TupleVectorTuple);
1962
1963
value_object<StructVector>("StructVector")
1964
.field("x", &StructVector::x)
1965
.field("y", &Vector::getY, &Vector::setY)
1966
.field("z", &readVectorZ, &writeVectorZ)
1967
.field("w", emscripten::index<3>())
1968
;
1969
1970
function("emval_test_return_StructVector", &emval_test_return_StructVector);
1971
function("emval_test_take_and_return_StructVector", &emval_test_take_and_return_StructVector);
1972
1973
value_object<TupleInStruct>("TupleInStruct")
1974
.field("field", &TupleInStruct::field)
1975
;
1976
1977
function("emval_test_take_and_return_TupleInStruct", &emval_test_take_and_return_TupleInStruct);
1978
1979
1980
value_array<std::array<int, 2>>("array_int_2")
1981
.element(emscripten::index<0>())
1982
.element(emscripten::index<1>())
1983
;
1984
value_array<std::array<NestedStruct, 2>>("array_NestedStruct_2")
1985
.element(emscripten::index<0>())
1986
.element(emscripten::index<1>())
1987
;
1988
value_object<NestedStruct>("NestedStruct")
1989
.field("x", &NestedStruct::x)
1990
.field("y", &NestedStruct::y)
1991
;
1992
1993
value_object<ArrayInStruct>("ArrayInStruct")
1994
.field("field1", &ArrayInStruct::field1)
1995
.field("field2", &ArrayInStruct::field2)
1996
;
1997
function("emval_test_take_and_return_ArrayInStruct", &emval_test_take_and_return_ArrayInStruct);
1998
1999
using namespace std::placeholders;
2000
2001
class_<ConstructFromFunctor<1>>("ConstructFromStdFunction")
2002
.constructor(std::function<ConstructFromFunctor<1>(const val&, int)>(&construct_from_functor_mixin<1>))
2003
.function("getVal", &ConstructFromFunctor<1>::getVal)
2004
.function("getA", &ConstructFromFunctor<1>::getA)
2005
;
2006
2007
class_<ConstructFromFunctor<2>>("ConstructFromFunctionObject")
2008
.constructor<ConstructFromFunctor<2>(const val&, int)>(std::bind(&construct_from_functor_mixin<2>, _1, _2))
2009
.function("getVal", &ConstructFromFunctor<2>::getVal)
2010
.function("getA", &ConstructFromFunctor<2>::getA)
2011
;
2012
2013
class_<ValHolder>("ValHolder")
2014
.smart_ptr<std::shared_ptr<ValHolder>>("std::shared_ptr<ValHolder>")
2015
.constructor<val>()
2016
.constructor<ValHolder(int, int)>(&valholder_from_sum, allow_raw_pointers()) // custom signature with policy
2017
.function("getVal", &ValHolder::getVal)
2018
.function("getValNonConst", &ValHolder::getValNonConst)
2019
.function("getConstVal", &ValHolder::getConstVal)
2020
.function("getValConstRef", &ValHolder::getValConstRef)
2021
.function("setVal", &ValHolder::setVal)
2022
.function("getValFunction", std::function<val(const ValHolder&)>(&valholder_get_value_mixin))
2023
.function("setValFunction", std::function<void(ValHolder&, const val&)>(&valholder_set_value_mixin))
2024
.function<ValHolder*(ValHolder&)>("getThisPointer", std::function<ValHolder*(ValHolder&)>(&valholder_get_this_ptr), allow_raw_pointer<ret_val>())
2025
.function<val(const ValHolder&)>("getValFunctor", std::bind(&valholder_get_value_mixin, _1))
2026
.function<void(ValHolder&, const val&)>("setValFunctor", std::bind(&valholder_set_value_mixin, _1, _2))
2027
.property("val", &ValHolder::getVal, &ValHolder::setVal)
2028
.property("val_readonly", &ValHolder::getVal)
2029
.property("readonly_function_val", std::function<val(const ValHolder&)>(&valholder_get_value_mixin))
2030
.property("function_val", std::function<val(const ValHolder&)>(&valholder_get_value_mixin),
2031
std::function<void(ValHolder&, const val&)>(&valholder_set_value_mixin))
2032
.property<val>("readonly_functor_val", std::bind(&valholder_get_value_mixin, _1))
2033
.property<val>("functor_val", std::bind(&valholder_get_value_mixin, _1),
2034
std::bind(&valholder_set_value_mixin, _1, _2))
2035
.class_function("makeConst", &ValHolder::makeConst, allow_raw_pointer<ret_val>())
2036
.class_function("makeValHolder", &ValHolder::makeValHolder)
2037
.class_function("some_class_method", &ValHolder::some_class_method)
2038
.class_function("set_via_raw_pointer",
2039
&ValHolder::set_via_raw_pointer,
2040
allow_raw_pointer<arg<0>>())
2041
.class_function("get_via_raw_pointer",
2042
&ValHolder::get_via_raw_pointer,
2043
allow_raw_pointer<arg<0>>())
2044
.class_function("transfer_via_raw_pointer",
2045
&ValHolder::transfer_via_raw_pointer,
2046
allow_raw_pointers())
2047
2048
// non-member method
2049
.function("setEmpty", &emval_test_set_ValHolder_to_empty_object)
2050
.function("getValNonMember", &ValHolder::getValNonMember)
2051
;
2052
2053
function("emval_test_return_ValHolder", &emval_test_return_ValHolder);
2054
function("emval_test_set_ValHolder_to_empty_object", &emval_test_set_ValHolder_to_empty_object);
2055
2056
class_<std::function<std::string(std::string)>>("StringFunctorString")
2057
.constructor<>()
2058
.function("opcall", &std::function<std::string(std::string)>::operator())
2059
;
2060
2061
function("emval_test_get_function_ptr", &emval_test_get_function_ptr);
2062
function("emval_test_take_and_call_functor", &emval_test_take_and_call_functor);
2063
2064
class_<StringHolder>("StringHolder")
2065
.smart_ptr<std::shared_ptr<StringHolder>>("shared_ptr<StringHolder>")
2066
.constructor<std::string>()
2067
.function("set", &StringHolder::set)
2068
.function("get", &StringHolder::get)
2069
.function("get_const_ref", &StringHolder::get_const_ref)
2070
;
2071
2072
class_<SharedPtrHolder>("SharedPtrHolder")
2073
.constructor<>()
2074
.function("get", &SharedPtrHolder::get)
2075
.function("set", &SharedPtrHolder::set)
2076
;
2077
2078
class_<SmallClass>("SmallClass")
2079
.constructor<>()
2080
.property("member", &SmallClass::member)
2081
;
2082
2083
class_<BigClass>("BigClass")
2084
.constructor<>()
2085
.property("member", &BigClass::member)
2086
.property("otherMember", &BigClass::otherMember)
2087
.property("yetAnotherMember", &BigClass::yetAnotherMember)
2088
.function("getMember", &BigClass::getMember)
2089
;
2090
2091
class_<ParentClass>("ParentClass")
2092
.constructor<>()
2093
.function("getBigClass", &ParentClass::getBigClass)
2094
;
2095
2096
class_<TemplateClass<int>>("IntTemplateClass")
2097
.constructor<int, int, int>()
2098
.function("getMember", &TemplateClass<int>::getMember)
2099
;
2100
2101
class_<NoExceptClass>("NoExceptClass")
2102
.function("embind_test_no_except_function", &embind_test_no_except_function)
2103
.function("getValue", &NoExceptClass::getValue)
2104
.function("getValueConst", &NoExceptClass::getValueConst)
2105
.property("x", &NoExceptClass::getX, &NoExceptClass::setX);
2106
2107
class_<ContainsTemplatedMemberClass>("ContainsTemplatedMemberClass")
2108
.constructor<>()
2109
.function("getTestTemplate", &ContainsTemplatedMemberClass::getTestTemplate)
2110
;
2111
2112
class_<SymbolNameClass>("SymbolNameClass")
2113
.constructor<>()
2114
.function("@@iterator", &SymbolNameClass::iterator)
2115
.class_function("@@species", &SymbolNameClass::species)
2116
;
2117
2118
// register Derived before Base as a test that it's possible to
2119
// register base classes afterwards
2120
class_<Derived, base<Base>>("Derived")
2121
.smart_ptr<std::shared_ptr<Derived>>("shared_ptr<Derived>")
2122
.constructor<>()
2123
.function("getClassName", &Derived::getClassName)
2124
.function("getMember", &Derived::getMember)
2125
.function("setMember", &Derived::setMember)
2126
.property("member", &Derived::member)
2127
.class_function("classFunction", &Derived::classFunction)
2128
;
2129
2130
class_<Base>("Base")
2131
.smart_ptr<std::shared_ptr<Base>>("shared_ptr<Base")
2132
.constructor<>()
2133
.function("getClassName", &Base::getClassName)
2134
.function("getClassNameFromBase", &Base::getClassNameFromBase)
2135
.function("getClassNameNotAvailableInDerivedClasses", &Base::getClassNameNotAvailableInDerivedClasses)
2136
.function("getMember", &Base::getMember)
2137
.function("setMember", &Base::setMember)
2138
.function("getBaseMember", &Base::getBaseMember)
2139
.function("setBaseMember", &Base::setBaseMember)
2140
.property("member", &Base::member)
2141
.property("baseMember", &Base::baseMember)
2142
.class_function("classFunction", &Base::classFunction)
2143
;
2144
2145
class_<SecondBase>("SecondBase")
2146
.smart_ptr<std::shared_ptr<SecondBase>>("shared_ptr<SecondBase>")
2147
.constructor<>()
2148
.function("getClassName", &SecondBase::getClassName)
2149
.function("getClassNameFromSecondBase", &SecondBase::getClassNameFromSecondBase)
2150
.function("getClassNameNotAvailableInDerivedClasses", &SecondBase::getClassNameNotAvailableInDerivedClasses)
2151
.function("getMember", &SecondBase::getMember)
2152
.function("setMember", &SecondBase::setMember)
2153
.function("getSecondBaseMember", &SecondBase::getSecondBaseMember)
2154
.function("setSecondBaseMember", &SecondBase::setSecondBaseMember)
2155
.property("member", &SecondBase::member)
2156
.property("secondBaseMember", &SecondBase::secondBaseMember)
2157
;
2158
2159
2160
class_<DerivedHolder>("DerivedHolder")
2161
.constructor<>()
2162
.function("newDerived", &DerivedHolder::newDerived)
2163
.function("deleteDerived", &DerivedHolder::deleteDerived)
2164
.function("getDerived", &DerivedHolder::getDerived)
2165
.function("getDerivedClassName", &DerivedHolder::getDerivedClassName)
2166
;
2167
2168
class_<SiblingDerived>("SiblingDerived")
2169
.smart_ptr<std::shared_ptr<SiblingDerived>>("shared_ptr<SiblingDerived>")
2170
.constructor<>()
2171
.function("getClassName", &SiblingDerived::getClassName)
2172
;
2173
2174
class_<MultiplyDerived, base<Base>>("MultiplyDerived")
2175
.smart_ptr<std::shared_ptr<MultiplyDerived>>("shared_ptr<MultiplyDerived>")
2176
.constructor<>()
2177
.function("getClassName", &MultiplyDerived::getClassName)
2178
.class_function("getInstanceCount", &MultiplyDerived::getInstanceCount)
2179
;
2180
2181
class_<DerivedTwice, base<Derived> >("DerivedTwice")
2182
.constructor<>()
2183
.function("getClassName", &DerivedTwice::getClassName)
2184
;
2185
2186
class_<DerivedThrice, base<Derived> >("DerivedThrice")
2187
.smart_ptr<std::shared_ptr<DerivedThrice>>("shared_ptr<DerivedThrice>")
2188
.constructor<>()
2189
.function("getClassName", &DerivedThrice::getClassName)
2190
;
2191
2192
class_<PolyBase>("PolyBase")
2193
.smart_ptr<std::shared_ptr<PolyBase>>("shared_ptr<PolyBase>")
2194
.constructor<>()
2195
.function("virtualGetClassName", &PolyBase::virtualGetClassName)
2196
.function("getClassName", &PolyBase::getClassName)
2197
;
2198
2199
class_<PolySecondBase>("PolySecondBase")
2200
.smart_ptr<std::shared_ptr<PolySecondBase>>("shared_ptr<PolySecondBase>")
2201
.constructor<>()
2202
.function("getClassName", &PolySecondBase::getClassName)
2203
;
2204
2205
class_<PolyDerived, base<PolyBase>>("PolyDerived")
2206
.smart_ptr<std::shared_ptr<PolyDerived>>("shared_ptr<PolyDerived>")
2207
.constructor<>()
2208
.function("virtualGetClassName", &PolyDerived::virtualGetClassName)
2209
.function("getClassName", &PolyDerived::getClassName)
2210
.class_function("setPtrDerived", &PolyDerived::setPtrDerived)
2211
.class_function("releasePtr", &PolyDerived::releasePtr)
2212
.class_function("getPtrClassName", &PolyDerived::getPtrClassName)
2213
.class_function("getPtr", &PolyDerived::getPtr)
2214
;
2215
// static void setPtrDerived() {
2216
// ptr = std::shared_ptr<PolyDerived>(new PolyDerived());
2217
// }
2218
//
2219
// static std::string getPtrClassName() {
2220
// return ptr->getClassName();
2221
// }
2222
//
2223
// static std::shared_ptr<PolyBase> getPtr() {
2224
// return ptr;
2225
// }
2226
2227
class_<PolySiblingDerived, base<PolyBase>>("PolySiblingDerived")
2228
.smart_ptr<std::shared_ptr<PolySiblingDerived>>("shared_ptr<PolySiblingDerived>")
2229
.constructor<>()
2230
.function("getClassName", &PolySiblingDerived::getClassName)
2231
;
2232
2233
class_<PolyMultiplyDerived, base<PolyBase>>("PolyMultiplyDerived")
2234
.smart_ptr<std::shared_ptr<PolyMultiplyDerived>>("shared_ptr<PolyMultiplyDerived>")
2235
.constructor<>()
2236
.function("getClassName", &PolyMultiplyDerived::getClassName)
2237
;
2238
2239
class_<PolyDerivedThrice, base<PolyDerived>>("PolyDerivedThrice")
2240
.smart_ptr<std::shared_ptr<PolyDerivedThrice>>("shared_ptr<PolyDerivedThrice>")
2241
.constructor<>()
2242
.function("getClassName", &PolyDerivedThrice::getClassName)
2243
;
2244
2245
class_<PolyDiamondBase>("PolyDiamondBase")
2246
.smart_ptr<std::shared_ptr<PolyDiamondBase>>("shared_ptr<PolyDiamondBase>")
2247
.constructor<>()
2248
.function("getClassName", &PolyDiamondBase::getClassName)
2249
;
2250
2251
class_<PolyDiamondDerived>("PolyDiamondDerived")
2252
.smart_ptr<std::shared_ptr<PolyDiamondDerived>>("shared_ptr<PolyDiamondDerived>")
2253
.constructor<>()
2254
.function("getClassName", &PolyDiamondDerived::getClassName)
2255
;
2256
2257
class_<PolyDiamondSiblingDerived>("PolyDiamondSiblingDerived")
2258
.smart_ptr<std::shared_ptr<PolyDiamondSiblingDerived>>("shared_ptr<PolyDiamondSiblingDerived>")
2259
.constructor<>()
2260
.function("getClassName", &PolyDiamondSiblingDerived::getClassName)
2261
;
2262
2263
class_<PolyDiamondMultiplyDerived>("PolyDiamondMultiplyDerived")
2264
.smart_ptr<std::shared_ptr<PolyDiamondMultiplyDerived>>("shared_ptr<PolyDiamondMultiplyDerived>")
2265
.constructor<>()
2266
.function("getClassName", &PolyDiamondMultiplyDerived::getClassName)
2267
;
2268
2269
function("embind_test_return_small_class_instance", &embind_test_return_small_class_instance);
2270
function("embind_test_return_big_class_instance", &embind_test_return_big_class_instance);
2271
function("embind_test_accept_small_class_instance", &embind_test_accept_small_class_instance);
2272
function("embind_test_accept_big_class_instance", &embind_test_accept_big_class_instance);
2273
2274
class_<UniquePtrToConstructor>("UniquePtrToConstructor")
2275
.function("getValue", &UniquePtrToConstructor::getValue)
2276
;
2277
class_<CharWrapper>("CharWrapper");
2278
2279
function("embind_test_construct_class_with_unique_ptr", embind_test_construct_class_with_unique_ptr, allow_raw_pointer<ret_val>());
2280
function("embind_test_return_unique_ptr", embind_test_return_unique_ptr);
2281
function("embind_test_accept_unique_ptr", embind_test_accept_unique_ptr);
2282
2283
function("embind_test_return_raw_base_ptr", embind_test_return_raw_base_ptr, allow_raw_pointer<ret_val>());
2284
function("embind_test_return_raw_derived_ptr_as_base", embind_test_return_raw_derived_ptr_as_base, allow_raw_pointer<ret_val>());
2285
function("embind_test_return_raw_sibling_derived_ptr_as_base", embind_test_return_raw_sibling_derived_ptr_as_base, allow_raw_pointer<ret_val>());
2286
function("embind_test_return_raw_polymorphic_derived_ptr_as_base", embind_test_return_raw_polymorphic_derived_ptr_as_base, allow_raw_pointer<ret_val>());
2287
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>());
2288
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>());
2289
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>());
2290
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>());
2291
function("embind_test_return_smart_derived_ptr", embind_test_return_smart_derived_ptr);
2292
function("embind_test_return_smart_sibling_derived_ptr", embind_test_return_smart_sibling_derived_ptr);
2293
function("embind_test_return_smart_multiply_derived_ptr", embind_test_return_smart_multiply_derived_ptr);
2294
function("embind_test_return_smart_derived_thrice_ptr", embind_test_return_smart_derived_thrice_ptr);
2295
function("embind_test_return_smart_base_ptr", embind_test_return_smart_base_ptr);
2296
function("embind_test_return_smart_polymorphic_base_ptr", embind_test_return_smart_polymorphic_base_ptr);
2297
function("embind_test_return_smart_polymorphic_derived_ptr", embind_test_return_smart_polymorphic_derived_ptr);
2298
function("embind_test_return_smart_polymorphic_sibling_derived_ptr", embind_test_return_smart_polymorphic_sibling_derived_ptr);
2299
function("embind_test_return_smart_polymorphic_multiply_derived_ptr", embind_test_return_smart_polymorphic_multiply_derived_ptr);
2300
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);
2301
function("embind_test_return_smart_poly_derived_thrice_ptr", embind_test_return_smart_poly_derived_thrice_ptr);
2302
function("embind_test_return_smart_derived_ptr_as_base", embind_test_return_smart_derived_ptr_as_base);
2303
function("embind_test_return_smart_derived_ptr_as_val", embind_test_return_smart_derived_ptr_as_val);
2304
function("embind_test_return_smart_polymorphic_derived_ptr_as_base", embind_test_return_smart_polymorphic_derived_ptr_as_base);
2305
function("embind_test_return_smart_polymorphic_sibling_derived_ptr_as_base", embind_test_return_smart_polymorphic_sibling_derived_ptr_as_base);
2306
function("embind_test_get_class_name_via_base_ptr", embind_test_get_class_name_via_base_ptr, allow_raw_pointer<arg<0>>());
2307
function("embind_test_get_class_name_via_second_base_ptr", embind_test_get_class_name_via_second_base_ptr, allow_raw_pointer<arg<0>>());
2308
function("embind_test_get_class_name_via_polymorphic_base_ptr", embind_test_get_class_name_via_polymorphic_base_ptr, allow_raw_pointer<arg<0>>());
2309
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>>());
2310
// todo: allow_raw_pointer should fail earlier if argument is not a pointer
2311
function("embind_test_get_class_name_via_smart_base_ptr", embind_test_get_class_name_via_smart_base_ptr);
2312
function("embind_test_get_class_name_via_reference_to_smart_base_ptr", embind_test_get_class_name_via_reference_to_smart_base_ptr);
2313
function("embind_test_get_class_name_via_smart_second_base_ptr", embind_test_get_class_name_via_smart_second_base_ptr);
2314
function("embind_test_get_class_name_via_smart_polymorphic_base_ptr", embind_test_get_class_name_via_smart_polymorphic_base_ptr);
2315
function("embind_test_get_virtual_class_name_via_smart_polymorphic_base_ptr", embind_test_get_virtual_class_name_via_smart_polymorphic_base_ptr);
2316
function("embind_test_get_class_name_via_smart_polymorphic_second_base_ptr", embind_test_get_class_name_via_smart_polymorphic_second_base_ptr);
2317
function("embind_modify_smart_pointer_passed_by_reference", embind_modify_smart_pointer_passed_by_reference);
2318
function("embind_attempt_to_modify_smart_pointer_when_passed_by_value", embind_attempt_to_modify_smart_pointer_when_passed_by_value);
2319
function("embind_save_smart_base_pointer", embind_save_smart_base_pointer);
2320
2321
class_<Base1>("Base1")
2322
.constructor()
2323
.function("getField", &Base1::getField)
2324
;
2325
2326
class_<Base2>("Base2")
2327
.function("getField", &Base2::getField)
2328
.property("field", &Base2::field2)
2329
;
2330
2331
class_<HasTwoBases, base<Base2>>("HasTwoBases")
2332
.constructor()
2333
;
2334
2335
class_<CustomStruct>("CustomStruct")
2336
.constructor<>()
2337
.property("field", &CustomStruct::field)
2338
.function("getField", &CustomStruct::getField)
2339
;
2340
2341
enum_<Enum>("Enum")
2342
.value("ONE", ONE)
2343
.value("TWO", TWO)
2344
;
2345
function("emval_test_take_and_return_Enum", &emval_test_take_and_return_Enum);
2346
2347
enum_<EnumClass>("EnumClass")
2348
.value("ONE", EnumClass::ONE)
2349
.value("TWO", EnumClass::TWO)
2350
;
2351
function("emval_test_take_and_return_EnumClass", &emval_test_take_and_return_EnumClass);
2352
2353
function("emval_test_call_function", &emval_test_call_function);
2354
2355
function("emval_test_return_unique_ptr", &emval_test_return_unique_ptr);
2356
2357
class_<UniquePtrLifetimeMock>("UniquePtrLifetimeMock");
2358
function("emval_test_return_unique_ptr_lifetime", &emval_test_return_unique_ptr_lifetime);
2359
2360
function("emval_test_return_shared_ptr", &emval_test_return_shared_ptr);
2361
function("emval_test_return_empty_shared_ptr", &emval_test_return_empty_shared_ptr);
2362
function("emval_test_is_shared_ptr_null", &emval_test_is_shared_ptr_null);
2363
2364
function("emval_test_return_vector", &emval_test_return_vector);
2365
function("emval_test_return_vector_of_vectors", &emval_test_return_vector_of_vectors);
2366
function("emval_test_return_vector_pointers", &emval_test_return_vector_pointers);
2367
2368
register_vector<std::shared_ptr<StringHolder>>("SharedPtrVector");
2369
function("emval_test_return_shared_ptr_vector", &emval_test_return_shared_ptr_vector);
2370
2371
function("get_module_property", &get_module_property);
2372
2373
register_vector<StringHolder>("StringHolderVector");
2374
class_<VectorHolder>("VectorHolder")
2375
.constructor<>()
2376
.function("get", &VectorHolder::get)
2377
.function("set", &VectorHolder::set)
2378
;
2379
2380
function("test_string_with_vec", &test_string_with_vec);
2381
2382
#if __cplusplus >= 201703L
2383
register_optional<int>();
2384
register_optional<float>();
2385
register_optional<SmallClass>();
2386
register_optional<SmallClass*>();
2387
register_optional<std::string>();
2388
function("embind_test_return_optional_int", &embind_test_return_optional_int);
2389
function("embind_test_return_optional_float", &embind_test_return_optional_float);
2390
function("embind_test_return_optional_small_class", &embind_test_return_optional_small_class);
2391
function("embind_test_return_optional_small_class_pointer", &embind_test_return_optional_small_class_pointer);
2392
function("embind_test_return_optional_string", &embind_test_return_optional_string);
2393
function("embind_test_optional_int_arg", &embind_test_optional_int_arg);
2394
function("embind_test_optional_float_arg", &embind_test_optional_float_arg);
2395
function("embind_test_optional_string_arg", &embind_test_optional_string_arg);
2396
function("embind_test_optional_small_class_arg", &embind_test_optional_small_class_arg);
2397
function("embind_test_optional_multiple_arg", &embind_test_optional_multiple_arg);
2398
value_object<StructWithOptionalProperty>("StructWithOptionalProperty")
2399
.field("x", &StructWithOptionalProperty::x)
2400
.field("y", &StructWithOptionalProperty::y)
2401
;
2402
function("embind_test_optional_property", &embind_test_optional_property);
2403
#endif
2404
2405
register_map<std::string, int>("StringIntMap");
2406
function("embind_test_get_string_int_map", embind_test_get_string_int_map);
2407
2408
register_map<int, std::string, std::greater<int>>("IntStringMapGreater");
2409
function("embind_test_get_int_string_greater_map", embind_test_get_int_string_greater_map);
2410
2411
function("embind_test_getglobal", &embind_test_getglobal);
2412
2413
function("embind_test_new_Object", &embind_test_new_Object);
2414
function("embind_test_new_factory", &embind_test_new_factory);
2415
2416
class_<HasExternalConstructor>("HasExternalConstructor")
2417
.constructor(&createHasExternalConstructor)
2418
.function("getString", &HasExternalConstructor::getString)
2419
;
2420
2421
class_<HasExternalConstructorNoCopy>("HasExternalConstructorNoCopy")
2422
.constructor(&HasExternalConstructorNoCopy::create)
2423
.function("getInt", &HasExternalConstructorNoCopy::getInt)
2424
;
2425
2426
auto HeldBySmartPtr_class = class_<HeldBySmartPtr>("HeldBySmartPtr");
2427
HeldBySmartPtr_class
2428
.smart_ptr<CustomSmartPtr<HeldBySmartPtr>>("CustomSmartPtr<HeldBySmartPtr>")
2429
.smart_ptr_constructor("shared_ptr<HeldbySmartPtr>", &std::make_shared<HeldBySmartPtr, int, std::string>)
2430
.class_function("newCustomPtr", HeldBySmartPtr::newCustomPtr)
2431
.function("returnThis", &takesHeldBySmartPtrSharedPtr)
2432
.property("i", &HeldBySmartPtr::i)
2433
.property("s", &HeldBySmartPtr::s)
2434
;
2435
function("takesHeldBySmartPtr", &takesHeldBySmartPtr);
2436
function("takesHeldBySmartPtrSharedPtr", &takesHeldBySmartPtrSharedPtr);
2437
2438
class_<HeldByCustomSmartPtr>("HeldByCustomSmartPtr")
2439
.smart_ptr<std::shared_ptr<HeldByCustomSmartPtr>>("shared_ptr<HeldByCustomSmartPtr>")
2440
.smart_ptr_constructor("CustomSmartPtr<HeldByCustomSmartPtr>", &HeldByCustomSmartPtr::create)
2441
.class_function("createSharedPtr", &HeldByCustomSmartPtr::createSharedPtr)
2442
.property("i", &HeldByCustomSmartPtr::i)
2443
.property("s", &HeldByCustomSmartPtr::s)
2444
;
2445
2446
function("passThroughRawPtr", &passThroughRawPtr, allow_raw_pointers());
2447
function("passThroughCustomSmartPtr", &passThroughCustomSmartPtr);
2448
2449
function("char_to_string", &char_to_string);
2450
function("signed_char_to_string", &signed_char_to_string);
2451
function("unsigned_char_to_string", &unsigned_char_to_string);
2452
function("short_to_string", &short_to_string);
2453
function("unsigned_short_to_string", &unsigned_short_to_string);
2454
function("int_to_string", &int_to_string);
2455
function("unsigned_int_to_string", &unsigned_int_to_string);
2456
function("long_to_string", &long_to_string);
2457
function("unsigned_long_to_string", &unsigned_long_to_string);
2458
2459
function("store_unsigned_char", &store_unsigned_char);
2460
function("load_unsigned_char", &load_unsigned_char);
2461
function("store_unsigned_short", &store_unsigned_short);
2462
function("load_unsigned_short", &load_unsigned_short);
2463
function("store_unsigned_int", &store_unsigned_int);
2464
function("load_unsigned_int", &load_unsigned_int);
2465
function("store_unsigned_long", &store_unsigned_long);
2466
function("load_unsigned_long", &load_unsigned_long);
2467
}
2468
2469
int overloaded_function(int i) {
2470
assert(i == 10);
2471
return 1;
2472
}
2473
2474
int overloaded_function(int i, int j) {
2475
assert(i == 20);
2476
assert(j == 20);
2477
return 2;
2478
}
2479
2480
class MultipleCtors {
2481
public:
2482
int value = 0;
2483
2484
MultipleCtors(int i) {
2485
value = 1;
2486
assert(i == 10);
2487
}
2488
MultipleCtors(int i, int j) {
2489
value = 2;
2490
assert(i == 20);
2491
assert(j == 20);
2492
}
2493
MultipleCtors(int i, int j, int k) {
2494
value = 3;
2495
assert(i == 30);
2496
assert(j == 30);
2497
assert(k == 30);
2498
}
2499
2500
int WhichCtorCalled() const {
2501
return value;
2502
}
2503
};
2504
2505
class MultipleSmartCtors {
2506
public:
2507
int value = 0;
2508
2509
MultipleSmartCtors(int i) {
2510
value = 1;
2511
assert(i == 10);
2512
}
2513
MultipleSmartCtors(int i, int j) {
2514
value = 2;
2515
assert(i == 20);
2516
assert(j == 20);
2517
}
2518
2519
int WhichCtorCalled() const {
2520
return value;
2521
}
2522
};
2523
2524
class MultipleOverloads {
2525
public:
2526
MultipleOverloads() {}
2527
2528
int value;
2529
static int staticValue;
2530
2531
int Func(int i) {
2532
assert(i == 10);
2533
value = 1;
2534
return 1;
2535
}
2536
int Func(int i, int j) {
2537
assert(i == 20);
2538
assert(j == 20);
2539
value = 2;
2540
return 2;
2541
}
2542
2543
int WhichFuncCalled() const {
2544
return value;
2545
}
2546
2547
static int StaticFunc(int i) {
2548
assert(i == 10);
2549
staticValue = 1;
2550
return 1;
2551
}
2552
static int StaticFunc(int i, int j) {
2553
assert(i == 20);
2554
assert(j == 20);
2555
staticValue = 2;
2556
return 2;
2557
}
2558
2559
static int WhichStaticFuncCalled() {
2560
return staticValue;
2561
}
2562
};
2563
2564
int MultipleOverloads::staticValue = 0;
2565
2566
class MultipleOverloadsDerived : public MultipleOverloads {
2567
public:
2568
MultipleOverloadsDerived() {
2569
}
2570
2571
int Func(int i, int j, int k) {
2572
assert(i == 30);
2573
assert(j == 30);
2574
assert(k == 30);
2575
value = 3;
2576
return 3;
2577
}
2578
int Func(int i, int j, int k, int l) {
2579
assert(i == 40);
2580
assert(j == 40);
2581
assert(k == 40);
2582
assert(l == 40);
2583
value = 4;
2584
return 4;
2585
}
2586
2587
static int StaticFunc(int i, int j, int k) {
2588
assert(i == 30);
2589
assert(j == 30);
2590
assert(k == 30);
2591
staticValue = 3;
2592
return 3;
2593
}
2594
static int StaticFunc(int i, int j, int k, int l) {
2595
assert(i == 40);
2596
assert(j == 40);
2597
assert(k == 40);
2598
assert(l == 40);
2599
staticValue = 4;
2600
return 4;
2601
}
2602
};
2603
2604
struct MultipleAccessors {
2605
int getConst() {
2606
return 1;
2607
}
2608
int getConst() const {
2609
return 2;
2610
}
2611
int getConst(int i) const {
2612
return i;
2613
}
2614
};
2615
2616
struct ConstAndNonConst {
2617
void method(int) {
2618
}
2619
2620
int method() const {
2621
return 10;
2622
}
2623
};
2624
2625
class DummyForOverloads {};
2626
2627
class MultipleOverloadsDependingOnDummy {
2628
public:
2629
DummyForOverloads dummy() {
2630
return DummyForOverloads();
2631
}
2632
2633
DummyForOverloads dummy(DummyForOverloads d) {
2634
return d;
2635
}
2636
2637
static DummyForOverloads staticDummy() {
2638
return DummyForOverloads();
2639
}
2640
2641
static DummyForOverloads staticDummy(DummyForOverloads d) {
2642
return d;
2643
}
2644
};
2645
2646
DummyForOverloads getDummy() {
2647
return DummyForOverloads();
2648
}
2649
2650
DummyForOverloads getDummy(DummyForOverloads d) {
2651
return d;
2652
}
2653
2654
EMSCRIPTEN_BINDINGS(overloads) {
2655
function("overloaded_function", select_overload<int(int)>(&overloaded_function));
2656
function("overloaded_function", select_overload<int(int, int)>(&overloaded_function));
2657
2658
class_<MultipleCtors>("MultipleCtors")
2659
.constructor<int>()
2660
.constructor<int, int>()
2661
.constructor<int, int, int>()
2662
.function("WhichCtorCalled", &MultipleCtors::WhichCtorCalled)
2663
;
2664
2665
class_<MultipleSmartCtors>("MultipleSmartCtors")
2666
.smart_ptr<std::shared_ptr<MultipleSmartCtors>>("shared_ptr<MultipleSmartCtors>")
2667
.constructor(&std::make_shared<MultipleSmartCtors, int>)
2668
.constructor(&std::make_shared<MultipleSmartCtors, int, int>)
2669
.function("WhichCtorCalled", &MultipleSmartCtors::WhichCtorCalled)
2670
;
2671
2672
class_<MultipleOverloads>("MultipleOverloads")
2673
.constructor<>()
2674
.function("Func", select_overload<int(int)>(&MultipleOverloads::Func))
2675
.function("Func", select_overload<int(int, int)>(&MultipleOverloads::Func))
2676
.function("WhichFuncCalled", &MultipleOverloads::WhichFuncCalled)
2677
.class_function("StaticFunc", select_overload<int(int)>(&MultipleOverloads::StaticFunc))
2678
.class_function("StaticFunc", select_overload<int(int,int)>(&MultipleOverloads::StaticFunc))
2679
.class_function("WhichStaticFuncCalled", &MultipleOverloads::WhichStaticFuncCalled)
2680
;
2681
2682
class_<MultipleOverloadsDerived, base<MultipleOverloads> >("MultipleOverloadsDerived")
2683
.constructor<>()
2684
.function("Func", select_overload<int(int,int,int)>(&MultipleOverloadsDerived::Func))
2685
.function("Func", select_overload<int(int,int,int,int)>(&MultipleOverloadsDerived::Func))
2686
.class_function("StaticFunc", select_overload<int(int,int,int)>(&MultipleOverloadsDerived::StaticFunc))
2687
.class_function("StaticFunc", select_overload<int(int,int,int,int)>(&MultipleOverloadsDerived::StaticFunc))
2688
;
2689
2690
class_<MultipleAccessors>("MultipleAccessors")
2691
.function("getConst", select_overload<int(int)const>(&MultipleAccessors::getConst))
2692
;
2693
2694
class_<ConstAndNonConst>("ConstAndNonConst")
2695
.function("method", select_const(&ConstAndNonConst::method))
2696
;
2697
2698
class_<DummyForOverloads>("DummyForOverloads").constructor();
2699
2700
class_<MultipleOverloadsDependingOnDummy>("MultipleOverloadsDependingOnDummy")
2701
.constructor()
2702
.function("dummy", select_overload<DummyForOverloads()>(&MultipleOverloadsDependingOnDummy::dummy))
2703
.function("dummy", select_overload<DummyForOverloads(DummyForOverloads)>(&MultipleOverloadsDependingOnDummy::dummy))
2704
.class_function("staticDummy", select_overload<DummyForOverloads()>(&MultipleOverloadsDependingOnDummy::staticDummy))
2705
.class_function("staticDummy", select_overload<DummyForOverloads(DummyForOverloads)>(&MultipleOverloadsDependingOnDummy::staticDummy))
2706
;
2707
2708
function("getDummy", select_overload<DummyForOverloads(void)>(&getDummy));
2709
function("getDummy", select_overload<DummyForOverloads(DummyForOverloads)>(&getDummy));
2710
}
2711
2712
// tests for out-of-order registration
2713
2714
class SecondElement {};
2715
2716
class FirstElement {};
2717
2718
struct OrderedTuple {
2719
FirstElement first;
2720
SecondElement second;
2721
};
2722
2723
struct OrderedStruct {
2724
FirstElement first;
2725
SecondElement second;
2726
};
2727
2728
OrderedTuple getOrderedTuple() {
2729
return OrderedTuple();
2730
}
2731
2732
OrderedStruct getOrderedStruct() {
2733
return OrderedStruct();
2734
}
2735
2736
EMSCRIPTEN_BINDINGS(order) {
2737
value_array<OrderedTuple>("OrderedTuple")
2738
.element(&OrderedTuple::first)
2739
.element(&OrderedTuple::second)
2740
;
2741
2742
value_object<OrderedStruct>("OrderedStruct")
2743
.field("first", &OrderedStruct::first)
2744
.field("second", &OrderedStruct::second)
2745
;
2746
2747
class_<SecondElement>("SecondElement")
2748
;
2749
2750
class_<FirstElement>("FirstElement")
2751
;
2752
2753
function("getOrderedTuple", &getOrderedTuple);
2754
function("getOrderedStruct", &getOrderedStruct);
2755
}
2756
2757
// tests for unbound types
2758
2759
template<typename T> T passThrough(T t) {
2760
return t;
2761
}
2762
2763
struct UnboundClass {};
2764
2765
struct HasUnboundBase : public UnboundClass {
2766
static void noop() {
2767
}
2768
};
2769
2770
HasUnboundBase getHasUnboundBase(HasUnboundBase f) {
2771
return f;
2772
}
2773
2774
struct HasConstructorUsingUnboundArgument {
2775
HasConstructorUsingUnboundArgument(UnboundClass) {
2776
}
2777
};
2778
2779
struct SecondUnboundClass {};
2780
2781
struct HasConstructorUsingUnboundArgumentAndUnboundBase
2782
: public SecondUnboundClass {
2783
HasConstructorUsingUnboundArgumentAndUnboundBase(UnboundClass) {
2784
}
2785
};
2786
2787
struct BoundClass {
2788
UnboundClass method(UnboundClass t) {
2789
return t;
2790
}
2791
2792
static UnboundClass classfunction(UnboundClass t) {
2793
return t;
2794
}
2795
2796
UnboundClass property;
2797
};
2798
2799
#ifndef SKIP_UNBOUND_TYPES
2800
EMSCRIPTEN_BINDINGS(incomplete) {
2801
constant("hasUnboundTypeNames", emscripten::has_unbound_type_names);
2802
2803
function("getUnboundClass", &passThrough<UnboundClass>);
2804
2805
class_<HasUnboundBase, base<UnboundClass>>("HasUnboundBase")
2806
.class_function("noop", &HasUnboundBase::noop)
2807
;
2808
function("getHasUnboundBase", &passThrough<HasUnboundBase>);
2809
2810
class_<HasConstructorUsingUnboundArgument>("HasConstructorUsingUnboundArgument")
2811
.constructor<UnboundClass>()
2812
;
2813
2814
class_<HasConstructorUsingUnboundArgumentAndUnboundBase, base<SecondUnboundClass>>("HasConstructorUsingUnboundArgumentAndUnboundBase")
2815
.constructor<UnboundClass>()
2816
;
2817
2818
class_<BoundClass>("BoundClass")
2819
.constructor<>()
2820
.function("method", &BoundClass::method)
2821
.class_function("classfunction", &BoundClass::classfunction)
2822
.property("property", &BoundClass::property)
2823
;
2824
}
2825
#endif
2826
2827
class Noncopyable {
2828
Noncopyable(const Noncopyable&) = delete;
2829
Noncopyable& operator=(const Noncopyable&) = delete;
2830
2831
public:
2832
Noncopyable() {
2833
}
2834
Noncopyable(Noncopyable&& other) {
2835
other.valid = false;
2836
}
2837
2838
std::string method() const {
2839
return "foo";
2840
}
2841
2842
bool valid = true;
2843
};
2844
2845
Noncopyable getNoncopyable() {
2846
return Noncopyable();
2847
}
2848
2849
EMSCRIPTEN_BINDINGS(noncopyable) {
2850
class_<Noncopyable>("Noncopyable")
2851
.constructor<>()
2852
.function("method", &Noncopyable::method)
2853
;
2854
2855
function("getNoncopyable", &getNoncopyable, return_value_policy::take_ownership());
2856
}
2857
2858
struct HasReadOnlyProperty {
2859
HasReadOnlyProperty(int i) : i(i) {
2860
}
2861
2862
const int i;
2863
};
2864
2865
EMSCRIPTEN_BINDINGS(read_only_properties) {
2866
class_<HasReadOnlyProperty>("HasReadOnlyProperty")
2867
.constructor<int>()
2868
.property("i", &HasReadOnlyProperty::i)
2869
;
2870
}
2871
2872
struct StaticConstIntStruct {
2873
static const int STATIC_CONST_INTEGER_VALUE_1;
2874
static const int STATIC_CONST_INTEGER_VALUE_1000;
2875
};
2876
2877
const int StaticConstIntStruct::STATIC_CONST_INTEGER_VALUE_1 = 1;
2878
const int StaticConstIntStruct::STATIC_CONST_INTEGER_VALUE_1000 = 1000;
2879
2880
EMSCRIPTEN_BINDINGS(constants) {
2881
constant("INT_CONSTANT", 10);
2882
2883
constant("STATIC_CONST_INTEGER_VALUE_1", StaticConstIntStruct::STATIC_CONST_INTEGER_VALUE_1);
2884
constant("STATIC_CONST_INTEGER_VALUE_1000", StaticConstIntStruct::STATIC_CONST_INTEGER_VALUE_1000);
2885
2886
constant("STRING_CONSTANT", std::string("some string"));
2887
2888
TupleVector tv(1, 2, 3, 4);
2889
constant("VALUE_ARRAY_CONSTANT", tv);
2890
2891
StructVector sv(1, 2, 3, 4);
2892
constant("VALUE_OBJECT_CONSTANT", sv);
2893
}
2894
2895
class DerivedWithOffset : public DummyDataToTestPointerAdjustment,
2896
public Base {};
2897
2898
std::shared_ptr<Base>
2899
return_Base_from_DerivedWithOffset(std::shared_ptr<DerivedWithOffset> ptr) {
2900
return ptr;
2901
}
2902
2903
EMSCRIPTEN_BINDINGS(with_adjustment) {
2904
class_<DerivedWithOffset, base<Base>>("DerivedWithOffset")
2905
.smart_ptr_constructor("shared_ptr<DerivedWithOffset>", &std::make_shared<DerivedWithOffset>)
2906
;
2907
2908
function("return_Base_from_DerivedWithOffset", &return_Base_from_DerivedWithOffset);
2909
}
2910
2911
void clear_StringHolder(StringHolder& sh) {
2912
sh.set("");
2913
}
2914
2915
EMSCRIPTEN_BINDINGS(references) {
2916
function("clear_StringHolder", &clear_StringHolder);
2917
}
2918
2919
StringHolder return_StringHolder_copy(val func) {
2920
return func.as<StringHolder>();
2921
}
2922
2923
StringHolder call_StringHolder_func(val func) {
2924
return func().as<StringHolder>();
2925
}
2926
2927
EMSCRIPTEN_BINDINGS(return_values) {
2928
function("return_StringHolder_copy", &return_StringHolder_copy);
2929
function("call_StringHolder_func", &call_StringHolder_func);
2930
}
2931
2932
struct Mixin {
2933
int get10() const {
2934
return 10;
2935
}
2936
};
2937
2938
template<typename ClassBinding>
2939
const ClassBinding& registerMixin(const ClassBinding& binding) {
2940
// need a wrapper for implicit conversion from DerivedWithMixin to Mixin
2941
struct Local {
2942
static int get10(const typename ClassBinding::class_type& self) {
2943
return self.get10();
2944
}
2945
};
2946
2947
return binding
2948
.function("get10", &Local::get10)
2949
;
2950
}
2951
2952
class DerivedWithMixin : public Base, public Mixin {
2953
};
2954
2955
EMSCRIPTEN_BINDINGS(mixins) {
2956
registerMixin(
2957
class_<DerivedWithMixin, base<Base>>("DerivedWithMixin")
2958
.constructor<>()
2959
);
2960
}
2961
2962
template<typename T> T val_as(const val& v) {
2963
return v.as<T>();
2964
}
2965
2966
EMSCRIPTEN_BINDINGS(val_as) {
2967
function("val_as_bool", &val_as<bool>);
2968
function("val_as_char", &val_as<char>);
2969
function("val_as_short", &val_as<short>);
2970
function("val_as_int", &val_as<int>);
2971
function("val_as_long", &val_as<long>);
2972
2973
function("val_as_float", &val_as<float>);
2974
function("val_as_double", &val_as<double>);
2975
2976
function("val_as_string", &val_as<std::string>);
2977
function("val_as_wstring", &val_as<std::wstring>);
2978
function("val_as_val", &val_as<val>);
2979
2980
function("val_as_value_object", &val_as<StructVector>);
2981
function("val_as_value_array", &val_as<TupleVector>);
2982
2983
function("val_as_enum", &val_as<Enum>);
2984
2985
// memory_view is always JS -> C++
2986
// function("val_as_memory_view", &val_as<memory_view>);
2987
}
2988
2989
val construct_with_6(val factory) {
2990
unsigned char a1 = 6;
2991
double a2 = -12.5;
2992
std::string a3("a3");
2993
StructVector a4(1, 2, 3, 4);
2994
EnumClass a5 = EnumClass::TWO;
2995
TupleVector a6(-1, -2, -3, -4);
2996
return factory.new_(a1, a2, a3, a4, a5, a6);
2997
}
2998
2999
val construct_with_memory_view(val factory) {
3000
static const char data[11] = "0123456789";
3001
return factory.new_(
3002
std::string("before"), typed_memory_view(10, data), std::string("after"));
3003
}
3004
3005
val construct_with_ints_and_float(val factory) {
3006
return factory.new_(65537, 4.0f, 65538);
3007
}
3008
3009
val construct_with_arguments_before_and_after_memory_growth() {
3010
auto out = val::array();
3011
out.set(0, val::global("Uint8Array").new_(5));
3012
force_memory_growth();
3013
out.set(1, val::global("Uint8Array").new_(5));
3014
return out;
3015
}
3016
3017
EMSCRIPTEN_BINDINGS(val_new_) {
3018
function("construct_with_6_arguments", &construct_with_6);
3019
function("construct_with_memory_view", &construct_with_memory_view);
3020
function("construct_with_ints_and_float", &construct_with_ints_and_float);
3021
function("construct_with_arguments_before_and_after_memory_growth",
3022
&construct_with_arguments_before_and_after_memory_growth);
3023
}
3024
3025
template<typename T> class intrusive_ptr {
3026
public:
3027
typedef T element_type;
3028
3029
intrusive_ptr(std::nullptr_t = nullptr) : px(nullptr) {
3030
}
3031
3032
template<typename U> explicit intrusive_ptr(U* px) : px(px) {
3033
addRef(px);
3034
}
3035
3036
intrusive_ptr(const intrusive_ptr& that) : px(that.px) {
3037
addRef(px);
3038
}
3039
3040
template<typename U>
3041
intrusive_ptr(const intrusive_ptr<U>& that) : px(that.get()) {
3042
addRef(px);
3043
}
3044
3045
intrusive_ptr& operator=(const intrusive_ptr& that) {
3046
reset(that.get());
3047
return *this;
3048
}
3049
3050
intrusive_ptr& operator=(intrusive_ptr&& that) {
3051
release(px);
3052
px = that.px;
3053
that.px = 0;
3054
return *this;
3055
}
3056
3057
template<typename U> intrusive_ptr& operator=(const intrusive_ptr<U>& that) {
3058
reset(that.get());
3059
return *this;
3060
}
3061
3062
template<typename U> intrusive_ptr& operator=(intrusive_ptr<U>&& that) {
3063
release(px);
3064
px = that.px;
3065
that.px = 0;
3066
return *this;
3067
}
3068
3069
~intrusive_ptr() {
3070
release(px);
3071
}
3072
3073
void reset(T* nx = nullptr) {
3074
addRef(nx);
3075
release(px);
3076
px = nx;
3077
}
3078
3079
T* get() const {
3080
return px;
3081
}
3082
3083
T& operator*() const {
3084
return *px;
3085
}
3086
3087
T* operator->() const {
3088
return px;
3089
}
3090
3091
explicit operator bool() const {
3092
return px != nullptr;
3093
}
3094
3095
void swap(intrusive_ptr& rhs) {
3096
std::swap(px, rhs.px);
3097
}
3098
3099
private:
3100
void addRef(T* px) {
3101
if (px) {
3102
++px->referenceCount;
3103
}
3104
}
3105
3106
void release(T* px) {
3107
if (px && --px->referenceCount == 0) {
3108
delete px;
3109
}
3110
}
3111
3112
T* px;
3113
3114
template<typename U> friend class intrusive_ptr;
3115
};
3116
3117
namespace emscripten {
3118
template<typename T> struct smart_ptr_trait<intrusive_ptr<T>> {
3119
typedef intrusive_ptr<T> pointer_type;
3120
typedef T element_type;
3121
3122
static sharing_policy get_sharing_policy() {
3123
return sharing_policy::INTRUSIVE;
3124
}
3125
3126
static T* get(const intrusive_ptr<T>& p) {
3127
return p.get();
3128
}
3129
3130
static intrusive_ptr<T> share(const intrusive_ptr<T>& r, T* ptr) {
3131
return intrusive_ptr<T>(ptr);
3132
}
3133
3134
static pointer_type* construct_null() {
3135
return new pointer_type;
3136
}
3137
};
3138
} // namespace emscripten
3139
3140
template<typename T> intrusive_ptr<T> make_intrusive_ptr() {
3141
return intrusive_ptr<T>(new T);
3142
}
3143
3144
struct IntrusiveClass {
3145
virtual ~IntrusiveClass() {}
3146
long referenceCount = 0;
3147
};
3148
3149
struct IntrusiveClassWrapper : public wrapper<IntrusiveClass> {
3150
EMSCRIPTEN_WRAPPER(IntrusiveClassWrapper);
3151
};
3152
3153
template<typename T> struct Holder {
3154
void set(const T& v) {
3155
value = v;
3156
}
3157
const T& get() const {
3158
return value;
3159
}
3160
T value;
3161
};
3162
3163
EMSCRIPTEN_BINDINGS(intrusive_pointers) {
3164
class_<IntrusiveClass>("IntrusiveClass")
3165
.smart_ptr_constructor("intrusive_ptr<IntrusiveClass>", &make_intrusive_ptr<IntrusiveClass>)
3166
.allow_subclass<IntrusiveClassWrapper, intrusive_ptr<IntrusiveClassWrapper>>("IntrusiveClassWrapper", "IntrusiveClassWrapperPtr")
3167
;
3168
3169
typedef Holder<intrusive_ptr<IntrusiveClass>> IntrusiveClassHolder;
3170
class_<IntrusiveClassHolder>("IntrusiveClassHolder")
3171
.constructor<>()
3172
.function("set", &IntrusiveClassHolder::set)
3173
.function("get", &IntrusiveClassHolder::get)
3174
;
3175
3176
function("passThroughIntrusiveClass", &passThrough<intrusive_ptr<IntrusiveClass>>);
3177
}
3178
3179
std::string getTypeOfVal(const val& v) {
3180
return v.typeOf().as<std::string>();
3181
}
3182
3183
EMSCRIPTEN_BINDINGS(typeOf) {
3184
function("getTypeOfVal", &getTypeOfVal);
3185
}
3186
3187
struct HasStaticMember {
3188
static const int c;
3189
static int v;
3190
};
3191
3192
const int HasStaticMember::c = 10;
3193
int HasStaticMember::v = 20;
3194
3195
EMSCRIPTEN_BINDINGS(static_member) {
3196
class_<HasStaticMember>("HasStaticMember")
3197
.class_property("c", &HasStaticMember::c)
3198
.class_property("v", &HasStaticMember::v)
3199
;
3200
}
3201
3202