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  template<typename Result, typename ...Params>
37  struct callable<Result(Params...)> : public refcounted
38  {
39  virtual Result operator()(Params...) = 0;
40  virtual ~callable(){}
41  };
42 
60 
61  template<typename Result, typename ...Params >
62  class callback<Result(Params...)>
63  {
64  public:
65  typedef Result result_type;
66  typedef callable<Result(Params...)> callable_type;
72 
73  template<typename R,typename F>
74  struct callable_impl : public callable_type {
75  F func;
76  callable_impl(F f) : func(f){}
77  virtual R operator()(Params... args)
78  { return func(args...); }
79  };
80 
81  template<typename F>
82  struct callable_impl<void,F> : public callable_type {
83  F func;
84  callable_impl(F f) : func(f){}
85  virtual void operator()(Params... args)
86  { func(args...); }
87  };
88 
92  callback(){}
93 
94  template<typename Call>
95  callback(intrusive_ptr<Call> c) : call_ptr(c)
96  {}
97 
98  template<typename Call>
99  callback(std::unique_ptr<Call> ptr) : call_ptr(ptr.release())
100  {}
101 
102  template<typename Call>
103  callback const &operator=(intrusive_ptr<Call> c)
104  { call_ptr = c; return *this; }
105 
106  template<typename Call>
107  callback const &operator=(std::unique_ptr<Call> c)
108  { call_ptr = 0; call_ptr = c.release(); return *this; }
109 
110  template<typename F>
111  callback(F func) : call_ptr(new callable_impl<Result,F>(func))
112  {}
113 
114  callback(callback const &other) : call_ptr(other.call_ptr) {}
115 
116  callback(callback &&other) : call_ptr(std::move(other.call_ptr))
117  {
118  }
119 
120  template<typename F>
121  callback const &operator=(F func)
122  {
123  call_ptr = new callable_impl<Result,F>(func);
124  return *this;
125  }
126 
127  callback &operator=(callback &&other)
128  {
129  call_ptr = std::move(other.call_ptr);
130  return *this;
131  }
132  callback const &operator=(callback const &other)
133  {
134  if(this != &other) { call_ptr=other.call_ptr; }
135  return *this;
136  }
137 
138  Result operator()(Params ...args) const
139  {
140  if(!call_ptr.get()) throw bad_callback_call();
141  return (*call_ptr)(args...);
142  }
143 
147  bool empty() const { return call_ptr.get()==0; }
148 
152  operator bool() const { return !empty(); }
153 
154 
155  void swap(callback &other) { call_ptr.swap(other.call_ptr); }
156 
157  pointer_type const &get_pointer() const { return call_ptr; }
158  pointer_type &get_pointer() { return call_ptr; }
159 
160  private:
161  pointer_type call_ptr;
162  };
163 
164 
165 } // booster
166 
167 
168 #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:71
Same as std::runtime_error but records stack trace.
Definition: backtrace.h:158
callback()
Definition: callback.h:92
Definition: callback.h:21
Definition: callback.h:18
This class is used as base class for reference counted objects that use intrusive_ptr. Deriving from this class allows simple way to manage reference counting for single object.
Definition: refcounted.h:25
bool empty() const
Definition: callback.h:147
Definition: callback.h:37
Booster library namespace. The library that implements Boost Like API in ABI backward compatible way...
Definition: application.h:23