-- Leo's gemini proxy
-- Connecting to git.thebackupbox.net:1965...
-- Connected
-- Sending request
-- Meta line: 20 text/gemini
repo: rxvt-unicode-sixel action: commit revision: path_from: revision_from: d2c3a6b3b5c4b2629b0a156d1a1cfac2e7158d09: path_to: revision_to:
commit d2c3a6b3b5c4b2629b0a156d1a1cfac2e7158d09 Author: Marc Lehmann <schmorp@schmorp.de> Date: Tue Dec 4 14:50:44 2007 +0000 experimental new callbacks, totally standards compliant, faster, smaller diff --git a/src/callback.h b/src/callback.h
--- a/src/callback.h +++ b/src/callback.h @@ -28,37 +28,50 @@ #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 @@ -67,52 +80,45 @@ public: } }; -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 @@ -121,52 +127,45 @@ public: } }; -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 @@ -175,52 +174,45 @@ public: } }; -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 @@ -229,52 +221,45 @@ public: } }; -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 @@ -283,52 +268,45 @@ public: } }; -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 @@ -337,52 +315,45 @@ public: } }; -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 @@ -391,52 +362,45 @@ public: } }; -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 @@ -445,52 +409,45 @@ public: } }; -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 @@ -499,52 +456,45 @@ public: } }; -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 @@ -553,52 +503,45 @@ public: } }; -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 @@ -607,38 +550,5 @@ public: } }; -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 diff --git a/src/main.C b/src/main.C
--- a/src/main.C +++ b/src/main.C @@ -155,15 +155,9 @@ int rxvt_composite_vec::expand (unicode_t c, wchar_t *r) rxvt_term::rxvt_term () : -#if ENABLE_TRANSPARENCY || ENABLE_PERL - rootwin_ev (this, &rxvt_term::rootwin_cb), -#endif #if HAVE_BG_PIXMAP update_background_ev(this, &rxvt_term::update_background_cb), #endif -#ifdef HAVE_SCROLLBARS - scrollbar_ev (this, &rxvt_term::x_cb), -#endif #ifdef CURSOR_BLINK cursor_blink_ev (this, &rxvt_term::cursor_blink_cb), #endif @@ -182,14 +176,9 @@ rxvt_term::rxvt_term () #ifdef POINTER_BLANK pointer_ev (this, &rxvt_term::pointer_cb), #endif -#ifdef USE_XIM - im_ev (this, &rxvt_term::im_cb), -#endif #ifndef NO_BELL bell_ev (this, &rxvt_term::bell_cb), #endif - termwin_ev (this, &rxvt_term::x_cb), - vt_ev (this, &rxvt_term::x_cb), child_ev (this, &rxvt_term::child_cb), prepare_ev (this, &rxvt_term::prepare_cb), flush_ev (this, &rxvt_term::flush_cb), @@ -197,6 +186,18 @@ rxvt_term::rxvt_term () pty_ev (this, &rxvt_term::pty_cb), incr_ev (this, &rxvt_term::incr_cb) { +#if ENABLE_TRANSPARENCY || ENABLE_PERL + callback_set (rootwin_ev , this, rxvt_term, rootwin_cb); +#endif +#ifdef HAVE_SCROLLBARS + callback_set (scrollbar_ev, this, rxvt_term, x_cb); +#endif +#ifdef USE_XIM + callback_set (im_ev , this, rxvt_term, im_cb); +#endif + callback_set (termwin_ev , this, rxvt_term, x_cb); + callback_set (vt_ev , this, rxvt_term, x_cb); + cmdbuf_ptr = cmdbuf_endp = cmdbuf_base; termlist.push_back (this); diff --git a/src/rxvtd.C b/src/rxvtd.C
--- a/src/rxvtd.C +++ b/src/rxvtd.C @@ -48,10 +48,10 @@ struct server : rxvt_connection { int getfd (int remote_fd); server (int fd) - : read_ev (this, &server::read_cb), - log_cb (this, &server::log_msg), - getfd_cb (this, &server::getfd) + : read_ev (this, &server::read_cb) { + callback_set (log_cb , this, server, log_msg); + callback_set (getfd_cb, this, server, getfd); this->fd = fd; fcntl (fd, F_SETFD, FD_CLOEXEC); fcntl (fd, F_SETFL, 0); diff --git a/src/rxvttoolkit.h b/src/rxvttoolkit.h
--- a/src/rxvttoolkit.h +++ b/src/rxvttoolkit.h @@ -258,11 +258,6 @@ struct rxvt_display : refcounted { #ifdef USE_XIM struct im_watcher : rxvt_watcher, callback<void (void)> { - template<class O, class M> - im_watcher (O object, M method) - : callback<void (void)> (object, method) - { } - void start (rxvt_display *display) { display->reg (this); @@ -278,11 +273,6 @@ struct im_watcher : rxvt_watcher, callback<void (void)> { struct xevent_watcher : rxvt_watcher, callback<void (XEvent &)> { Window window; - template<class O, class M> - xevent_watcher (O object, M method) - : callback<void (XEvent &)> (object, method) - { } - void start (rxvt_display *display, Window window) { this->window = window;
-----END OF PAGE-----
-- Response ended
-- Page fetched on Sun Jun 2 10:35:21 2024