Wiselib
|
00001 /* 00002 (c) Sergey Ryazanov (http://home.onego.ru/~ryazanov) 00003 00004 Template file. May be included many times with different predefined macros. 00005 */ 00006 #if SRUTIL_DELEGATE_PARAM_COUNT > 0 00007 #define SRUTIL_DELEGATE_SEPARATOR , 00008 #else 00009 #define SRUTIL_DELEGATE_SEPARATOR 00010 #endif 00011 00012 // see BOOST_JOIN for explanation 00013 #define SRUTIL_DELEGATE_JOIN_MACRO( X, Y) SRUTIL_DELEGATE_DO_JOIN( X, Y ) 00014 #define SRUTIL_DELEGATE_DO_JOIN( X, Y ) SRUTIL_DELEGATE_DO_JOIN2(X,Y) 00015 #define SRUTIL_DELEGATE_DO_JOIN2( X, Y ) X##Y 00016 00017 // namespace srutil 00018 // { 00019 #ifdef SRUTIL_DELEGATE_PREFERRED_SYNTAX 00020 #define SRUTIL_DELEGATE_CLASS_NAME delegate 00021 #define SRUTIL_DELEGATE_INVOKER_CLASS_NAME delegate_invoker 00022 #else 00023 #define SRUTIL_DELEGATE_CLASS_NAME SRUTIL_DELEGATE_JOIN_MACRO(delegate,SRUTIL_DELEGATE_PARAM_COUNT) 00024 #define SRUTIL_DELEGATE_INVOKER_CLASS_NAME SRUTIL_DELEGATE_JOIN_MACRO(delegate_invoker,SRUTIL_DELEGATE_PARAM_COUNT) 00025 template <typename R SRUTIL_DELEGATE_SEPARATOR SRUTIL_DELEGATE_TEMPLATE_PARAMS> 00026 class SRUTIL_DELEGATE_INVOKER_CLASS_NAME; 00027 #endif 00028 00029 template <typename R SRUTIL_DELEGATE_SEPARATOR SRUTIL_DELEGATE_TEMPLATE_PARAMS> 00030 #ifdef SRUTIL_DELEGATE_PREFERRED_SYNTAX 00031 class SRUTIL_DELEGATE_CLASS_NAME<R (SRUTIL_DELEGATE_TEMPLATE_ARGS)> 00032 #else 00033 class SRUTIL_DELEGATE_CLASS_NAME 00034 #endif 00035 { 00036 public: 00037 typedef R return_type; 00038 #ifdef SRUTIL_DELEGATE_PREFERRED_SYNTAX 00039 typedef return_type (SRUTIL_DELEGATE_CALLTYPE *signature_type)(SRUTIL_DELEGATE_TEMPLATE_ARGS); 00040 typedef SRUTIL_DELEGATE_INVOKER_CLASS_NAME<signature_type> invoker_type; 00041 #else 00042 typedef return_type (SRUTIL_DELEGATE_CALLTYPE *signature_type)(SRUTIL_DELEGATE_TEMPLATE_ARGS); 00043 typedef SRUTIL_DELEGATE_INVOKER_CLASS_NAME<R SRUTIL_DELEGATE_SEPARATOR SRUTIL_DELEGATE_TEMPLATE_ARGS> invoker_type; 00044 #endif 00045 00046 SRUTIL_DELEGATE_CLASS_NAME() 00047 : object_ptr(0) 00048 , stub_ptr(0) 00049 {} 00050 00051 template <return_type (*TMethod)(SRUTIL_DELEGATE_TEMPLATE_ARGS)> 00052 static SRUTIL_DELEGATE_CLASS_NAME from_function() 00053 { 00054 return from_stub(0, &function_stub<TMethod>); 00055 } 00056 00057 template <class T, return_type (T::*TMethod)(SRUTIL_DELEGATE_TEMPLATE_ARGS)> 00058 static SRUTIL_DELEGATE_CLASS_NAME from_method(T* object_ptr) 00059 { 00060 return from_stub(object_ptr, &method_stub<T, TMethod>); 00061 } 00062 00063 template <class T, return_type (T::*TMethod)(SRUTIL_DELEGATE_TEMPLATE_ARGS) const> 00064 static SRUTIL_DELEGATE_CLASS_NAME from_const_method(T const* object_ptr) 00065 { 00066 return from_stub(const_cast<T*>(object_ptr), &const_method_stub<T, TMethod>); 00067 } 00068 00069 return_type operator()(SRUTIL_DELEGATE_PARAMS) const 00070 { 00071 return (*stub_ptr)(object_ptr SRUTIL_DELEGATE_SEPARATOR SRUTIL_DELEGATE_ARGS); 00072 } 00073 00074 operator bool () const 00075 { 00076 return stub_ptr != 0; 00077 } 00078 00079 bool operator!() const 00080 { 00081 return !(operator bool()); 00082 } 00083 00084 void* obj_ptr() { return object_ptr; }; 00085 00086 private: 00087 00088 typedef return_type (SRUTIL_DELEGATE_CALLTYPE *stub_type)(void* object_ptr SRUTIL_DELEGATE_SEPARATOR SRUTIL_DELEGATE_PARAMS); 00089 00090 void* object_ptr; 00091 stub_type stub_ptr; 00092 00093 static SRUTIL_DELEGATE_CLASS_NAME from_stub(void* object_ptr, stub_type stub_ptr) 00094 { 00095 SRUTIL_DELEGATE_CLASS_NAME d; 00096 d.object_ptr = object_ptr; 00097 d.stub_ptr = stub_ptr; 00098 return d; 00099 } 00100 00101 template <return_type (*TMethod)(SRUTIL_DELEGATE_TEMPLATE_ARGS)> 00102 static return_type SRUTIL_DELEGATE_CALLTYPE function_stub(void* SRUTIL_DELEGATE_SEPARATOR SRUTIL_DELEGATE_PARAMS) 00103 { 00104 return (TMethod)(SRUTIL_DELEGATE_ARGS); 00105 } 00106 00107 template <class T, return_type (T::*TMethod)(SRUTIL_DELEGATE_TEMPLATE_ARGS)> 00108 static return_type SRUTIL_DELEGATE_CALLTYPE method_stub(void* object_ptr SRUTIL_DELEGATE_SEPARATOR SRUTIL_DELEGATE_PARAMS) 00109 { 00110 T* p = static_cast<T*>(object_ptr); 00111 return (p->*TMethod)(SRUTIL_DELEGATE_ARGS); 00112 } 00113 00114 template <class T, return_type (T::*TMethod)(SRUTIL_DELEGATE_TEMPLATE_ARGS) const> 00115 static return_type SRUTIL_DELEGATE_CALLTYPE const_method_stub(void* object_ptr SRUTIL_DELEGATE_SEPARATOR SRUTIL_DELEGATE_PARAMS) 00116 { 00117 T const* p = static_cast<T*>(object_ptr); 00118 return (p->*TMethod)(SRUTIL_DELEGATE_ARGS); 00119 } 00120 }; 00121 00122 template <typename R SRUTIL_DELEGATE_SEPARATOR SRUTIL_DELEGATE_TEMPLATE_PARAMS> 00123 #ifdef SRUTIL_DELEGATE_PREFERRED_SYNTAX 00124 class SRUTIL_DELEGATE_INVOKER_CLASS_NAME<R (SRUTIL_DELEGATE_TEMPLATE_ARGS)> 00125 #else 00126 class SRUTIL_DELEGATE_INVOKER_CLASS_NAME 00127 #endif 00128 { 00129 SRUTIL_DELEGATE_INVOKER_DATA 00130 00131 public: 00132 SRUTIL_DELEGATE_INVOKER_CLASS_NAME(SRUTIL_DELEGATE_PARAMS) 00133 #if SRUTIL_DELEGATE_PARAM_COUNT > 0 00134 : 00135 #endif 00136 SRUTIL_DELEGATE_INVOKER_INITIALIZATION_LIST 00137 { 00138 } 00139 00140 template <class TDelegate> 00141 R operator()(TDelegate d) const 00142 { 00143 return d(SRUTIL_DELEGATE_ARGS); 00144 } 00145 }; 00146 // } 00147 00148 #undef SRUTIL_DELEGATE_CLASS_NAME 00149 #undef SRUTIL_DELEGATE_SEPARATOR 00150 #undef SRUTIL_DELEGATE_JOIN_MACRO 00151 #undef SRUTIL_DELEGATE_DO_JOIN 00152 #undef SRUTIL_DELEGATE_DO_JOIN2