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