compose.hpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. // Copyright Cromwell D. Enage 2019.
  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_COMPOSE_HPP
  6. #define BOOST_PARAMETER_COMPOSE_HPP
  7. #include <boost/parameter/aux_/arg_list.hpp>
  8. namespace boost { namespace parameter {
  9. inline BOOST_CONSTEXPR ::boost::parameter::aux::empty_arg_list compose()
  10. {
  11. return ::boost::parameter::aux::empty_arg_list();
  12. }
  13. }} // namespace boost::parameter
  14. #include <boost/parameter/config.hpp>
  15. #if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
  16. namespace boost { namespace parameter { namespace aux {
  17. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  18. template <typename ...TaggedArgs>
  19. struct compose_arg_list
  20. {
  21. using type = ::boost::parameter::aux::flat_like_arg_list<
  22. ::boost::parameter::aux::flat_like_arg_tuple<
  23. typename TaggedArgs::base_type::key_type
  24. , typename TaggedArgs::base_type
  25. >...
  26. >;
  27. };
  28. #else // !defined(BOOST_PARAMETER_CAN_USE_MP11)
  29. template <typename TaggedArg0, typename ...TaggedArgs>
  30. struct compose_arg_list;
  31. template <typename TaggedArg0>
  32. struct compose_arg_list<TaggedArg0>
  33. {
  34. typedef ::boost::parameter::aux::arg_list<TaggedArg0> type;
  35. };
  36. template <typename TaggedArg0, typename ...TaggedArgs>
  37. struct compose_arg_list
  38. {
  39. typedef ::boost::parameter::aux::arg_list<
  40. TaggedArg0
  41. , typename ::boost::parameter::aux
  42. ::compose_arg_list<TaggedArgs...>::type
  43. > type;
  44. };
  45. #endif // BOOST_PARAMETER_CAN_USE_MP11
  46. }}} // namespace boost::parameter::aux
  47. #include <boost/parameter/are_tagged_arguments.hpp>
  48. #include <boost/core/enable_if.hpp>
  49. namespace boost { namespace parameter { namespace result_of {
  50. template <typename ...TaggedArgs>
  51. struct compose
  52. : ::boost::lazy_enable_if<
  53. ::boost::parameter::are_tagged_arguments<TaggedArgs...>
  54. , ::boost::parameter::aux::compose_arg_list<TaggedArgs...>
  55. >
  56. {
  57. };
  58. template <>
  59. struct compose<>
  60. {
  61. typedef ::boost::parameter::aux::empty_arg_list type;
  62. };
  63. }}} // namespace boost::parameter::result_of
  64. namespace boost { namespace parameter {
  65. template <typename TaggedArg0, typename ...TaggedArgs>
  66. inline BOOST_CONSTEXPR typename ::boost::parameter::result_of
  67. ::compose<TaggedArg0,TaggedArgs...>::type
  68. compose(TaggedArg0 const& arg0, TaggedArgs const&... args)
  69. {
  70. return typename ::boost::parameter::aux
  71. ::compose_arg_list<TaggedArg0,TaggedArgs...>::type(
  72. ::boost::parameter::aux::value_type_is_not_void()
  73. , arg0
  74. , args...
  75. );
  76. }
  77. }} // namespace boost::parameter
  78. #else // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
  79. #define BOOST_PARAMETER_compose_arg_list_type_suffix(z, n, suffix) suffix
  80. #include <boost/preprocessor/cat.hpp>
  81. #define BOOST_PARAMETER_compose_arg_list_type_prefix(z, n, prefix) \
  82. ::boost::parameter::aux::arg_list<BOOST_PP_CAT(prefix, n)
  83. /**/
  84. #include <boost/preprocessor/facilities/intercept.hpp>
  85. #include <boost/preprocessor/repetition/enum.hpp>
  86. #include <boost/preprocessor/repetition/repeat.hpp>
  87. #define BOOST_PARAMETER_compose_arg_list_type(z, n, prefix) \
  88. BOOST_PP_CAT(BOOST_PP_ENUM_, z)( \
  89. n, BOOST_PARAMETER_compose_arg_list_type_prefix, prefix \
  90. ) BOOST_PP_CAT(BOOST_PP_REPEAT_, z)( \
  91. n, BOOST_PARAMETER_compose_arg_list_type_suffix, > \
  92. )
  93. /**/
  94. #include <boost/parameter/aux_/void.hpp>
  95. #include <boost/preprocessor/arithmetic/inc.hpp>
  96. #include <boost/preprocessor/arithmetic/sub.hpp>
  97. #include <boost/preprocessor/repetition/enum_params.hpp>
  98. #include <boost/preprocessor/repetition/enum_binary_params.hpp>
  99. #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
  100. #if defined(BOOST_NO_SFINAE)
  101. #define BOOST_PARAMETER_compose_arg_list_function_overload(z, n, prefix) \
  102. template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename prefix)> \
  103. inline BOOST_CONSTEXPR \
  104. BOOST_PARAMETER_compose_arg_list_type(z, n, prefix) \
  105. compose(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, prefix, const& a)) \
  106. { \
  107. return BOOST_PARAMETER_compose_arg_list_type(z, n, prefix)( \
  108. BOOST_PP_ENUM_PARAMS_Z(z, n, a) \
  109. BOOST_PP_ENUM_TRAILING_PARAMS_Z( \
  110. z \
  111. , BOOST_PP_SUB(BOOST_PARAMETER_COMPOSE_MAX_ARITY, n) \
  112. , ::boost::parameter::aux::void_reference() BOOST_PP_INTERCEPT \
  113. ) \
  114. ); \
  115. }
  116. /**/
  117. #else // !defined(BOOST_NO_SFINAE)
  118. #include <boost/parameter/are_tagged_arguments.hpp>
  119. #include <boost/core/enable_if.hpp>
  120. namespace boost { namespace parameter { namespace result_of {
  121. template <
  122. BOOST_PP_ENUM_BINARY_PARAMS(
  123. BOOST_PP_INC(BOOST_PARAMETER_COMPOSE_MAX_ARITY)
  124. , typename TaggedArg
  125. , = void BOOST_PP_INTERCEPT
  126. )
  127. >
  128. struct compose;
  129. template <>
  130. struct compose<>
  131. {
  132. typedef ::boost::parameter::aux::empty_arg_list type;
  133. };
  134. }}} // namespace boost::parameter::result_of
  135. #define BOOST_PARAMETER_compose_arg_list_function_overload(z, n, prefix) \
  136. namespace boost { namespace parameter { namespace result_of { \
  137. template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename prefix)> \
  138. struct compose<BOOST_PP_ENUM_PARAMS_Z(z, n, prefix)> \
  139. : ::boost::enable_if< \
  140. ::boost::parameter \
  141. ::are_tagged_arguments<BOOST_PP_ENUM_PARAMS_Z(z, n, prefix)> \
  142. , BOOST_PARAMETER_compose_arg_list_type(z, n, prefix) \
  143. > \
  144. { \
  145. }; \
  146. }}} \
  147. namespace boost { namespace parameter { \
  148. template <BOOST_PP_ENUM_PARAMS_Z(z, n, typename prefix)> \
  149. inline BOOST_CONSTEXPR typename ::boost::parameter::result_of \
  150. ::compose<BOOST_PP_ENUM_PARAMS_Z(z, n, prefix)>::type \
  151. compose(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, prefix, const& a)) \
  152. { \
  153. return BOOST_PARAMETER_compose_arg_list_type(z, n, prefix)( \
  154. BOOST_PP_ENUM_PARAMS_Z(z, n, a) \
  155. BOOST_PP_ENUM_TRAILING_PARAMS_Z( \
  156. z \
  157. , BOOST_PP_SUB(BOOST_PARAMETER_COMPOSE_MAX_ARITY, n) \
  158. , ::boost::parameter::aux::void_reference() BOOST_PP_INTERCEPT \
  159. ) \
  160. ); \
  161. } \
  162. }}
  163. /**/
  164. #endif // BOOST_NO_SFINAE
  165. #include <boost/preprocessor/repetition/repeat_from_to.hpp>
  166. BOOST_PP_REPEAT_FROM_TO(
  167. 1
  168. , BOOST_PP_INC(BOOST_PARAMETER_COMPOSE_MAX_ARITY)
  169. , BOOST_PARAMETER_compose_arg_list_function_overload
  170. , TaggedArg
  171. )
  172. #undef BOOST_PARAMETER_compose_arg_list_function_overload
  173. #undef BOOST_PARAMETER_compose_arg_list_type
  174. #undef BOOST_PARAMETER_compose_arg_list_type_prefix
  175. #undef BOOST_PARAMETER_compose_arg_list_type_suffix
  176. #endif // BOOST_PARAMETER_HAS_PERFECT_FORWARDING
  177. #endif // include guard