light_function_pp.hpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. /*
  2. * Copyright Andrey Semashev 2007 - 2015.
  3. * Distributed under the Boost Software License, Version 1.0.
  4. * (See accompanying file LICENSE_1_0.txt or copy at
  5. * http://www.boost.org/LICENSE_1_0.txt)
  6. */
  7. template<
  8. typename ResultT
  9. BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), typename ArgT)
  10. >
  11. class light_function< ResultT (BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), ArgT)) >
  12. {
  13. typedef light_function this_type;
  14. BOOST_COPYABLE_AND_MOVABLE(this_type)
  15. public:
  16. typedef ResultT result_type;
  17. private:
  18. struct impl_base
  19. {
  20. typedef result_type (*invoke_type)(void* BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), ArgT));
  21. const invoke_type invoke;
  22. typedef impl_base* (*clone_type)(const void*);
  23. const clone_type clone;
  24. typedef void (*destroy_type)(void*);
  25. const destroy_type destroy;
  26. impl_base(invoke_type inv, clone_type cl, destroy_type dstr) : invoke(inv), clone(cl), destroy(dstr)
  27. {
  28. }
  29. BOOST_DELETED_FUNCTION(impl_base(impl_base const&))
  30. BOOST_DELETED_FUNCTION(impl_base& operator= (impl_base const&))
  31. };
  32. #if !defined(BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS)
  33. template< typename FunT >
  34. class impl;
  35. template< typename FunT >
  36. friend class impl;
  37. #endif
  38. template< typename FunT >
  39. class impl :
  40. public impl_base
  41. {
  42. typedef impl< FunT > this_type;
  43. FunT m_Function;
  44. public:
  45. explicit impl(FunT const& fun) :
  46. impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
  47. m_Function(fun)
  48. {
  49. }
  50. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  51. explicit impl(FunT&& fun) :
  52. impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
  53. m_Function(boost::move(fun))
  54. {
  55. }
  56. #endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  57. static void destroy_impl(void* self)
  58. {
  59. delete static_cast< impl* >(static_cast< impl_base* >(self));
  60. }
  61. static impl_base* clone_impl(const void* self)
  62. {
  63. return new impl(static_cast< const impl* >(static_cast< const impl_base* >(self))->m_Function);
  64. }
  65. static result_type invoke_impl(void* self BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(BOOST_PP_ITERATION(), ArgT, arg))
  66. {
  67. return static_cast< impl* >(static_cast< impl_base* >(self))->m_Function(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), arg));
  68. }
  69. BOOST_DELETED_FUNCTION(impl(impl const&))
  70. BOOST_DELETED_FUNCTION(impl& operator= (impl const&))
  71. };
  72. private:
  73. impl_base* m_pImpl;
  74. public:
  75. BOOST_CONSTEXPR light_function() BOOST_NOEXCEPT : m_pImpl(NULL)
  76. {
  77. }
  78. light_function(this_type const& that)
  79. {
  80. if (that.m_pImpl)
  81. m_pImpl = that.m_pImpl->clone(that.m_pImpl);
  82. else
  83. m_pImpl = NULL;
  84. }
  85. light_function(BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
  86. {
  87. m_pImpl = that.m_pImpl;
  88. that.m_pImpl = NULL;
  89. }
  90. light_function(BOOST_RV_REF(const this_type) that) BOOST_NOEXCEPT
  91. {
  92. m_pImpl = that.m_pImpl;
  93. ((this_type&)that).m_pImpl = NULL;
  94. }
  95. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  96. template< typename FunT >
  97. light_function(FunT&& fun) :
  98. m_pImpl(new impl< typename remove_cv< typename remove_reference< FunT >::type >::type >(boost::forward< FunT >(fun)))
  99. {
  100. }
  101. #else
  102. template< typename FunT >
  103. light_function(FunT const& fun, typename boost::disable_if_c< is_rv_or_same< FunT, this_type >::value, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()) :
  104. m_pImpl(new impl< FunT >(fun))
  105. {
  106. }
  107. template< typename FunT >
  108. light_function(BOOST_RV_REF(FunT) fun, typename boost::disable_if_c< is_cv_same< FunT, this_type >::value, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()) :
  109. m_pImpl(new impl< typename remove_cv< FunT >::type >(fun))
  110. {
  111. }
  112. #endif
  113. //! Constructor from NULL
  114. #if !defined(BOOST_NO_CXX11_NULLPTR)
  115. BOOST_CONSTEXPR light_function(std::nullptr_t) BOOST_NOEXCEPT
  116. #else
  117. BOOST_CONSTEXPR light_function(int p) BOOST_NOEXCEPT
  118. #endif
  119. : m_pImpl(NULL)
  120. {
  121. #if defined(BOOST_NO_CXX11_NULLPTR)
  122. BOOST_ASSERT(p == 0);
  123. #endif
  124. }
  125. ~light_function()
  126. {
  127. clear();
  128. }
  129. light_function& operator= (BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
  130. {
  131. this->swap(that);
  132. return *this;
  133. }
  134. light_function& operator= (BOOST_COPY_ASSIGN_REF(this_type) that)
  135. {
  136. light_function tmp = static_cast< this_type const& >(that);
  137. this->swap(tmp);
  138. return *this;
  139. }
  140. //! Assignment of NULL
  141. #if !defined(BOOST_NO_CXX11_NULLPTR)
  142. light_function& operator= (std::nullptr_t)
  143. #else
  144. light_function& operator= (int p)
  145. #endif
  146. {
  147. #if defined(BOOST_NO_CXX11_NULLPTR)
  148. BOOST_ASSERT(p == 0);
  149. #endif
  150. clear();
  151. return *this;
  152. }
  153. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  154. template< typename FunT >
  155. light_function& operator= (FunT&& fun)
  156. {
  157. light_function tmp(boost::forward< FunT >(fun));
  158. this->swap(tmp);
  159. return *this;
  160. }
  161. #else
  162. template< typename FunT >
  163. typename boost::disable_if_c< is_rv_or_same< FunT, this_type >::value, this_type& >::type
  164. operator= (FunT const& fun)
  165. {
  166. light_function tmp(fun);
  167. this->swap(tmp);
  168. return *this;
  169. }
  170. #endif
  171. result_type operator() (BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), ArgT, arg)) const
  172. {
  173. return m_pImpl->invoke(m_pImpl BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), arg));
  174. }
  175. BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
  176. bool operator! () const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
  177. bool empty() const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
  178. void clear() BOOST_NOEXCEPT
  179. {
  180. if (m_pImpl)
  181. {
  182. m_pImpl->destroy(m_pImpl);
  183. m_pImpl = NULL;
  184. }
  185. }
  186. void swap(this_type& that) BOOST_NOEXCEPT
  187. {
  188. impl_base* p = m_pImpl;
  189. m_pImpl = that.m_pImpl;
  190. that.m_pImpl = p;
  191. }
  192. };
  193. template<
  194. BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), typename ArgT)
  195. >
  196. class light_function< void (BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), ArgT)) >
  197. {
  198. typedef light_function this_type;
  199. BOOST_COPYABLE_AND_MOVABLE(this_type)
  200. public:
  201. typedef void result_type;
  202. private:
  203. struct impl_base
  204. {
  205. typedef void (*invoke_type)(void* BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), ArgT));
  206. const invoke_type invoke;
  207. typedef impl_base* (*clone_type)(const void*);
  208. const clone_type clone;
  209. typedef void (*destroy_type)(void*);
  210. const destroy_type destroy;
  211. impl_base(invoke_type inv, clone_type cl, destroy_type dstr) : invoke(inv), clone(cl), destroy(dstr)
  212. {
  213. }
  214. BOOST_DELETED_FUNCTION(impl_base(impl_base const&))
  215. BOOST_DELETED_FUNCTION(impl_base& operator= (impl_base const&))
  216. };
  217. #if !defined(BOOST_LOG_NO_MEMBER_TEMPLATE_FRIENDS)
  218. template< typename FunT >
  219. class impl;
  220. template< typename FunT >
  221. friend class impl;
  222. #endif
  223. template< typename FunT >
  224. class impl :
  225. public impl_base
  226. {
  227. typedef impl< FunT > this_type;
  228. FunT m_Function;
  229. public:
  230. explicit impl(FunT const& fun) :
  231. impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
  232. m_Function(fun)
  233. {
  234. }
  235. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  236. explicit impl(FunT&& fun) :
  237. impl_base(&this_type::invoke_impl, &this_type::clone_impl, &this_type::destroy_impl),
  238. m_Function(boost::move(fun))
  239. {
  240. }
  241. #endif // !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  242. static void destroy_impl(void* self)
  243. {
  244. delete static_cast< impl* >(static_cast< impl_base* >(self));
  245. }
  246. static impl_base* clone_impl(const void* self)
  247. {
  248. return new impl(static_cast< const impl* >(static_cast< const impl_base* >(self))->m_Function);
  249. }
  250. static result_type invoke_impl(void* self BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(BOOST_PP_ITERATION(), ArgT, arg))
  251. {
  252. static_cast< impl* >(static_cast< impl_base* >(self))->m_Function(BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(), arg));
  253. }
  254. BOOST_DELETED_FUNCTION(impl(impl const&))
  255. BOOST_DELETED_FUNCTION(impl& operator= (impl const&))
  256. };
  257. private:
  258. impl_base* m_pImpl;
  259. public:
  260. BOOST_CONSTEXPR light_function() BOOST_NOEXCEPT : m_pImpl(NULL)
  261. {
  262. }
  263. light_function(this_type const& that)
  264. {
  265. if (that.m_pImpl)
  266. m_pImpl = that.m_pImpl->clone(that.m_pImpl);
  267. else
  268. m_pImpl = NULL;
  269. }
  270. light_function(BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
  271. {
  272. m_pImpl = that.m_pImpl;
  273. that.m_pImpl = NULL;
  274. }
  275. light_function(BOOST_RV_REF(const this_type) that) BOOST_NOEXCEPT
  276. {
  277. m_pImpl = that.m_pImpl;
  278. ((this_type&)that).m_pImpl = NULL;
  279. }
  280. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  281. template< typename FunT >
  282. light_function(FunT&& fun) :
  283. m_pImpl(new impl< typename remove_cv< typename remove_reference< FunT >::type >::type >(boost::forward< FunT >(fun)))
  284. {
  285. }
  286. #else
  287. template< typename FunT >
  288. light_function(FunT const& fun, typename boost::disable_if_c< is_rv_or_same< FunT, this_type >::value, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()) :
  289. m_pImpl(new impl< FunT >(fun))
  290. {
  291. }
  292. template< typename FunT >
  293. light_function(BOOST_RV_REF(FunT) fun, typename boost::disable_if_c< is_cv_same< FunT, this_type >::value, boost::log::aux::sfinae_dummy >::type = boost::log::aux::sfinae_dummy()) :
  294. m_pImpl(new impl< typename remove_cv< FunT >::type >(fun))
  295. {
  296. }
  297. #endif
  298. //! Constructor from NULL
  299. #if !defined(BOOST_NO_CXX11_NULLPTR)
  300. BOOST_CONSTEXPR light_function(std::nullptr_t) BOOST_NOEXCEPT
  301. #else
  302. BOOST_CONSTEXPR light_function(int p) BOOST_NOEXCEPT
  303. #endif
  304. : m_pImpl(NULL)
  305. {
  306. #if defined(BOOST_NO_CXX11_NULLPTR)
  307. BOOST_ASSERT(p == 0);
  308. #endif
  309. }
  310. ~light_function()
  311. {
  312. clear();
  313. }
  314. light_function& operator= (BOOST_RV_REF(this_type) that) BOOST_NOEXCEPT
  315. {
  316. this->swap(that);
  317. return *this;
  318. }
  319. light_function& operator= (BOOST_COPY_ASSIGN_REF(this_type) that)
  320. {
  321. light_function tmp = static_cast< this_type const& >(that);
  322. this->swap(tmp);
  323. return *this;
  324. }
  325. //! Assignment of NULL
  326. #if !defined(BOOST_NO_CXX11_NULLPTR)
  327. light_function& operator= (std::nullptr_t)
  328. #else
  329. light_function& operator= (int p)
  330. #endif
  331. {
  332. #if defined(BOOST_NO_CXX11_NULLPTR)
  333. BOOST_ASSERT(p == 0);
  334. #endif
  335. clear();
  336. return *this;
  337. }
  338. #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
  339. template< typename FunT >
  340. light_function& operator= (FunT&& fun)
  341. {
  342. light_function tmp(boost::forward< FunT >(fun));
  343. this->swap(tmp);
  344. return *this;
  345. }
  346. #else
  347. template< typename FunT >
  348. typename boost::disable_if_c< is_rv_or_same< FunT, this_type >::value, this_type& >::type
  349. operator= (FunT const& fun)
  350. {
  351. light_function tmp(fun);
  352. this->swap(tmp);
  353. return *this;
  354. }
  355. #endif
  356. result_type operator() (BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_ITERATION(), ArgT, arg)) const
  357. {
  358. m_pImpl->invoke(m_pImpl BOOST_PP_ENUM_TRAILING_PARAMS(BOOST_PP_ITERATION(), arg));
  359. }
  360. BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
  361. bool operator! () const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
  362. bool empty() const BOOST_NOEXCEPT { return (m_pImpl == NULL); }
  363. void clear() BOOST_NOEXCEPT
  364. {
  365. if (m_pImpl)
  366. {
  367. m_pImpl->destroy(m_pImpl);
  368. m_pImpl = NULL;
  369. }
  370. }
  371. void swap(this_type& that) BOOST_NOEXCEPT
  372. {
  373. impl_base* p = m_pImpl;
  374. m_pImpl = that.m_pImpl;
  375. that.m_pImpl = p;
  376. }
  377. };