CppCMS
callback.h
1 //
2 // Copyright (C) 2009-2012 Artyom Beilis (Tonkikh)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See
5 // accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 //
8 #ifndef BOOSTER_CALLBACK_H
9 #define BOOSTER_CALLBACK_H
10 
11 #include <booster/backtrace.h>
12 #include <booster/auto_ptr_inc.h>
13 #include <booster/intrusive_ptr.h>
14 #include <booster/refcounted.h>
15 
16 namespace booster {
17  template<typename Type>
18  class callback;
19 
20  template<typename Type>
21  struct callable;
22 
28  public:
30  booster::runtime_error("bad_callback_call")
31  {
32  }
33  };
34 
35 
36  #ifdef BOOSTER_DOXYGEN_DOCS
37  template<typename Result,typename ...Params>
55  class callback<Result(Params...)>
56  {
57  public:
66  typedef Result result_type;
70  callback();
75  template<typename F>
76  callback(F func);
77 
81  callback(callback const &other);
82 
87  template<typename F>
88  callback const &operator=(F func);
89 
93  callback const &operator=(callback const &other);
94 
98  result_type operator()(Params... params) const;
102  bool empty() const;
106  operator bool() const;
107 
111  void swap(callback &other);
116  pointer_type const &get_pointer() const;
121  pointer_type &get_pointer();
122  };
123 
124  #else
125 
126  #define BOOSTER_CALLBACK \
127  template<typename Result BOOSTER_TEMPLATE_PARAMS > \
128  struct callable<Result(BOOSTER_TEMPLATE_TYPE_PARAMS)> :public refcounted\
129  { \
130  virtual Result operator()(BOOSTER_TYPE_PARAMS) = 0; \
131  virtual ~callable(){} \
132  }; \
133  \
134  template<typename Result BOOSTER_TEMPLATE_PARAMS > \
135  class callback<Result(BOOSTER_TEMPLATE_TYPE_PARAMS)> \
136  { \
137  public: \
138  typedef Result result_type; \
139  \
140  typedef callable<Result(BOOSTER_TEMPLATE_TYPE_PARAMS)> \
141  callable_type; \
142  typedef intrusive_ptr<callable_type> pointer_type; \
143  \
144  template<typename R,typename F> \
145  struct callable_impl : public callable_type { \
146  F func; \
147  callable_impl(F f) : func(f){} \
148  virtual R operator()(BOOSTER_TYPE_PARAMS) \
149  { return func(BOOSTER_CALL_PARAMS); } \
150  }; \
151  \
152  template<typename F> \
153  struct callable_impl<void,F> : public callable_type { \
154  F func; \
155  callable_impl(F f) : func(f){} \
156  virtual void operator()(BOOSTER_TYPE_PARAMS) \
157  { func(BOOSTER_CALL_PARAMS); } \
158  }; \
159  \
160  callback(){} \
161  \
162  template<typename Call> \
163  callback(intrusive_ptr<Call> c) : call_ptr(c) \
164  {} \
165  \
166  template<typename Call> \
167  callback(std::auto_ptr<Call> ptr) : call_ptr(ptr.release()) \
168  {} \
169  \
170  template<typename Call> \
171  callback const &operator=(intrusive_ptr<Call> c) \
172  { call_ptr = c; return *this; } \
173  \
174  template<typename Call> \
175  callback const &operator=(std::auto_ptr<Call> c) \
176  { call_ptr = 0; call_ptr = c.release(); return *this; } \
177  \
178  template<typename F> \
179  callback(F func) : call_ptr(new callable_impl<Result,F>(func)) \
180  {} \
181  \
182  callback(callback const &other) : call_ptr(other.call_ptr) {} \
183  \
184  template<typename F> \
185  callback const &operator=(F func) \
186  { \
187  call_ptr = new callable_impl<Result,F>(func); \
188  return *this; \
189  } \
190  \
191  callback const &operator=(callback const &other) \
192  { \
193  if(this != &other) { call_ptr=other.call_ptr; } \
194  return *this; \
195  } \
196  \
197  Result operator()(BOOSTER_TYPE_PARAMS) const \
198  { \
199  if(!call_ptr.get()) throw bad_callback_call(); \
200  return (*call_ptr)(BOOSTER_CALL_PARAMS); \
201  } \
202  \
203  bool empty() const { return call_ptr.get()==0; } \
204  \
205  operator bool() const { return !empty(); } \
206  \
207  void swap(callback &other) { call_ptr.swap(other.call_ptr); } \
208  pointer_type const &get_pointer() const { return call_ptr; } \
209  pointer_type &get_pointer() { return call_ptr; } \
210  \
211  private: \
212  pointer_type call_ptr; \
213  }; \
214 
215  #define BOOSTER_TEMPLATE_PARAMS
216  #define BOOSTER_TEMPLATE_TYPE_PARAMS
217  #define BOOSTER_TYPE_PARAMS
218  #define BOOSTER_CALL_PARAMS
219  BOOSTER_CALLBACK
220  #undef BOOSTER_TEMPLATE_PARAMS
221  #undef BOOSTER_TEMPLATE_TYPE_PARAMS
222  #undef BOOSTER_TYPE_PARAMS
223  #undef BOOSTER_CALL_PARAMS
224 
225  #define BOOSTER_TEMPLATE_PARAMS ,typename P1
226  #define BOOSTER_TEMPLATE_TYPE_PARAMS P1
227  #define BOOSTER_TYPE_PARAMS P1 a1
228  #define BOOSTER_CALL_PARAMS a1
229  BOOSTER_CALLBACK
230  #undef BOOSTER_TEMPLATE_PARAMS
231  #undef BOOSTER_TEMPLATE_TYPE_PARAMS
232  #undef BOOSTER_TYPE_PARAMS
233  #undef BOOSTER_CALL_PARAMS
234 
235  #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2
236  #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2
237  #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2
238  #define BOOSTER_CALL_PARAMS a1,a2
239  BOOSTER_CALLBACK
240  #undef BOOSTER_TEMPLATE_PARAMS
241  #undef BOOSTER_TEMPLATE_TYPE_PARAMS
242  #undef BOOSTER_TYPE_PARAMS
243  #undef BOOSTER_CALL_PARAMS
244 
245  #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3
246  #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3
247  #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3
248  #define BOOSTER_CALL_PARAMS a1,a2,a3
249  BOOSTER_CALLBACK
250  #undef BOOSTER_TEMPLATE_PARAMS
251  #undef BOOSTER_TEMPLATE_TYPE_PARAMS
252  #undef BOOSTER_TYPE_PARAMS
253  #undef BOOSTER_CALL_PARAMS
254 
255  #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3,typename P4
256  #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3, P4
257  #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3,P4 a4
258  #define BOOSTER_CALL_PARAMS a1,a2,a3,a4
259  BOOSTER_CALLBACK
260  #undef BOOSTER_TEMPLATE_PARAMS
261  #undef BOOSTER_TEMPLATE_TYPE_PARAMS
262  #undef BOOSTER_TYPE_PARAMS
263  #undef BOOSTER_CALL_PARAMS
264 
265  #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3,typename P4,typename P5
266  #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3, P4, P5
267  #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3,P4 a4,P5 a5
268  #define BOOSTER_CALL_PARAMS a1,a2,a3,a4,a5
269  BOOSTER_CALLBACK
270  #undef BOOSTER_TEMPLATE_PARAMS
271  #undef BOOSTER_TEMPLATE_TYPE_PARAMS
272  #undef BOOSTER_TYPE_PARAMS
273  #undef BOOSTER_CALL_PARAMS
274 
275  #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3,typename P4,typename P5,typename P6
276  #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3, P4, P5, P6
277  #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3,P4 a4,P5 a5,P6 a6
278  #define BOOSTER_CALL_PARAMS a1,a2,a3,a4,a5,a6
279  BOOSTER_CALLBACK
280  #undef BOOSTER_TEMPLATE_PARAMS
281  #undef BOOSTER_TEMPLATE_TYPE_PARAMS
282  #undef BOOSTER_TYPE_PARAMS
283  #undef BOOSTER_CALL_PARAMS
284 
285  #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3,typename P4,typename P5,typename P6,typename P7
286  #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3, P4, P5, P6, P7
287  #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3,P4 a4,P5 a5,P6 a6,P7 a7
288  #define BOOSTER_CALL_PARAMS a1,a2,a3,a4,a5,a6,a7
289  BOOSTER_CALLBACK
290  #undef BOOSTER_TEMPLATE_PARAMS
291  #undef BOOSTER_TEMPLATE_TYPE_PARAMS
292  #undef BOOSTER_TYPE_PARAMS
293  #undef BOOSTER_CALL_PARAMS
294 
295  #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3,typename P4,typename P5,typename P6,typename P7,typename P8
296  #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3, P4, P5, P6, P7, P8
297  #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3,P4 a4,P5 a5,P6 a6,P7 a7,P8 a8
298  #define BOOSTER_CALL_PARAMS a1,a2,a3,a4,a5,a6,a7,a8
299  BOOSTER_CALLBACK
300  #undef BOOSTER_TEMPLATE_PARAMS
301  #undef BOOSTER_TEMPLATE_TYPE_PARAMS
302  #undef BOOSTER_TYPE_PARAMS
303  #undef BOOSTER_CALL_PARAMS
304 
305  #undef BOOSTER_CALLBACK
306 
307  #endif // DOC
308 
309 } // booster
310 
311 
312 #endif
this exception is thrown in case of calling unassigned/empty function
Definition: callback.h:27
intrusive_ptr< callable_type > pointer_type
Definition: callback.h:62
Same as std::runtime_error but records stack trace.
Definition: backtrace.h:158
Result result_type
Definition: callback.h:66
Definition: callback.h:21
Definition: callback.h:18
intrusive_ptr is the class taken as-is from boost.
Definition: intrusive_ptr.h:42
Booster library namespace. The library that implements Boost Like API in ABI backward compatible way...
Definition: application.h:23