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