ChipMaster's trial hacks on C++CMS starting with v1.2.1. Not sure I'll follow on with the v2 since it looks to be breaking and mostly frivolous.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

313 lines
9.2 KiB

  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. #include <booster/backtrace.h>
  11. #include <booster/auto_ptr_inc.h>
  12. #include <booster/intrusive_ptr.h>
  13. #include <booster/refcounted.h>
  14. namespace booster {
  15. template<typename Type>
  16. class callback;
  17. template<typename Type>
  18. struct callable;
  19. ///
  20. /// \brief this exception is thrown in case of calling unassigned/empty
  21. /// function
  22. ///
  23. class bad_callback_call : public booster::runtime_error {
  24. public:
  25. bad_callback_call() :
  26. booster::runtime_error("bad_callback_call")
  27. {
  28. }
  29. };
  30. #ifdef BOOSTER_DOXYGEN_DOCS
  31. ///
  32. /// \brief This is Booster's implementation of std::tr1::callback/booster::callback.
  33. ///
  34. /// This callback is created from generic object that can be "called" i.e.
  35. /// a class with operator() or callback pointer that has same signature as
  36. /// the callback.
  37. ///
  38. /// See: http://www.boost.org/doc/html/function.html
  39. ///
  40. /// Notes:
  41. ///
  42. /// - this code is not taken from Boost and has slightly different interface.
  43. /// - as most of compilers do not support Variadic templates yet, this class
  44. /// is explicitly specialized for Params of size 0 to 8. So maximal amout
  45. /// of parameters that can be used is 8.
  46. ///
  47. ///
  48. template<typename Result,typename ...Params>
  49. class callback<Result(Params...)>
  50. {
  51. public:
  52. ///
  53. /// Pointer to callable object
  54. ///
  55. /// \ver{v1_2}
  56. typedef intrusive_ptr<callable_type> pointer_type;
  57. ///
  58. /// Type of result, for use with boost::bind
  59. ///
  60. typedef Result result_type;
  61. ///
  62. /// Default constructor, creates an empty callbacks
  63. ///
  64. callback();
  65. ///
  66. /// Creates a callback from a callbackal \a func of type F. func
  67. /// should be copyable. It is copied and stored inside callback object.
  68. ///
  69. template<typename F>
  70. callback(F func);
  71. ///
  72. /// Copy callback, Copies underlying callbackal object.
  73. ///
  74. callback(callback const &other);
  75. ///
  76. /// Assign a callbackal \a func of type F. func
  77. /// should be copyable. It is copied and stored inside callback object.
  78. ///
  79. template<typename F>
  80. callback const &operator=(F func);
  81. ///
  82. /// Assignment operator. Copies underlying callbackal object.
  83. ///
  84. callback const &operator=(callback const &other);
  85. ///
  86. /// Calls underling callbackal object. If the callback is empty, throws bad_callback_call.
  87. ///
  88. result_type operator()(Params... params) const;
  89. ///
  90. /// Return true if the callback is empty
  91. ///
  92. bool empty() const;
  93. ///
  94. /// Returns true if the callback is not empty
  95. ///
  96. operator bool() const;
  97. ///
  98. /// Swaps two callbackal object. Does not throw.
  99. ///
  100. void swap(callback &other);
  101. ///
  102. /// Get underlying pointer to callable_type
  103. ///
  104. /// \ver{v1_2}
  105. pointer_type const &get_pointer() const;
  106. ///
  107. /// Get underlying pointer to callable_type
  108. ///
  109. /// \ver{v1_2}
  110. pointer_type &get_pointer();
  111. };
  112. #else
  113. #define BOOSTER_CALLBACK \
  114. template<typename Result BOOSTER_TEMPLATE_PARAMS > \
  115. struct callable<Result(BOOSTER_TEMPLATE_TYPE_PARAMS)> :public refcounted\
  116. { \
  117. virtual Result operator()(BOOSTER_TYPE_PARAMS) = 0; \
  118. virtual ~callable(){} \
  119. }; \
  120. \
  121. template<typename Result BOOSTER_TEMPLATE_PARAMS > \
  122. class callback<Result(BOOSTER_TEMPLATE_TYPE_PARAMS)> \
  123. { \
  124. public: \
  125. typedef Result result_type; \
  126. \
  127. typedef callable<Result(BOOSTER_TEMPLATE_TYPE_PARAMS)> \
  128. callable_type; \
  129. typedef intrusive_ptr<callable_type> pointer_type; \
  130. \
  131. template<typename R,typename F> \
  132. struct callable_impl : public callable_type { \
  133. F func; \
  134. callable_impl(F f) : func(f){} \
  135. virtual R operator()(BOOSTER_TYPE_PARAMS) \
  136. { return func(BOOSTER_CALL_PARAMS); } \
  137. }; \
  138. \
  139. template<typename F> \
  140. struct callable_impl<void,F> : public callable_type { \
  141. F func; \
  142. callable_impl(F f) : func(f){} \
  143. virtual void operator()(BOOSTER_TYPE_PARAMS) \
  144. { func(BOOSTER_CALL_PARAMS); } \
  145. }; \
  146. \
  147. callback(){} \
  148. \
  149. template<typename Call> \
  150. callback(intrusive_ptr<Call> c) : call_ptr(c) \
  151. {} \
  152. \
  153. template<typename Call> \
  154. callback(std::auto_ptr<Call> ptr) : call_ptr(ptr.release()) \
  155. {} \
  156. \
  157. template<typename Call> \
  158. callback const &operator=(intrusive_ptr<Call> c) \
  159. { call_ptr = c; return *this; } \
  160. \
  161. template<typename Call> \
  162. callback const &operator=(std::auto_ptr<Call> c) \
  163. { call_ptr = 0; call_ptr = c.release(); return *this; } \
  164. \
  165. template<typename F> \
  166. callback(F func) : call_ptr(new callable_impl<Result,F>(func)) \
  167. {} \
  168. \
  169. callback(callback const &other) : call_ptr(other.call_ptr) {} \
  170. \
  171. template<typename F> \
  172. callback const &operator=(F func) \
  173. { \
  174. call_ptr = new callable_impl<Result,F>(func); \
  175. return *this; \
  176. } \
  177. \
  178. callback const &operator=(callback const &other) \
  179. { \
  180. if(this != &other) { call_ptr=other.call_ptr; } \
  181. return *this; \
  182. } \
  183. \
  184. Result operator()(BOOSTER_TYPE_PARAMS) const \
  185. { \
  186. if(!call_ptr.get()) throw bad_callback_call(); \
  187. return (*call_ptr)(BOOSTER_CALL_PARAMS); \
  188. } \
  189. \
  190. bool empty() const { return call_ptr.get()==0; } \
  191. \
  192. operator bool() const { return !empty(); } \
  193. \
  194. void swap(callback &other) { call_ptr.swap(other.call_ptr); } \
  195. pointer_type const &get_pointer() const { return call_ptr; } \
  196. pointer_type &get_pointer() { return call_ptr; } \
  197. \
  198. private: \
  199. pointer_type call_ptr; \
  200. }; \
  201. #define BOOSTER_TEMPLATE_PARAMS
  202. #define BOOSTER_TEMPLATE_TYPE_PARAMS
  203. #define BOOSTER_TYPE_PARAMS
  204. #define BOOSTER_CALL_PARAMS
  205. BOOSTER_CALLBACK
  206. #undef BOOSTER_TEMPLATE_PARAMS
  207. #undef BOOSTER_TEMPLATE_TYPE_PARAMS
  208. #undef BOOSTER_TYPE_PARAMS
  209. #undef BOOSTER_CALL_PARAMS
  210. #define BOOSTER_TEMPLATE_PARAMS ,typename P1
  211. #define BOOSTER_TEMPLATE_TYPE_PARAMS P1
  212. #define BOOSTER_TYPE_PARAMS P1 a1
  213. #define BOOSTER_CALL_PARAMS a1
  214. BOOSTER_CALLBACK
  215. #undef BOOSTER_TEMPLATE_PARAMS
  216. #undef BOOSTER_TEMPLATE_TYPE_PARAMS
  217. #undef BOOSTER_TYPE_PARAMS
  218. #undef BOOSTER_CALL_PARAMS
  219. #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2
  220. #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2
  221. #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2
  222. #define BOOSTER_CALL_PARAMS a1,a2
  223. BOOSTER_CALLBACK
  224. #undef BOOSTER_TEMPLATE_PARAMS
  225. #undef BOOSTER_TEMPLATE_TYPE_PARAMS
  226. #undef BOOSTER_TYPE_PARAMS
  227. #undef BOOSTER_CALL_PARAMS
  228. #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3
  229. #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3
  230. #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3
  231. #define BOOSTER_CALL_PARAMS a1,a2,a3
  232. BOOSTER_CALLBACK
  233. #undef BOOSTER_TEMPLATE_PARAMS
  234. #undef BOOSTER_TEMPLATE_TYPE_PARAMS
  235. #undef BOOSTER_TYPE_PARAMS
  236. #undef BOOSTER_CALL_PARAMS
  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. #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3,typename P4,typename P5
  247. #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3, P4, P5
  248. #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3,P4 a4,P5 a5
  249. #define BOOSTER_CALL_PARAMS a1,a2,a3,a4,a5
  250. BOOSTER_CALLBACK
  251. #undef BOOSTER_TEMPLATE_PARAMS
  252. #undef BOOSTER_TEMPLATE_TYPE_PARAMS
  253. #undef BOOSTER_TYPE_PARAMS
  254. #undef BOOSTER_CALL_PARAMS
  255. #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3,typename P4,typename P5,typename P6
  256. #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3, P4, P5, P6
  257. #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3,P4 a4,P5 a5,P6 a6
  258. #define BOOSTER_CALL_PARAMS a1,a2,a3,a4,a5,a6
  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. #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3,typename P4,typename P5,typename P6,typename P7
  265. #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3, P4, P5, P6, P7
  266. #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3,P4 a4,P5 a5,P6 a6,P7 a7
  267. #define BOOSTER_CALL_PARAMS a1,a2,a3,a4,a5,a6,a7
  268. BOOSTER_CALLBACK
  269. #undef BOOSTER_TEMPLATE_PARAMS
  270. #undef BOOSTER_TEMPLATE_TYPE_PARAMS
  271. #undef BOOSTER_TYPE_PARAMS
  272. #undef BOOSTER_CALL_PARAMS
  273. #define BOOSTER_TEMPLATE_PARAMS ,typename P1,typename P2,typename P3,typename P4,typename P5,typename P6,typename P7,typename P8
  274. #define BOOSTER_TEMPLATE_TYPE_PARAMS P1, P2, P3, P4, P5, P6, P7, P8
  275. #define BOOSTER_TYPE_PARAMS P1 a1,P2 a2,P3 a3,P4 a4,P5 a5,P6 a6,P7 a7,P8 a8
  276. #define BOOSTER_CALL_PARAMS a1,a2,a3,a4,a5,a6,a7,a8
  277. BOOSTER_CALLBACK
  278. #undef BOOSTER_TEMPLATE_PARAMS
  279. #undef BOOSTER_TEMPLATE_TYPE_PARAMS
  280. #undef BOOSTER_TYPE_PARAMS
  281. #undef BOOSTER_CALL_PARAMS
  282. #undef BOOSTER_CALLBACK
  283. #endif // DOC
  284. } // booster
  285. #endif