C++98 用 std::function もどき

Formato
C++
Post date
2016-02-14 19:54
Publication Period
Unlimited
  1. #pragma once
  2. #include <algorithm>
  3. #include <stdexcept>
  4. class FunctionCallException : public std::logic_error
  5. {
  6. public:
  7. FunctionCallException() : logic_error("FunctionCallException")
  8. {
  9. }
  10. };
  11. template<typename T>
  12. class Function;
  13. #define DEFINE_FUNC \
  14. template<typename TRet TYPENAMES_DECL_C TYPENAMES_DECL> \
  15. class Function<TRet(TYPES)> \
  16. { \
  17. class ICallable \
  18. { \
  19. public: \
  20. virtual ~ICallable() \
  21. { \
  22. } \
  23. \
  24. virtual TRet operator()(ARGS_DECL) const = 0; \
  25. virtual ICallable* Clone() const = 0; \
  26. }; \
  27. \
  28. template<typename TObject> \
  29. class CallableImpl : public ICallable \
  30. { \
  31. public: \
  32. explicit CallableImpl(TObject obj) : m_Object(obj) \
  33. { \
  34. } \
  35. \
  36. virtual TRet operator()(ARGS_DECL) const \
  37. { \
  38. return m_Object(ARGS); \
  39. } \
  40. \
  41. virtual ICallable* Clone() const \
  42. { \
  43. return new CallableImpl<TObject>(m_Object); \
  44. } \
  45. \
  46. private: \
  47. TObject m_Object; \
  48. }; \
  49. \
  50. public: \
  51. Function() : m_pCallable(NULL) \
  52. { \
  53. } \
  54. \
  55. template<typename TObject> \
  56. Function(TObject obj) : m_pCallable(new CallableImpl<TObject>(obj)) \
  57. { \
  58. } \
  59. \
  60. Function(const Function& rhs) : m_pCallable(rhs.m_pCallable ? rhs.m_pCallable->Clone() : NULL) \
  61. { \
  62. } \
  63. \
  64. Function& operator=(const Function& rhs) \
  65. { \
  66. Function(rhs).Swap(*this); \
  67. return *this; \
  68. } \
  69. \
  70. void Swap(Function& rhs) \
  71. { \
  72. using std::swap; \
  73. swap(m_pCallable, rhs.m_pCallable); \
  74. } \
  75. \
  76. TRet operator()(ARGS_DECL) const \
  77. { \
  78. if (!m_pCallable) \
  79. { \
  80. throw FunctionCallException(); \
  81. } \
  82. \
  83. return (*m_pCallable)(ARGS); \
  84. } \
  85. \
  86. private: \
  87. ICallable* m_pCallable; \
  88. }; \
  89. \
  90. template<TYPENAMES_DECL> \
  91. class Function<void(TYPES)> \
  92. { \
  93. class ICallable \
  94. { \
  95. public: \
  96. virtual ~ICallable() \
  97. { \
  98. } \
  99. \
  100. virtual void operator()(ARGS_DECL) const = 0; \
  101. virtual ICallable* Clone() const = 0; \
  102. }; \
  103. \
  104. template<typename TObject> \
  105. class CallableImpl : public ICallable \
  106. { \
  107. public: \
  108. explicit CallableImpl(TObject obj) : m_Object(obj) \
  109. { \
  110. } \
  111. \
  112. virtual void operator()(ARGS_DECL) const \
  113. { \
  114. m_Object(ARGS); \
  115. } \
  116. \
  117. virtual ICallable* Clone() const \
  118. { \
  119. return new CallableImpl<TObject>(m_Object); \
  120. } \
  121. \
  122. private: \
  123. TObject m_Object; \
  124. }; \
  125. \
  126. public: \
  127. Function() : m_pCallable(NULL) \
  128. { \
  129. } \
  130. \
  131. template<typename TObject> \
  132. Function(TObject obj) : m_pCallable(new CallableImpl<TObject>(obj)) \
  133. { \
  134. } \
  135. \
  136. Function(const Function& rhs) : m_pCallable(rhs.m_pCallable ? rhs.m_pCallable->Clone() : NULL) \
  137. { \
  138. } \
  139. \
  140. Function& operator=(const Function& rhs) \
  141. { \
  142. Function(rhs).Swap(*this); \
  143. return *this; \
  144. } \
  145. \
  146. void Swap(Function& rhs) \
  147. { \
  148. using std::swap; \
  149. swap(m_pCallable, rhs.m_pCallable); \
  150. } \
  151. \
  152. void operator()(ARGS_DECL) const \
  153. { \
  154. if (!m_pCallable) \
  155. { \
  156. throw FunctionCallException(); \
  157. } \
  158. \
  159. (*m_pCallable)(ARGS); \
  160. } \
  161. \
  162. private: \
  163. ICallable* m_pCallable; \
  164. };
  165. // 0
  166. #define TYPENAMES_DECL_C
  167. #define TYPENAMES_DECL
  168. #define TYPES
  169. #define ARGS_DECL
  170. #define ARGS
  171. DEFINE_FUNC
  172. #undef TYPENAMES_DECL_C
  173. #undef TYPENAMES_DECL
  174. #undef TYPES
  175. #undef ARGS_DECL
  176. #undef ARGS
  177. // ---
  178. #define TYPENAMES_DECL_C ,
  179. // 1
  180. #define TYPENAMES_DECL typename TArg1
  181. #define TYPES TArg1
  182. #define ARGS_DECL TArg1 arg1
  183. #define ARGS arg1
  184. DEFINE_FUNC
  185. #undef TYPENAMES_DECL
  186. #undef TYPES
  187. #undef ARGS_DECL
  188. #undef ARGS
  189. // 2
  190. #define TYPENAMES_DECL typename TArg1, typename TArg2
  191. #define TYPES TArg1, TArg2
  192. #define ARGS_DECL TArg1 arg1, TArg2 arg2
  193. #define ARGS arg1, arg2
  194. DEFINE_FUNC
  195. #undef TYPENAMES_DECL
  196. #undef TYPES
  197. #undef ARGS_DECL
  198. #undef ARGS
  199. // 3
  200. #define TYPENAMES_DECL typename TArg1, typename TArg2, typename TArg3
  201. #define TYPES TArg1, TArg2, TArg3
  202. #define ARGS_DECL TArg1 arg1, TArg2 arg2, TArg3 arg3
  203. #define ARGS arg1, arg2, arg3
  204. DEFINE_FUNC
  205. #undef TYPENAMES_DECL
  206. #undef TYPES
  207. #undef ARGS_DECL
  208. #undef ARGS
  209. // 4
  210. #define TYPENAMES_DECL typename TArg1, typename TArg2, typename TArg3, typename TArg4
  211. #define TYPES TArg1, TArg2, TArg3, TArg4
  212. #define ARGS_DECL TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4
  213. #define ARGS arg1, arg2, arg3, arg4
  214. DEFINE_FUNC
  215. #undef TYPENAMES_DECL
  216. #undef TYPES
  217. #undef ARGS_DECL
  218. #undef ARGS
  219. // ---
  220. #undef TYPENAMES_DECL_C
  221. template<typename T>
  222. void swap(Function<T>& lhs, Function<T>& rhs)
  223. {
  224. lhs.Swap(rhs);
  225. }
Descargar Printable view

URL of this paste

Embed with JavaScript

Embed with iframe

Raw text