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)
6 #ifndef BOOST_PARAMETER_AUX_PACK_MAKE_PARAMETER_SPEC_ITEMS_HPP
7 #define BOOST_PARAMETER_AUX_PACK_MAKE_PARAMETER_SPEC_ITEMS_HPP
9 namespace boost { namespace parameter { namespace aux {
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;
17 // Helper for match_parameters_base_cond<...>, below.
18 template <typename ArgumentPackAndError, typename SpecSeq>
19 struct match_parameters_base_cond_helper;
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
26 #include <boost/parameter/aux_/void.hpp>
28 namespace boost { namespace parameter { namespace aux {
30 template <typename SpecSeq>
31 struct make_parameter_spec_items_helper<SpecSeq>
33 typedef ::boost::parameter::void_ type;
35 }}} // namespace boost::parameter::aux
37 #include <boost/parameter/aux_/pack/make_deduced_items.hpp>
39 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
40 #include <boost/mp11/list.hpp>
42 #include <boost/mpl/front.hpp>
43 #include <boost/mpl/pop_front.hpp>
46 namespace boost { namespace parameter { namespace aux {
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>
54 typename ::boost::mpl::front<SpecSeq>::type
56 , ::boost::parameter::aux::make_deduced_list<
57 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
58 ::boost::mp11::mp_pop_front<SpecSeq>
60 typename ::boost::mpl::pop_front<SpecSeq>::type
66 }}} // namespace boost::parameter::aux
68 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
69 #include <boost/mp11/utility.hpp>
71 #include <boost/mpl/eval_if.hpp>
72 #include <boost/mpl/empty.hpp>
73 #include <boost/mpl/identity.hpp>
76 namespace boost { namespace parameter { namespace aux {
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_>
85 : ::boost::mpl::eval_if<
86 ::boost::mpl::empty<SpecSeq>
87 , ::boost::mpl::identity< ::boost::parameter::void_>
89 , ::boost::parameter::aux::make_deduced_list_not_empty<SpecSeq>
93 }}} // namespace boost::parameter::aux
95 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
96 #include <type_traits>
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>
103 namespace boost { namespace parameter { namespace aux {
105 template <typename ArgumentPackAndError>
106 struct is_arg_pack_error_void
109 typename ::boost::mpl::second<ArgumentPackAndError>::type
110 , ::boost::parameter::void_
112 , ::boost::mpl::true_
113 , ::boost::mpl::false_
117 }}} // namespace boost::parameter::aux
119 #endif // BOOST_PARAMETER_CAN_USE_MP11
121 namespace boost { namespace parameter { namespace aux {
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>
131 ::boost::mp11::mp_at_c<ArgumentPackAndError,1>
132 , ::boost::parameter::void_
134 , ::boost::parameter::aux::match_parameters_base_cond_helper<
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<
152 #endif // BOOST_PARAMETER_CAN_USE_MP11
153 }}} // namespace boost::parameter::aux
155 #include <boost/parameter/aux_/pack/satisfies.hpp>
157 namespace boost { namespace parameter { namespace aux {
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<
164 : ::boost::mpl::eval_if<
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>
171 typename ::boost::mpl::first<ArgumentPackAndError>::type
172 , typename ::boost::mpl::front<SpecSeq>::type
175 , ::boost::parameter::aux::match_parameters_base_cond<
177 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
178 , ::boost::mp11::mp_pop_front<SpecSeq>
180 , typename ::boost::mpl::pop_front<SpecSeq>::type
183 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
184 , ::boost::mp11::mp_false
186 , ::boost::mpl::false_
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...>
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...>
215 }}} // namespace boost::parameter::aux
217 #include <boost/parameter/aux_/pack/make_items.hpp>
219 namespace boost { namespace parameter { namespace aux {
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>
227 typename ::boost::mpl::front<SpecSeq>::type
230 , ::boost::parameter::aux::make_parameter_spec_items<
231 #if defined(BOOST_PARAMETER_CAN_USE_MP11)
232 ::boost::mp11::mp_pop_front<SpecSeq>
234 typename ::boost::mpl::pop_front<SpecSeq>::type
241 }}} // namespace boost::parameter::aux
243 #endif // include guard