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_FUNCTION_H 00009 #define BOOSTER_FUNCTION_H 00010 00011 #include <booster/backtrace.h> 00012 #include <booster/clone_ptr.h> 00013 00014 namespace booster { 00015 template<typename Type> 00016 class function; 00017 00022 class bad_function_call : public booster::runtime_error { 00023 public: 00024 bad_function_call() : 00025 booster::runtime_error("bad_function_call") 00026 { 00027 } 00028 }; 00029 00030 00031 #ifdef BOOSTER_DOXYGEN_DOCS 00032 00033 00034 00035 00036 00037 00038 00039 00040 00041 00042 00043 00044 00045 00046 00047 00048 00049 template<typename Result,typename ...Params> 00050 class function<Result(Params...)> 00051 { 00052 public: 00056 typedef Result result_type; 00060 function(); 00065 template<typename F> 00066 function(F func); 00067 00071 function(function const &other); 00072 00077 template<typename F> 00078 function const &operator=(F func); 00079 00083 function const &operator=(function const &other); 00084 00088 result_type operator()(Params... params) const; 00092 bool empty() const; 00096 operator bool() const; 00097 00101 void swap(function &other); 00102 }; 00103 00104 #else 00105 00106 #define BOOSTER_FUNCTION \ 00107 template<typename Result BOOSTER_TEMPLATE_PARAMS > \ 00108 class function<Result(BOOSTER_TEMPLATE_TYPE_PARAMS)> \ 00109 { \ 00110 public: \ 00111 typedef Result result_type; \ 00112 struct callable { \ 00113 virtual Result call(BOOSTER_TYPE_PARAMS) =0; \ 00114 virtual callable *clone() const = 0; \ 00115 virtual ~callable(){} \ 00116 }; \ 00117 \ 00118 template<typename R,typename F> \ 00119 struct callable_impl : public callable { \ 00120 F func; \ 00121 callable_impl(F f) : func(f){} \ 00122 virtual R call(BOOSTER_TYPE_PARAMS) \ 00123 { return func(BOOSTER_CALL_PARAMS); } \ 00124 virtual callable *clone() const \ 00125 { return new callable_impl<R,F>(func); } \ 00126 }; \ 00127 template<typename F> \ 00128 struct callable_impl<void,F> : public callable { \ 00129 F func; \ 00130 callable_impl(F f) : func(f){} \ 00131 virtual void call(BOOSTER_TYPE_PARAMS) \ 00132 { func(BOOSTER_CALL_PARAMS); } \ 00133 virtual callable *clone() const \ 00134 { return new callable_impl<void,F>(func); } \ 00135 }; \ 00136 function(){} \ 00137 template<typename F> \ 00138 function(F func) : call_ptr(new callable_impl<Result,F>(func)) \ 00139 {} \ 00140 function(function const &other) : call_ptr(other.call_ptr) {} \ 00141 template<typename F> \ 00142 function const &operator=(F func) \ 00143 { \ 00144 call_ptr.reset(new callable_impl<Result,F>(func)); \ 00145 return *this; \ 00146 } \ 00147 function const &operator=(function const &other) \ 00148 { \ 00149 if(this != &other) { call_ptr=other.call_ptr; } \ 00150 return *this; \ 00151 } \ 00152 Result operator()(BOOSTER_TYPE_PARAMS) const \ 00153 { \ 00154 if(!call_ptr.get()) throw bad_function_call(); \ 00155 return call_ptr->call(BOOSTER_CALL_PARAMS); \ 00156 } \ 00157 bool empty() const { return call_ptr.get()==0; } \ 00158 operator bool() const { return !empty(); } \ 00159 void swap(function &other) { call_ptr.swap(other.call_ptr); } \ 00160 private: \ 00161 clone_ptr<callable> call_ptr; \ 00162 }; \ 00163 00164 #define BOOSTER_TEMPLATE_PARAMS 00165 #define BOOSTER_TEMPLATE_TYPE_PARAMS 00166 #define BOOSTER_TYPE_PARAMS 00167 #define BOOSTER_CALL_PARAMS 00168 BOOSTER_FUNCTION 00169 #undef BOOSTER_TEMPLATE_PARAMS 00170 #undef BOOSTER_TEMPLATE_TYPE_PARAMS 00171 #undef BOOSTER_TYPE_PARAMS 00172 #undef BOOSTER_CALL_PARAMS 00173 00174 #define BOOSTER_TEMPLATE_PARAMS ,typename P1 00175 #define BOOSTER_TEMPLATE_TYPE_PARAMS P1 00176 #define BOOSTER_TYPE_PARAMS P1 a1 00177 #define BOOSTER_CALL_PARAMS a1 00178 BOOSTER_FUNCTION 00179 #undef BOOSTER_TEMPLATE_PARAMS 00180 #undef BOOSTER_TEMPLATE_TYPE_PARAMS 00181 #undef BOOSTER_TYPE_PARAMS 00182 #undef BOOSTER_CALL_PARAMS 00183 00184 #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2 00185 #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2 00186 #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2 00187 #define BOOSTER_CALL_PARAMS a1,a2 00188 BOOSTER_FUNCTION 00189 #undef BOOSTER_TEMPLATE_PARAMS 00190 #undef BOOSTER_TEMPLATE_TYPE_PARAMS 00191 #undef BOOSTER_TYPE_PARAMS 00192 #undef BOOSTER_CALL_PARAMS 00193 00194 #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3 00195 #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3 00196 #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3 00197 #define BOOSTER_CALL_PARAMS a1,a2,a3 00198 BOOSTER_FUNCTION 00199 #undef BOOSTER_TEMPLATE_PARAMS 00200 #undef BOOSTER_TEMPLATE_TYPE_PARAMS 00201 #undef BOOSTER_TYPE_PARAMS 00202 #undef BOOSTER_CALL_PARAMS 00203 00204 #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3,typename P4 00205 #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3, P4 00206 #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3,P4 a4 00207 #define BOOSTER_CALL_PARAMS a1,a2,a3,a4 00208 BOOSTER_FUNCTION 00209 #undef BOOSTER_TEMPLATE_PARAMS 00210 #undef BOOSTER_TEMPLATE_TYPE_PARAMS 00211 #undef BOOSTER_TYPE_PARAMS 00212 #undef BOOSTER_CALL_PARAMS 00213 00214 #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3,typename P4,typename P5 00215 #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3, P4, P5 00216 #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3,P4 a4,P5 a5 00217 #define BOOSTER_CALL_PARAMS a1,a2,a3,a4,a5 00218 BOOSTER_FUNCTION 00219 #undef BOOSTER_TEMPLATE_PARAMS 00220 #undef BOOSTER_TEMPLATE_TYPE_PARAMS 00221 #undef BOOSTER_TYPE_PARAMS 00222 #undef BOOSTER_CALL_PARAMS 00223 00224 #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3,typename P4,typename P5,typename P6 00225 #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3, P4, P5, P6 00226 #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3,P4 a4,P5 a5,P6 a6 00227 #define BOOSTER_CALL_PARAMS a1,a2,a3,a4,a5,a6 00228 BOOSTER_FUNCTION 00229 #undef BOOSTER_TEMPLATE_PARAMS 00230 #undef BOOSTER_TEMPLATE_TYPE_PARAMS 00231 #undef BOOSTER_TYPE_PARAMS 00232 #undef BOOSTER_CALL_PARAMS 00233 00234 #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3,typename P4,typename P5,typename P6,typename P7 00235 #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3, P4, P5, P6, P7 00236 #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3,P4 a4,P5 a5,P6 a6,P7 a7 00237 #define BOOSTER_CALL_PARAMS a1,a2,a3,a4,a5,a6,a7 00238 BOOSTER_FUNCTION 00239 #undef BOOSTER_TEMPLATE_PARAMS 00240 #undef BOOSTER_TEMPLATE_TYPE_PARAMS 00241 #undef BOOSTER_TYPE_PARAMS 00242 #undef BOOSTER_CALL_PARAMS 00243 00244 #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3,typename P4,typename P5,typename P6,typename P7,typename P8 00245 #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3, P4, P5, P6, P7, P8 00246 #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3,P4 a4,P5 a5,P6 a6,P7 a7,P8 a8 00247 #define BOOSTER_CALL_PARAMS a1,a2,a3,a4,a5,a6,a7,a8 00248 BOOSTER_FUNCTION 00249 #undef BOOSTER_TEMPLATE_PARAMS 00250 #undef BOOSTER_TEMPLATE_TYPE_PARAMS 00251 #undef BOOSTER_TYPE_PARAMS 00252 #undef BOOSTER_CALL_PARAMS 00253 00254 #undef BOOSTER_FUNCTION 00255 00256 #endif // DOC 00257 00258 } // booster 00259 00260 00261 #endif