make_parameter_spec_items.hpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. // Copyright Cromwell D. Enage 2017.
  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_PACK_MAKE_PARAMETER_SPEC_ITEMS_HPP
  6. #define BOOST_PARAMETER_AUX_PACK_MAKE_PARAMETER_SPEC_ITEMS_HPP
  7. namespace boost { namespace parameter { namespace aux {
  8. // This recursive metafunction forwards successive elements of
  9. // parameters::parameter_spec to make_deduced_items<>.
  10. // -- Cromwell D. Enage
  11. template <typename SpecSeq>
  12. struct make_deduced_list;
  13. // Helper for match_parameters_base_cond<...>, below.
  14. template <typename ArgumentPackAndError, typename SpecSeq>
  15. struct match_parameters_base_cond_helper;
  16. // Helper metafunction for make_parameter_spec_items<...>, below.
  17. template <typename SpecSeq, typename ...Args>
  18. struct make_parameter_spec_items_helper;
  19. }}} // namespace boost::parameter::aux
  20. #include <boost/parameter/aux_/void.hpp>
  21. namespace boost { namespace parameter { namespace aux {
  22. template <typename SpecSeq>
  23. struct make_parameter_spec_items_helper<SpecSeq>
  24. {
  25. typedef ::boost::parameter::void_ type;
  26. };
  27. }}} // namespace boost::parameter::aux
  28. #include <boost/parameter/aux_/pack/make_deduced_items.hpp>
  29. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  30. #include <boost/mp11/list.hpp>
  31. #else
  32. #include <boost/mpl/front.hpp>
  33. #include <boost/mpl/pop_front.hpp>
  34. #endif
  35. namespace boost { namespace parameter { namespace aux {
  36. template <typename SpecSeq>
  37. struct make_deduced_list_not_empty
  38. : ::boost::parameter::aux::make_deduced_items<
  39. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  40. ::boost::mp11::mp_front<SpecSeq>
  41. #else
  42. typename ::boost::mpl::front<SpecSeq>::type
  43. #endif
  44. , ::boost::parameter::aux::make_deduced_list<
  45. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  46. ::boost::mp11::mp_pop_front<SpecSeq>
  47. #else
  48. typename ::boost::mpl::pop_front<SpecSeq>::type
  49. #endif
  50. >
  51. >
  52. {
  53. };
  54. }}} // namespace boost::parameter::aux
  55. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  56. #include <boost/mp11/utility.hpp>
  57. #else
  58. #include <boost/mpl/eval_if.hpp>
  59. #include <boost/mpl/empty.hpp>
  60. #include <boost/mpl/identity.hpp>
  61. #endif
  62. namespace boost { namespace parameter { namespace aux {
  63. template <typename SpecSeq>
  64. struct make_deduced_list
  65. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  66. : ::boost::mp11::mp_if<
  67. ::boost::mp11::mp_empty<SpecSeq>
  68. , ::boost::mp11::mp_identity< ::boost::parameter::void_>
  69. #else
  70. : ::boost::mpl::eval_if<
  71. ::boost::mpl::empty<SpecSeq>
  72. , ::boost::mpl::identity< ::boost::parameter::void_>
  73. #endif
  74. , ::boost::parameter::aux::make_deduced_list_not_empty<SpecSeq>
  75. >
  76. {
  77. };
  78. }}} // namespace boost::parameter::aux
  79. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  80. #include <type_traits>
  81. #else
  82. #include <boost/mpl/bool.hpp>
  83. #include <boost/mpl/pair.hpp>
  84. #include <boost/mpl/if.hpp>
  85. #include <boost/type_traits/is_same.hpp>
  86. namespace boost { namespace parameter { namespace aux {
  87. template <typename ArgumentPackAndError>
  88. struct is_arg_pack_error_void
  89. : ::boost::mpl::if_<
  90. ::boost::is_same<
  91. typename ::boost::mpl::second<ArgumentPackAndError>::type
  92. , ::boost::parameter::void_
  93. >
  94. , ::boost::mpl::true_
  95. , ::boost::mpl::false_
  96. >::type
  97. {
  98. };
  99. }}} // namespace boost::parameter::aux
  100. #endif // BOOST_PARAMETER_CAN_USE_MP11
  101. namespace boost { namespace parameter { namespace aux {
  102. // Checks if the arguments match the criteria of overload resolution.
  103. // If NamedList satisfies the PS0, PS1, ..., this is a metafunction
  104. // returning parameters. Otherwise it has no nested ::type.
  105. template <typename ArgumentPackAndError, typename SpecSeq>
  106. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  107. using match_parameters_base_cond = ::boost::mp11::mp_if<
  108. ::boost::mp11::mp_empty<SpecSeq>
  109. , ::std::is_same<
  110. ::boost::mp11::mp_at_c<ArgumentPackAndError,1>
  111. , ::boost::parameter::void_
  112. >
  113. , ::boost::parameter::aux::match_parameters_base_cond_helper<
  114. ArgumentPackAndError
  115. , SpecSeq
  116. >
  117. >;
  118. #else
  119. struct match_parameters_base_cond
  120. : ::boost::mpl::eval_if<
  121. ::boost::mpl::empty<SpecSeq>
  122. , ::boost::parameter::aux
  123. ::is_arg_pack_error_void<ArgumentPackAndError>
  124. , ::boost::parameter::aux::match_parameters_base_cond_helper<
  125. ArgumentPackAndError
  126. , SpecSeq
  127. >
  128. >
  129. {
  130. };
  131. #endif // BOOST_PARAMETER_CAN_USE_MP11
  132. }}} // namespace boost::parameter::aux
  133. #include <boost/parameter/aux_/pack/satisfies.hpp>
  134. namespace boost { namespace parameter { namespace aux {
  135. template <typename ArgumentPackAndError, typename SpecSeq>
  136. struct match_parameters_base_cond_helper
  137. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  138. : ::boost::mp11::mp_if<
  139. #else
  140. : ::boost::mpl::eval_if<
  141. #endif
  142. ::boost::parameter::aux::satisfies_requirements_of<
  143. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  144. ::boost::mp11::mp_at_c<ArgumentPackAndError,0>
  145. , ::boost::mp11::mp_front<SpecSeq>
  146. #else
  147. typename ::boost::mpl::first<ArgumentPackAndError>::type
  148. , typename ::boost::mpl::front<SpecSeq>::type
  149. #endif
  150. >
  151. , ::boost::parameter::aux::match_parameters_base_cond<
  152. ArgumentPackAndError
  153. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  154. , ::boost::mp11::mp_pop_front<SpecSeq>
  155. #else
  156. , typename ::boost::mpl::pop_front<SpecSeq>::type
  157. #endif
  158. >
  159. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  160. , ::boost::mp11::mp_false
  161. #else
  162. , ::boost::mpl::false_
  163. #endif
  164. >
  165. {
  166. };
  167. // This parameters item chaining metafunction class does not require
  168. // the lengths of the SpecSeq and of Args parameter pack to match.
  169. // Used by argument_pack to build the items in the resulting arg_list.
  170. // -- Cromwell D. Enage
  171. template <typename SpecSeq, typename ...Args>
  172. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  173. using make_parameter_spec_items = ::boost::mp11::mp_if<
  174. ::boost::mp11::mp_empty<SpecSeq>
  175. , ::boost::mp11::mp_identity< ::boost::parameter::void_>
  176. , ::boost::parameter::aux
  177. ::make_parameter_spec_items_helper<SpecSeq,Args...>
  178. >;
  179. #else
  180. struct make_parameter_spec_items
  181. : ::boost::mpl::eval_if<
  182. ::boost::mpl::empty<SpecSeq>
  183. , ::boost::mpl::identity< ::boost::parameter::void_>
  184. , ::boost::parameter::aux
  185. ::make_parameter_spec_items_helper<SpecSeq,Args...>
  186. >
  187. {
  188. };
  189. #endif
  190. }}} // namespace boost::parameter::aux
  191. #include <boost/parameter/aux_/pack/make_items.hpp>
  192. namespace boost { namespace parameter { namespace aux {
  193. template <typename SpecSeq, typename A0, typename ...Args>
  194. struct make_parameter_spec_items_helper<SpecSeq,A0,Args...>
  195. : ::boost::parameter::aux::make_items<
  196. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  197. ::boost::mp11::mp_front<SpecSeq>
  198. #else
  199. typename ::boost::mpl::front<SpecSeq>::type
  200. #endif
  201. , A0
  202. , ::boost::parameter::aux::make_parameter_spec_items<
  203. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  204. ::boost::mp11::mp_pop_front<SpecSeq>
  205. #else
  206. typename ::boost::mpl::pop_front<SpecSeq>::type
  207. #endif
  208. , Args...
  209. >
  210. >
  211. {
  212. };
  213. }}} // namespace boost::parameter::aux
  214. #endif // include guard