#define CALLBACK_H_VERSION 3
-template<class signature>
-struct callback_funtype_trait;
+template<typename signature>
+struct callback;
-template<int arity, class signature>
-struct callback_get_impl;
+#define callback_set(callback,obj,klass,method) callback.set<klass, &klass::method> (obj)
template<class R>
-class callback0
+struct callback<R ()>
{
- struct klass; // it is vital that this is never defined
+ typedef R (*ptr_type)(void *self);
- typedef R (klass::*ptr_type)();
+private:
- klass *o;
- R (klass::*m)();
+ void *self;
+ ptr_type func;
+
+protected:
+
+ template<typename method>
+ struct thunktype;
+
+ template<class klass>
+ struct thunktype<R (klass::*)>
+ {
+ typedef klass K;
+ };
+
+ template<class klass, R (klass::*method)()>
+ static R thunk (void *self)
+ {
+ klass *obj = static_cast<klass *>(self);
+ return (obj->*method) ();
+ }
public:
- template<class O1, class O2>
- explicit callback0 (O1 *object, R (O2::*method)())
+ template<class K, R (K::*method)()>
+ void set (K *object)
{
- o = reinterpret_cast<klass *>(object);
- m = reinterpret_cast<R (klass::*)()>(method);
+ self = object;
+ func = thunk<K, method>;
}
- // this works because a standards-compliant C++ compiler
- // basically can't help it: it doesn't have the knowledge
- // required to miscompile (klass is not defined anywhere
- // and nothing is known about the constructor arguments) :)
- R call() const
+ R call () const
{
- return (o->*m) ();
+ return func (self);
}
R operator ()() const
}
};
-template<class R>
-struct callback_funtype_trait0
+template<class R, class A1>
+struct callback<R (A1)>
{
- static const int arity = 0;
- typedef R type (void);
- typedef R result_type;
-
-};
+ typedef R (*ptr_type)(void *self, A1);
-template<class R>
-struct callback_funtype_trait<R ()> : callback_funtype_trait0<R>
-{
-};
+private:
-template<class signature>
-struct callback_get_impl<0, signature>
-{
- typedef callback_funtype_trait<signature> T;
- typedef callback0<typename T::result_type> type;
-};
-
-template<class R, class A1>
-class callback1
-{
- struct klass; // it is vital that this is never defined
+ void *self;
+ ptr_type func;
- typedef R (klass::*ptr_type)(A1);
+protected:
- klass *o;
- R (klass::*m)(A1);
+ template<typename method>
+ struct thunktype;
+
+ template<class klass>
+ struct thunktype<R (klass::*)>
+ {
+ typedef klass K;
+ };
+
+ template<class klass, R (klass::*method)(A1)>
+ static R thunk (void *self, A1 a1)
+ {
+ klass *obj = static_cast<klass *>(self);
+ return (obj->*method) (a1);
+ }
public:
- template<class O1, class O2>
- explicit callback1 (O1 *object, R (O2::*method)(A1))
+ template<class K, R (K::*method)(A1)>
+ void set (K *object)
{
- o = reinterpret_cast<klass *>(object);
- m = reinterpret_cast<R (klass::*)(A1)>(method);
+ self = object;
+ func = thunk<K, method>;
}
- // this works because a standards-compliant C++ compiler
- // basically can't help it: it doesn't have the knowledge
- // required to miscompile (klass is not defined anywhere
- // and nothing is known about the constructor arguments) :)
- R call(A1 a1) const
+ R call (A1 a1) const
{
- return (o->*m) (a1);
+ return func (self, a1);
}
R operator ()(A1 a1) const
}
};
-template<class R, class A1>
-struct callback_funtype_trait1
+template<class R, class A1, class A2>
+struct callback<R (A1, A2)>
{
- static const int arity = 1;
- typedef R type (A1);
- typedef R result_type;
- typedef A1 arg1_type;
-};
+ typedef R (*ptr_type)(void *self, A1, A2);
-template<class R, class A1>
-struct callback_funtype_trait<R (A1)> : callback_funtype_trait1<R, A1>
-{
-};
+private:
-template<class signature>
-struct callback_get_impl<1, signature>
-{
- typedef callback_funtype_trait<signature> T;
- typedef callback1<typename T::result_type, typename T::arg1_type> type;
-};
-
-template<class R, class A1, class A2>
-class callback2
-{
- struct klass; // it is vital that this is never defined
+ void *self;
+ ptr_type func;
+
+protected:
- typedef R (klass::*ptr_type)(A1, A2);
+ template<typename method>
+ struct thunktype;
- klass *o;
- R (klass::*m)(A1, A2);
+ template<class klass>
+ struct thunktype<R (klass::*)>
+ {
+ typedef klass K;
+ };
+
+ template<class klass, R (klass::*method)(A1, A2)>
+ static R thunk (void *self, A1 a1, A2 a2)
+ {
+ klass *obj = static_cast<klass *>(self);
+ return (obj->*method) (a1, a2);
+ }
public:
- template<class O1, class O2>
- explicit callback2 (O1 *object, R (O2::*method)(A1, A2))
+ template<class K, R (K::*method)(A1, A2)>
+ void set (K *object)
{
- o = reinterpret_cast<klass *>(object);
- m = reinterpret_cast<R (klass::*)(A1, A2)>(method);
+ self = object;
+ func = thunk<K, method>;
}
- // this works because a standards-compliant C++ compiler
- // basically can't help it: it doesn't have the knowledge
- // required to miscompile (klass is not defined anywhere
- // and nothing is known about the constructor arguments) :)
- R call(A1 a1, A2 a2) const
+ R call (A1 a1, A2 a2) const
{
- return (o->*m) (a1, a2);
+ return func (self, a1, a2);
}
R operator ()(A1 a1, A2 a2) const
}
};
-template<class R, class A1, class A2>
-struct callback_funtype_trait2
+template<class R, class A1, class A2, class A3>
+struct callback<R (A1, A2, A3)>
{
- static const int arity = 2;
- typedef R type (A1, A2);
- typedef R result_type;
- typedef A1 arg1_type; typedef A2 arg2_type;
-};
+ typedef R (*ptr_type)(void *self, A1, A2, A3);
-template<class R, class A1, class A2>
-struct callback_funtype_trait<R (A1, A2)> : callback_funtype_trait2<R, A1, A2>
-{
-};
+private:
-template<class signature>
-struct callback_get_impl<2, signature>
-{
- typedef callback_funtype_trait<signature> T;
- typedef callback2<typename T::result_type, typename T::arg1_type, typename T::arg2_type> type;
-};
-
-template<class R, class A1, class A2, class A3>
-class callback3
-{
- struct klass; // it is vital that this is never defined
+ void *self;
+ ptr_type func;
- typedef R (klass::*ptr_type)(A1, A2, A3);
+protected:
- klass *o;
- R (klass::*m)(A1, A2, A3);
+ template<typename method>
+ struct thunktype;
+
+ template<class klass>
+ struct thunktype<R (klass::*)>
+ {
+ typedef klass K;
+ };
+
+ template<class klass, R (klass::*method)(A1, A2, A3)>
+ static R thunk (void *self, A1 a1, A2 a2, A3 a3)
+ {
+ klass *obj = static_cast<klass *>(self);
+ return (obj->*method) (a1, a2, a3);
+ }
public:
- template<class O1, class O2>
- explicit callback3 (O1 *object, R (O2::*method)(A1, A2, A3))
+ template<class K, R (K::*method)(A1, A2, A3)>
+ void set (K *object)
{
- o = reinterpret_cast<klass *>(object);
- m = reinterpret_cast<R (klass::*)(A1, A2, A3)>(method);
+ self = object;
+ func = thunk<K, method>;
}
- // this works because a standards-compliant C++ compiler
- // basically can't help it: it doesn't have the knowledge
- // required to miscompile (klass is not defined anywhere
- // and nothing is known about the constructor arguments) :)
- R call(A1 a1, A2 a2, A3 a3) const
+ R call (A1 a1, A2 a2, A3 a3) const
{
- return (o->*m) (a1, a2, a3);
+ return func (self, a1, a2, a3);
}
R operator ()(A1 a1, A2 a2, A3 a3) const
}
};
-template<class R, class A1, class A2, class A3>
-struct callback_funtype_trait3
+template<class R, class A1, class A2, class A3, class A4>
+struct callback<R (A1, A2, A3, A4)>
{
- static const int arity = 3;
- typedef R type (A1, A2, A3);
- typedef R result_type;
- typedef A1 arg1_type; typedef A2 arg2_type; typedef A3 arg3_type;
-};
+ typedef R (*ptr_type)(void *self, A1, A2, A3, A4);
-template<class R, class A1, class A2, class A3>
-struct callback_funtype_trait<R (A1, A2, A3)> : callback_funtype_trait3<R, A1, A2, A3>
-{
-};
+private:
-template<class signature>
-struct callback_get_impl<3, signature>
-{
- typedef callback_funtype_trait<signature> T;
- typedef callback3<typename T::result_type, typename T::arg1_type, typename T::arg2_type, typename T::arg3_type> type;
-};
-
-template<class R, class A1, class A2, class A3, class A4>
-class callback4
-{
- struct klass; // it is vital that this is never defined
+ void *self;
+ ptr_type func;
+
+protected:
- typedef R (klass::*ptr_type)(A1, A2, A3, A4);
+ template<typename method>
+ struct thunktype;
- klass *o;
- R (klass::*m)(A1, A2, A3, A4);
+ template<class klass>
+ struct thunktype<R (klass::*)>
+ {
+ typedef klass K;
+ };
+
+ template<class klass, R (klass::*method)(A1, A2, A3, A4)>
+ static R thunk (void *self, A1 a1, A2 a2, A3 a3, A4 a4)
+ {
+ klass *obj = static_cast<klass *>(self);
+ return (obj->*method) (a1, a2, a3, a4);
+ }
public:
- template<class O1, class O2>
- explicit callback4 (O1 *object, R (O2::*method)(A1, A2, A3, A4))
+ template<class K, R (K::*method)(A1, A2, A3, A4)>
+ void set (K *object)
{
- o = reinterpret_cast<klass *>(object);
- m = reinterpret_cast<R (klass::*)(A1, A2, A3, A4)>(method);
+ self = object;
+ func = thunk<K, method>;
}
- // this works because a standards-compliant C++ compiler
- // basically can't help it: it doesn't have the knowledge
- // required to miscompile (klass is not defined anywhere
- // and nothing is known about the constructor arguments) :)
- R call(A1 a1, A2 a2, A3 a3, A4 a4) const
+ R call (A1 a1, A2 a2, A3 a3, A4 a4) const
{
- return (o->*m) (a1, a2, a3, a4);
+ return func (self, a1, a2, a3, a4);
}
R operator ()(A1 a1, A2 a2, A3 a3, A4 a4) const
}
};
-template<class R, class A1, class A2, class A3, class A4>
-struct callback_funtype_trait4
+template<class R, class A1, class A2, class A3, class A4, class A5>
+struct callback<R (A1, A2, A3, A4, A5)>
{
- static const int arity = 4;
- typedef R type (A1, A2, A3, A4);
- typedef R result_type;
- typedef A1 arg1_type; typedef A2 arg2_type; typedef A3 arg3_type; typedef A4 arg4_type;
-};
+ typedef R (*ptr_type)(void *self, A1, A2, A3, A4, A5);
-template<class R, class A1, class A2, class A3, class A4>
-struct callback_funtype_trait<R (A1, A2, A3, A4)> : callback_funtype_trait4<R, A1, A2, A3, A4>
-{
-};
+private:
-template<class signature>
-struct callback_get_impl<4, signature>
-{
- typedef callback_funtype_trait<signature> T;
- typedef callback4<typename T::result_type, typename T::arg1_type, typename T::arg2_type, typename T::arg3_type, typename T::arg4_type> type;
-};
-
-template<class R, class A1, class A2, class A3, class A4, class A5>
-class callback5
-{
- struct klass; // it is vital that this is never defined
+ void *self;
+ ptr_type func;
- typedef R (klass::*ptr_type)(A1, A2, A3, A4, A5);
+protected:
- klass *o;
- R (klass::*m)(A1, A2, A3, A4, A5);
+ template<typename method>
+ struct thunktype;
+
+ template<class klass>
+ struct thunktype<R (klass::*)>
+ {
+ typedef klass K;
+ };
+
+ template<class klass, R (klass::*method)(A1, A2, A3, A4, A5)>
+ static R thunk (void *self, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
+ {
+ klass *obj = static_cast<klass *>(self);
+ return (obj->*method) (a1, a2, a3, a4, a5);
+ }
public:
- template<class O1, class O2>
- explicit callback5 (O1 *object, R (O2::*method)(A1, A2, A3, A4, A5))
+ template<class K, R (K::*method)(A1, A2, A3, A4, A5)>
+ void set (K *object)
{
- o = reinterpret_cast<klass *>(object);
- m = reinterpret_cast<R (klass::*)(A1, A2, A3, A4, A5)>(method);
+ self = object;
+ func = thunk<K, method>;
}
- // this works because a standards-compliant C++ compiler
- // basically can't help it: it doesn't have the knowledge
- // required to miscompile (klass is not defined anywhere
- // and nothing is known about the constructor arguments) :)
- R call(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const
+ R call (A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const
{
- return (o->*m) (a1, a2, a3, a4, a5);
+ return func (self, a1, a2, a3, a4, a5);
}
R operator ()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const
}
};
-template<class R, class A1, class A2, class A3, class A4, class A5>
-struct callback_funtype_trait5
+template<class R, class A1, class A2, class A3, class A4, class A5, class A6>
+struct callback<R (A1, A2, A3, A4, A5, A6)>
{
- static const int arity = 5;
- typedef R type (A1, A2, A3, A4, A5);
- typedef R result_type;
- typedef A1 arg1_type; typedef A2 arg2_type; typedef A3 arg3_type; typedef A4 arg4_type; typedef A5 arg5_type;
-};
+ typedef R (*ptr_type)(void *self, A1, A2, A3, A4, A5, A6);
-template<class R, class A1, class A2, class A3, class A4, class A5>
-struct callback_funtype_trait<R (A1, A2, A3, A4, A5)> : callback_funtype_trait5<R, A1, A2, A3, A4, A5>
-{
-};
+private:
-template<class signature>
-struct callback_get_impl<5, signature>
-{
- typedef callback_funtype_trait<signature> T;
- typedef callback5<typename T::result_type, typename T::arg1_type, typename T::arg2_type, typename T::arg3_type, typename T::arg4_type, typename T::arg5_type> type;
-};
-
-template<class R, class A1, class A2, class A3, class A4, class A5, class A6>
-class callback6
-{
- struct klass; // it is vital that this is never defined
+ void *self;
+ ptr_type func;
- typedef R (klass::*ptr_type)(A1, A2, A3, A4, A5, A6);
+protected:
- klass *o;
- R (klass::*m)(A1, A2, A3, A4, A5, A6);
+ template<typename method>
+ struct thunktype;
+
+ template<class klass>
+ struct thunktype<R (klass::*)>
+ {
+ typedef klass K;
+ };
+
+ template<class klass, R (klass::*method)(A1, A2, A3, A4, A5, A6)>
+ static R thunk (void *self, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
+ {
+ klass *obj = static_cast<klass *>(self);
+ return (obj->*method) (a1, a2, a3, a4, a5, a6);
+ }
public:
- template<class O1, class O2>
- explicit callback6 (O1 *object, R (O2::*method)(A1, A2, A3, A4, A5, A6))
+ template<class K, R (K::*method)(A1, A2, A3, A4, A5, A6)>
+ void set (K *object)
{
- o = reinterpret_cast<klass *>(object);
- m = reinterpret_cast<R (klass::*)(A1, A2, A3, A4, A5, A6)>(method);
+ self = object;
+ func = thunk<K, method>;
}
- // this works because a standards-compliant C++ compiler
- // basically can't help it: it doesn't have the knowledge
- // required to miscompile (klass is not defined anywhere
- // and nothing is known about the constructor arguments) :)
- R call(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const
+ R call (A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const
{
- return (o->*m) (a1, a2, a3, a4, a5, a6);
+ return func (self, a1, a2, a3, a4, a5, a6);
}
R operator ()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const
}
};
-template<class R, class A1, class A2, class A3, class A4, class A5, class A6>
-struct callback_funtype_trait6
+template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
+struct callback<R (A1, A2, A3, A4, A5, A6, A7)>
{
- static const int arity = 6;
- typedef R type (A1, A2, A3, A4, A5, A6);
- typedef R result_type;
- typedef A1 arg1_type; typedef A2 arg2_type; typedef A3 arg3_type; typedef A4 arg4_type; typedef A5 arg5_type; typedef A6 arg6_type;
-};
+ typedef R (*ptr_type)(void *self, A1, A2, A3, A4, A5, A6, A7);
-template<class R, class A1, class A2, class A3, class A4, class A5, class A6>
-struct callback_funtype_trait<R (A1, A2, A3, A4, A5, A6)> : callback_funtype_trait6<R, A1, A2, A3, A4, A5, A6>
-{
-};
+private:
-template<class signature>
-struct callback_get_impl<6, signature>
-{
- typedef callback_funtype_trait<signature> T;
- typedef callback6<typename T::result_type, typename T::arg1_type, typename T::arg2_type, typename T::arg3_type, typename T::arg4_type, typename T::arg5_type, typename T::arg6_type> type;
-};
-
-template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
-class callback7
-{
- struct klass; // it is vital that this is never defined
+ void *self;
+ ptr_type func;
- typedef R (klass::*ptr_type)(A1, A2, A3, A4, A5, A6, A7);
+protected:
- klass *o;
- R (klass::*m)(A1, A2, A3, A4, A5, A6, A7);
+ template<typename method>
+ struct thunktype;
+
+ template<class klass>
+ struct thunktype<R (klass::*)>
+ {
+ typedef klass K;
+ };
+
+ template<class klass, R (klass::*method)(A1, A2, A3, A4, A5, A6, A7)>
+ static R thunk (void *self, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
+ {
+ klass *obj = static_cast<klass *>(self);
+ return (obj->*method) (a1, a2, a3, a4, a5, a6, a7);
+ }
public:
- template<class O1, class O2>
- explicit callback7 (O1 *object, R (O2::*method)(A1, A2, A3, A4, A5, A6, A7))
+ template<class K, R (K::*method)(A1, A2, A3, A4, A5, A6, A7)>
+ void set (K *object)
{
- o = reinterpret_cast<klass *>(object);
- m = reinterpret_cast<R (klass::*)(A1, A2, A3, A4, A5, A6, A7)>(method);
+ self = object;
+ func = thunk<K, method>;
}
- // this works because a standards-compliant C++ compiler
- // basically can't help it: it doesn't have the knowledge
- // required to miscompile (klass is not defined anywhere
- // and nothing is known about the constructor arguments) :)
- R call(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const
+ R call (A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const
{
- return (o->*m) (a1, a2, a3, a4, a5, a6, a7);
+ return func (self, a1, a2, a3, a4, a5, a6, a7);
}
R operator ()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const
}
};
-template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
-struct callback_funtype_trait7
+template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
+struct callback<R (A1, A2, A3, A4, A5, A6, A7, A8)>
{
- static const int arity = 7;
- typedef R type (A1, A2, A3, A4, A5, A6, A7);
- typedef R result_type;
- typedef A1 arg1_type; typedef A2 arg2_type; typedef A3 arg3_type; typedef A4 arg4_type; typedef A5 arg5_type; typedef A6 arg6_type; typedef A7 arg7_type;
-};
+ typedef R (*ptr_type)(void *self, A1, A2, A3, A4, A5, A6, A7, A8);
-template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7>
-struct callback_funtype_trait<R (A1, A2, A3, A4, A5, A6, A7)> : callback_funtype_trait7<R, A1, A2, A3, A4, A5, A6, A7>
-{
-};
+private:
-template<class signature>
-struct callback_get_impl<7, signature>
-{
- typedef callback_funtype_trait<signature> T;
- typedef callback7<typename T::result_type, typename T::arg1_type, typename T::arg2_type, typename T::arg3_type, typename T::arg4_type, typename T::arg5_type, typename T::arg6_type, typename T::arg7_type> type;
-};
-
-template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
-class callback8
-{
- struct klass; // it is vital that this is never defined
+ void *self;
+ ptr_type func;
+
+protected:
- typedef R (klass::*ptr_type)(A1, A2, A3, A4, A5, A6, A7, A8);
+ template<typename method>
+ struct thunktype;
+
+ template<class klass>
+ struct thunktype<R (klass::*)>
+ {
+ typedef klass K;
+ };
- klass *o;
- R (klass::*m)(A1, A2, A3, A4, A5, A6, A7, A8);
+ template<class klass, R (klass::*method)(A1, A2, A3, A4, A5, A6, A7, A8)>
+ static R thunk (void *self, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
+ {
+ klass *obj = static_cast<klass *>(self);
+ return (obj->*method) (a1, a2, a3, a4, a5, a6, a7, a8);
+ }
public:
- template<class O1, class O2>
- explicit callback8 (O1 *object, R (O2::*method)(A1, A2, A3, A4, A5, A6, A7, A8))
+ template<class K, R (K::*method)(A1, A2, A3, A4, A5, A6, A7, A8)>
+ void set (K *object)
{
- o = reinterpret_cast<klass *>(object);
- m = reinterpret_cast<R (klass::*)(A1, A2, A3, A4, A5, A6, A7, A8)>(method);
+ self = object;
+ func = thunk<K, method>;
}
- // this works because a standards-compliant C++ compiler
- // basically can't help it: it doesn't have the knowledge
- // required to miscompile (klass is not defined anywhere
- // and nothing is known about the constructor arguments) :)
- R call(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const
+ R call (A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const
{
- return (o->*m) (a1, a2, a3, a4, a5, a6, a7, a8);
+ return func (self, a1, a2, a3, a4, a5, a6, a7, a8);
}
R operator ()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const
}
};
-template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
-struct callback_funtype_trait8
+template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
+struct callback<R (A1, A2, A3, A4, A5, A6, A7, A8, A9)>
{
- static const int arity = 8;
- typedef R type (A1, A2, A3, A4, A5, A6, A7, A8);
- typedef R result_type;
- typedef A1 arg1_type; typedef A2 arg2_type; typedef A3 arg3_type; typedef A4 arg4_type; typedef A5 arg5_type; typedef A6 arg6_type; typedef A7 arg7_type; typedef A8 arg8_type;
-};
+ typedef R (*ptr_type)(void *self, A1, A2, A3, A4, A5, A6, A7, A8, A9);
-template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8>
-struct callback_funtype_trait<R (A1, A2, A3, A4, A5, A6, A7, A8)> : callback_funtype_trait8<R, A1, A2, A3, A4, A5, A6, A7, A8>
-{
-};
+private:
-template<class signature>
-struct callback_get_impl<8, signature>
-{
- typedef callback_funtype_trait<signature> T;
- typedef callback8<typename T::result_type, typename T::arg1_type, typename T::arg2_type, typename T::arg3_type, typename T::arg4_type, typename T::arg5_type, typename T::arg6_type, typename T::arg7_type, typename T::arg8_type> type;
-};
-
-template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
-class callback9
-{
- struct klass; // it is vital that this is never defined
+ void *self;
+ ptr_type func;
+
+protected:
- typedef R (klass::*ptr_type)(A1, A2, A3, A4, A5, A6, A7, A8, A9);
+ template<typename method>
+ struct thunktype;
- klass *o;
- R (klass::*m)(A1, A2, A3, A4, A5, A6, A7, A8, A9);
+ template<class klass>
+ struct thunktype<R (klass::*)>
+ {
+ typedef klass K;
+ };
+
+ template<class klass, R (klass::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9)>
+ static R thunk (void *self, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
+ {
+ klass *obj = static_cast<klass *>(self);
+ return (obj->*method) (a1, a2, a3, a4, a5, a6, a7, a8, a9);
+ }
public:
- template<class O1, class O2>
- explicit callback9 (O1 *object, R (O2::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9))
+ template<class K, R (K::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9)>
+ void set (K *object)
{
- o = reinterpret_cast<klass *>(object);
- m = reinterpret_cast<R (klass::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9)>(method);
+ self = object;
+ func = thunk<K, method>;
}
- // this works because a standards-compliant C++ compiler
- // basically can't help it: it doesn't have the knowledge
- // required to miscompile (klass is not defined anywhere
- // and nothing is known about the constructor arguments) :)
- R call(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) const
+ R call (A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) const
{
- return (o->*m) (a1, a2, a3, a4, a5, a6, a7, a8, a9);
+ return func (self, a1, a2, a3, a4, a5, a6, a7, a8, a9);
}
R operator ()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) const
}
};
-template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
-struct callback_funtype_trait9
+template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
+struct callback<R (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)>
{
- static const int arity = 9;
- typedef R type (A1, A2, A3, A4, A5, A6, A7, A8, A9);
- typedef R result_type;
- typedef A1 arg1_type; typedef A2 arg2_type; typedef A3 arg3_type; typedef A4 arg4_type; typedef A5 arg5_type; typedef A6 arg6_type; typedef A7 arg7_type; typedef A8 arg8_type; typedef A9 arg9_type;
-};
+ typedef R (*ptr_type)(void *self, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
-template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9>
-struct callback_funtype_trait<R (A1, A2, A3, A4, A5, A6, A7, A8, A9)> : callback_funtype_trait9<R, A1, A2, A3, A4, A5, A6, A7, A8, A9>
-{
-};
+private:
-template<class signature>
-struct callback_get_impl<9, signature>
-{
- typedef callback_funtype_trait<signature> T;
- typedef callback9<typename T::result_type, typename T::arg1_type, typename T::arg2_type, typename T::arg3_type, typename T::arg4_type, typename T::arg5_type, typename T::arg6_type, typename T::arg7_type, typename T::arg8_type, typename T::arg9_type> type;
-};
-
-template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
-class callback10
-{
- struct klass; // it is vital that this is never defined
+ void *self;
+ ptr_type func;
- typedef R (klass::*ptr_type)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
+protected:
- klass *o;
- R (klass::*m)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
+ template<typename method>
+ struct thunktype;
+
+ template<class klass>
+ struct thunktype<R (klass::*)>
+ {
+ typedef klass K;
+ };
+
+ template<class klass, R (klass::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)>
+ static R thunk (void *self, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10)
+ {
+ klass *obj = static_cast<klass *>(self);
+ return (obj->*method) (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
+ }
public:
- template<class O1, class O2>
- explicit callback10 (O1 *object, R (O2::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10))
+ template<class K, R (K::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)>
+ void set (K *object)
{
- o = reinterpret_cast<klass *>(object);
- m = reinterpret_cast<R (klass::*)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)>(method);
+ self = object;
+ func = thunk<K, method>;
}
- // this works because a standards-compliant C++ compiler
- // basically can't help it: it doesn't have the knowledge
- // required to miscompile (klass is not defined anywhere
- // and nothing is known about the constructor arguments) :)
- R call(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) const
+ R call (A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) const
{
- return (o->*m) (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
+ return func (self, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
}
R operator ()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) const
}
};
-template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
-struct callback_funtype_trait10
-{
- static const int arity = 10;
- typedef R type (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10);
- typedef R result_type;
- typedef A1 arg1_type; typedef A2 arg2_type; typedef A3 arg3_type; typedef A4 arg4_type; typedef A5 arg5_type; typedef A6 arg6_type; typedef A7 arg7_type; typedef A8 arg8_type; typedef A9 arg9_type; typedef A10 arg10_type;
-};
-
-template<class R, class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9, class A10>
-struct callback_funtype_trait<R (A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)> : callback_funtype_trait10<R, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10>
-{
-};
-
-template<class signature>
-struct callback_get_impl<10, signature>
-{
- typedef callback_funtype_trait<signature> T;
- typedef callback10<typename T::result_type, typename T::arg1_type, typename T::arg2_type, typename T::arg3_type, typename T::arg4_type, typename T::arg5_type, typename T::arg6_type, typename T::arg7_type, typename T::arg8_type, typename T::arg9_type, typename T::arg10_type> type;
-};
-
-
-template<class signature>
-struct callback : callback_get_impl<callback_funtype_trait<signature>::arity, signature>::type
-{
- typedef typename callback_get_impl<callback_funtype_trait<signature>::arity, signature>::type base_type;
-
- template<class O, class M>
- explicit callback (O object, M method)
- : base_type (object, method)
- {
- }
-};
#endif