CppCMS
|
00001 // 00002 // Copyright (C) 2009-2012 Artyom Beilis (Tonkikh) 00003 // 00004 // Distributed under the Boost Software License, Version 1.0. (See 00005 // accompanying file LICENSE_1_0.txt or copy at 00006 // http://www.boost.org/LICENSE_1_0.txt) 00007 // 00008 #ifndef BOOSTER_CALLBACK_H 00009 #define BOOSTER_CALLBACK_H 00010 00011 #include <booster/backtrace.h> 00012 #include <memory> 00013 #include <booster/intrusive_ptr.h> 00014 #include <booster/refcounted.h> 00015 00016 namespace booster { 00017 template<typename Type> 00018 class callback; 00019 00020 template<typename Type> 00021 struct callable; 00022 00027 class bad_callback_call : public booster::runtime_error { 00028 public: 00029 bad_callback_call() : 00030 booster::runtime_error("bad_callback_call") 00031 { 00032 } 00033 }; 00034 00035 00036 #ifdef BOOSTER_DOXYGEN_DOCS 00037 00038 00039 00040 00041 00042 00043 00044 00045 00046 00047 00048 00049 00050 00051 00052 00053 00054 template<typename Result,typename ...Params> 00055 class callback<Result(Params...)> 00056 { 00057 public: 00061 typedef Result result_type; 00065 callback(); 00070 template<typename F> 00071 callback(F func); 00072 00076 callback(callback const &other); 00077 00082 template<typename F> 00083 callback const &operator=(F func); 00084 00088 callback const &operator=(callback const &other); 00089 00093 result_type operator()(Params... params) const; 00097 bool empty() const; 00101 operator bool() const; 00102 00106 void swap(callback &other); 00107 }; 00108 00109 #else 00110 00111 #define BOOSTER_CALLBACK \ 00112 template<typename Result BOOSTER_TEMPLATE_PARAMS > \ 00113 struct callable<Result(BOOSTER_TEMPLATE_TYPE_PARAMS)> :public refcounted\ 00114 { \ 00115 virtual Result operator()(BOOSTER_TYPE_PARAMS) = 0; \ 00116 virtual ~callable(){} \ 00117 }; \ 00118 \ 00119 template<typename Result BOOSTER_TEMPLATE_PARAMS > \ 00120 class callback<Result(BOOSTER_TEMPLATE_TYPE_PARAMS)> \ 00121 { \ 00122 public: \ 00123 typedef Result result_type; \ 00124 \ 00125 typedef callable<Result(BOOSTER_TEMPLATE_TYPE_PARAMS)> \ 00126 callable_type; \ 00127 \ 00128 template<typename R,typename F> \ 00129 struct callable_impl : public callable_type { \ 00130 F func; \ 00131 callable_impl(F f) : func(f){} \ 00132 virtual R operator()(BOOSTER_TYPE_PARAMS) \ 00133 { return func(BOOSTER_CALL_PARAMS); } \ 00134 }; \ 00135 \ 00136 template<typename F> \ 00137 struct callable_impl<void,F> : public callable_type { \ 00138 F func; \ 00139 callable_impl(F f) : func(f){} \ 00140 virtual void operator()(BOOSTER_TYPE_PARAMS) \ 00141 { func(BOOSTER_CALL_PARAMS); } \ 00142 }; \ 00143 \ 00144 callback(){} \ 00145 \ 00146 template<typename Call> \ 00147 callback(intrusive_ptr<Call> c) : call_ptr(c) \ 00148 {} \ 00149 \ 00150 template<typename Call> \ 00151 callback(std::auto_ptr<Call> ptr) : call_ptr(ptr.release()) \ 00152 {} \ 00153 \ 00154 template<typename Call> \ 00155 callback const &operator=(intrusive_ptr<Call> c) \ 00156 { call_ptr = c; return *this; } \ 00157 \ 00158 template<typename Call> \ 00159 callback const &operator=(std::auto_ptr<Call> c) \ 00160 { call_ptr = 0; call_ptr = c.release(); return *this; } \ 00161 \ 00162 template<typename F> \ 00163 callback(F func) : call_ptr(new callable_impl<Result,F>(func)) \ 00164 {} \ 00165 \ 00166 callback(callback const &other) : call_ptr(other.call_ptr) {} \ 00167 \ 00168 template<typename F> \ 00169 callback const &operator=(F func) \ 00170 { \ 00171 call_ptr = new callable_impl<Result,F>(func); \ 00172 return *this; \ 00173 } \ 00174 \ 00175 callback const &operator=(callback const &other) \ 00176 { \ 00177 if(this != &other) { call_ptr=other.call_ptr; } \ 00178 return *this; \ 00179 } \ 00180 \ 00181 Result operator()(BOOSTER_TYPE_PARAMS) const \ 00182 { \ 00183 if(!call_ptr.get()) throw bad_callback_call(); \ 00184 return (*call_ptr)(BOOSTER_CALL_PARAMS); \ 00185 } \ 00186 \ 00187 bool empty() const { return call_ptr.get()==0; } \ 00188 \ 00189 operator bool() const { return !empty(); } \ 00190 \ 00191 void swap(callback &other) { call_ptr.swap(other.call_ptr); } \ 00192 \ 00193 private: \ 00194 intrusive_ptr<callable_type> call_ptr; \ 00195 }; \ 00196 00197 #define BOOSTER_TEMPLATE_PARAMS 00198 #define BOOSTER_TEMPLATE_TYPE_PARAMS 00199 #define BOOSTER_TYPE_PARAMS 00200 #define BOOSTER_CALL_PARAMS 00201 BOOSTER_CALLBACK 00202 #undef BOOSTER_TEMPLATE_PARAMS 00203 #undef BOOSTER_TEMPLATE_TYPE_PARAMS 00204 #undef BOOSTER_TYPE_PARAMS 00205 #undef BOOSTER_CALL_PARAMS 00206 00207 #define BOOSTER_TEMPLATE_PARAMS ,typename P1 00208 #define BOOSTER_TEMPLATE_TYPE_PARAMS P1 00209 #define BOOSTER_TYPE_PARAMS P1 a1 00210 #define BOOSTER_CALL_PARAMS a1 00211 BOOSTER_CALLBACK 00212 #undef BOOSTER_TEMPLATE_PARAMS 00213 #undef BOOSTER_TEMPLATE_TYPE_PARAMS 00214 #undef BOOSTER_TYPE_PARAMS 00215 #undef BOOSTER_CALL_PARAMS 00216 00217 #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2 00218 #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2 00219 #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2 00220 #define BOOSTER_CALL_PARAMS a1,a2 00221 BOOSTER_CALLBACK 00222 #undef BOOSTER_TEMPLATE_PARAMS 00223 #undef BOOSTER_TEMPLATE_TYPE_PARAMS 00224 #undef BOOSTER_TYPE_PARAMS 00225 #undef BOOSTER_CALL_PARAMS 00226 00227 #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3 00228 #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3 00229 #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3 00230 #define BOOSTER_CALL_PARAMS a1,a2,a3 00231 BOOSTER_CALLBACK 00232 #undef BOOSTER_TEMPLATE_PARAMS 00233 #undef BOOSTER_TEMPLATE_TYPE_PARAMS 00234 #undef BOOSTER_TYPE_PARAMS 00235 #undef BOOSTER_CALL_PARAMS 00236 00237 #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3,typename P4 00238 #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3, P4 00239 #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3,P4 a4 00240 #define BOOSTER_CALL_PARAMS a1,a2,a3,a4 00241 BOOSTER_CALLBACK 00242 #undef BOOSTER_TEMPLATE_PARAMS 00243 #undef BOOSTER_TEMPLATE_TYPE_PARAMS 00244 #undef BOOSTER_TYPE_PARAMS 00245 #undef BOOSTER_CALL_PARAMS 00246 00247 #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3,typename P4,typename P5 00248 #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3, P4, P5 00249 #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3,P4 a4,P5 a5 00250 #define BOOSTER_CALL_PARAMS a1,a2,a3,a4,a5 00251 BOOSTER_CALLBACK 00252 #undef BOOSTER_TEMPLATE_PARAMS 00253 #undef BOOSTER_TEMPLATE_TYPE_PARAMS 00254 #undef BOOSTER_TYPE_PARAMS 00255 #undef BOOSTER_CALL_PARAMS 00256 00257 #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3,typename P4,typename P5,typename P6 00258 #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3, P4, P5, P6 00259 #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3,P4 a4,P5 a5,P6 a6 00260 #define BOOSTER_CALL_PARAMS a1,a2,a3,a4,a5,a6 00261 BOOSTER_CALLBACK 00262 #undef BOOSTER_TEMPLATE_PARAMS 00263 #undef BOOSTER_TEMPLATE_TYPE_PARAMS 00264 #undef BOOSTER_TYPE_PARAMS 00265 #undef BOOSTER_CALL_PARAMS 00266 00267 #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3,typename P4,typename P5,typename P6,typename P7 00268 #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3, P4, P5, P6, P7 00269 #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3,P4 a4,P5 a5,P6 a6,P7 a7 00270 #define BOOSTER_CALL_PARAMS a1,a2,a3,a4,a5,a6,a7 00271 BOOSTER_CALLBACK 00272 #undef BOOSTER_TEMPLATE_PARAMS 00273 #undef BOOSTER_TEMPLATE_TYPE_PARAMS 00274 #undef BOOSTER_TYPE_PARAMS 00275 #undef BOOSTER_CALL_PARAMS 00276 00277 #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3,typename P4,typename P5,typename P6,typename P7,typename P8 00278 #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3, P4, P5, P6, P7, P8 00279 #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3,P4 a4,P5 a5,P6 a6,P7 a7,P8 a8 00280 #define BOOSTER_CALL_PARAMS a1,a2,a3,a4,a5,a6,a7,a8 00281 BOOSTER_CALLBACK 00282 #undef BOOSTER_TEMPLATE_PARAMS 00283 #undef BOOSTER_TEMPLATE_TYPE_PARAMS 00284 #undef BOOSTER_TYPE_PARAMS 00285 #undef BOOSTER_CALL_PARAMS 00286 00287 #undef BOOSTER_CALLBACK 00288 00289 #endif // DOC 00290 00291 } // booster 00292 00293 00294 #endif