--- rxvt-unicode/src/callback.h 2006/05/31 00:32:56 1.8 +++ rxvt-unicode/src/callback.h 2007/12/02 01:07:29 1.9 @@ -4,7 +4,7 @@ /* callback.h -- C++ callback mechanism - Copyright (C) 2003-2006 Marc Lehmann + Copyright (C) 2003-2007 Marc Lehmann This file is part of GVPE. @@ -26,7 +26,7 @@ #ifndef CALLBACK_H__ #define CALLBACK_H__ -#define CALLBACK_H_VERSION 2 +#define CALLBACK_H_VERSION 3 template struct callback_funtype_trait; @@ -37,47 +37,34 @@ template class callback0 { - struct object { }; + struct klass; // it is vital that this is never defined - typedef R (object::*ptr_type)(); + typedef R (klass::*ptr_type)(); - void *obj; - R (object::*meth)(); - - /* a proxy is a kind of recipe on how to call a specific class method */ - struct proxy_base { - virtual R call (void *obj, R (object::*meth)()) const = 0; - }; - template - struct proxy : proxy_base { - virtual R call (void *obj, R (object::*meth)()) const - { - return (R)((reinterpret_cast(obj)) ->* (reinterpret_cast(meth))) - (); - } - }; - - proxy_base *prxy; + klass *o; + R (klass::*m)(); public: template explicit callback0 (O1 *object, R (O2::*method)()) - { - static proxy p; - obj = reinterpret_cast(object); - meth = reinterpret_cast(method); - prxy = &p; - } - + { + o = reinterpret_cast(object); + m = reinterpret_cast(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 - { - return prxy->call (obj, meth); - } + { + return (o->*m) (); + } R operator ()() const - { - return call (); - } + { + return call (); + } }; template @@ -104,47 +91,34 @@ template class callback1 { - struct object { }; - - typedef R (object::*ptr_type)(A1); - - void *obj; - R (object::*meth)(A1); + struct klass; // it is vital that this is never defined - /* a proxy is a kind of recipe on how to call a specific class method */ - struct proxy_base { - virtual R call (void *obj, R (object::*meth)(A1), A1 a1) const = 0; - }; - template - struct proxy : proxy_base { - virtual R call (void *obj, R (object::*meth)(A1), A1 a1) const - { - return (R)((reinterpret_cast(obj)) ->* (reinterpret_cast(meth))) - (a1); - } - }; + typedef R (klass::*ptr_type)(A1); - proxy_base *prxy; + klass *o; + R (klass::*m)(A1); public: template explicit callback1 (O1 *object, R (O2::*method)(A1)) - { - static proxy p; - obj = reinterpret_cast(object); - meth = reinterpret_cast(method); - prxy = &p; - } - + { + o = reinterpret_cast(object); + m = reinterpret_cast(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 - { - return prxy->call (obj, meth, a1); - } + { + return (o->*m) (a1); + } R operator ()(A1 a1) const - { - return call (a1); - } + { + return call (a1); + } }; template @@ -171,47 +145,34 @@ template class callback2 { - struct object { }; - - typedef R (object::*ptr_type)(A1, A2); + struct klass; // it is vital that this is never defined - void *obj; - R (object::*meth)(A1, A2); + typedef R (klass::*ptr_type)(A1, A2); - /* a proxy is a kind of recipe on how to call a specific class method */ - struct proxy_base { - virtual R call (void *obj, R (object::*meth)(A1, A2), A1 a1, A2 a2) const = 0; - }; - template - struct proxy : proxy_base { - virtual R call (void *obj, R (object::*meth)(A1, A2), A1 a1, A2 a2) const - { - return (R)((reinterpret_cast(obj)) ->* (reinterpret_cast(meth))) - (a1, a2); - } - }; - - proxy_base *prxy; + klass *o; + R (klass::*m)(A1, A2); public: template explicit callback2 (O1 *object, R (O2::*method)(A1, A2)) - { - static proxy p; - obj = reinterpret_cast(object); - meth = reinterpret_cast(method); - prxy = &p; - } - + { + o = reinterpret_cast(object); + m = reinterpret_cast(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 - { - return prxy->call (obj, meth, a1, a2); - } + { + return (o->*m) (a1, a2); + } R operator ()(A1 a1, A2 a2) const - { - return call (a1, a2); - } + { + return call (a1, a2); + } }; template @@ -238,47 +199,34 @@ template class callback3 { - struct object { }; + struct klass; // it is vital that this is never defined - typedef R (object::*ptr_type)(A1, A2, A3); + typedef R (klass::*ptr_type)(A1, A2, A3); - void *obj; - R (object::*meth)(A1, A2, A3); - - /* a proxy is a kind of recipe on how to call a specific class method */ - struct proxy_base { - virtual R call (void *obj, R (object::*meth)(A1, A2, A3), A1 a1, A2 a2, A3 a3) const = 0; - }; - template - struct proxy : proxy_base { - virtual R call (void *obj, R (object::*meth)(A1, A2, A3), A1 a1, A2 a2, A3 a3) const - { - return (R)((reinterpret_cast(obj)) ->* (reinterpret_cast(meth))) - (a1, a2, a3); - } - }; - - proxy_base *prxy; + klass *o; + R (klass::*m)(A1, A2, A3); public: template explicit callback3 (O1 *object, R (O2::*method)(A1, A2, A3)) - { - static proxy p; - obj = reinterpret_cast(object); - meth = reinterpret_cast(method); - prxy = &p; - } - + { + o = reinterpret_cast(object); + m = reinterpret_cast(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 - { - return prxy->call (obj, meth, a1, a2, a3); - } + { + return (o->*m) (a1, a2, a3); + } R operator ()(A1 a1, A2 a2, A3 a3) const - { - return call (a1, a2, a3); - } + { + return call (a1, a2, a3); + } }; template @@ -305,47 +253,34 @@ template class callback4 { - struct object { }; - - typedef R (object::*ptr_type)(A1, A2, A3, A4); + struct klass; // it is vital that this is never defined - void *obj; - R (object::*meth)(A1, A2, A3, A4); + typedef R (klass::*ptr_type)(A1, A2, A3, A4); - /* a proxy is a kind of recipe on how to call a specific class method */ - struct proxy_base { - virtual R call (void *obj, R (object::*meth)(A1, A2, A3, A4), A1 a1, A2 a2, A3 a3, A4 a4) const = 0; - }; - template - struct proxy : proxy_base { - virtual R call (void *obj, R (object::*meth)(A1, A2, A3, A4), A1 a1, A2 a2, A3 a3, A4 a4) const - { - return (R)((reinterpret_cast(obj)) ->* (reinterpret_cast(meth))) - (a1, a2, a3, a4); - } - }; - - proxy_base *prxy; + klass *o; + R (klass::*m)(A1, A2, A3, A4); public: template explicit callback4 (O1 *object, R (O2::*method)(A1, A2, A3, A4)) - { - static proxy p; - obj = reinterpret_cast(object); - meth = reinterpret_cast(method); - prxy = &p; - } - + { + o = reinterpret_cast(object); + m = reinterpret_cast(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 - { - return prxy->call (obj, meth, a1, a2, a3, a4); - } + { + return (o->*m) (a1, a2, a3, a4); + } R operator ()(A1 a1, A2 a2, A3 a3, A4 a4) const - { - return call (a1, a2, a3, a4); - } + { + return call (a1, a2, a3, a4); + } }; template @@ -372,47 +307,34 @@ template class callback5 { - struct object { }; - - typedef R (object::*ptr_type)(A1, A2, A3, A4, A5); - - void *obj; - R (object::*meth)(A1, A2, A3, A4, A5); + struct klass; // it is vital that this is never defined - /* a proxy is a kind of recipe on how to call a specific class method */ - struct proxy_base { - virtual R call (void *obj, R (object::*meth)(A1, A2, A3, A4, A5), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const = 0; - }; - template - struct proxy : proxy_base { - virtual R call (void *obj, R (object::*meth)(A1, A2, A3, A4, A5), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const - { - return (R)((reinterpret_cast(obj)) ->* (reinterpret_cast(meth))) - (a1, a2, a3, a4, a5); - } - }; + typedef R (klass::*ptr_type)(A1, A2, A3, A4, A5); - proxy_base *prxy; + klass *o; + R (klass::*m)(A1, A2, A3, A4, A5); public: template explicit callback5 (O1 *object, R (O2::*method)(A1, A2, A3, A4, A5)) - { - static proxy p; - obj = reinterpret_cast(object); - meth = reinterpret_cast(method); - prxy = &p; - } - + { + o = reinterpret_cast(object); + m = reinterpret_cast(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 - { - return prxy->call (obj, meth, a1, a2, a3, a4, a5); - } + { + return (o->*m) (a1, a2, a3, a4, a5); + } R operator ()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const - { - return call (a1, a2, a3, a4, a5); - } + { + return call (a1, a2, a3, a4, a5); + } }; template @@ -439,47 +361,34 @@ template class callback6 { - struct object { }; - - typedef R (object::*ptr_type)(A1, A2, A3, A4, A5, A6); + struct klass; // it is vital that this is never defined - void *obj; - R (object::*meth)(A1, A2, A3, A4, A5, A6); + typedef R (klass::*ptr_type)(A1, A2, A3, A4, A5, A6); - /* a proxy is a kind of recipe on how to call a specific class method */ - struct proxy_base { - virtual R call (void *obj, R (object::*meth)(A1, A2, A3, A4, A5, A6), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const = 0; - }; - template - struct proxy : proxy_base { - virtual R call (void *obj, R (object::*meth)(A1, A2, A3, A4, A5, A6), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const - { - return (R)((reinterpret_cast(obj)) ->* (reinterpret_cast(meth))) - (a1, a2, a3, a4, a5, a6); - } - }; - - proxy_base *prxy; + klass *o; + R (klass::*m)(A1, A2, A3, A4, A5, A6); public: template explicit callback6 (O1 *object, R (O2::*method)(A1, A2, A3, A4, A5, A6)) - { - static proxy p; - obj = reinterpret_cast(object); - meth = reinterpret_cast(method); - prxy = &p; - } - + { + o = reinterpret_cast(object); + m = reinterpret_cast(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 - { - return prxy->call (obj, meth, a1, a2, a3, a4, a5, a6); - } + { + return (o->*m) (a1, a2, a3, a4, a5, a6); + } R operator ()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const - { - return call (a1, a2, a3, a4, a5, a6); - } + { + return call (a1, a2, a3, a4, a5, a6); + } }; template @@ -506,47 +415,34 @@ template class callback7 { - struct object { }; + struct klass; // it is vital that this is never defined - typedef R (object::*ptr_type)(A1, A2, A3, A4, A5, A6, A7); + typedef R (klass::*ptr_type)(A1, A2, A3, A4, A5, A6, A7); - void *obj; - R (object::*meth)(A1, A2, A3, A4, A5, A6, A7); - - /* a proxy is a kind of recipe on how to call a specific class method */ - struct proxy_base { - virtual R call (void *obj, R (object::*meth)(A1, A2, A3, A4, A5, A6, A7), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const = 0; - }; - template - struct proxy : proxy_base { - virtual R call (void *obj, R (object::*meth)(A1, A2, A3, A4, A5, A6, A7), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const - { - return (R)((reinterpret_cast(obj)) ->* (reinterpret_cast(meth))) - (a1, a2, a3, a4, a5, a6, a7); - } - }; - - proxy_base *prxy; + klass *o; + R (klass::*m)(A1, A2, A3, A4, A5, A6, A7); public: template explicit callback7 (O1 *object, R (O2::*method)(A1, A2, A3, A4, A5, A6, A7)) - { - static proxy p; - obj = reinterpret_cast(object); - meth = reinterpret_cast(method); - prxy = &p; - } - + { + o = reinterpret_cast(object); + m = reinterpret_cast(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 - { - return prxy->call (obj, meth, a1, a2, a3, a4, a5, a6, a7); - } + { + return (o->*m) (a1, a2, a3, a4, a5, a6, a7); + } R operator ()(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const - { - return call (a1, a2, a3, a4, a5, a6, a7); - } + { + return call (a1, a2, a3, a4, a5, a6, a7); + } }; template @@ -573,47 +469,34 @@ template class callback8 { - struct object { }; - - typedef R (object::*ptr_type)(A1, A2, A3, A4, A5, A6, A7, A8); + struct klass; // it is vital that this is never defined - void *obj; - R (object::*meth)(A1, A2, A3, A4, A5, A6, A7, A8); + typedef R (klass::*ptr_type)(A1, A2, A3, A4, A5, A6, A7, A8); - /* a proxy is a kind of recipe on how to call a specific class method */ - struct proxy_base { - virtual R call (void *obj, R (object::*meth)(A1, A2, A3, A4, A5, A6, A7, A8), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const = 0; - }; - template - struct proxy : proxy_base { - virtual R call (void *obj, R (object::*meth)(A1, A2, A3, A4, A5, A6, A7, A8), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const - { - return (R)((reinterpret_cast(obj)) ->* (reinterpret_cast(meth))) - (a1, a2, a3, a4, a5, a6, a7, a8); - } - }; - - proxy_base *prxy; + klass *o; + R (klass::*m)(A1, A2, A3, A4, A5, A6, A7, A8); public: template explicit callback8 (O1 *object, R (O2::*method)(A1, A2, A3, A4, A5, A6, A7, A8)) - { - static proxy p; - obj = reinterpret_cast(object); - meth = reinterpret_cast(method); - prxy = &p; - } - + { + o = reinterpret_cast(object); + m = reinterpret_cast(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 - { - return prxy->call (obj, meth, a1, a2, a3, a4, a5, a6, a7, a8); - } + { + return (o->*m) (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 - { - return call (a1, a2, a3, a4, a5, a6, a7, a8); - } + { + return call (a1, a2, a3, a4, a5, a6, a7, a8); + } }; template @@ -640,47 +523,34 @@ template class callback9 { - struct object { }; - - typedef R (object::*ptr_type)(A1, A2, A3, A4, A5, A6, A7, A8, A9); - - void *obj; - R (object::*meth)(A1, A2, A3, A4, A5, A6, A7, A8, A9); + struct klass; // it is vital that this is never defined - /* a proxy is a kind of recipe on how to call a specific class method */ - struct proxy_base { - virtual R call (void *obj, R (object::*meth)(A1, A2, A3, A4, A5, A6, A7, A8, A9), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) const = 0; - }; - template - struct proxy : proxy_base { - virtual R call (void *obj, R (object::*meth)(A1, A2, A3, A4, A5, A6, A7, A8, A9), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) const - { - return (R)((reinterpret_cast(obj)) ->* (reinterpret_cast(meth))) - (a1, a2, a3, a4, a5, a6, a7, a8, a9); - } - }; + typedef R (klass::*ptr_type)(A1, A2, A3, A4, A5, A6, A7, A8, A9); - proxy_base *prxy; + klass *o; + R (klass::*m)(A1, A2, A3, A4, A5, A6, A7, A8, A9); public: template explicit callback9 (O1 *object, R (O2::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9)) - { - static proxy p; - obj = reinterpret_cast(object); - meth = reinterpret_cast(method); - prxy = &p; - } - + { + o = reinterpret_cast(object); + m = reinterpret_cast(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 - { - return prxy->call (obj, meth, a1, a2, a3, a4, a5, a6, a7, a8, a9); - } + { + return (o->*m) (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 - { - return call (a1, a2, a3, a4, a5, a6, a7, a8, a9); - } + { + return call (a1, a2, a3, a4, a5, a6, a7, a8, a9); + } }; template @@ -707,47 +577,34 @@ template class callback10 { - struct object { }; - - typedef R (object::*ptr_type)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); + struct klass; // it is vital that this is never defined - void *obj; - R (object::*meth)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); + typedef R (klass::*ptr_type)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); - /* a proxy is a kind of recipe on how to call a specific class method */ - struct proxy_base { - virtual R call (void *obj, R (object::*meth)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) const = 0; - }; - template - struct proxy : proxy_base { - virtual R call (void *obj, R (object::*meth)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10), A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10) const - { - return (R)((reinterpret_cast(obj)) ->* (reinterpret_cast(meth))) - (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); - } - }; - - proxy_base *prxy; + klass *o; + R (klass::*m)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); public: template explicit callback10 (O1 *object, R (O2::*method)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10)) - { - static proxy p; - obj = reinterpret_cast(object); - meth = reinterpret_cast(method); - prxy = &p; - } - + { + o = reinterpret_cast(object); + m = reinterpret_cast(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 - { - return prxy->call (obj, meth, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); - } + { + return (o->*m) (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 - { - return call (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); - } + { + return call (a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); + } }; template @@ -779,9 +636,9 @@ template explicit callback (O object, M method) - : base_type (object, method) - { - } + : base_type (object, method) + { + } }; #endif