Wiselib
wiselib.stable/util/delegates/detail/delegate_template.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines