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.
 
 
 
 
 
 

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