~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to system/include/emscripten/bind.h

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#pragma once
 
2
 
 
3
#include <stddef.h>
 
4
#include <assert.h>
 
5
#include <string>
 
6
#include <functional>
 
7
#include <vector>
 
8
#include <map>
 
9
#include <type_traits>
 
10
#include <emscripten/val.h>
 
11
#include <emscripten/wire.h>
 
12
 
 
13
namespace emscripten {
 
14
    enum class sharing_policy {
 
15
        NONE = 0,
 
16
        INTRUSIVE = 1,
 
17
        BY_EMVAL = 2,
 
18
    };
 
19
 
 
20
    namespace internal {
 
21
        typedef void (*GenericFunction)();
 
22
        typedef long GenericEnumValue;
 
23
 
 
24
        // Implemented in JavaScript.  Don't call these directly.
 
25
        extern "C" {
 
26
            void _embind_fatal_error(
 
27
                const char* name,
 
28
                const char* payload) __attribute__((noreturn));
 
29
 
 
30
            void _embind_register_void(
 
31
                TYPEID voidType,
 
32
                const char* name);
 
33
 
 
34
            void _embind_register_bool(
 
35
                TYPEID boolType,
 
36
                const char* name,
 
37
                bool trueValue,
 
38
                bool falseValue);
 
39
 
 
40
            void _embind_register_integer(
 
41
                TYPEID integerType,
 
42
                const char* name,
 
43
                long minRange,
 
44
                unsigned long maxRange);
 
45
 
 
46
            void _embind_register_float(
 
47
                TYPEID floatType,
 
48
                const char* name);
 
49
            
 
50
            void _embind_register_std_string(
 
51
                TYPEID stringType,
 
52
                const char* name);
 
53
 
 
54
            void _embind_register_std_wstring(
 
55
                TYPEID stringType,
 
56
                size_t charSize,
 
57
                const char* name);
 
58
 
 
59
            void _embind_register_emval(
 
60
                TYPEID emvalType,
 
61
                const char* name);
 
62
 
 
63
            void _embind_register_function(
 
64
                const char* name,
 
65
                unsigned argCount,
 
66
                TYPEID argTypes[],
 
67
                GenericFunction invoker,
 
68
                GenericFunction function);
 
69
 
 
70
            void _embind_register_tuple(
 
71
                TYPEID tupleType,
 
72
                const char* name,
 
73
                GenericFunction constructor,
 
74
                GenericFunction destructor);
 
75
            
 
76
            void _embind_register_tuple_element(
 
77
                TYPEID tupleType,
 
78
                TYPEID getterReturnType,
 
79
                GenericFunction getter,
 
80
                void* getterContext,
 
81
                TYPEID setterArgumentType,
 
82
                GenericFunction setter,
 
83
                void* setterContext);
 
84
 
 
85
            void _embind_finalize_tuple(TYPEID tupleType);
 
86
 
 
87
            void _embind_register_struct(
 
88
                TYPEID structType,
 
89
                const char* fieldName,
 
90
                GenericFunction constructor,
 
91
                GenericFunction destructor);
 
92
            
 
93
            void _embind_register_struct_field(
 
94
                TYPEID structType,
 
95
                const char* fieldName,
 
96
                TYPEID getterReturnType,
 
97
                GenericFunction getter,
 
98
                void* getterContext,
 
99
                TYPEID setterArgumentType,
 
100
                GenericFunction setter,
 
101
                void* setterContext);
 
102
 
 
103
            void _embind_finalize_struct(TYPEID structType);
 
104
 
 
105
            void _embind_register_smart_ptr(
 
106
                TYPEID pointerType,
 
107
                TYPEID pointeeType,
 
108
                const char* pointerName,
 
109
                sharing_policy sharingPolicy,
 
110
                GenericFunction getPointee,
 
111
                GenericFunction constructor,
 
112
                GenericFunction share,
 
113
                GenericFunction destructor);
 
114
 
 
115
            void _embind_register_class(
 
116
                TYPEID classType,
 
117
                TYPEID pointerType,
 
118
                TYPEID constPointerType,
 
119
                TYPEID baseClassType,
 
120
                GenericFunction getActualType,
 
121
                GenericFunction upcast,
 
122
                GenericFunction downcast,
 
123
                const char* className,
 
124
                GenericFunction destructor);
 
125
 
 
126
            void _embind_register_class_constructor(
 
127
                TYPEID classType,
 
128
                unsigned argCount,
 
129
                TYPEID argTypes[],
 
130
                GenericFunction invoker,
 
131
                GenericFunction constructor);
 
132
 
 
133
            void _embind_register_class_function(
 
134
                TYPEID classType,
 
135
                const char* methodName,
 
136
                unsigned argCount,
 
137
                TYPEID argTypes[],
 
138
                GenericFunction invoker,
 
139
                void* context);
 
140
 
 
141
            void _embind_register_class_property(
 
142
                TYPEID classType,
 
143
                const char* fieldName,
 
144
                TYPEID getterReturnType,
 
145
                GenericFunction getter,
 
146
                void* getterContext,
 
147
                TYPEID setterArgumentType,
 
148
                GenericFunction setter,
 
149
                void* setterContext);
 
150
 
 
151
            void _embind_register_class_class_function(
 
152
                TYPEID classType,
 
153
                const char* methodName,
 
154
                unsigned argCount,
 
155
                TYPEID argTypes[],
 
156
                GenericFunction invoker,
 
157
                GenericFunction method);
 
158
 
 
159
            void _embind_register_enum(
 
160
                TYPEID enumType,
 
161
                const char* name);
 
162
 
 
163
            void _embind_register_enum_value(
 
164
                TYPEID enumType,
 
165
                const char* valueName,
 
166
                GenericEnumValue value);
 
167
 
 
168
            void _embind_register_interface(
 
169
                TYPEID interfaceType,
 
170
                const char* name,
 
171
                GenericFunction constructor,
 
172
                GenericFunction destructor);
 
173
 
 
174
            void _embind_register_constant(
 
175
                const char* name,
 
176
                TYPEID constantType,
 
177
                uintptr_t value);
 
178
        }
 
179
    }
 
180
}
 
181
 
 
182
namespace emscripten {
 
183
    ////////////////////////////////////////////////////////////////////////////////
 
184
    // POLICIES
 
185
    ////////////////////////////////////////////////////////////////////////////////
 
186
 
 
187
    template<int Index>
 
188
    struct arg {
 
189
        static constexpr int index = Index + 1;
 
190
    };
 
191
 
 
192
    struct ret_val {
 
193
        static constexpr int index = 0;
 
194
    };
 
195
 
 
196
    /*
 
197
    template<typename Slot>
 
198
    struct allow_raw_pointer {
 
199
        template<typename InputType, int Index>
 
200
        struct Transform {
 
201
            typedef typename std::conditional<
 
202
                Index == Slot::index,
 
203
                internal::AllowedRawPointer<typename std::remove_pointer<InputType>::type>,
 
204
                InputType
 
205
            >::type type;
 
206
        };
 
207
    };
 
208
    */
 
209
 
 
210
    // whitelist all raw pointers
 
211
    struct allow_raw_pointers {
 
212
        template<typename InputType, int Index>
 
213
        struct Transform {
 
214
            typedef typename std::conditional<
 
215
                std::is_pointer<InputType>::value,
 
216
                internal::AllowedRawPointer<typename std::remove_pointer<InputType>::type>,
 
217
                InputType
 
218
            >::type type;
 
219
        };
 
220
    };
 
221
 
 
222
    // this is temporary until arg policies are reworked
 
223
    template<typename Slot>
 
224
    struct allow_raw_pointer : public allow_raw_pointers {
 
225
    };
 
226
 
 
227
    template<typename Signature>
 
228
    typename std::add_pointer<Signature>::type select_overload(typename std::add_pointer<Signature>::type fn) {
 
229
        return fn;
 
230
    }
 
231
 
 
232
    namespace internal {
 
233
        template<typename ClassType, typename Signature>
 
234
        struct MemberFunctionType {
 
235
            typedef Signature (ClassType::*type);
 
236
        };
 
237
    }
 
238
 
 
239
    template<typename Signature, typename ClassType>
 
240
    typename internal::MemberFunctionType<ClassType, Signature>::type select_overload(Signature (ClassType::*fn)) {
 
241
        return fn;
 
242
    }
 
243
 
 
244
    namespace internal {
 
245
        template<typename ReturnType, typename... Args>
 
246
        struct Invoker {
 
247
            static typename internal::BindingType<ReturnType>::WireType invoke(
 
248
                ReturnType (*fn)(Args...),
 
249
                typename internal::BindingType<Args>::WireType... args
 
250
            ) {
 
251
                return internal::BindingType<ReturnType>::toWireType(
 
252
                    fn(
 
253
                        internal::BindingType<Args>::fromWireType(args)...
 
254
                    )
 
255
                );
 
256
            }
 
257
        };
 
258
 
 
259
        template<typename... Args>
 
260
        struct Invoker<void, Args...> {
 
261
            static void invoke(
 
262
                void (*fn)(Args...),
 
263
                typename internal::BindingType<Args>::WireType... args
 
264
            ) {
 
265
                return fn(
 
266
                    internal::BindingType<Args>::fromWireType(args)...
 
267
                );
 
268
            }
 
269
        };
 
270
    }
 
271
 
 
272
    ////////////////////////////////////////////////////////////////////////////////
 
273
    // FUNCTIONS
 
274
    ////////////////////////////////////////////////////////////////////////////////
 
275
 
 
276
    extern "C" {
 
277
        void* __getDynamicPointerType(void* p);
 
278
    }
 
279
 
 
280
    template<typename ReturnType, typename... Args, typename... Policies>
 
281
    void function(const char* name, ReturnType (*fn)(Args...), Policies...) {
 
282
        using namespace internal;
 
283
        typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, Args...> args;
 
284
        _embind_register_function(
 
285
            name,
 
286
            args.count,
 
287
            args.types,
 
288
            reinterpret_cast<GenericFunction>(&Invoker<ReturnType, Args...>::invoke),
 
289
            reinterpret_cast<GenericFunction>(fn));
 
290
    }
 
291
 
 
292
    namespace internal {
 
293
        template<typename ClassType, typename... Args>
 
294
        ClassType* operator_new(Args... args) {
 
295
            return new ClassType(args...);
 
296
        }
 
297
 
 
298
        template<typename WrapperType, typename ClassType, typename... Args>
 
299
        WrapperType wrapped_new(Args&&... args) {
 
300
            return WrapperType(new ClassType(std::forward<Args>(args)...));
 
301
        }
 
302
 
 
303
        template<typename ClassType, typename... Args>
 
304
        ClassType* raw_constructor(
 
305
            typename internal::BindingType<Args>::WireType... args
 
306
        ) {
 
307
            return new ClassType(
 
308
                internal::BindingType<Args>::fromWireType(args)...
 
309
            );
 
310
        }
 
311
 
 
312
        template<typename ClassType>
 
313
        void raw_destructor(ClassType* ptr) {
 
314
            delete ptr;
 
315
        }
 
316
 
 
317
        template<typename FunctionPointerType, typename ReturnType, typename ThisType, typename... Args>
 
318
        struct FunctionInvoker {
 
319
            static typename internal::BindingType<ReturnType>::WireType invoke(
 
320
                FunctionPointerType* function,
 
321
                typename internal::BindingType<ThisType>::WireType wireThis,
 
322
                typename internal::BindingType<Args>::WireType... args
 
323
            ) {
 
324
                return internal::BindingType<ReturnType>::toWireType(
 
325
                    (*function)(
 
326
                        internal::BindingType<ThisType>::fromWireType(wireThis),
 
327
                        internal::BindingType<Args>::fromWireType(args)...)
 
328
                );
 
329
            }
 
330
        };
 
331
 
 
332
        template<typename FunctionPointerType, typename ThisType, typename... Args>
 
333
        struct FunctionInvoker<FunctionPointerType, void, ThisType, Args...> {
 
334
            static void invoke(
 
335
                FunctionPointerType* function,
 
336
                typename internal::BindingType<ThisType>::WireType wireThis,
 
337
                typename internal::BindingType<Args>::WireType... args
 
338
            ) {
 
339
                (*function)(
 
340
                    internal::BindingType<ThisType>::fromWireType(wireThis),
 
341
                    internal::BindingType<Args>::fromWireType(args)...);
 
342
            }
 
343
        };
 
344
 
 
345
        template<typename MemberPointer,
 
346
                 typename ReturnType,
 
347
                 typename ThisType,
 
348
                 typename... Args>
 
349
        struct MethodInvoker {
 
350
            static typename internal::BindingType<ReturnType>::WireType invoke(
 
351
                const MemberPointer& method,
 
352
                typename internal::BindingType<ThisType>::WireType wireThis,
 
353
                typename internal::BindingType<Args>::WireType... args
 
354
            ) {
 
355
                return internal::BindingType<ReturnType>::toWireType(
 
356
                    (internal::BindingType<ThisType>::fromWireType(wireThis)->*method)(
 
357
                        internal::BindingType<Args>::fromWireType(args)...
 
358
                    )
 
359
                );
 
360
            }
 
361
        };
 
362
 
 
363
        template<typename MemberPointer,
 
364
                 typename ThisType,
 
365
                 typename... Args>
 
366
        struct MethodInvoker<MemberPointer, void, ThisType, Args...> {
 
367
            static void invoke(
 
368
                const MemberPointer& method,
 
369
                typename internal::BindingType<ThisType>::WireType wireThis,
 
370
                typename internal::BindingType<Args>::WireType... args
 
371
            ) {
 
372
                return (internal::BindingType<ThisType>::fromWireType(wireThis)->*method)(
 
373
                    internal::BindingType<Args>::fromWireType(args)...
 
374
                );
 
375
            }
 
376
        };
 
377
 
 
378
        template<typename InstanceType, typename MemberType>
 
379
        struct MemberAccess {
 
380
            typedef MemberType InstanceType::*MemberPointer;
 
381
            typedef internal::BindingType<MemberType> MemberBinding;
 
382
            typedef typename MemberBinding::WireType WireType;
 
383
            
 
384
            template<typename ClassType>
 
385
            static WireType getWire(
 
386
                const MemberPointer& field,
 
387
                const ClassType& ptr
 
388
            ) {
 
389
                return MemberBinding::toWireType(ptr.*field);
 
390
            }
 
391
            
 
392
            template<typename ClassType>
 
393
            static void setWire(
 
394
                const MemberPointer& field,
 
395
                ClassType& ptr,
 
396
                WireType value
 
397
            ) {
 
398
                ptr.*field = MemberBinding::fromWireType(value);
 
399
            }
 
400
        };
 
401
 
 
402
        // TODO: This could do a reinterpret-cast if sizeof(T) === sizeof(void*)
 
403
        template<typename T>
 
404
        inline void* getContext(const T& t) {
 
405
            // not a leak because this is called once per binding
 
406
            void* p = malloc(sizeof(T));
 
407
            assert(p);
 
408
            memcpy(p, &t, sizeof(T));
 
409
            return p;
 
410
        }
 
411
 
 
412
        template<typename T>
 
413
        struct GetterPolicy;
 
414
 
 
415
        template<typename GetterReturnType, typename GetterThisType>
 
416
        struct GetterPolicy<GetterReturnType (GetterThisType::*)() const> {
 
417
            typedef GetterReturnType ReturnType;
 
418
            typedef GetterReturnType (GetterThisType::*Context)() const;
 
419
 
 
420
            typedef internal::BindingType<ReturnType> Binding;
 
421
            typedef typename Binding::WireType WireType;
 
422
 
 
423
            template<typename ClassType>
 
424
            static WireType get(const Context& context, const ClassType& ptr) {
 
425
                return Binding::toWireType((ptr.*context)());
 
426
            }
 
427
 
 
428
            static void* getContext(Context context) {
 
429
                return internal::getContext(context);
 
430
            }
 
431
        };
 
432
 
 
433
        template<typename GetterReturnType, typename GetterThisType>
 
434
        struct GetterPolicy<GetterReturnType (*)(const GetterThisType&)> {
 
435
            typedef GetterReturnType ReturnType;
 
436
            typedef GetterReturnType (*Context)(const GetterThisType&);
 
437
 
 
438
            typedef internal::BindingType<ReturnType> Binding;
 
439
            typedef typename Binding::WireType WireType;
 
440
 
 
441
            template<typename ClassType>
 
442
            static WireType get(const Context& context, const ClassType& ptr) {
 
443
                return Binding::toWireType(context(ptr));
 
444
            }
 
445
 
 
446
            static void* getContext(Context context) {
 
447
                return internal::getContext(context);
 
448
            }
 
449
        };
 
450
 
 
451
        template<typename T>
 
452
        struct SetterPolicy;
 
453
 
 
454
        template<typename SetterThisType, typename SetterArgumentType>
 
455
        struct SetterPolicy<void (SetterThisType::*)(SetterArgumentType)> {
 
456
            typedef SetterArgumentType ArgumentType;
 
457
            typedef void (SetterThisType::*Context)(SetterArgumentType);
 
458
 
 
459
            typedef internal::BindingType<SetterArgumentType> Binding;
 
460
            typedef typename Binding::WireType WireType;
 
461
 
 
462
            template<typename ClassType>
 
463
            static void set(const Context& context, ClassType& ptr, WireType wt) {
 
464
                (ptr.*context)(Binding::fromWireType(wt));
 
465
            }
 
466
 
 
467
            static void* getContext(Context context) {
 
468
                return internal::getContext(context);
 
469
            }
 
470
        };
 
471
 
 
472
        template<typename SetterThisType, typename SetterArgumentType>
 
473
        struct SetterPolicy<void (*)(SetterThisType&, SetterArgumentType)> {
 
474
            typedef SetterArgumentType ArgumentType;
 
475
            typedef void (*Context)(SetterThisType&, SetterArgumentType);
 
476
 
 
477
            typedef internal::BindingType<SetterArgumentType> Binding;
 
478
            typedef typename Binding::WireType WireType;
 
479
 
 
480
            template<typename ClassType>
 
481
            static void set(const Context& context, ClassType& ptr, WireType wt) {
 
482
                context(ptr, Binding::fromWireType(wt));
 
483
            }
 
484
 
 
485
            static void* getContext(Context context) {
 
486
                return internal::getContext(context);
 
487
            }
 
488
        };
 
489
 
 
490
        class noncopyable {
 
491
        protected:
 
492
            noncopyable() {}
 
493
            ~noncopyable() {}
 
494
        private:
 
495
            noncopyable(const noncopyable&) = delete;
 
496
            const noncopyable& operator=(const noncopyable&) = delete;
 
497
        };
 
498
 
 
499
        template<typename ClassType, typename ElementType>
 
500
        typename BindingType<ElementType>::WireType get_by_index(int index, ClassType& ptr) {
 
501
            return BindingType<ElementType>::toWireType(ptr[index]);
 
502
        }
 
503
 
 
504
        template<typename ClassType, typename ElementType>
 
505
        void set_by_index(int index, ClassType& ptr, typename BindingType<ElementType>::WireType wt) {
 
506
            ptr[index] = BindingType<ElementType>::fromWireType(wt);
 
507
        }
 
508
    }
 
509
 
 
510
    template<int Index>
 
511
    struct index {
 
512
    };
 
513
 
 
514
    ////////////////////////////////////////////////////////////////////////////////
 
515
    // VALUE TUPLES
 
516
    ////////////////////////////////////////////////////////////////////////////////
 
517
 
 
518
    template<typename ClassType>
 
519
    class value_tuple : public internal::noncopyable {
 
520
    public:
 
521
        value_tuple(const char* name) {
 
522
            using namespace internal;
 
523
            _embind_register_tuple(
 
524
                TypeID<ClassType>::get(),
 
525
                name,
 
526
                reinterpret_cast<GenericFunction>(&raw_constructor<ClassType>),
 
527
                reinterpret_cast<GenericFunction>(&raw_destructor<ClassType>));
 
528
        }
 
529
 
 
530
        ~value_tuple() {
 
531
            using namespace internal;
 
532
            _embind_finalize_tuple(TypeID<ClassType>::get());
 
533
        }
 
534
 
 
535
        template<typename InstanceType, typename ElementType>
 
536
        value_tuple& element(ElementType InstanceType::*field) {
 
537
            using namespace internal;
 
538
            _embind_register_tuple_element(
 
539
                TypeID<ClassType>::get(),
 
540
                TypeID<ElementType>::get(),
 
541
                reinterpret_cast<GenericFunction>(
 
542
                    &MemberAccess<InstanceType, ElementType>
 
543
                    ::template getWire<ClassType>),
 
544
                getContext(field),
 
545
                TypeID<ElementType>::get(),
 
546
                reinterpret_cast<GenericFunction>(
 
547
                    &MemberAccess<InstanceType, ElementType>
 
548
                    ::template setWire<ClassType>),
 
549
                getContext(field));
 
550
            return *this;
 
551
        }
 
552
 
 
553
        template<typename Getter, typename Setter>
 
554
        value_tuple& element(Getter getter, Setter setter) {
 
555
            using namespace internal;
 
556
            typedef GetterPolicy<Getter> GP;
 
557
            typedef SetterPolicy<Setter> SP;
 
558
            _embind_register_tuple_element(
 
559
                TypeID<ClassType>::get(),
 
560
                TypeID<typename GP::ReturnType>::get(),
 
561
                reinterpret_cast<GenericFunction>(&GP::template get<ClassType>),
 
562
                GP::getContext(getter),
 
563
                TypeID<typename SP::ArgumentType>::get(),
 
564
                reinterpret_cast<GenericFunction>(&SP::template set<ClassType>),
 
565
                SP::getContext(setter));
 
566
            return *this;
 
567
        }
 
568
 
 
569
        template<int Index>
 
570
        value_tuple& element(index<Index>) {
 
571
            using namespace internal;
 
572
            ClassType* null = 0;
 
573
            typedef typename std::remove_reference<decltype((*null)[Index])>::type ElementType;
 
574
            _embind_register_tuple_element(
 
575
                TypeID<ClassType>::get(),
 
576
                TypeID<ElementType>::get(),
 
577
                reinterpret_cast<GenericFunction>(&internal::get_by_index<ClassType, ElementType>),
 
578
                reinterpret_cast<void*>(Index),
 
579
                TypeID<ElementType>::get(),
 
580
                reinterpret_cast<GenericFunction>(&internal::set_by_index<ClassType, ElementType>),
 
581
                reinterpret_cast<void*>(Index));
 
582
            return *this;
 
583
        }
 
584
    };
 
585
 
 
586
    ////////////////////////////////////////////////////////////////////////////////
 
587
    // VALUE STRUCTS
 
588
    ////////////////////////////////////////////////////////////////////////////////
 
589
 
 
590
    template<typename ClassType>
 
591
    class value_struct : public internal::noncopyable {
 
592
    public:
 
593
        value_struct(const char* name) {
 
594
            using namespace internal;
 
595
            _embind_register_struct(
 
596
                TypeID<ClassType>::get(),
 
597
                name,
 
598
                reinterpret_cast<GenericFunction>(&raw_constructor<ClassType>),
 
599
                reinterpret_cast<GenericFunction>(&raw_destructor<ClassType>));
 
600
        }
 
601
 
 
602
        ~value_struct() {
 
603
            _embind_finalize_struct(internal::TypeID<ClassType>::get());
 
604
        }
 
605
 
 
606
        template<typename InstanceType, typename FieldType>
 
607
        value_struct& field(const char* fieldName, FieldType InstanceType::*field) {
 
608
            using namespace internal;
 
609
            _embind_register_struct_field(
 
610
                TypeID<ClassType>::get(),
 
611
                fieldName,
 
612
                TypeID<FieldType>::get(),
 
613
                reinterpret_cast<GenericFunction>(
 
614
                    &MemberAccess<InstanceType, FieldType>
 
615
                    ::template getWire<ClassType>),
 
616
                getContext(field),
 
617
                TypeID<FieldType>::get(),
 
618
                reinterpret_cast<GenericFunction>(
 
619
                    &MemberAccess<InstanceType, FieldType>
 
620
                    ::template setWire<ClassType>),
 
621
                getContext(field));
 
622
            return *this;
 
623
        }
 
624
    
 
625
        template<typename Getter, typename Setter>
 
626
        value_struct& field(
 
627
            const char* fieldName,
 
628
            Getter getter,
 
629
            Setter setter
 
630
        ) {
 
631
            using namespace internal;
 
632
            typedef GetterPolicy<Getter> GP;
 
633
            typedef SetterPolicy<Setter> SP;
 
634
            _embind_register_struct_field(
 
635
                TypeID<ClassType>::get(),
 
636
                fieldName,
 
637
                TypeID<typename GP::ReturnType>::get(),
 
638
                reinterpret_cast<GenericFunction>(&GP::template get<ClassType>),
 
639
                GP::getContext(getter),
 
640
                TypeID<typename SP::ArgumentType>::get(),
 
641
                reinterpret_cast<GenericFunction>(&SP::template set<ClassType>),
 
642
                SP::getContext(setter));
 
643
            return *this;
 
644
        }
 
645
 
 
646
        template<int Index>
 
647
        value_struct& field(const char* fieldName, index<Index>) {
 
648
            using namespace internal;
 
649
            ClassType* null = 0;
 
650
            typedef typename std::remove_reference<decltype((*null)[Index])>::type ElementType;
 
651
            _embind_register_struct_field(
 
652
                TypeID<ClassType>::get(),
 
653
                fieldName,
 
654
                TypeID<ElementType>::get(),
 
655
                reinterpret_cast<GenericFunction>(&internal::get_by_index<ClassType, ElementType>),
 
656
                reinterpret_cast<void*>(Index),
 
657
                TypeID<ElementType>::get(),
 
658
                reinterpret_cast<GenericFunction>(&internal::set_by_index<ClassType, ElementType>),
 
659
                reinterpret_cast<void*>(Index));
 
660
            return *this;
 
661
        }
 
662
    };
 
663
 
 
664
    ////////////////////////////////////////////////////////////////////////////////
 
665
    // SMART POINTERS
 
666
    ////////////////////////////////////////////////////////////////////////////////
 
667
 
 
668
    template<typename PointerType>
 
669
    struct default_smart_ptr_trait {
 
670
        static sharing_policy get_sharing_policy() {
 
671
            return sharing_policy::NONE;
 
672
        }
 
673
 
 
674
        static void* share(void* v) {
 
675
            return 0; // no sharing
 
676
        }
 
677
    };
 
678
 
 
679
    // specialize if you have a different pointer type
 
680
    template<typename PointerType>
 
681
    struct smart_ptr_trait : public default_smart_ptr_trait<PointerType> {
 
682
        typedef typename PointerType::element_type element_type;
 
683
 
 
684
        static element_type* get(const PointerType& ptr) {
 
685
            return ptr.get();
 
686
        }
 
687
    };
 
688
 
 
689
    template<typename PointeeType>
 
690
    struct smart_ptr_trait<std::shared_ptr<PointeeType>> {
 
691
        typedef std::shared_ptr<PointeeType> PointerType;
 
692
        typedef typename PointerType::element_type element_type;
 
693
 
 
694
        static element_type* get(const PointerType& ptr) {
 
695
            return ptr.get();
 
696
        }
 
697
 
 
698
        static sharing_policy get_sharing_policy() {
 
699
            return sharing_policy::BY_EMVAL;
 
700
        }
 
701
 
 
702
        static std::shared_ptr<PointeeType>* share(PointeeType* p, internal::EM_VAL v) {
 
703
            return new std::shared_ptr<PointeeType>(
 
704
                p,
 
705
                val_deleter(val::take_ownership(v)));
 
706
        }
 
707
 
 
708
    private:
 
709
        class val_deleter {
 
710
        public:
 
711
            val_deleter() = delete;
 
712
            explicit val_deleter(val v)
 
713
                : v(v)
 
714
            {}
 
715
            void operator()(void const*) {
 
716
                v();
 
717
                // eventually we'll need to support emptied out val
 
718
                v = val::undefined();
 
719
            }
 
720
        private:
 
721
            val v;
 
722
        };
 
723
    };
 
724
 
 
725
    ////////////////////////////////////////////////////////////////////////////////
 
726
    // CLASSES
 
727
    ////////////////////////////////////////////////////////////////////////////////
 
728
 
 
729
    // abstract classes
 
730
    template<typename T>
 
731
    class wrapper : public T {
 
732
    public:
 
733
        explicit wrapper(val&& wrapped)
 
734
            : wrapped(std::forward<val>(wrapped))
 
735
        {}
 
736
 
 
737
        template<typename ReturnType, typename... Args>
 
738
        ReturnType call(const char* name, Args&&... args) const {
 
739
            return Caller<ReturnType, Args...>::call(wrapped, name, std::forward<Args>(args)...);
 
740
        }
 
741
 
 
742
        template<typename ReturnType, typename... Args, typename Default>
 
743
        ReturnType optional_call(const char* name, Default def, Args&&... args) const {
 
744
            if (has_function(name)) {
 
745
                return Caller<ReturnType, Args...>::call(wrapped, name, std::forward<Args>(args)...);
 
746
            } else {
 
747
                return def();
 
748
            }
 
749
        }
 
750
 
 
751
    private:
 
752
        bool has_function(const char* name) const {
 
753
            return wrapped.has_function(name);
 
754
        }
 
755
 
 
756
        // this class only exists because you can't partially specialize function templates
 
757
        template<typename ReturnType, typename... Args>
 
758
        struct Caller {
 
759
            static ReturnType call(const val& v, const char* name, Args&&... args) {
 
760
                return v.call(name, std::forward<Args>(args)...).template as<ReturnType>();
 
761
            }
 
762
        };
 
763
 
 
764
        template<typename... Args>
 
765
        struct Caller<void, Args...> {
 
766
            static void call(const val& v, const char* name, Args&&... args) {
 
767
                v.call_void(name, std::forward<Args>(args)...);
 
768
            }
 
769
        };
 
770
 
 
771
        val wrapped;
 
772
    };
 
773
 
 
774
#define EMSCRIPTEN_WRAPPER(T) \
 
775
    T(::emscripten::val&& v): wrapper(std::forward<::emscripten::val>(v)) {}
 
776
 
 
777
    namespace internal {
 
778
        struct NoBaseClass {
 
779
            template<typename ClassType>
 
780
            static void verify() {
 
781
            }
 
782
 
 
783
            static TYPEID get() {
 
784
                return nullptr;
 
785
            }
 
786
 
 
787
            template<typename ClassType>
 
788
            static GenericFunction getUpcaster() {
 
789
                return nullptr;
 
790
            }
 
791
 
 
792
            template<typename ClassType>
 
793
            static GenericFunction getDowncaster() {
 
794
                return nullptr;
 
795
            }
 
796
        };
 
797
 
 
798
        // NOTE: this returns the class type, not the pointer type
 
799
        template<typename T>
 
800
        inline TYPEID getActualType(T* ptr) {
 
801
            assert(ptr);
 
802
            return reinterpret_cast<TYPEID>(&typeid(*ptr));
 
803
        };
 
804
    }
 
805
 
 
806
    template<typename BaseClass>
 
807
    struct base {
 
808
        template<typename ClassType>
 
809
        static void verify() {
 
810
            static_assert(!std::is_same<ClassType, BaseClass>::value, "Base must not have same type as class");
 
811
            static_assert(std::is_base_of<BaseClass, ClassType>::value, "Derived class must derive from base");
 
812
        }
 
813
 
 
814
        static internal::TYPEID get() {
 
815
            return internal::TypeID<BaseClass>::get();
 
816
        }
 
817
        
 
818
        template<typename ClassType>
 
819
        static internal::GenericFunction getUpcaster() {
 
820
            return reinterpret_cast<internal::GenericFunction>(&convertPointer<ClassType, BaseClass>);
 
821
        }
 
822
        
 
823
        template<typename ClassType>
 
824
        static internal::GenericFunction getDowncaster() {
 
825
            return reinterpret_cast<internal::GenericFunction>(&convertPointer<BaseClass, ClassType>);
 
826
        }
 
827
 
 
828
        template<typename From, typename To>
 
829
        static To* convertPointer(From* ptr) {
 
830
            return static_cast<To*>(ptr);
 
831
        }
 
832
    };
 
833
 
 
834
    template<typename PointerType>
 
835
    struct ptr {
 
836
        typedef PointerType pointer_type;
 
837
    };
 
838
 
 
839
    namespace internal {
 
840
        template<typename T>
 
841
        struct is_ptr {
 
842
            enum { value = false };
 
843
        };
 
844
 
 
845
        template<typename T>
 
846
        struct is_ptr<ptr<T>> {
 
847
            enum { value = true };
 
848
        };
 
849
 
 
850
        template<typename T>
 
851
        struct SmartPtrIfNeeded {
 
852
            template<typename U>
 
853
            SmartPtrIfNeeded(U& cls) {
 
854
                cls.template smart_ptr<T>();
 
855
            }
 
856
        };
 
857
 
 
858
        template<typename T>
 
859
        struct SmartPtrIfNeeded<T*> {
 
860
            template<typename U>
 
861
            SmartPtrIfNeeded(U&) {
 
862
            }
 
863
        };
 
864
    };
 
865
 
 
866
    template<typename ClassType, typename BaseSpecifier = internal::NoBaseClass>
 
867
    class class_ {
 
868
    public:
 
869
        class_() = delete;
 
870
 
 
871
        template<typename = typename std::enable_if<!internal::is_ptr<ClassType>::value>::type>
 
872
        explicit class_(const char* name) {
 
873
            using namespace internal;
 
874
 
 
875
            BaseSpecifier::template verify<ClassType>();
 
876
 
 
877
            _embind_register_class(
 
878
                TypeID<ClassType>::get(),
 
879
                TypeID<AllowedRawPointer<ClassType>>::get(),
 
880
                TypeID<AllowedRawPointer<const ClassType>>::get(),
 
881
                BaseSpecifier::get(),
 
882
                reinterpret_cast<GenericFunction>(&getActualType<ClassType>),
 
883
                BaseSpecifier::template getUpcaster<ClassType>(),
 
884
                BaseSpecifier::template getDowncaster<ClassType>(),
 
885
                name,
 
886
                reinterpret_cast<GenericFunction>(&raw_destructor<ClassType>));
 
887
        }
 
888
 
 
889
        template<typename PointerType>
 
890
        class_& smart_ptr() {
 
891
            using namespace internal;
 
892
 
 
893
            typedef smart_ptr_trait<PointerType> PointerTrait;
 
894
            typedef typename PointerTrait::element_type PointeeType;
 
895
            
 
896
            static_assert(std::is_same<ClassType, typename std::remove_cv<PointeeType>::type>::value, "smart pointer must point to this class");
 
897
 
 
898
            _embind_register_smart_ptr(
 
899
                TypeID<PointerType>::get(),
 
900
                TypeID<PointeeType>::get(),
 
901
                typeid(PointerType).name(),
 
902
                PointerTrait::get_sharing_policy(),
 
903
                reinterpret_cast<GenericFunction>(&PointerTrait::get),
 
904
                reinterpret_cast<GenericFunction>(&operator_new<PointerType>),
 
905
                reinterpret_cast<GenericFunction>(&PointerTrait::share),
 
906
                reinterpret_cast<GenericFunction>(&raw_destructor<PointerType>));
 
907
            return *this;
 
908
        };
 
909
 
 
910
        template<typename... ConstructorArgs, typename... Policies>
 
911
        class_& constructor(Policies... policies) {
 
912
            return constructor(
 
913
                &internal::operator_new<ClassType, ConstructorArgs...>,
 
914
                policies...);
 
915
        }
 
916
 
 
917
        template<typename... Args, typename... Policies>
 
918
        class_& constructor(ClassType* (*factory)(Args...), Policies...) {
 
919
            using namespace internal;
 
920
 
 
921
            typename WithPolicies<Policies...>::template ArgTypeList<AllowedRawPointer<ClassType>, Args...> args;
 
922
            _embind_register_class_constructor(
 
923
                TypeID<ClassType>::get(),
 
924
                args.count,
 
925
                args.types,
 
926
                reinterpret_cast<GenericFunction>(&Invoker<ClassType*, Args...>::invoke),
 
927
                reinterpret_cast<GenericFunction>(factory));
 
928
            return *this;
 
929
        }
 
930
 
 
931
        template<typename SmartPtr, typename... Args, typename... Policies>
 
932
        class_& smart_ptr_constructor(SmartPtr (*factory)(Args...), Policies...) {
 
933
            using namespace internal;
 
934
 
 
935
            smart_ptr<SmartPtr>();
 
936
 
 
937
            typename WithPolicies<Policies...>::template ArgTypeList<SmartPtr, Args...> args;
 
938
            _embind_register_class_constructor(
 
939
                TypeID<ClassType>::get(),
 
940
                args.count,
 
941
                args.types,
 
942
                reinterpret_cast<GenericFunction>(&Invoker<SmartPtr, Args...>::invoke),
 
943
                reinterpret_cast<GenericFunction>(factory));
 
944
            return *this;
 
945
        }
 
946
 
 
947
        template<typename WrapperType, typename PointerType = WrapperType*>
 
948
        class_& allow_subclass() {
 
949
            using namespace internal;
 
950
 
 
951
            auto cls = class_<WrapperType, base<ClassType>>(typeid(WrapperType).name())
 
952
                ;
 
953
            SmartPtrIfNeeded<PointerType> _(cls);
 
954
 
 
955
            return class_function(
 
956
                "implement",
 
957
                &wrapped_new<PointerType, WrapperType, val>,
 
958
                allow_raw_pointer<ret_val>());
 
959
        }
 
960
 
 
961
        template<typename ReturnType, typename... Args, typename... Policies>
 
962
        class_& function(const char* methodName, ReturnType (ClassType::*memberFunction)(Args...), Policies...) {
 
963
            using namespace internal;
 
964
 
 
965
            typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, AllowedRawPointer<ClassType>, Args...> args;
 
966
            _embind_register_class_function(
 
967
                TypeID<ClassType>::get(),
 
968
                methodName,
 
969
                args.count,
 
970
                args.types,
 
971
                reinterpret_cast<GenericFunction>(&MethodInvoker<decltype(memberFunction), ReturnType, ClassType*, Args...>::invoke),
 
972
                getContext(memberFunction));
 
973
            return *this;
 
974
        }
 
975
 
 
976
        template<typename ReturnType, typename... Args, typename... Policies>
 
977
        class_& function(const char* methodName, ReturnType (ClassType::*memberFunction)(Args...) const, Policies...) {
 
978
            using namespace internal;
 
979
 
 
980
            typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, AllowedRawPointer<const ClassType>, Args...> args;
 
981
            _embind_register_class_function(
 
982
                TypeID<ClassType>::get(),
 
983
                methodName,
 
984
                args.count,
 
985
                args.types,
 
986
                reinterpret_cast<GenericFunction>(&MethodInvoker<decltype(memberFunction), ReturnType, const ClassType*, Args...>::invoke),
 
987
                getContext(memberFunction));
 
988
            return *this;
 
989
        }
 
990
 
 
991
        template<typename ReturnType, typename ThisType, typename... Args, typename... Policies>
 
992
        class_& function(const char* methodName, ReturnType (*function)(ThisType, Args...), Policies...) {
 
993
            using namespace internal;
 
994
 
 
995
            typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, ThisType, Args...> args;
 
996
            _embind_register_class_function(
 
997
                TypeID<ClassType>::get(),
 
998
                methodName,
 
999
                args.count,
 
1000
                args.types,
 
1001
                reinterpret_cast<GenericFunction>(&FunctionInvoker<decltype(function), ReturnType, ThisType, Args...>::invoke),
 
1002
                getContext(function));
 
1003
            return *this;
 
1004
        }
 
1005
 
 
1006
        template<typename FieldType, typename = typename std::enable_if<!std::is_function<FieldType>::value>::type>
 
1007
        class_& property(const char* fieldName, const FieldType ClassType::*field) {
 
1008
            using namespace internal;
 
1009
 
 
1010
            _embind_register_class_property(
 
1011
                TypeID<ClassType>::get(),
 
1012
                fieldName,
 
1013
                TypeID<FieldType>::get(),
 
1014
                reinterpret_cast<GenericFunction>(&MemberAccess<ClassType, FieldType>::template getWire<ClassType>),
 
1015
                getContext(field),
 
1016
                0,
 
1017
                0,
 
1018
                0);
 
1019
            return *this;
 
1020
        }
 
1021
 
 
1022
        template<typename FieldType, typename = typename std::enable_if<!std::is_function<FieldType>::value>::type>
 
1023
        class_& property(const char* fieldName, FieldType ClassType::*field) {
 
1024
            using namespace internal;
 
1025
 
 
1026
            _embind_register_class_property(
 
1027
                TypeID<ClassType>::get(),
 
1028
                fieldName,
 
1029
                TypeID<FieldType>::get(),
 
1030
                reinterpret_cast<GenericFunction>(&MemberAccess<ClassType, FieldType>::template getWire<ClassType>),
 
1031
                getContext(field),
 
1032
                TypeID<FieldType>::get(),
 
1033
                reinterpret_cast<GenericFunction>(&MemberAccess<ClassType, FieldType>::template setWire<ClassType>),
 
1034
                getContext(field));
 
1035
            return *this;
 
1036
        }
 
1037
 
 
1038
        template<typename Getter>
 
1039
        class_& property(const char* fieldName, Getter getter) {
 
1040
            using namespace internal;
 
1041
            typedef GetterPolicy<Getter> GP;
 
1042
            _embind_register_class_property(
 
1043
                TypeID<ClassType>::get(),
 
1044
                fieldName,
 
1045
                TypeID<typename GP::ReturnType>::get(),
 
1046
                reinterpret_cast<GenericFunction>(&GP::template get<ClassType>),
 
1047
                GP::getContext(getter),
 
1048
                0,
 
1049
                0,
 
1050
                0);
 
1051
            return *this;
 
1052
        }
 
1053
 
 
1054
        template<typename Getter, typename Setter>
 
1055
        class_& property(const char* fieldName, Getter getter, Setter setter) {
 
1056
            using namespace internal;
 
1057
            typedef GetterPolicy<Getter> GP;
 
1058
            typedef SetterPolicy<Setter> SP;
 
1059
            _embind_register_class_property(
 
1060
                TypeID<ClassType>::get(),
 
1061
                fieldName,
 
1062
                TypeID<typename GP::ReturnType>::get(),
 
1063
                reinterpret_cast<GenericFunction>(&GP::template get<ClassType>),
 
1064
                GP::getContext(getter),
 
1065
                TypeID<typename SP::ArgumentType>::get(),
 
1066
                reinterpret_cast<GenericFunction>(&SP::template set<ClassType>),
 
1067
                SP::getContext(setter));
 
1068
            return *this;
 
1069
        }
 
1070
 
 
1071
        template<typename ReturnType, typename... Args, typename... Policies>
 
1072
        class_& class_function(const char* methodName, ReturnType (*classMethod)(Args...), Policies...) {
 
1073
            using namespace internal;
 
1074
 
 
1075
            typename WithPolicies<Policies...>::template ArgTypeList<ReturnType, Args...> args;
 
1076
            _embind_register_class_class_function(
 
1077
                TypeID<ClassType>::get(),
 
1078
                methodName,
 
1079
                args.count,
 
1080
                args.types,
 
1081
                reinterpret_cast<internal::GenericFunction>(&internal::Invoker<ReturnType, Args...>::invoke),
 
1082
                reinterpret_cast<GenericFunction>(classMethod));
 
1083
            return *this;
 
1084
        }
 
1085
    };
 
1086
 
 
1087
    ////////////////////////////////////////////////////////////////////////////////
 
1088
    // VECTORS
 
1089
    ////////////////////////////////////////////////////////////////////////////////
 
1090
 
 
1091
    namespace internal {
 
1092
        template<typename VectorType>
 
1093
        struct VectorAccess {
 
1094
            static val get(
 
1095
                const VectorType& v,
 
1096
                typename VectorType::size_type index
 
1097
            ) {
 
1098
                if (index < v.size()) {
 
1099
                    return val(v[index]);
 
1100
                } else {
 
1101
                    return val::undefined();
 
1102
                }
 
1103
            }
 
1104
 
 
1105
            static bool set(
 
1106
                VectorType& v,
 
1107
                typename VectorType::size_type index,
 
1108
                const typename VectorType::value_type& value
 
1109
            ) {
 
1110
                v[index] = value;
 
1111
                return true;
 
1112
            }
 
1113
        };
 
1114
    }
 
1115
 
 
1116
    template<typename T>
 
1117
    class_<std::vector<T>> register_vector(const char* name) {
 
1118
        typedef std::vector<T> VecType;
 
1119
 
 
1120
        void (VecType::*push_back)(const T&) = &VecType::push_back;
 
1121
        return class_<std::vector<T>>(name)
 
1122
            .template constructor<>()
 
1123
            .function("push_back", push_back)
 
1124
            .function("size", &VecType::size)
 
1125
            .function("get", &internal::VectorAccess<VecType>::get)
 
1126
            .function("set", &internal::VectorAccess<VecType>::set)
 
1127
            ;
 
1128
    }
 
1129
 
 
1130
    ////////////////////////////////////////////////////////////////////////////////
 
1131
    // MAPS
 
1132
    ////////////////////////////////////////////////////////////////////////////////
 
1133
 
 
1134
    namespace internal {
 
1135
        template<typename MapType>
 
1136
        struct MapAccess {
 
1137
            static val get(
 
1138
                const MapType& m,
 
1139
                const typename MapType::key_type& k
 
1140
            ) {
 
1141
                auto i = m.find(k);
 
1142
                if (i == m.end()) {
 
1143
                    return val::undefined();
 
1144
                } else {
 
1145
                    return val(i->second);
 
1146
                }
 
1147
            }
 
1148
 
 
1149
            static void set(
 
1150
                MapType& m,
 
1151
                const typename MapType::key_type& k,
 
1152
                const typename MapType::mapped_type& v
 
1153
            ) {
 
1154
                m[k] = v;
 
1155
            }
 
1156
        };
 
1157
    }
 
1158
 
 
1159
    template<typename K, typename V>
 
1160
    class_<std::map<K, V>> register_map(const char* name) {
 
1161
        typedef std::map<K,V> MapType;
 
1162
 
 
1163
        return class_<MapType>(name)
 
1164
            .template constructor<>()
 
1165
            .function("size", &MapType::size)
 
1166
            .function("get", internal::MapAccess<MapType>::get)
 
1167
            .function("set", internal::MapAccess<MapType>::set)
 
1168
            ;
 
1169
    }
 
1170
 
 
1171
 
 
1172
    ////////////////////////////////////////////////////////////////////////////////
 
1173
    // ENUMS
 
1174
    ////////////////////////////////////////////////////////////////////////////////
 
1175
 
 
1176
    template<typename EnumType>
 
1177
    class enum_ {
 
1178
    public:
 
1179
        enum_(const char* name) {
 
1180
            _embind_register_enum(
 
1181
                internal::TypeID<EnumType>::get(),
 
1182
                name);
 
1183
        }
 
1184
 
 
1185
        enum_& value(const char* name, EnumType value) {
 
1186
            // TODO: there's still an issue here.
 
1187
            // if EnumType is an unsigned long, then JS may receive it as a signed long
 
1188
            static_assert(sizeof(value) <= sizeof(internal::GenericEnumValue), "enum type must fit in a GenericEnumValue");
 
1189
 
 
1190
            _embind_register_enum_value(
 
1191
                internal::TypeID<EnumType>::get(),
 
1192
                name,
 
1193
                static_cast<internal::GenericEnumValue>(value));
 
1194
            return *this;
 
1195
        }
 
1196
    };
 
1197
 
 
1198
    ////////////////////////////////////////////////////////////////////////////////
 
1199
    // CONSTANTS
 
1200
    ////////////////////////////////////////////////////////////////////////////////
 
1201
 
 
1202
    namespace internal {
 
1203
        template<typename T>
 
1204
        uintptr_t asGenericValue(T t) {
 
1205
            return static_cast<uintptr_t>(t);
 
1206
        }
 
1207
 
 
1208
        template<typename T>
 
1209
        uintptr_t asGenericValue(T* p) {
 
1210
            return reinterpret_cast<uintptr_t>(p);
 
1211
        }
 
1212
    }
 
1213
 
 
1214
    template<typename ConstantType>
 
1215
    void constant(const char* name, const ConstantType& v) {
 
1216
        using namespace internal;
 
1217
        typedef BindingType<const ConstantType&> BT;
 
1218
        _embind_register_constant(
 
1219
            name,
 
1220
            TypeID<const ConstantType&>::get(),
 
1221
            asGenericValue(BindingType<const ConstantType&>::toWireType(v)));
 
1222
    }
 
1223
 
 
1224
    namespace internal {
 
1225
        template<typename T>
 
1226
        class optional {
 
1227
        public:            
 
1228
            optional()
 
1229
                : initialized(false)
 
1230
            {}
 
1231
 
 
1232
            ~optional() {
 
1233
                if (initialized) {
 
1234
                    get()->~T();
 
1235
                }
 
1236
            }
 
1237
 
 
1238
            optional(const optional& rhs)
 
1239
                : initialized(false)
 
1240
            {
 
1241
                *this = rhs;
 
1242
            }
 
1243
 
 
1244
            T& operator*() {
 
1245
                assert(initialized);
 
1246
                return *get();
 
1247
            }
 
1248
 
 
1249
            const T& operator*() const {
 
1250
                assert(initialized);
 
1251
                return *get();
 
1252
            }
 
1253
 
 
1254
            explicit operator bool() const {
 
1255
                return initialized;
 
1256
            }
 
1257
 
 
1258
            optional& operator=(const T& v) {
 
1259
                if (initialized) {
 
1260
                    get()->~T();
 
1261
                }
 
1262
                new(get()) T(v);
 
1263
                initialized = true;
 
1264
                return *this;
 
1265
            }
 
1266
 
 
1267
            optional& operator=(const optional& o) {
 
1268
                if (initialized) {
 
1269
                    get()->~T();
 
1270
                }
 
1271
                if (o.initialized) {
 
1272
                    new(get()) T(*o);
 
1273
                }
 
1274
                initialized = o.initialized;
 
1275
                return *this;
 
1276
            }
 
1277
 
 
1278
        private:
 
1279
            T* get() {
 
1280
                return reinterpret_cast<T*>(&data);
 
1281
            }
 
1282
 
 
1283
            T const* get() const {
 
1284
                return reinterpret_cast<T const*>(&data);
 
1285
            }
 
1286
 
 
1287
            bool initialized;
 
1288
            typename std::aligned_storage<sizeof(T)>::type data;
 
1289
        };
 
1290
    }
 
1291
}
 
1292
 
 
1293
namespace emscripten {
 
1294
    namespace internal {
 
1295
        class BindingsDefinition {
 
1296
        public:
 
1297
            template<typename Function>
 
1298
            BindingsDefinition(Function fn) {
 
1299
                fn();
 
1300
            }
 
1301
        };
 
1302
    }
 
1303
}
 
1304
 
 
1305
#define EMSCRIPTEN_BINDINGS(name)                                       \
 
1306
    static struct BindingInitializer_##name {                           \
 
1307
        BindingInitializer_##name();                                    \
 
1308
    } BindingInitializer_##name##_instance;                             \
 
1309
    BindingInitializer_##name::BindingInitializer_##name()