~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-06-11 15:45:24 UTC
  • mfrom: (1.2.1) (2.1.1 experimental)
  • Revision ID: package-import@ubuntu.com-20130611154524-rppb3w6tixlegv4n
Tags: 1.4.7~20130611~a1eb425-1
* New snapshot release
* Upload to unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
    };
19
19
 
20
20
    namespace internal {
21
 
        typedef void (*GenericFunction)();
22
21
        typedef long GenericEnumValue;
23
22
 
24
23
        // Implemented in JavaScript.  Don't call these directly.
60
59
                TYPEID emvalType,
61
60
                const char* name);
62
61
 
 
62
            void _embind_register_memory_view(
 
63
                TYPEID memoryViewType,
 
64
                const char* name);
 
65
 
63
66
            void _embind_register_function(
64
67
                const char* name,
65
68
                unsigned argCount,
224
227
    struct allow_raw_pointer : public allow_raw_pointers {
225
228
    };
226
229
 
 
230
    ////////////////////////////////////////////////////////////////////////////////
 
231
    // select_overload and select_const
 
232
    ////////////////////////////////////////////////////////////////////////////////
 
233
 
227
234
    template<typename Signature>
228
235
    typename std::add_pointer<Signature>::type select_overload(typename std::add_pointer<Signature>::type fn) {
229
236
        return fn;
241
248
        return fn;
242
249
    }
243
250
 
 
251
    template<typename ClassType, typename ReturnType, typename... Args>
 
252
    auto select_const(ReturnType (ClassType::*method)(Args...) const) -> decltype(method) {
 
253
        return method;
 
254
    }
 
255
 
 
256
    ////////////////////////////////////////////////////////////////////////////////
 
257
    // Invoker
 
258
    ////////////////////////////////////////////////////////////////////////////////
 
259
 
244
260
    namespace internal {
245
261
        template<typename ReturnType, typename... Args>
246
262
        struct Invoker {
401
417
 
402
418
        // TODO: This could do a reinterpret-cast if sizeof(T) === sizeof(void*)
403
419
        template<typename T>
404
 
        inline void* getContext(const T& t) {
 
420
        inline T* getContext(const T& t) {
405
421
            // 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));
 
422
            T* p = reinterpret_cast<T*>(malloc(sizeof(T)));
 
423
            new(p) T(t);
409
424
            return p;
410
425
        }
411
426
 
736
751
 
737
752
        template<typename ReturnType, typename... Args>
738
753
        ReturnType call(const char* name, Args&&... args) const {
739
 
            return Caller<ReturnType, Args...>::call(wrapped, name, std::forward<Args>(args)...);
 
754
            return wrapped.call<ReturnType>(name, std::forward<Args>(args)...);
740
755
        }
741
756
 
742
757
        template<typename ReturnType, typename... Args, typename Default>
743
758
        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)...);
 
759
            if (wrapped.has_function(name)) {
 
760
                return call<ReturnType>(name, std::forward<Args>(args)...);
746
761
            } else {
747
762
                return def();
748
763
            }
749
764
        }
750
765
 
751
766
    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
767
        val wrapped;
772
768
    };
773
769
 
831
827
        }
832
828
    };
833
829
 
834
 
    template<typename PointerType>
835
 
    struct ptr {
836
 
        typedef PointerType pointer_type;
837
 
    };
838
 
 
839
830
    namespace internal {
840
831
        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
832
        struct SmartPtrIfNeeded {
852
833
            template<typename U>
853
834
            SmartPtrIfNeeded(U& cls) {
868
849
    public:
869
850
        class_() = delete;
870
851
 
871
 
        template<typename = typename std::enable_if<!internal::is_ptr<ClassType>::value>::type>
872
852
        explicit class_(const char* name) {
873
853
            using namespace internal;
874
854
 
914
894
                policies...);
915
895
        }
916
896
 
917
 
        template<typename... Args, typename... Policies>
918
 
        class_& constructor(ClassType* (*factory)(Args...), Policies...) {
 
897
        template<typename... Args, typename ReturnType, typename... Policies>
 
898
        class_& constructor(ReturnType (*factory)(Args...), Policies...) {
919
899
            using namespace internal;
920
900
 
921
 
            typename WithPolicies<Policies...>::template ArgTypeList<AllowedRawPointer<ClassType>, Args...> args;
 
901
            // TODO: allows all raw pointers... policies need a rethink
 
902
            typename WithPolicies<allow_raw_pointers, Policies...>::template ArgTypeList<ReturnType, Args...> args;
922
903
            _embind_register_class_constructor(
923
904
                TypeID<ClassType>::get(),
924
905
                args.count,
925
906
                args.types,
926
 
                reinterpret_cast<GenericFunction>(&Invoker<ClassType*, Args...>::invoke),
 
907
                reinterpret_cast<GenericFunction>(&Invoker<ReturnType, Args...>::invoke),
927
908
                reinterpret_cast<GenericFunction>(factory));
928
909
            return *this;
929
910
        }
1220
1201
            TypeID<const ConstantType&>::get(),
1221
1202
            asGenericValue(BindingType<const ConstantType&>::toWireType(v)));
1222
1203
    }
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
1204
}
1304
1205
 
1305
1206
#define EMSCRIPTEN_BINDINGS(name)                                       \
1306
 
    static struct BindingInitializer_##name {                           \
1307
 
        BindingInitializer_##name();                                    \
1308
 
    } BindingInitializer_##name##_instance;                             \
1309
 
    BindingInitializer_##name::BindingInitializer_##name()
 
1207
    static struct EmscriptenBindingInitializer_##name {                 \
 
1208
        EmscriptenBindingInitializer_##name();                          \
 
1209
    } EmscriptenBindingInitializer_##name##_instance;                   \
 
1210
    EmscriptenBindingInitializer_##name::EmscriptenBindingInitializer_##name()