[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

delegate_template.hxx VIGRA

1 /*
2  (c) Sergey Ryazanov (http://home.onego.ru/~ryazanov)
3 
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
10 
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13 
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 THE SOFTWARE.
21 
22 For details, see "The Impossibly Fast C++ Delegates" at
23 http://www.codeproject.com/Articles/11015/The-Impossibly-Fast-C-Delegates
24 */
25 
26 #if VIGRA_DELEGATE_PARAM_COUNT > 0
27 #define VIGRA_DELEGATE_SEPARATOR ,
28 #else
29 #define VIGRA_DELEGATE_SEPARATOR
30 #endif
31 
32 // see BOOST_JOIN for explanation
33 #define VIGRA_DELEGATE_JOIN_MACRO( X, Y) VIGRA_DELEGATE_DO_JOIN( X, Y )
34 #define VIGRA_DELEGATE_DO_JOIN( X, Y ) VIGRA_DELEGATE_DO_JOIN2(X,Y)
35 #define VIGRA_DELEGATE_DO_JOIN2( X, Y ) X##Y
36 
37 namespace vigra
38 {
39 #ifdef VIGRA_DELEGATE_PREFERRED_SYNTAX
40 #define VIGRA_DELEGATE_CLASS_NAME delegate
41 #define VIGRA_DELEGATE_INVOKER_CLASS_NAME delegate_invoker
42 #else
43 #define VIGRA_DELEGATE_CLASS_NAME VIGRA_DELEGATE_JOIN_MACRO(delegate,VIGRA_DELEGATE_PARAM_COUNT)
44 #define VIGRA_DELEGATE_INVOKER_CLASS_NAME VIGRA_DELEGATE_JOIN_MACRO(delegate_invoker,VIGRA_DELEGATE_PARAM_COUNT)
45  template <typename R VIGRA_DELEGATE_SEPARATOR VIGRA_DELEGATE_TEMPLATE_PARAMS>
46  class VIGRA_DELEGATE_INVOKER_CLASS_NAME;
47 #endif
48 
49  template <typename R VIGRA_DELEGATE_SEPARATOR VIGRA_DELEGATE_TEMPLATE_PARAMS>
50 #ifdef VIGRA_DELEGATE_PREFERRED_SYNTAX
51  class VIGRA_DELEGATE_CLASS_NAME<R (VIGRA_DELEGATE_TEMPLATE_ARGS)>
52 #else
53  class VIGRA_DELEGATE_CLASS_NAME
54 #endif
55  {
56  public:
57  typedef R return_type;
58 #ifdef VIGRA_DELEGATE_PREFERRED_SYNTAX
59  typedef return_type (VIGRA_DELEGATE_CALLTYPE *signature_type)(VIGRA_DELEGATE_TEMPLATE_ARGS);
60  typedef VIGRA_DELEGATE_INVOKER_CLASS_NAME<signature_type> invoker_type;
61 #else
62  typedef VIGRA_DELEGATE_INVOKER_CLASS_NAME<R VIGRA_DELEGATE_SEPARATOR VIGRA_DELEGATE_TEMPLATE_ARGS> invoker_type;
63 #endif
64 
65  VIGRA_DELEGATE_CLASS_NAME()
66  : object_ptr(0)
67  , stub_ptr(0)
68  {}
69 
70  template <return_type (*TMethod)(VIGRA_DELEGATE_TEMPLATE_ARGS)>
71  static VIGRA_DELEGATE_CLASS_NAME from_function()
72  {
73  return from_stub(0, &function_stub<TMethod>);
74  }
75 
76  template <class T, return_type (T::*TMethod)(VIGRA_DELEGATE_TEMPLATE_ARGS)>
77  static VIGRA_DELEGATE_CLASS_NAME from_method(T* object_ptr)
78  {
79  return from_stub(object_ptr, &method_stub<T, TMethod>);
80  }
81 
82  template <class T, return_type (T::*TMethod)(VIGRA_DELEGATE_TEMPLATE_ARGS) const>
83  static VIGRA_DELEGATE_CLASS_NAME from_const_method(T const* object_ptr)
84  {
85  return from_stub(const_cast<T*>(object_ptr), &const_method_stub<T, TMethod>);
86  }
87 
88  return_type operator()(VIGRA_DELEGATE_PARAMS) const
89  {
90  return (*stub_ptr)(object_ptr VIGRA_DELEGATE_SEPARATOR VIGRA_DELEGATE_ARGS);
91  }
92 
93  operator bool () const
94  {
95  return stub_ptr != 0;
96  }
97 
98  bool operator!() const
99  {
100  return !(operator bool());
101  }
102 
103  private:
104 
105  typedef return_type (VIGRA_DELEGATE_CALLTYPE *stub_type)(void* object_ptr VIGRA_DELEGATE_SEPARATOR VIGRA_DELEGATE_PARAMS);
106 
107  void* object_ptr;
108  stub_type stub_ptr;
109 
110  static VIGRA_DELEGATE_CLASS_NAME from_stub(void* object_ptr, stub_type stub_ptr)
111  {
112  VIGRA_DELEGATE_CLASS_NAME d;
113  d.object_ptr = object_ptr;
114  d.stub_ptr = stub_ptr;
115  return d;
116  }
117 
118  template <return_type (*TMethod)(VIGRA_DELEGATE_TEMPLATE_ARGS)>
119  static return_type VIGRA_DELEGATE_CALLTYPE function_stub(void* VIGRA_DELEGATE_SEPARATOR VIGRA_DELEGATE_PARAMS)
120  {
121  return (TMethod)(VIGRA_DELEGATE_ARGS);
122  }
123 
124  template <class T, return_type (T::*TMethod)(VIGRA_DELEGATE_TEMPLATE_ARGS)>
125  static return_type VIGRA_DELEGATE_CALLTYPE method_stub(void* object_ptr VIGRA_DELEGATE_SEPARATOR VIGRA_DELEGATE_PARAMS)
126  {
127  T* p = static_cast<T*>(object_ptr);
128  return (p->*TMethod)(VIGRA_DELEGATE_ARGS);
129  }
130 
131  template <class T, return_type (T::*TMethod)(VIGRA_DELEGATE_TEMPLATE_ARGS) const>
132  static return_type VIGRA_DELEGATE_CALLTYPE const_method_stub(void* object_ptr VIGRA_DELEGATE_SEPARATOR VIGRA_DELEGATE_PARAMS)
133  {
134  T const* p = static_cast<T*>(object_ptr);
135  return (p->*TMethod)(VIGRA_DELEGATE_ARGS);
136  }
137  };
138 
139  template <typename R VIGRA_DELEGATE_SEPARATOR VIGRA_DELEGATE_TEMPLATE_PARAMS>
140 #ifdef VIGRA_DELEGATE_PREFERRED_SYNTAX
141  class VIGRA_DELEGATE_INVOKER_CLASS_NAME<R (VIGRA_DELEGATE_TEMPLATE_ARGS)>
142 #else
143  class VIGRA_DELEGATE_INVOKER_CLASS_NAME
144 #endif
145  {
146  VIGRA_DELEGATE_INVOKER_DATA
147 
148  public:
149  VIGRA_DELEGATE_INVOKER_CLASS_NAME(VIGRA_DELEGATE_PARAMS)
150 #if VIGRA_DELEGATE_PARAM_COUNT > 0
151  :
152 #endif
153  VIGRA_DELEGATE_INVOKER_INITIALIZATION_LIST
154  {
155  }
156 
157  template <class TDelegate>
158  R operator()(TDelegate d) const
159  {
160  return d(VIGRA_DELEGATE_ARGS);
161  }
162  };
163 }
164 
165 #undef VIGRA_DELEGATE_CLASS_NAME
166 #undef VIGRA_DELEGATE_SEPARATOR
167 #undef VIGRA_DELEGATE_JOIN_MACRO
168 #undef VIGRA_DELEGATE_DO_JOIN
169 #undef VIGRA_DELEGATE_DO_JOIN2

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.11.1 (Fri May 19 2017)