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 <memory>
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:
61  typedef Result result_type;
65  callback();
70  template<typename F>
71  callback(F func);
72 
76  callback(callback const &other);
77 
82  template<typename F>
83  callback const &operator=(F func);
84 
88  callback const &operator=(callback const &other);
89 
93  result_type operator()(Params... params) const;
97  bool empty() const;
101  operator bool() const;
102 
106  void swap(callback &other);
107  };
108 
109  #else
110 
111  #define BOOSTER_CALLBACK \
112  template<typename Result BOOSTER_TEMPLATE_PARAMS > \
113  struct callable<Result(BOOSTER_TEMPLATE_TYPE_PARAMS)> :public refcounted\
114  { \
115  virtual Result operator()(BOOSTER_TYPE_PARAMS) = 0; \
116  virtual ~callable(){} \
117  }; \
118  \
119  template<typename Result BOOSTER_TEMPLATE_PARAMS > \
120  class callback<Result(BOOSTER_TEMPLATE_TYPE_PARAMS)> \
121  { \
122  public: \
123  typedef Result result_type; \
124  \
125  typedef callable<Result(BOOSTER_TEMPLATE_TYPE_PARAMS)> \
126  callable_type; \
127  \
128  template<typename R,typename F> \
129  struct callable_impl : public callable_type { \
130  F func; \
131  callable_impl(F f) : func(f){} \
132  virtual R operator()(BOOSTER_TYPE_PARAMS) \
133  { return func(BOOSTER_CALL_PARAMS); } \
134  }; \
135  \
136  template<typename F> \
137  struct callable_impl<void,F> : public callable_type { \
138  F func; \
139  callable_impl(F f) : func(f){} \
140  virtual void operator()(BOOSTER_TYPE_PARAMS) \
141  { func(BOOSTER_CALL_PARAMS); } \
142  }; \
143  \
144  callback(){} \
145  \
146  template<typename Call> \
147  callback(intrusive_ptr<Call> c) : call_ptr(c) \
148  {} \
149  \
150  template<typename Call> \
151  callback(std::auto_ptr<Call> ptr) : call_ptr(ptr.release()) \
152  {} \
153  \
154  template<typename Call> \
155  callback const &operator=(intrusive_ptr<Call> c) \
156  { call_ptr = c; return *this; } \
157  \
158  template<typename Call> \
159  callback const &operator=(std::auto_ptr<Call> c) \
160  { call_ptr = 0; call_ptr = c.release(); return *this; } \
161  \
162  template<typename F> \
163  callback(F func) : call_ptr(new callable_impl<Result,F>(func)) \
164  {} \
165  \
166  callback(callback const &other) : call_ptr(other.call_ptr) {} \
167  \
168  template<typename F> \
169  callback const &operator=(F func) \
170  { \
171  call_ptr = new callable_impl<Result,F>(func); \
172  return *this; \
173  } \
174  \
175  callback const &operator=(callback const &other) \
176  { \
177  if(this != &other) { call_ptr=other.call_ptr; } \
178  return *this; \
179  } \
180  \
181  Result operator()(BOOSTER_TYPE_PARAMS) const \
182  { \
183  if(!call_ptr.get()) throw bad_callback_call(); \
184  return (*call_ptr)(BOOSTER_CALL_PARAMS); \
185  } \
186  \
187  bool empty() const { return call_ptr.get()==0; } \
188  \
189  operator bool() const { return !empty(); } \
190  \
191  void swap(callback &other) { call_ptr.swap(other.call_ptr); } \
192  \
193  private: \
194  intrusive_ptr<callable_type> call_ptr; \
195  }; \
196 
197  #define BOOSTER_TEMPLATE_PARAMS
198  #define BOOSTER_TEMPLATE_TYPE_PARAMS
199  #define BOOSTER_TYPE_PARAMS
200  #define BOOSTER_CALL_PARAMS
201  BOOSTER_CALLBACK
202  #undef BOOSTER_TEMPLATE_PARAMS
203  #undef BOOSTER_TEMPLATE_TYPE_PARAMS
204  #undef BOOSTER_TYPE_PARAMS
205  #undef BOOSTER_CALL_PARAMS
206 
207  #define BOOSTER_TEMPLATE_PARAMS ,typename P1
208  #define BOOSTER_TEMPLATE_TYPE_PARAMS P1
209  #define BOOSTER_TYPE_PARAMS P1 a1
210  #define BOOSTER_CALL_PARAMS a1
211  BOOSTER_CALLBACK
212  #undef BOOSTER_TEMPLATE_PARAMS
213  #undef BOOSTER_TEMPLATE_TYPE_PARAMS
214  #undef BOOSTER_TYPE_PARAMS
215  #undef BOOSTER_CALL_PARAMS
216 
217  #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2
218  #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2
219  #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2
220  #define BOOSTER_CALL_PARAMS a1,a2
221  BOOSTER_CALLBACK
222  #undef BOOSTER_TEMPLATE_PARAMS
223  #undef BOOSTER_TEMPLATE_TYPE_PARAMS
224  #undef BOOSTER_TYPE_PARAMS
225  #undef BOOSTER_CALL_PARAMS
226 
227  #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3
228  #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3
229  #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3
230  #define BOOSTER_CALL_PARAMS a1,a2,a3
231  BOOSTER_CALLBACK
232  #undef BOOSTER_TEMPLATE_PARAMS
233  #undef BOOSTER_TEMPLATE_TYPE_PARAMS
234  #undef BOOSTER_TYPE_PARAMS
235  #undef BOOSTER_CALL_PARAMS
236 
237  #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3,typename P4
238  #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3, P4
239  #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3,P4 a4
240  #define BOOSTER_CALL_PARAMS a1,a2,a3,a4
241  BOOSTER_CALLBACK
242  #undef BOOSTER_TEMPLATE_PARAMS
243  #undef BOOSTER_TEMPLATE_TYPE_PARAMS
244  #undef BOOSTER_TYPE_PARAMS
245  #undef BOOSTER_CALL_PARAMS
246 
247  #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3,typename P4,typename P5
248  #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3, P4, P5
249  #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3,P4 a4,P5 a5
250  #define BOOSTER_CALL_PARAMS a1,a2,a3,a4,a5
251  BOOSTER_CALLBACK
252  #undef BOOSTER_TEMPLATE_PARAMS
253  #undef BOOSTER_TEMPLATE_TYPE_PARAMS
254  #undef BOOSTER_TYPE_PARAMS
255  #undef BOOSTER_CALL_PARAMS
256 
257  #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3,typename P4,typename P5,typename P6
258  #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3, P4, P5, P6
259  #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3,P4 a4,P5 a5,P6 a6
260  #define BOOSTER_CALL_PARAMS a1,a2,a3,a4,a5,a6
261  BOOSTER_CALLBACK
262  #undef BOOSTER_TEMPLATE_PARAMS
263  #undef BOOSTER_TEMPLATE_TYPE_PARAMS
264  #undef BOOSTER_TYPE_PARAMS
265  #undef BOOSTER_CALL_PARAMS
266 
267  #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3,typename P4,typename P5,typename P6,typename P7
268  #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3, P4, P5, P6, P7
269  #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3,P4 a4,P5 a5,P6 a6,P7 a7
270  #define BOOSTER_CALL_PARAMS a1,a2,a3,a4,a5,a6,a7
271  BOOSTER_CALLBACK
272  #undef BOOSTER_TEMPLATE_PARAMS
273  #undef BOOSTER_TEMPLATE_TYPE_PARAMS
274  #undef BOOSTER_TYPE_PARAMS
275  #undef BOOSTER_CALL_PARAMS
276 
277  #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3,typename P4,typename P5,typename P6,typename P7,typename P8
278  #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3, P4, P5, P6, P7, P8
279  #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3,P4 a4,P5 a5,P6 a6,P7 a7,P8 a8
280  #define BOOSTER_CALL_PARAMS a1,a2,a3,a4,a5,a6,a7,a8
281  BOOSTER_CALLBACK
282  #undef BOOSTER_TEMPLATE_PARAMS
283  #undef BOOSTER_TEMPLATE_TYPE_PARAMS
284  #undef BOOSTER_TYPE_PARAMS
285  #undef BOOSTER_CALL_PARAMS
286 
287  #undef BOOSTER_CALLBACK
288 
289  #endif // DOC
290 
291 } // booster
292 
293 
294 #endif
this exception is thrown in case of calling unassigned/empty function
Definition: callback.h:27
Same as std::runtime_error but records stack trace.
Definition: backtrace.h:158
Result result_type
Definition: callback.h:61
Definition: callback.h:21
Definition: callback.h:18