binding.hpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. // Copyright David Abrahams 2005.
  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_BINDING_DWA200558_HPP
  6. #define BOOST_PARAMETER_BINDING_DWA200558_HPP
  7. #include <boost/parameter/aux_/void.hpp>
  8. #include <boost/parameter/config.hpp>
  9. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  10. #include <boost/mp11/integral.hpp>
  11. #include <boost/mp11/list.hpp>
  12. #include <boost/mp11/utility.hpp>
  13. #include <type_traits>
  14. #else
  15. #include <boost/mpl/bool.hpp>
  16. #include <boost/mpl/if.hpp>
  17. #include <boost/mpl/eval_if.hpp>
  18. #include <boost/mpl/identity.hpp>
  19. #include <boost/mpl/apply_wrap.hpp>
  20. #include <boost/mpl/assert.hpp>
  21. #include <boost/type_traits/is_same.hpp>
  22. #endif
  23. namespace boost { namespace parameter {
  24. // A metafunction that, given an argument pack, returns the reference type
  25. // of the parameter identified by the given keyword. If no such parameter
  26. // has been specified, returns Default
  27. template <typename Parameters, typename Keyword, typename Default>
  28. struct binding0
  29. {
  30. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  31. using type = ::boost::mp11::mp_apply_q<
  32. typename Parameters::binding
  33. , ::boost::mp11::mp_list<Keyword,Default,::boost::mp11::mp_true>
  34. >;
  35. static_assert(
  36. ::boost::mp11::mp_if<
  37. ::std::is_same<Default,::boost::parameter::void_>
  38. , ::boost::mp11::mp_if<
  39. ::std::is_same<type,::boost::parameter::void_>
  40. , ::boost::mp11::mp_false
  41. , ::boost::mp11::mp_true
  42. >
  43. , ::boost::mp11::mp_true
  44. >::value
  45. , "required parameters must not result in void_ type"
  46. );
  47. #else // !defined(BOOST_PARAMETER_CAN_USE_MP11)
  48. typedef typename ::boost::mpl::apply_wrap3<
  49. typename Parameters::binding
  50. , Keyword
  51. , Default
  52. , ::boost::mpl::true_
  53. >::type type;
  54. BOOST_MPL_ASSERT((
  55. typename ::boost::mpl::eval_if<
  56. ::boost::is_same<Default,::boost::parameter::void_>
  57. , ::boost::mpl::if_<
  58. ::boost::is_same<type,::boost::parameter::void_>
  59. , ::boost::mpl::false_
  60. , ::boost::mpl::true_
  61. >
  62. , ::boost::mpl::true_
  63. >::type
  64. ));
  65. #endif // BOOST_PARAMETER_CAN_USE_MP11
  66. };
  67. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  68. template <typename Placeholder, typename Keyword, typename Default>
  69. struct binding1
  70. {
  71. using type = ::boost::mp11::mp_apply_q<
  72. Placeholder
  73. , ::boost::mp11::mp_list<Keyword,Default,::boost::mp11::mp_true>
  74. >;
  75. static_assert(
  76. ::boost::mp11::mp_if<
  77. ::std::is_same<Default,::boost::parameter::void_>
  78. , ::boost::mp11::mp_if<
  79. ::std::is_same<type,::boost::parameter::void_>
  80. , ::boost::mp11::mp_false
  81. , ::boost::mp11::mp_true
  82. >
  83. , ::boost::mp11::mp_true
  84. >::value
  85. , "required parameters must not result in void_ type"
  86. );
  87. };
  88. #endif // BOOST_PARAMETER_CAN_USE_MP11
  89. }} // namespace boost::parameter
  90. #include <boost/parameter/aux_/is_placeholder.hpp>
  91. namespace boost { namespace parameter {
  92. template <
  93. typename Parameters
  94. , typename Keyword
  95. , typename Default = ::boost::parameter::void_
  96. >
  97. struct binding
  98. #if !defined(BOOST_PARAMETER_CAN_USE_MP11)
  99. : ::boost::mpl::eval_if<
  100. ::boost::parameter::aux::is_mpl_placeholder<Parameters>
  101. , ::boost::mpl::identity<int>
  102. , ::boost::parameter::binding0<Parameters,Keyword,Default>
  103. >
  104. #endif
  105. {
  106. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  107. using type = typename ::boost::mp11::mp_if<
  108. ::boost::parameter::aux::is_mpl_placeholder<Parameters>
  109. , ::boost::mp11::mp_identity<int>
  110. , ::boost::mp11::mp_if<
  111. ::boost::parameter::aux::is_mp11_placeholder<Parameters>
  112. , ::boost::parameter::binding1<Parameters,Keyword,Default>
  113. , ::boost::parameter::binding0<Parameters,Keyword,Default>
  114. >
  115. >::type;
  116. #endif
  117. };
  118. }} // namespace boost::parameter
  119. #include <boost/parameter/aux_/result_of0.hpp>
  120. namespace boost { namespace parameter {
  121. // A metafunction that, given an argument pack, returns the reference type
  122. // of the parameter identified by the given keyword. If no such parameter
  123. // has been specified, returns the type returned by invoking DefaultFn
  124. template <typename Parameters, typename Keyword, typename DefaultFn>
  125. struct lazy_binding
  126. {
  127. #if defined(BOOST_PARAMETER_CAN_USE_MP11)
  128. using type = ::boost::mp11::mp_apply_q<
  129. typename Parameters::binding
  130. , ::boost::mp11::mp_list<
  131. Keyword
  132. , typename ::boost::parameter::aux::result_of0<DefaultFn>::type
  133. , ::boost::mp11::mp_true
  134. >
  135. >;
  136. #else
  137. typedef typename ::boost::mpl::apply_wrap3<
  138. typename Parameters::binding
  139. , Keyword
  140. , typename ::boost::parameter::aux::result_of0<DefaultFn>::type
  141. , ::boost::mpl::true_
  142. >::type type;
  143. #endif // BOOST_PARAMETER_CAN_USE_MP11
  144. };
  145. }} // namespace boost::parameter
  146. #endif // include guard