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