deduce_tag.hpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. // Copyright David Abrahams, Daniel Wallin 2003.
  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_DEDUCE_TAG_HPP
  6. #define BOOST_PARAMETER_AUX_PACK_DEDUCE_TAG_HPP
  7. namespace boost { namespace parameter { namespace aux {
  8. template <
  9. typename Argument
  10. , typename ArgumentPack
  11. , typename DeducedArgs
  12. , typename UsedArgs
  13. , typename TagFn
  14. , typename EmitsErrors
  15. >
  16. struct deduce_tag;
  17. }}} // namespace boost::parameter::aux
  18. #include <boost/parameter/aux_/lambda_tag.hpp>
  19. #include <boost/parameter/config.hpp>
  20. #include <boost/mpl/apply_wrap.hpp>
  21. #include <boost/mpl/lambda.hpp>
  22. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  23. namespace boost { namespace parameter { namespace aux {
  24. template <typename Predicate, typename Argument, typename ArgumentPack>
  25. struct deduce_tag_condition_mpl
  26. : ::boost::mpl::apply_wrap2<
  27. typename ::boost::mpl::lambda<
  28. Predicate
  29. , ::boost::parameter::aux::lambda_tag
  30. >::type
  31. , Argument
  32. , ArgumentPack
  33. >
  34. {
  35. };
  36. }}} // namespace boost::parameter::aux
  37. #include <boost/parameter/aux_/has_nested_template_fn.hpp>
  38. #include <boost/mp11/list.hpp>
  39. #include <boost/mp11/utility.hpp>
  40. namespace boost { namespace parameter { namespace aux {
  41. template <typename Predicate, typename Argument, typename ArgumentPack>
  42. struct deduce_tag_condition_mp11
  43. {
  44. using type = ::boost::mp11::mp_apply_q<
  45. Predicate
  46. , ::boost::mp11::mp_list<Argument,ArgumentPack>
  47. >;
  48. };
  49. template <typename Predicate, typename Argument, typename ArgumentPack>
  50. using deduce_tag_condition = ::boost::mp11::mp_if<
  51. ::boost::parameter::aux::has_nested_template_fn<Predicate>
  52. , ::boost::parameter::aux
  53. ::deduce_tag_condition_mp11<Predicate,Argument,ArgumentPack>
  54. , ::boost::parameter::aux
  55. ::deduce_tag_condition_mpl<Predicate,Argument,ArgumentPack>
  56. >;
  57. }}} // namespace boost::parameter::aux
  58. #else
  59. #include <boost/mpl/bool.hpp>
  60. #include <boost/mpl/if.hpp>
  61. #include <boost/mpl/eval_if.hpp>
  62. #include <boost/mpl/assert.hpp>
  63. #endif // BOOST_PARAMETER_CAN_USE_MP11
  64. #include <boost/parameter/aux_/set.hpp>
  65. #include <boost/parameter/aux_/pack/tag_type.hpp>
  66. #include <boost/parameter/aux_/pack/tag_deduced.hpp>
  67. namespace boost { namespace parameter { namespace aux {
  68. // Helper for deduce_tag<...>, below.
  69. template <
  70. typename Argument
  71. , typename ArgumentPack
  72. , typename DeducedArgs
  73. , typename UsedArgs
  74. , typename TagFn
  75. , typename EmitsErrors
  76. >
  77. class deduce_tag0
  78. {
  79. typedef typename DeducedArgs::spec _spec;
  80. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  81. typedef typename ::boost::parameter::aux::deduce_tag_condition<
  82. typename _spec::predicate
  83. #else
  84. typedef typename ::boost::mpl::apply_wrap2<
  85. typename ::boost::mpl::lambda<
  86. typename _spec::predicate
  87. , ::boost::parameter::aux::lambda_tag
  88. >::type
  89. #endif
  90. , Argument
  91. , ArgumentPack
  92. >::type _condition;
  93. #if !defined(BOOST_PARAMETER_CAN_USE_MP11)
  94. // Deduced parameter matches several arguments.
  95. BOOST_MPL_ASSERT((
  96. typename ::boost::mpl::eval_if<
  97. typename ::boost::parameter::aux::has_key_<
  98. UsedArgs
  99. , typename ::boost::parameter::aux::tag_type<_spec>::type
  100. >::type
  101. , ::boost::mpl::eval_if<
  102. _condition
  103. , ::boost::mpl::if_<
  104. EmitsErrors
  105. , ::boost::mpl::false_
  106. , ::boost::mpl::true_
  107. >
  108. , ::boost::mpl::true_
  109. >
  110. , ::boost::mpl::true_
  111. >::type
  112. ));
  113. #endif // BOOST_PARAMETER_CAN_USE_MP11
  114. public:
  115. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  116. using type = typename ::boost::mp11::mp_if<
  117. #else
  118. typedef typename ::boost::mpl::eval_if<
  119. #endif
  120. _condition
  121. , ::boost::parameter::aux
  122. ::tag_deduced<UsedArgs,_spec,Argument,TagFn>
  123. , ::boost::parameter::aux::deduce_tag<
  124. Argument
  125. , ArgumentPack
  126. , typename DeducedArgs::tail
  127. , UsedArgs
  128. , TagFn
  129. , EmitsErrors
  130. >
  131. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  132. >::type;
  133. #else
  134. >::type type;
  135. #endif
  136. };
  137. }}} // namespace boost::parameter::aux
  138. #include <boost/parameter/aux_/void.hpp>
  139. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  140. #include <type_traits>
  141. #else
  142. #include <boost/mpl/pair.hpp>
  143. #include <boost/type_traits/is_same.hpp>
  144. #endif
  145. namespace boost { namespace parameter { namespace aux {
  146. // Tries to deduced a keyword tag for a given Argument.
  147. // Returns an mpl::pair<> consisting of the tagged_argument<>,
  148. // and an mpl::set<> where the new tag has been inserted.
  149. //
  150. // Argument: The argument type to be tagged.
  151. //
  152. // ArgumentPack: The ArgumentPack built so far.
  153. //
  154. // DeducedArgs: A specialization of deduced_item<> (see below).
  155. // A list containing only the deduced ParameterSpecs.
  156. //
  157. // UsedArgs: An mpl::set<> containing the keyword tags used so far.
  158. //
  159. // TagFn: A metafunction class used to tag positional or deduced
  160. // arguments with a keyword tag.
  161. template <
  162. typename Argument
  163. , typename ArgumentPack
  164. , typename DeducedArgs
  165. , typename UsedArgs
  166. , typename TagFn
  167. , typename EmitsErrors
  168. >
  169. struct deduce_tag
  170. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  171. : ::boost::mp11::mp_if<
  172. ::std::is_same<DeducedArgs,::boost::parameter::void_>
  173. , ::boost::mp11::mp_identity<
  174. ::boost::mp11::mp_list< ::boost::parameter::void_,UsedArgs>
  175. >
  176. #else
  177. : ::boost::mpl::eval_if<
  178. ::boost::is_same<DeducedArgs,::boost::parameter::void_>
  179. , ::boost::mpl::pair< ::boost::parameter::void_,UsedArgs>
  180. #endif
  181. , ::boost::parameter::aux::deduce_tag0<
  182. Argument
  183. , ArgumentPack
  184. , DeducedArgs
  185. , UsedArgs
  186. , TagFn
  187. , EmitsErrors
  188. >
  189. >
  190. {
  191. };
  192. }}} // namespace boost::parameter::aux
  193. #endif // include guard