no_spec_overloads.hpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. // Copyright Cromwell D. Enage 2018.
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. #ifndef BOOST_PARAMETER_AUX_PREPROCESSOR_IMPL_NO_SPEC_OVERLOADS_HPP
  6. #define BOOST_PARAMETER_AUX_PREPROCESSOR_IMPL_NO_SPEC_OVERLOADS_HPP
  7. #include <boost/parameter/aux_/preprocessor/impl/function_name.hpp>
  8. // Defines the no-spec implementation function header.
  9. #define BOOST_PARAMETER_NO_SPEC_FUNCTION_IMPL_HEAD(name, is_const) \
  10. template <typename ResultType, typename Args> \
  11. BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(name) ResultType \
  12. BOOST_PARAMETER_NO_SPEC_FUNCTION_IMPL_NAME( \
  13. name, is_const \
  14. )(ResultType(*)(), Args const& args)
  15. /**/
  16. #include <boost/parameter/config.hpp>
  17. #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
  18. #include <boost/parameter/aux_/preprocessor/impl/parenthesized_return_type.hpp>
  19. // Expands to the result metafunction for the specified no-spec function.
  20. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  21. #define BOOST_PARAMETER_NO_SPEC_FUNCTION_HEAD(result, name, is_const) \
  22. template <typename TaggedArg0, typename ...TaggedArgs> \
  23. using BOOST_PARAMETER_NO_SPEC_FUNCTION_RESULT_NAME(name, is_const) \
  24. = typename BOOST_PARAMETER_PARENTHESIZED_RETURN_TYPE(result);
  25. /**/
  26. #else
  27. #define BOOST_PARAMETER_NO_SPEC_FUNCTION_HEAD(result, name, is_const) \
  28. template <typename TaggedArg0, typename ...TaggedArgs> \
  29. struct BOOST_PARAMETER_NO_SPEC_FUNCTION_RESULT_NAME(name, is_const) \
  30. : BOOST_PARAMETER_PARENTHESIZED_RETURN_TYPE(result) \
  31. { \
  32. };
  33. /**/
  34. #endif // BOOST_PARAMETER_CAN_USE_MP11
  35. #include <boost/parameter/compose.hpp>
  36. #include <boost/parameter/are_tagged_arguments.hpp>
  37. #include <boost/parameter/aux_/preprocessor/impl/parenthesized_type.hpp>
  38. #include <boost/core/enable_if.hpp>
  39. // Exapnds to a variadic constructor that is enabled if and only if all its
  40. // arguments are tagged arguments. The enclosing class must inherit from the
  41. // specified base class, which in turn must implement a constructor that takes
  42. // in the argument pack that this one passes on.
  43. #define BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR(class_, base) \
  44. template < \
  45. typename TaggedArg0 \
  46. , typename ...TaggedArgs \
  47. , typename = typename ::boost::enable_if< \
  48. ::boost::parameter \
  49. ::are_tagged_arguments<TaggedArg0,TaggedArgs...> \
  50. >::type \
  51. > inline explicit \
  52. class_(TaggedArg0 const& arg0, TaggedArgs const&... args) \
  53. : BOOST_PARAMETER_PARENTHESIZED_TYPE(base)( \
  54. ::boost::parameter::compose(arg0, args...) \
  55. ) \
  56. { \
  57. }
  58. /**/
  59. // Exapnds to a variadic constructor that is enabled if and only if all its
  60. // arguments are tagged arguments. The specified function must be able to
  61. // take in the argument pack that this constructor passes on.
  62. #define BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR(class_, func) \
  63. template < \
  64. typename TaggedArg0 \
  65. , typename ...TaggedArgs \
  66. , typename = typename ::boost::enable_if< \
  67. ::boost::parameter \
  68. ::are_tagged_arguments<TaggedArg0,TaggedArgs...> \
  69. >::type \
  70. > inline explicit \
  71. class_(TaggedArg0 const& arg0, TaggedArgs const&... args) \
  72. { \
  73. func(::boost::parameter::compose(arg0, args...)); \
  74. }
  75. /**/
  76. #include <boost/parameter/aux_/preprocessor/nullptr.hpp>
  77. #include <boost/preprocessor/control/expr_if.hpp>
  78. // Exapnds to a variadic function that is enabled if and only if
  79. // all its arguments are tagged arguments.
  80. #define BOOST_PARAMETER_NO_SPEC_FUNCTION_OVERLOAD(name, impl, is_m, c) \
  81. template <typename TaggedArg0, typename ...TaggedArgs> \
  82. BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(impl) \
  83. inline typename ::boost::lazy_enable_if< \
  84. ::boost::parameter \
  85. ::are_tagged_arguments<TaggedArg0,TaggedArgs...> \
  86. , BOOST_PARAMETER_NO_SPEC_FUNCTION_RESULT_NAME( \
  87. impl, c \
  88. )<TaggedArg0,TaggedArgs...> \
  89. >::type BOOST_PARAMETER_MEMBER_FUNCTION_NAME(name) \
  90. (TaggedArg0 const& arg0, TaggedArgs const&... args) \
  91. BOOST_PP_EXPR_IF(c, const) \
  92. { \
  93. return BOOST_PP_EXPR_IF(is_m, this->) \
  94. BOOST_PARAMETER_NO_SPEC_FUNCTION_IMPL_NAME(impl, c)( \
  95. static_cast< \
  96. typename BOOST_PARAMETER_NO_SPEC_FUNCTION_RESULT_NAME( \
  97. impl, c \
  98. )<TaggedArg0,TaggedArgs...>::type(*)() \
  99. >(BOOST_PARAMETER_AUX_PP_NULLPTR) \
  100. , ::boost::parameter::compose(arg0, args...) \
  101. ); \
  102. }
  103. /**/
  104. #else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
  105. #include <boost/parameter/aux_/void.hpp>
  106. #include <boost/parameter/aux_/preprocessor/impl/parenthesized_return_type.hpp>
  107. #include <boost/preprocessor/facilities/intercept.hpp>
  108. #include <boost/preprocessor/repetition/enum_binary_params.hpp>
  109. // Expands to the result metafunction for the specified no-spec function.
  110. #define BOOST_PARAMETER_NO_SPEC_FUNCTION_HEAD(result, name, is_const) \
  111. template < \
  112. BOOST_PP_ENUM_BINARY_PARAMS( \
  113. BOOST_PARAMETER_COMPOSE_MAX_ARITY \
  114. , typename TaggedArg \
  115. , = ::boost::parameter::void_ BOOST_PP_INTERCEPT \
  116. ) \
  117. > \
  118. struct BOOST_PARAMETER_NO_SPEC_FUNCTION_RESULT_NAME(name, is_const) \
  119. : BOOST_PARAMETER_PARENTHESIZED_RETURN_TYPE(result) \
  120. { \
  121. };
  122. /**/
  123. #include <boost/parameter/compose.hpp>
  124. #include <boost/parameter/aux_/preprocessor/impl/parenthesized_type.hpp>
  125. #include <boost/preprocessor/comparison/equal.hpp>
  126. #include <boost/preprocessor/control/expr_if.hpp>
  127. #include <boost/preprocessor/repetition/enum_params.hpp>
  128. #include <boost/preprocessor/tuple/elem.hpp>
  129. #if defined(BOOST_NO_SFINAE)
  130. // Exapnds to a tagged-argument constructor overload that passes the argument
  131. // pack to the base class delegate constructor.
  132. #define BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR_OVERLOAD_Z(z, n, data) \
  133. template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename TaggedArg)> \
  134. BOOST_PP_EXPR_IF(BOOST_PP_EQUAL(n, 1), explicit) inline \
  135. BOOST_PP_TUPLE_ELEM(2, 0, data)( \
  136. BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, TaggedArg, const& arg) \
  137. ) : BOOST_PARAMETER_PARENTHESIZED_TYPE(BOOST_PP_TUPLE_ELEM(2, 1, data))( \
  138. ::boost::parameter::compose(BOOST_PP_ENUM_PARAMS_Z(z, n, arg)) \
  139. ) \
  140. { \
  141. }
  142. /**/
  143. // Exapnds to a tagged-argument constructor overload that passes the argument
  144. // pack to the delegate function.
  145. #define BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR_OVERLOAD_Z(z, n, data) \
  146. template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename TaggedArg)> \
  147. BOOST_PP_EXPR_IF(BOOST_PP_EQUAL(n, 1), explicit) inline \
  148. BOOST_PP_TUPLE_ELEM(2, 0, data)( \
  149. BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, TaggedArg, const& a) \
  150. ) \
  151. { \
  152. BOOST_PP_TUPLE_ELEM(2, 1, data)( \
  153. ::boost::parameter::compose(BOOST_PP_ENUM_PARAMS_Z(z, n, a)) \
  154. ); \
  155. }
  156. /**/
  157. #include <boost/parameter/aux_/preprocessor/nullptr.hpp>
  158. // Exapnds to a tagged-argument function overload.
  159. #define BOOST_PARAMETER_NO_SPEC_FUNCTION_OVERLOAD_Z(z, n, data) \
  160. template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename TaggedArg)> \
  161. BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(BOOST_PP_TUPLE_ELEM(4, 1, data)) \
  162. inline typename BOOST_PARAMETER_NO_SPEC_FUNCTION_RESULT_NAME( \
  163. BOOST_PP_TUPLE_ELEM(4, 1, data) \
  164. , BOOST_PP_TUPLE_ELEM(4, 3, data) \
  165. )<BOOST_PP_ENUM_PARAMS_Z(z, n, TaggedArg)>::type \
  166. BOOST_PARAMETER_MEMBER_FUNCTION_NAME( \
  167. BOOST_PP_TUPLE_ELEM(4, 0, data) \
  168. )(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, TaggedArg, const& arg)) \
  169. BOOST_PP_EXPR_IF(BOOST_PP_TUPLE_ELEM(4, 3, data), const) \
  170. { \
  171. return BOOST_PP_EXPR_IF(BOOST_PP_TUPLE_ELEM(4, 2, data), this->) \
  172. BOOST_PARAMETER_NO_SPEC_FUNCTION_IMPL_NAME( \
  173. BOOST_PP_TUPLE_ELEM(4, 1, data) \
  174. , BOOST_PP_TUPLE_ELEM(4, 3, data) \
  175. )( \
  176. static_cast< \
  177. typename BOOST_PARAMETER_NO_SPEC_FUNCTION_RESULT_NAME( \
  178. BOOST_PP_TUPLE_ELEM(4, 1, data) \
  179. , BOOST_PP_TUPLE_ELEM(4, 3, data) \
  180. )<BOOST_PP_ENUM_PARAMS_Z(z, n, TaggedArg)>::type(*)() \
  181. >(BOOST_PARAMETER_AUX_PP_NULLPTR) \
  182. , ::boost::parameter::compose(BOOST_PP_ENUM_PARAMS_Z(z, n, arg)) \
  183. ); \
  184. }
  185. /**/
  186. #else // !defined(BOOST_NO_SFINAE)
  187. #include <boost/parameter/are_tagged_arguments.hpp>
  188. #include <boost/parameter/aux_/preprocessor/nullptr.hpp>
  189. #include <boost/core/enable_if.hpp>
  190. // Exapnds to a tagged-argument constructor overload that passes the argument
  191. // pack to the base class delegate constructor. This constructor is enabled
  192. // if and only if all its arguments are tagged arguments.
  193. #define BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR_OVERLOAD_Z(z, n, data) \
  194. template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename TaggedArg)> \
  195. BOOST_PP_EXPR_IF(BOOST_PP_EQUAL(n, 1), explicit) inline \
  196. BOOST_PP_TUPLE_ELEM(2, 0, data)( \
  197. BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, TaggedArg, const& arg) \
  198. , typename ::boost::enable_if< \
  199. ::boost::parameter::are_tagged_arguments< \
  200. BOOST_PP_ENUM_PARAMS_Z(z, n, TaggedArg) \
  201. > \
  202. >::type* = BOOST_PARAMETER_AUX_PP_NULLPTR \
  203. ) : BOOST_PARAMETER_PARENTHESIZED_TYPE(BOOST_PP_TUPLE_ELEM(2, 1, data))( \
  204. ::boost::parameter::compose(BOOST_PP_ENUM_PARAMS_Z(z, n, arg)) \
  205. ) \
  206. { \
  207. }
  208. /**/
  209. // Exapnds to a tagged-argument constructor overload that passes the argument
  210. // pack to the delegate function. This constructor is enabled if and only if
  211. // all its arguments are tagged arguments.
  212. #define BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR_OVERLOAD_Z(z, n, data) \
  213. template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename TaggedArg)> \
  214. BOOST_PP_EXPR_IF(BOOST_PP_EQUAL(n, 1), explicit) inline \
  215. BOOST_PP_TUPLE_ELEM(2, 0, data)( \
  216. BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, TaggedArg, const& a) \
  217. , typename ::boost::enable_if< \
  218. ::boost::parameter::are_tagged_arguments< \
  219. BOOST_PP_ENUM_PARAMS_Z(z, n, TaggedArg) \
  220. > \
  221. >::type* = BOOST_PARAMETER_AUX_PP_NULLPTR \
  222. ) \
  223. { \
  224. BOOST_PP_TUPLE_ELEM(2, 1, data)( \
  225. ::boost::parameter::compose(BOOST_PP_ENUM_PARAMS_Z(z, n, a)) \
  226. ); \
  227. }
  228. /**/
  229. // Exapnds to a function overload that is enabled if and only if
  230. // all its arguments are tagged arguments.
  231. #define BOOST_PARAMETER_NO_SPEC_FUNCTION_OVERLOAD_Z(z, n, data) \
  232. template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename TaggedArg)> \
  233. BOOST_PARAMETER_MEMBER_FUNCTION_STATIC(BOOST_PP_TUPLE_ELEM(4, 1, data)) \
  234. inline typename ::boost::lazy_enable_if< \
  235. ::boost::parameter \
  236. ::are_tagged_arguments<BOOST_PP_ENUM_PARAMS_Z(z, n, TaggedArg)> \
  237. , BOOST_PARAMETER_NO_SPEC_FUNCTION_RESULT_NAME( \
  238. BOOST_PP_TUPLE_ELEM(4, 1, data) \
  239. , BOOST_PP_TUPLE_ELEM(4, 3, data) \
  240. )<BOOST_PP_ENUM_PARAMS_Z(z, n, TaggedArg)> \
  241. >::type BOOST_PARAMETER_MEMBER_FUNCTION_NAME( \
  242. BOOST_PP_TUPLE_ELEM(4, 0, data) \
  243. )(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, TaggedArg, const& arg)) \
  244. BOOST_PP_EXPR_IF(BOOST_PP_TUPLE_ELEM(4, 3, data), const) \
  245. { \
  246. return BOOST_PP_EXPR_IF(BOOST_PP_TUPLE_ELEM(4, 2, data), this->) \
  247. BOOST_PARAMETER_NO_SPEC_FUNCTION_IMPL_NAME( \
  248. BOOST_PP_TUPLE_ELEM(4, 1, data) \
  249. , BOOST_PP_TUPLE_ELEM(4, 3, data) \
  250. )( \
  251. static_cast< \
  252. typename BOOST_PARAMETER_NO_SPEC_FUNCTION_RESULT_NAME( \
  253. BOOST_PP_TUPLE_ELEM(4, 1, data) \
  254. , BOOST_PP_TUPLE_ELEM(4, 3, data) \
  255. )<BOOST_PP_ENUM_PARAMS_Z(z, n, TaggedArg)>::type(*)() \
  256. >(BOOST_PARAMETER_AUX_PP_NULLPTR) \
  257. , ::boost::parameter::compose(BOOST_PP_ENUM_PARAMS_Z(z, n, arg)) \
  258. ); \
  259. }
  260. /**/
  261. #endif // BOOST_NO_SFINAE
  262. #include <boost/preprocessor/arithmetic/inc.hpp>
  263. #include <boost/preprocessor/repetition/repeat_from_to.hpp>
  264. // Emulates a variadic constructor that is enabled if and only if all its
  265. // arguments are tagged arguments. The enclosing class must inherit from the
  266. // specified base class, which in turn must implement a constructor that takes
  267. // in the argument pack that this one passes on.
  268. #define BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR(class_, base) \
  269. BOOST_PP_REPEAT_FROM_TO( \
  270. 1 \
  271. , BOOST_PP_INC(BOOST_PARAMETER_COMPOSE_MAX_ARITY) \
  272. , BOOST_PARAMETER_NO_SPEC_CONSTRUCTOR_OVERLOAD_Z \
  273. , (class_, base) \
  274. )
  275. /**/
  276. // Emulates a variadic constructor that is enabled if and only if all its
  277. // arguments are tagged arguments. The specified function must be able to
  278. // take in the argument pack that this constructor passes on.
  279. #define BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR(class_, func) \
  280. BOOST_PP_REPEAT_FROM_TO( \
  281. 1 \
  282. , BOOST_PP_INC(BOOST_PARAMETER_COMPOSE_MAX_ARITY) \
  283. , BOOST_PARAMETER_NO_SPEC_NO_BASE_CONSTRUCTOR_OVERLOAD_Z \
  284. , (class_, func) \
  285. )
  286. /**/
  287. // Emulates a variadic function that is enabled if and only if
  288. // all its arguments are tagged arguments.
  289. #define BOOST_PARAMETER_NO_SPEC_FUNCTION_OVERLOAD(name, impl, is_m, c) \
  290. BOOST_PP_REPEAT_FROM_TO( \
  291. 1 \
  292. , BOOST_PP_INC(BOOST_PARAMETER_COMPOSE_MAX_ARITY) \
  293. , BOOST_PARAMETER_NO_SPEC_FUNCTION_OVERLOAD_Z \
  294. , (name, impl, is_m, c) \
  295. )
  296. /**/
  297. #endif // BOOST_PARAMETER_HAS_PERFECT_FORWARDING
  298. #endif // include guard