Chris@16
|
1 // Copyright David Abrahams, Daniel Wallin 2003. Use, modification and
|
Chris@16
|
2 // distribution is subject to the Boost Software License, Version 1.0.
|
Chris@16
|
3 // (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
4 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
5
|
Chris@16
|
6 #ifndef BOOST_PARAMETERS_031014_HPP
|
Chris@16
|
7 #define BOOST_PARAMETERS_031014_HPP
|
Chris@16
|
8
|
Chris@16
|
9 #include <boost/detail/is_xxx.hpp>
|
Chris@16
|
10
|
Chris@16
|
11 #include <boost/type_traits/is_const.hpp>
|
Chris@16
|
12
|
Chris@16
|
13 #include <boost/mpl/lambda.hpp>
|
Chris@16
|
14 #include <boost/mpl/apply.hpp>
|
Chris@16
|
15 #include <boost/mpl/always.hpp>
|
Chris@16
|
16 #include <boost/mpl/and.hpp>
|
Chris@16
|
17 #include <boost/mpl/or.hpp>
|
Chris@16
|
18 #include <boost/mpl/if.hpp>
|
Chris@16
|
19 #include <boost/mpl/identity.hpp>
|
Chris@16
|
20 #include <boost/mpl/not.hpp>
|
Chris@16
|
21 #include <boost/mpl/eval_if.hpp>
|
Chris@16
|
22 #include <boost/mpl/pair.hpp>
|
Chris@16
|
23
|
Chris@16
|
24 #include <boost/type_traits/is_same.hpp>
|
Chris@16
|
25 #include <boost/type_traits/remove_reference.hpp>
|
Chris@16
|
26
|
Chris@16
|
27 #include <boost/preprocessor/repetition/enum.hpp>
|
Chris@16
|
28 #include <boost/preprocessor/repetition/enum_params.hpp>
|
Chris@16
|
29 #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
|
Chris@16
|
30 #include <boost/preprocessor/arithmetic/sub.hpp>
|
Chris@16
|
31 #include <boost/preprocessor/repetition/repeat.hpp>
|
Chris@16
|
32 #include <boost/preprocessor/repetition/enum_shifted.hpp>
|
Chris@16
|
33 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
Chris@16
|
34 #include <boost/preprocessor/repetition/enum_shifted_params.hpp>
|
Chris@16
|
35 #include <boost/preprocessor/seq/elem.hpp>
|
Chris@16
|
36 #include <boost/preprocessor/iteration/iterate.hpp>
|
Chris@16
|
37 #include <boost/preprocessor/facilities/intercept.hpp>
|
Chris@16
|
38 #include <boost/preprocessor/cat.hpp>
|
Chris@16
|
39
|
Chris@16
|
40 #include <boost/parameter/aux_/arg_list.hpp>
|
Chris@16
|
41 #include <boost/parameter/aux_/yesno.hpp>
|
Chris@16
|
42 #include <boost/parameter/aux_/void.hpp>
|
Chris@16
|
43 #include <boost/parameter/aux_/default.hpp>
|
Chris@16
|
44 #include <boost/parameter/aux_/unwrap_cv_reference.hpp>
|
Chris@16
|
45 #include <boost/parameter/aux_/tagged_argument.hpp>
|
Chris@16
|
46 #include <boost/parameter/aux_/tag.hpp>
|
Chris@16
|
47 #include <boost/parameter/aux_/template_keyword.hpp>
|
Chris@16
|
48 #include <boost/parameter/aux_/set.hpp>
|
Chris@16
|
49 #include <boost/parameter/config.hpp>
|
Chris@16
|
50
|
Chris@16
|
51 namespace parameter_
|
Chris@16
|
52 {
|
Chris@16
|
53 template <class T>
|
Chris@16
|
54 struct unmatched_argument
|
Chris@16
|
55 {
|
Chris@16
|
56 BOOST_MPL_ASSERT((boost::is_same<T,void>));
|
Chris@16
|
57 typedef int type;
|
Chris@16
|
58 };
|
Chris@16
|
59 } // namespace parameter_
|
Chris@16
|
60
|
Chris@16
|
61 namespace boost {
|
Chris@16
|
62
|
Chris@16
|
63 template<class T> class reference_wrapper;
|
Chris@16
|
64
|
Chris@16
|
65 namespace parameter {
|
Chris@16
|
66
|
Chris@16
|
67 namespace aux { struct use_default {}; }
|
Chris@16
|
68
|
Chris@16
|
69 // These templates can be used to describe the treatment of particular
|
Chris@16
|
70 // named parameters for the purposes of overload elimination with
|
Chris@16
|
71 // SFINAE, by placing specializations in the parameters<...> list. In
|
Chris@16
|
72 // order for a treated function to participate in overload resolution:
|
Chris@16
|
73 //
|
Chris@16
|
74 // - all keyword tags wrapped in required<...> must have a matching
|
Chris@16
|
75 // actual argument
|
Chris@16
|
76 //
|
Chris@16
|
77 // - The actual argument type matched by every keyword tag
|
Chris@16
|
78 // associated with a predicate must satisfy that predicate
|
Chris@16
|
79 //
|
Chris@16
|
80 // If a keyword k is specified without an optional<...> or
|
Chris@16
|
81 // required<...>, wrapper, it is treated as though optional<k> were
|
Chris@16
|
82 // specified.
|
Chris@16
|
83 //
|
Chris@16
|
84 // If a keyword k is specified with deduced<...>, that keyword
|
Chris@16
|
85 // will be automatically deduced from the argument list.
|
Chris@16
|
86 //
|
Chris@16
|
87 template <class Tag, class Predicate = aux::use_default>
|
Chris@16
|
88 struct required
|
Chris@16
|
89 {
|
Chris@16
|
90 typedef Tag key_type;
|
Chris@16
|
91 typedef Predicate predicate;
|
Chris@16
|
92 };
|
Chris@16
|
93
|
Chris@16
|
94 template <class Tag, class Predicate = aux::use_default>
|
Chris@16
|
95 struct optional
|
Chris@16
|
96 {
|
Chris@16
|
97 typedef Tag key_type;
|
Chris@16
|
98 typedef Predicate predicate;
|
Chris@16
|
99 };
|
Chris@16
|
100
|
Chris@16
|
101 template <class Tag>
|
Chris@16
|
102 struct deduced
|
Chris@16
|
103 {
|
Chris@16
|
104 typedef Tag key_type;
|
Chris@16
|
105 };
|
Chris@16
|
106
|
Chris@16
|
107 namespace aux
|
Chris@16
|
108 {
|
Chris@16
|
109 // Defines metafunctions, is_required and is_optional, that
|
Chris@16
|
110 // identify required<...>, optional<...> and deduced<...> specializations.
|
Chris@16
|
111 BOOST_DETAIL_IS_XXX_DEF(required, required, 2)
|
Chris@16
|
112 BOOST_DETAIL_IS_XXX_DEF(optional, optional, 2)
|
Chris@16
|
113 BOOST_DETAIL_IS_XXX_DEF(deduced_aux, deduced, 1)
|
Chris@16
|
114
|
Chris@16
|
115 template <class S>
|
Chris@16
|
116 struct is_deduced0
|
Chris@16
|
117 : is_deduced_aux<
|
Chris@16
|
118 typename S::key_type
|
Chris@16
|
119 >::type
|
Chris@16
|
120 {};
|
Chris@16
|
121
|
Chris@16
|
122 template <class S>
|
Chris@16
|
123 struct is_deduced
|
Chris@16
|
124 : mpl::eval_if<
|
Chris@16
|
125 mpl::or_<
|
Chris@16
|
126 is_optional<S>, is_required<S>
|
Chris@16
|
127 >
|
Chris@16
|
128 , is_deduced0<S>
|
Chris@16
|
129 , mpl::false_
|
Chris@16
|
130 >::type
|
Chris@16
|
131 {};
|
Chris@16
|
132
|
Chris@16
|
133 //
|
Chris@16
|
134 // key_type, has_default, and predicate --
|
Chris@16
|
135 //
|
Chris@16
|
136 // These metafunctions accept a ParameterSpec and extract the
|
Chris@16
|
137 // keyword tag, whether or not a default is supplied for the
|
Chris@16
|
138 // parameter, and the predicate that the corresponding actual
|
Chris@16
|
139 // argument type is required match.
|
Chris@16
|
140 //
|
Chris@16
|
141 // a ParameterSpec is a specialization of either keyword<...>,
|
Chris@16
|
142 // required<...>, optional<...>
|
Chris@16
|
143 //
|
Chris@16
|
144
|
Chris@16
|
145 // helper for key_type<...>, below.
|
Chris@16
|
146 template <class T>
|
Chris@16
|
147 struct get_tag_type0
|
Chris@16
|
148 {
|
Chris@16
|
149 typedef typename T::key_type type;
|
Chris@16
|
150 };
|
Chris@16
|
151
|
Chris@16
|
152 template <class T>
|
Chris@16
|
153 struct get_tag_type
|
Chris@16
|
154 : mpl::eval_if<
|
Chris@16
|
155 is_deduced_aux<typename T::key_type>
|
Chris@16
|
156 , get_tag_type0<typename T::key_type>
|
Chris@16
|
157 , mpl::identity<typename T::key_type>
|
Chris@16
|
158 >
|
Chris@16
|
159 {};
|
Chris@16
|
160
|
Chris@16
|
161 template <class T>
|
Chris@16
|
162 struct tag_type
|
Chris@16
|
163 : mpl::eval_if<
|
Chris@16
|
164 mpl::or_<
|
Chris@16
|
165 is_optional<T>
|
Chris@16
|
166 , is_required<T>
|
Chris@16
|
167 >
|
Chris@16
|
168 , get_tag_type<T>
|
Chris@16
|
169 , mpl::identity<T>
|
Chris@16
|
170 >
|
Chris@16
|
171 {};
|
Chris@16
|
172
|
Chris@16
|
173 template <class T>
|
Chris@16
|
174 struct has_default
|
Chris@16
|
175 : mpl::not_<is_required<T> >
|
Chris@16
|
176 {};
|
Chris@16
|
177
|
Chris@16
|
178 // helper for get_predicate<...>, below
|
Chris@16
|
179 template <class T>
|
Chris@16
|
180 struct get_predicate_or_default
|
Chris@16
|
181 {
|
Chris@16
|
182 typedef T type;
|
Chris@16
|
183 };
|
Chris@16
|
184
|
Chris@16
|
185 template <>
|
Chris@16
|
186 struct get_predicate_or_default<use_default>
|
Chris@16
|
187 {
|
Chris@16
|
188 typedef mpl::always<mpl::true_> type;
|
Chris@16
|
189 };
|
Chris@16
|
190
|
Chris@16
|
191 // helper for predicate<...>, below
|
Chris@16
|
192 template <class T>
|
Chris@16
|
193 struct get_predicate
|
Chris@16
|
194 {
|
Chris@16
|
195 typedef typename
|
Chris@16
|
196 get_predicate_or_default<typename T::predicate>::type
|
Chris@16
|
197 type;
|
Chris@16
|
198 };
|
Chris@16
|
199
|
Chris@16
|
200 template <class T>
|
Chris@16
|
201 struct predicate
|
Chris@16
|
202 : mpl::eval_if<
|
Chris@16
|
203 mpl::or_<
|
Chris@16
|
204 is_optional<T>
|
Chris@16
|
205 , is_required<T>
|
Chris@16
|
206 >
|
Chris@16
|
207 , get_predicate<T>
|
Chris@16
|
208 , mpl::identity<mpl::always<mpl::true_> >
|
Chris@16
|
209 >
|
Chris@16
|
210 {
|
Chris@16
|
211 };
|
Chris@16
|
212
|
Chris@16
|
213
|
Chris@16
|
214 // Converts a ParameterSpec into a specialization of
|
Chris@16
|
215 // parameter_requirements. We need to do this in order to get the
|
Chris@16
|
216 // tag_type into the type in a way that can be conveniently matched
|
Chris@16
|
217 // by a satisfies(...) member function in arg_list.
|
Chris@16
|
218 template <class ParameterSpec>
|
Chris@16
|
219 struct as_parameter_requirements
|
Chris@16
|
220 {
|
Chris@16
|
221 typedef parameter_requirements<
|
Chris@16
|
222 typename tag_type<ParameterSpec>::type
|
Chris@16
|
223 , typename predicate<ParameterSpec>::type
|
Chris@16
|
224 , typename has_default<ParameterSpec>::type
|
Chris@16
|
225 > type;
|
Chris@16
|
226 };
|
Chris@16
|
227
|
Chris@16
|
228 template <class T>
|
Chris@16
|
229 struct is_named_argument
|
Chris@16
|
230 : mpl::or_<
|
Chris@16
|
231 is_template_keyword<T>
|
Chris@16
|
232 , is_tagged_argument<T>
|
Chris@16
|
233 >
|
Chris@16
|
234 {};
|
Chris@16
|
235
|
Chris@16
|
236 // Returns mpl::true_ iff the given ParameterRequirements are
|
Chris@16
|
237 // satisfied by ArgList.
|
Chris@16
|
238 template <class ArgList, class ParameterRequirements>
|
Chris@16
|
239 struct satisfies
|
Chris@16
|
240 {
|
Chris@16
|
241 #if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
|
Chris@16
|
242 // VC7.1 can't handle the sizeof() implementation below,
|
Chris@16
|
243 // so we use this instead.
|
Chris@16
|
244 typedef typename mpl::apply_wrap3<
|
Chris@16
|
245 typename ArgList::binding
|
Chris@16
|
246 , typename ParameterRequirements::keyword
|
Chris@16
|
247 , void_
|
Chris@16
|
248 , mpl::false_
|
Chris@16
|
249 >::type bound;
|
Chris@16
|
250
|
Chris@16
|
251 typedef typename mpl::eval_if<
|
Chris@16
|
252 is_same<bound, void_>
|
Chris@16
|
253 , typename ParameterRequirements::has_default
|
Chris@16
|
254 , mpl::apply_wrap2<
|
Chris@16
|
255 typename mpl::lambda<
|
Chris@16
|
256 typename ParameterRequirements::predicate, lambda_tag
|
Chris@16
|
257 >::type
|
Chris@16
|
258 , bound
|
Chris@16
|
259 , ArgList
|
Chris@16
|
260 >
|
Chris@16
|
261 >::type type;
|
Chris@16
|
262 #else
|
Chris@16
|
263 BOOST_STATIC_CONSTANT(
|
Chris@16
|
264 bool, value = (
|
Chris@16
|
265 sizeof(
|
Chris@16
|
266 aux::to_yesno(
|
Chris@16
|
267 ArgList::satisfies((ParameterRequirements*)0, (ArgList*)0)
|
Chris@16
|
268 )
|
Chris@16
|
269 ) == sizeof(yes_tag)
|
Chris@16
|
270 )
|
Chris@16
|
271 );
|
Chris@16
|
272
|
Chris@16
|
273 typedef mpl::bool_<satisfies::value> type;
|
Chris@16
|
274 #endif
|
Chris@16
|
275 };
|
Chris@16
|
276
|
Chris@16
|
277 // Returns mpl::true_ if the requirements of the given ParameterSpec
|
Chris@16
|
278 // are satisfied by ArgList.
|
Chris@16
|
279 template <class ArgList, class ParameterSpec>
|
Chris@16
|
280 struct satisfies_requirements_of
|
Chris@16
|
281 : satisfies<
|
Chris@16
|
282 ArgList
|
Chris@16
|
283 , typename as_parameter_requirements<ParameterSpec>::type
|
Chris@16
|
284 >
|
Chris@16
|
285 {};
|
Chris@16
|
286
|
Chris@16
|
287 // Tags a deduced argument Arg with the keyword tag of Spec using TagFn.
|
Chris@16
|
288 // Returns the tagged argument and the mpl::set<> UsedArgs with the
|
Chris@16
|
289 // tag of Spec inserted.
|
Chris@16
|
290 template <class UsedArgs, class Spec, class Arg, class TagFn>
|
Chris@16
|
291 struct tag_deduced
|
Chris@16
|
292 {
|
Chris@16
|
293 typedef mpl::pair<
|
Chris@16
|
294 typename mpl::apply_wrap2<TagFn, typename tag_type<Spec>::type, Arg>::type
|
Chris@16
|
295 , typename aux::insert_<UsedArgs, typename tag_type<Spec>::type>::type
|
Chris@16
|
296 > type;
|
Chris@16
|
297 };
|
Chris@16
|
298
|
Chris@16
|
299 template <
|
Chris@16
|
300 class Argument
|
Chris@16
|
301 , class ArgumentPack
|
Chris@16
|
302 , class DeducedArgs
|
Chris@16
|
303 , class UsedArgs
|
Chris@16
|
304 , class TagFn
|
Chris@16
|
305 >
|
Chris@16
|
306 struct deduce_tag;
|
Chris@16
|
307
|
Chris@16
|
308 // Tag type passed to MPL lambda.
|
Chris@16
|
309 struct lambda_tag;
|
Chris@16
|
310
|
Chris@16
|
311 // Helper for deduce_tag<> below.
|
Chris@16
|
312 template <
|
Chris@16
|
313 class Argument
|
Chris@16
|
314 , class ArgumentPack
|
Chris@16
|
315 , class DeducedArgs
|
Chris@16
|
316 , class UsedArgs
|
Chris@16
|
317 , class TagFn
|
Chris@16
|
318 >
|
Chris@16
|
319 struct deduce_tag0
|
Chris@16
|
320 {
|
Chris@16
|
321 typedef typename DeducedArgs::spec spec;
|
Chris@16
|
322
|
Chris@16
|
323 typedef typename mpl::apply_wrap2<
|
Chris@16
|
324 typename mpl::lambda<
|
Chris@16
|
325 typename spec::predicate, lambda_tag
|
Chris@16
|
326 >::type
|
Chris@16
|
327 , Argument
|
Chris@16
|
328 , ArgumentPack
|
Chris@16
|
329 >::type condition;
|
Chris@16
|
330
|
Chris@16
|
331 // Deduced parameter matches several arguments.
|
Chris@16
|
332
|
Chris@16
|
333 BOOST_MPL_ASSERT((
|
Chris@16
|
334 mpl::not_<mpl::and_<
|
Chris@16
|
335 condition
|
Chris@16
|
336 , aux::has_key_<UsedArgs, typename tag_type<spec>::type>
|
Chris@16
|
337 > >
|
Chris@16
|
338 ));
|
Chris@16
|
339
|
Chris@16
|
340 typedef typename mpl::eval_if<
|
Chris@16
|
341 condition
|
Chris@16
|
342 , tag_deduced<UsedArgs, spec, Argument, TagFn>
|
Chris@16
|
343 , deduce_tag<Argument, ArgumentPack, typename DeducedArgs::tail, UsedArgs, TagFn>
|
Chris@16
|
344 >::type type;
|
Chris@16
|
345 };
|
Chris@16
|
346
|
Chris@16
|
347 // Tries to deduced a keyword tag for a given Argument.
|
Chris@16
|
348 // Returns an mpl::pair<> consisting of the tagged_argument<>,
|
Chris@16
|
349 // and an mpl::set<> where the new tag has been inserted.
|
Chris@16
|
350 //
|
Chris@16
|
351 // Argument: The argument type to be tagged.
|
Chris@16
|
352 //
|
Chris@16
|
353 // ArgumentPack: The ArgumentPack built so far.
|
Chris@16
|
354 //
|
Chris@16
|
355 // DeducedArgs: A specialization of deduced_item<> (see below).
|
Chris@16
|
356 // A list containing only the deduced ParameterSpecs.
|
Chris@16
|
357 //
|
Chris@16
|
358 // UsedArgs: An mpl::set<> containing the keyword tags used so far.
|
Chris@16
|
359 //
|
Chris@16
|
360 // TagFn: A metafunction class used to tag positional or deduced
|
Chris@16
|
361 // arguments with a keyword tag.
|
Chris@16
|
362
|
Chris@16
|
363 template <
|
Chris@16
|
364 class Argument
|
Chris@16
|
365 , class ArgumentPack
|
Chris@16
|
366 , class DeducedArgs
|
Chris@16
|
367 , class UsedArgs
|
Chris@16
|
368 , class TagFn
|
Chris@16
|
369 >
|
Chris@16
|
370 struct deduce_tag
|
Chris@16
|
371 {
|
Chris@16
|
372 typedef typename mpl::eval_if<
|
Chris@16
|
373 is_same<DeducedArgs, void_>
|
Chris@16
|
374 , mpl::pair<void_, UsedArgs>
|
Chris@16
|
375 , deduce_tag0<Argument, ArgumentPack, DeducedArgs, UsedArgs, TagFn>
|
Chris@16
|
376 >::type type;
|
Chris@16
|
377 };
|
Chris@16
|
378
|
Chris@16
|
379 template <
|
Chris@16
|
380 class List
|
Chris@16
|
381 , class DeducedArgs
|
Chris@16
|
382 , class TagFn
|
Chris@16
|
383 , class Positional
|
Chris@16
|
384 , class UsedArgs
|
Chris@16
|
385 , class ArgumentPack
|
Chris@16
|
386 , class Error
|
Chris@16
|
387 >
|
Chris@16
|
388 struct make_arg_list_aux;
|
Chris@16
|
389
|
Chris@16
|
390 // Inserts Tagged::key_type into the UserArgs set.
|
Chris@16
|
391 // Extra indirection to lazily evaluate Tagged::key_type.
|
Chris@16
|
392 template <class UsedArgs, class Tagged>
|
Chris@16
|
393 struct insert_tagged
|
Chris@16
|
394 {
|
Chris@16
|
395 typedef typename aux::insert_<
|
Chris@16
|
396 UsedArgs, typename Tagged::key_type
|
Chris@16
|
397 >::type type;
|
Chris@16
|
398 };
|
Chris@16
|
399
|
Chris@16
|
400 // Borland needs the insane extra-indirection workaround below
|
Chris@16
|
401 // so that it doesn't magically drop the const qualifier from
|
Chris@16
|
402 // the argument type.
|
Chris@16
|
403
|
Chris@16
|
404 template <
|
Chris@16
|
405 class List
|
Chris@16
|
406 , class DeducedArgs
|
Chris@16
|
407 , class TagFn
|
Chris@16
|
408 , class Positional
|
Chris@16
|
409 , class UsedArgs
|
Chris@16
|
410 , class ArgumentPack
|
Chris@16
|
411 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
Chris@16
|
412 , class argument
|
Chris@16
|
413 #endif
|
Chris@16
|
414 , class Error
|
Chris@16
|
415 >
|
Chris@16
|
416 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
Chris@16
|
417 struct make_arg_list00
|
Chris@16
|
418 #else
|
Chris@16
|
419 struct make_arg_list0
|
Chris@16
|
420 #endif
|
Chris@16
|
421 {
|
Chris@16
|
422 #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
Chris@16
|
423 typedef typename List::arg argument;
|
Chris@16
|
424 #endif
|
Chris@16
|
425 typedef typename List::spec parameter_spec;
|
Chris@16
|
426 typedef typename tag_type<parameter_spec>::type tag_;
|
Chris@16
|
427
|
Chris@16
|
428 typedef is_named_argument<argument> is_tagged;
|
Chris@16
|
429
|
Chris@16
|
430 // If this argument is either explicitly tagged or a deduced
|
Chris@16
|
431 // parameter, we turn off positional matching.
|
Chris@16
|
432 typedef mpl::and_<
|
Chris@16
|
433 mpl::not_<
|
Chris@16
|
434 mpl::or_<is_deduced<parameter_spec>, is_tagged>
|
Chris@16
|
435 >
|
Chris@16
|
436 , Positional
|
Chris@16
|
437 > positional;
|
Chris@16
|
438
|
Chris@16
|
439 // If this parameter is explicitly tagged we add it to the
|
Chris@16
|
440 // used-parmeters set. We only really need to add parameters
|
Chris@16
|
441 // that are deduced, but we would need a way to check if
|
Chris@16
|
442 // a given tag corresponds to a deduced parameter spec.
|
Chris@16
|
443 typedef typename mpl::eval_if<
|
Chris@16
|
444 is_tagged
|
Chris@16
|
445 , insert_tagged<UsedArgs, argument>
|
Chris@16
|
446 , mpl::identity<UsedArgs>
|
Chris@16
|
447 >::type used_args;
|
Chris@16
|
448
|
Chris@16
|
449 // If this parameter is neither explicitly tagged, nor
|
Chris@16
|
450 // positionally matched; deduce the tag from the deduced
|
Chris@16
|
451 // parameter specs.
|
Chris@16
|
452 typedef typename mpl::eval_if<
|
Chris@16
|
453 mpl::or_<is_tagged, positional>
|
Chris@16
|
454 , mpl::pair<void_, used_args>
|
Chris@16
|
455 , deduce_tag<argument, ArgumentPack, DeducedArgs, used_args, TagFn>
|
Chris@16
|
456 >::type deduced_data;
|
Chris@16
|
457
|
Chris@16
|
458 // If this parameter is explicitly tagged..
|
Chris@16
|
459 typedef typename mpl::eval_if<
|
Chris@16
|
460 is_tagged
|
Chris@16
|
461 , mpl::identity<argument> // .. just use it
|
Chris@16
|
462 , mpl::eval_if< // .. else, if positional matching is turned on..
|
Chris@16
|
463 positional
|
Chris@16
|
464 , mpl::apply_wrap2<TagFn, tag_, argument> // .. tag it positionally
|
Chris@16
|
465 , mpl::first<deduced_data> // .. else, use the deduced tag
|
Chris@16
|
466 >
|
Chris@16
|
467 >::type tagged;
|
Chris@16
|
468
|
Chris@16
|
469 // We build the arg_list incrementally as we go, prepending new
|
Chris@16
|
470 // nodes.
|
Chris@16
|
471
|
Chris@16
|
472 typedef typename mpl::if_<
|
Chris@16
|
473 mpl::and_<
|
Chris@16
|
474 is_same<Error, void_>
|
Chris@16
|
475 , is_same<tagged, void_>
|
Chris@16
|
476 >
|
Chris@16
|
477 , parameter_::unmatched_argument<argument>
|
Chris@16
|
478 , void_
|
Chris@16
|
479 >::type error;
|
Chris@16
|
480
|
Chris@16
|
481 typedef typename mpl::if_<
|
Chris@16
|
482 is_same<tagged, void_>
|
Chris@16
|
483 , ArgumentPack
|
Chris@16
|
484 , arg_list<tagged, ArgumentPack>
|
Chris@16
|
485 >::type argument_pack;
|
Chris@16
|
486
|
Chris@16
|
487 typedef typename make_arg_list_aux<
|
Chris@16
|
488 typename List::tail
|
Chris@16
|
489 , DeducedArgs
|
Chris@16
|
490 , TagFn
|
Chris@16
|
491 , positional
|
Chris@16
|
492 , typename deduced_data::second
|
Chris@16
|
493 , argument_pack
|
Chris@16
|
494 , error
|
Chris@16
|
495 >::type type;
|
Chris@16
|
496 };
|
Chris@16
|
497
|
Chris@16
|
498 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
Chris@16
|
499 template <
|
Chris@16
|
500 class List
|
Chris@16
|
501 , class DeducedArgs
|
Chris@16
|
502 , class TagFn
|
Chris@16
|
503 , class Positional
|
Chris@16
|
504 , class UsedArgs
|
Chris@16
|
505 , class ArgumentPack
|
Chris@16
|
506 , class Error
|
Chris@16
|
507 >
|
Chris@16
|
508 struct make_arg_list0
|
Chris@16
|
509 {
|
Chris@16
|
510 typedef typename mpl::eval_if<
|
Chris@16
|
511 typename List::is_arg_const
|
Chris@16
|
512 , make_arg_list00<
|
Chris@16
|
513 List
|
Chris@16
|
514 , DeducedArgs
|
Chris@16
|
515 , TagFn
|
Chris@16
|
516 , Positional
|
Chris@16
|
517 , UsedArgs
|
Chris@16
|
518 , ArgumentPack
|
Chris@16
|
519 , typename List::arg const
|
Chris@16
|
520 , Error
|
Chris@16
|
521 >
|
Chris@16
|
522 , make_arg_list00<
|
Chris@16
|
523 List
|
Chris@16
|
524 , DeducedArgs
|
Chris@16
|
525 , TagFn
|
Chris@16
|
526 , Positional
|
Chris@16
|
527 , UsedArgs
|
Chris@16
|
528 , ArgumentPack
|
Chris@16
|
529 , typename List::arg
|
Chris@16
|
530 , Error
|
Chris@16
|
531 >
|
Chris@16
|
532 >::type type;
|
Chris@16
|
533 };
|
Chris@16
|
534 #endif
|
Chris@16
|
535
|
Chris@16
|
536 // Returns an ArgumentPack where the list of arguments has
|
Chris@16
|
537 // been tagged with keyword tags.
|
Chris@16
|
538 //
|
Chris@16
|
539 // List: A specialization of item<> (see below). Contains
|
Chris@16
|
540 // both the ordered ParameterSpecs, and the given arguments.
|
Chris@16
|
541 //
|
Chris@16
|
542 // DeducedArgs: A specialization of deduced_item<> (see below).
|
Chris@16
|
543 // A list containing only the deduced ParameterSpecs.
|
Chris@16
|
544 //
|
Chris@16
|
545 // TagFn: A metafunction class used to tag positional or deduced
|
Chris@16
|
546 // arguments with a keyword tag.
|
Chris@16
|
547 //
|
Chris@16
|
548 // Position: An mpl::bool_<> specialization indicating if positional
|
Chris@16
|
549 // matching is to be performed.
|
Chris@16
|
550 //
|
Chris@16
|
551 // DeducedSet: An mpl::set<> containing the keyword tags used so far.
|
Chris@16
|
552 //
|
Chris@16
|
553 // ArgumentPack: The ArgumentPack built so far. This is initially an
|
Chris@16
|
554 // empty_arg_list and is built incrementally.
|
Chris@16
|
555 //
|
Chris@16
|
556
|
Chris@16
|
557 template <
|
Chris@16
|
558 class List
|
Chris@16
|
559 , class DeducedArgs
|
Chris@16
|
560 , class TagFn
|
Chris@16
|
561 , class Positional
|
Chris@16
|
562 , class DeducedSet
|
Chris@16
|
563 , class ArgumentPack
|
Chris@16
|
564 , class Error
|
Chris@16
|
565 >
|
Chris@16
|
566 struct make_arg_list_aux
|
Chris@16
|
567 {
|
Chris@16
|
568 typedef typename mpl::eval_if<
|
Chris@16
|
569 is_same<List, void_>
|
Chris@16
|
570 , mpl::identity<mpl::pair<ArgumentPack, Error> >
|
Chris@16
|
571 , make_arg_list0<List, DeducedArgs, TagFn, Positional, DeducedSet, ArgumentPack, Error>
|
Chris@16
|
572 >::type type;
|
Chris@16
|
573 };
|
Chris@16
|
574
|
Chris@16
|
575 // VC6.5 was choking on the default parameters for make_arg_list_aux, so
|
Chris@16
|
576 // this just forwards to that adding in the defaults.
|
Chris@16
|
577 template <
|
Chris@16
|
578 class List
|
Chris@16
|
579 , class DeducedArgs
|
Chris@16
|
580 , class TagFn
|
Chris@16
|
581 , class EmitErrors = mpl::true_
|
Chris@16
|
582 >
|
Chris@16
|
583 struct make_arg_list
|
Chris@16
|
584 {
|
Chris@16
|
585 typedef typename make_arg_list_aux<
|
Chris@16
|
586 List, DeducedArgs, TagFn, mpl::true_, aux::set0, empty_arg_list, void_
|
Chris@16
|
587 >::type type;
|
Chris@16
|
588 };
|
Chris@16
|
589
|
Chris@16
|
590 // A parameter spec item typelist.
|
Chris@16
|
591 template <class Spec, class Arg, class Tail = void_>
|
Chris@16
|
592 struct item
|
Chris@16
|
593 {
|
Chris@16
|
594 typedef Spec spec;
|
Chris@16
|
595
|
Chris@16
|
596 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
Chris@16
|
597 typedef is_const<Arg> is_arg_const;
|
Chris@16
|
598 #endif
|
Chris@16
|
599
|
Chris@16
|
600 typedef Arg arg;
|
Chris@16
|
601 typedef Tail tail;
|
Chris@16
|
602 };
|
Chris@16
|
603
|
Chris@16
|
604 template <class Spec, class Arg, class Tail>
|
Chris@16
|
605 struct make_item
|
Chris@16
|
606 {
|
Chris@16
|
607 typedef item<Spec, Arg, typename Tail::type> type;
|
Chris@16
|
608 };
|
Chris@16
|
609
|
Chris@16
|
610 // Creates a item typelist.
|
Chris@16
|
611 template <class Spec, class Arg, class Tail>
|
Chris@16
|
612 struct make_items
|
Chris@16
|
613 {
|
Chris@16
|
614 typedef typename mpl::eval_if<
|
Chris@16
|
615 is_same<Arg, void_>
|
Chris@16
|
616 , mpl::identity<void_>
|
Chris@16
|
617 , make_item<Spec, Arg, Tail>
|
Chris@16
|
618 >::type type;
|
Chris@16
|
619 };
|
Chris@16
|
620
|
Chris@16
|
621 // A typelist that stored deduced parameter specs.
|
Chris@16
|
622 template <class ParameterSpec, class Tail = void_>
|
Chris@16
|
623 struct deduced_item
|
Chris@16
|
624 {
|
Chris@16
|
625 typedef ParameterSpec spec;
|
Chris@16
|
626 typedef Tail tail;
|
Chris@16
|
627 };
|
Chris@16
|
628
|
Chris@16
|
629 // Evaluate Tail and construct deduced_item list.
|
Chris@16
|
630 template <class Spec, class Tail>
|
Chris@16
|
631 struct make_deduced_item
|
Chris@16
|
632 {
|
Chris@16
|
633 typedef deduced_item<Spec, typename Tail::type> type;
|
Chris@16
|
634 };
|
Chris@16
|
635
|
Chris@16
|
636 template <class Spec, class Tail>
|
Chris@16
|
637 struct make_deduced_items
|
Chris@16
|
638 {
|
Chris@16
|
639 typedef typename mpl::eval_if<
|
Chris@16
|
640 is_same<Spec, void_>
|
Chris@16
|
641 , mpl::identity<void_>
|
Chris@16
|
642 , mpl::eval_if<
|
Chris@16
|
643 is_deduced<Spec>
|
Chris@16
|
644 , make_deduced_item<Spec, Tail>
|
Chris@16
|
645 , Tail
|
Chris@16
|
646 >
|
Chris@16
|
647 >::type type;
|
Chris@16
|
648 };
|
Chris@16
|
649
|
Chris@16
|
650 // Generates:
|
Chris@16
|
651 //
|
Chris@16
|
652 // make<
|
Chris@16
|
653 // parameter_spec#0, argument_type#0
|
Chris@16
|
654 // , make<
|
Chris@16
|
655 // parameter_spec#1, argument_type#1
|
Chris@16
|
656 // , ... mpl::identity<aux::empty_arg_list>
|
Chris@16
|
657 // ...>
|
Chris@16
|
658 // >
|
Chris@16
|
659 #define BOOST_PARAMETER_make_arg_list(z, n, names) \
|
Chris@16
|
660 BOOST_PP_SEQ_ELEM(0,names)< \
|
Chris@16
|
661 BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(1,names), n), \
|
Chris@16
|
662 BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(2,names), n),
|
Chris@16
|
663
|
Chris@16
|
664 #define BOOST_PARAMETER_right_angle(z, n, text) >
|
Chris@16
|
665
|
Chris@16
|
666 #define BOOST_PARAMETER_build_arg_list(n, make, parameter_spec, argument_type) \
|
Chris@16
|
667 BOOST_PP_REPEAT( \
|
Chris@16
|
668 n, BOOST_PARAMETER_make_arg_list, (make)(parameter_spec)(argument_type)) \
|
Chris@16
|
669 mpl::identity<void_> \
|
Chris@16
|
670 BOOST_PP_REPEAT(n, BOOST_PARAMETER_right_angle, _)
|
Chris@16
|
671
|
Chris@16
|
672 #define BOOST_PARAMETER_make_deduced_list(z, n, names) \
|
Chris@16
|
673 BOOST_PP_SEQ_ELEM(0,names)< \
|
Chris@16
|
674 BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(1,names), n),
|
Chris@16
|
675
|
Chris@16
|
676 #define BOOST_PARAMETER_build_deduced_list(n, make, parameter_spec) \
|
Chris@16
|
677 BOOST_PP_REPEAT( \
|
Chris@16
|
678 n, BOOST_PARAMETER_make_deduced_list, (make)(parameter_spec)) \
|
Chris@16
|
679 mpl::identity<void_> \
|
Chris@16
|
680 BOOST_PP_REPEAT(n, BOOST_PARAMETER_right_angle, _)
|
Chris@16
|
681
|
Chris@16
|
682 struct tag_keyword_arg
|
Chris@16
|
683 {
|
Chris@16
|
684 template <class K, class T>
|
Chris@16
|
685 struct apply
|
Chris@16
|
686 : tag<K,T>
|
Chris@16
|
687 {};
|
Chris@16
|
688 };
|
Chris@16
|
689
|
Chris@16
|
690 struct tag_template_keyword_arg
|
Chris@16
|
691 {
|
Chris@16
|
692 template <class K, class T>
|
Chris@16
|
693 struct apply
|
Chris@16
|
694 {
|
Chris@16
|
695 typedef template_keyword<K,T> type;
|
Chris@16
|
696 };
|
Chris@16
|
697 };
|
Chris@16
|
698
|
Chris@16
|
699 } // namespace aux
|
Chris@16
|
700
|
Chris@16
|
701 #define BOOST_PARAMETER_FORWARD_TYPEDEF(z, i, names) \
|
Chris@16
|
702 typedef BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(0,names),i) BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(1,names),i);
|
Chris@16
|
703
|
Chris@16
|
704 #define BOOST_PARAMETER_FORWARD_TYPEDEFS(n, src, dest) \
|
Chris@16
|
705 BOOST_PP_REPEAT(n, BOOST_PARAMETER_FORWARD_TYPEDEF, (src)(dest))
|
Chris@16
|
706
|
Chris@16
|
707
|
Chris@16
|
708 #define BOOST_PARAMETER_TEMPLATE_ARGS(z, n, text) class BOOST_PP_CAT(PS, n) = void_
|
Chris@16
|
709
|
Chris@16
|
710 template<
|
Chris@16
|
711 class PS0
|
Chris@16
|
712 , BOOST_PP_ENUM_SHIFTED(BOOST_PARAMETER_MAX_ARITY, BOOST_PARAMETER_TEMPLATE_ARGS, _)
|
Chris@16
|
713 >
|
Chris@16
|
714 struct parameters
|
Chris@16
|
715 {
|
Chris@16
|
716 #undef BOOST_PARAMETER_TEMPLATE_ARGS
|
Chris@16
|
717
|
Chris@16
|
718 typedef typename BOOST_PARAMETER_build_deduced_list(
|
Chris@16
|
719 BOOST_PARAMETER_MAX_ARITY, aux::make_deduced_items, PS
|
Chris@16
|
720 )::type deduced_list;
|
Chris@16
|
721
|
Chris@16
|
722 // if the elements of NamedList match the criteria of overload
|
Chris@16
|
723 // resolution, returns a type which can be constructed from
|
Chris@16
|
724 // parameters. Otherwise, this is not a valid metafunction (no nested
|
Chris@16
|
725 // ::type).
|
Chris@16
|
726
|
Chris@16
|
727
|
Chris@16
|
728 #if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
|
Chris@16
|
729 // If NamedList satisfies the PS0, PS1, ..., this is a
|
Chris@16
|
730 // metafunction returning parameters. Otherwise it
|
Chris@16
|
731 // has no nested ::type.
|
Chris@16
|
732 template <class ArgumentPackAndError>
|
Chris@16
|
733 struct match_base
|
Chris@16
|
734 : mpl::if_<
|
Chris@16
|
735 // mpl::and_<
|
Chris@16
|
736 // aux::satisfies_requirements_of<NamedList,PS0>
|
Chris@16
|
737 // , mpl::and_<
|
Chris@16
|
738 // aux::satisfies_requirements_of<NamedList,PS1>...
|
Chris@16
|
739 // ..., mpl::true_
|
Chris@16
|
740 // ...> >
|
Chris@16
|
741
|
Chris@16
|
742 # define BOOST_PARAMETER_satisfies(z, n, text) \
|
Chris@16
|
743 mpl::and_< \
|
Chris@16
|
744 aux::satisfies_requirements_of< \
|
Chris@16
|
745 typename mpl::first<ArgumentPackAndError>::type \
|
Chris@16
|
746 , BOOST_PP_CAT(PS, n)> \
|
Chris@16
|
747 ,
|
Chris@16
|
748 mpl::and_<
|
Chris@16
|
749 is_same<typename mpl::second<ArgumentPackAndError>::type, void_>
|
Chris@16
|
750 , BOOST_PP_REPEAT(BOOST_PARAMETER_MAX_ARITY, BOOST_PARAMETER_satisfies, _)
|
Chris@16
|
751 mpl::true_
|
Chris@16
|
752 BOOST_PP_REPEAT(BOOST_PARAMETER_MAX_ARITY, BOOST_PARAMETER_right_angle, _)
|
Chris@16
|
753 >
|
Chris@16
|
754
|
Chris@16
|
755 # undef BOOST_PARAMETER_satisfies
|
Chris@16
|
756
|
Chris@16
|
757 , mpl::identity<parameters>
|
Chris@16
|
758 , void_
|
Chris@16
|
759 >
|
Chris@16
|
760 {};
|
Chris@16
|
761 #endif
|
Chris@16
|
762
|
Chris@16
|
763 // Specializations are to be used as an optional argument to
|
Chris@16
|
764 // eliminate overloads via SFINAE
|
Chris@16
|
765 template<
|
Chris@16
|
766 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
Chris@16
|
767 // Borland simply can't handle default arguments in member
|
Chris@16
|
768 // class templates. People wishing to write portable code can
|
Chris@16
|
769 // explicitly specify BOOST_PARAMETER_MAX_ARITY arguments
|
Chris@16
|
770 BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, class A)
|
Chris@16
|
771 #else
|
Chris@16
|
772 BOOST_PP_ENUM_BINARY_PARAMS(
|
Chris@16
|
773 BOOST_PARAMETER_MAX_ARITY, class A, = void_ BOOST_PP_INTERCEPT
|
Chris@16
|
774 )
|
Chris@16
|
775 #endif
|
Chris@16
|
776 >
|
Chris@16
|
777 struct match
|
Chris@16
|
778 # if ! defined(BOOST_NO_SFINAE) && ! BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x592))
|
Chris@16
|
779 : match_base<
|
Chris@16
|
780 typename aux::make_arg_list<
|
Chris@16
|
781 typename BOOST_PARAMETER_build_arg_list(
|
Chris@16
|
782 BOOST_PARAMETER_MAX_ARITY, aux::make_items, PS, A
|
Chris@16
|
783 )::type
|
Chris@16
|
784 , deduced_list
|
Chris@16
|
785 , aux::tag_keyword_arg
|
Chris@16
|
786 , mpl::false_ // Don't emit errors when doing SFINAE
|
Chris@16
|
787 >::type
|
Chris@16
|
788 >::type
|
Chris@16
|
789 {};
|
Chris@16
|
790 # else
|
Chris@16
|
791 {
|
Chris@16
|
792 typedef parameters<
|
Chris@16
|
793 BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, PS)
|
Chris@16
|
794 > type;
|
Chris@16
|
795 };
|
Chris@16
|
796 # endif
|
Chris@16
|
797
|
Chris@16
|
798 // Metafunction that returns an ArgumentPack.
|
Chris@16
|
799
|
Chris@16
|
800 // TODO, bind has to instantiate the error type in the result
|
Chris@16
|
801 // of make_arg_list.
|
Chris@16
|
802
|
Chris@16
|
803 template <
|
Chris@16
|
804 #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
Chris@16
|
805 // Borland simply can't handle default arguments in member
|
Chris@16
|
806 // class templates. People wishing to write portable code can
|
Chris@16
|
807 // explicitly specify BOOST_PARAMETER_MAX_ARITY arguments
|
Chris@16
|
808 BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, class A)
|
Chris@16
|
809 #else
|
Chris@16
|
810 BOOST_PP_ENUM_BINARY_PARAMS(
|
Chris@16
|
811 BOOST_PARAMETER_MAX_ARITY, class A, = void_ BOOST_PP_INTERCEPT
|
Chris@16
|
812 )
|
Chris@16
|
813 #endif
|
Chris@16
|
814 >
|
Chris@16
|
815 struct bind
|
Chris@16
|
816 {
|
Chris@16
|
817 typedef typename aux::make_arg_list<
|
Chris@16
|
818 typename BOOST_PARAMETER_build_arg_list(
|
Chris@16
|
819 BOOST_PARAMETER_MAX_ARITY, aux::make_items, PS, A
|
Chris@16
|
820 )::type
|
Chris@16
|
821 , deduced_list
|
Chris@16
|
822 , aux::tag_template_keyword_arg
|
Chris@16
|
823 >::type result;
|
Chris@16
|
824
|
Chris@16
|
825 typedef typename mpl::first<result>::type type;
|
Chris@16
|
826 };
|
Chris@16
|
827
|
Chris@16
|
828 BOOST_PARAMETER_FORWARD_TYPEDEFS(BOOST_PARAMETER_MAX_ARITY, PS, parameter_spec)
|
Chris@16
|
829
|
Chris@16
|
830 //
|
Chris@16
|
831 // The function call operator is used to build an arg_list that
|
Chris@16
|
832 // labels the positional parameters and maintains whatever other
|
Chris@16
|
833 // tags may have been specified by the caller.
|
Chris@16
|
834 //
|
Chris@16
|
835 // !!!NOTE!!!
|
Chris@16
|
836 //
|
Chris@16
|
837 // The make_arg_list<> produces a reversed arg_list, so
|
Chris@16
|
838 // we need to pass the arguments to its constructor
|
Chris@16
|
839 // reversed.
|
Chris@16
|
840 //
|
Chris@16
|
841 aux::empty_arg_list operator()() const
|
Chris@16
|
842 {
|
Chris@16
|
843 return aux::empty_arg_list();
|
Chris@16
|
844 }
|
Chris@16
|
845
|
Chris@16
|
846 template<class A0>
|
Chris@16
|
847 typename mpl::first<
|
Chris@16
|
848 typename aux::make_arg_list<
|
Chris@16
|
849 aux::item<
|
Chris@16
|
850 PS0,A0
|
Chris@16
|
851 >
|
Chris@16
|
852 , deduced_list
|
Chris@16
|
853 , aux::tag_keyword_arg
|
Chris@16
|
854 >::type
|
Chris@16
|
855 >::type
|
Chris@16
|
856 operator()(A0& a0) const
|
Chris@16
|
857 {
|
Chris@16
|
858 typedef typename aux::make_arg_list<
|
Chris@16
|
859 aux::item<
|
Chris@16
|
860 PS0,A0
|
Chris@16
|
861 >
|
Chris@16
|
862 , deduced_list
|
Chris@16
|
863 , aux::tag_keyword_arg
|
Chris@16
|
864 >::type result;
|
Chris@16
|
865
|
Chris@16
|
866 typedef typename mpl::first<result>::type result_type;
|
Chris@16
|
867 typedef typename mpl::second<result>::type error;
|
Chris@16
|
868 error();
|
Chris@16
|
869
|
Chris@16
|
870 return result_type(
|
Chris@16
|
871 a0
|
Chris@16
|
872 // , void_(), void_(), void_() ...
|
Chris@16
|
873 BOOST_PP_ENUM_TRAILING_PARAMS(
|
Chris@16
|
874 BOOST_PP_SUB(BOOST_PARAMETER_MAX_ARITY, 1)
|
Chris@16
|
875 , aux::void_reference() BOOST_PP_INTERCEPT)
|
Chris@16
|
876 );
|
Chris@16
|
877 }
|
Chris@16
|
878
|
Chris@16
|
879 template<class A0, class A1>
|
Chris@16
|
880 typename mpl::first<
|
Chris@16
|
881 typename aux::make_arg_list<
|
Chris@16
|
882 aux::item<
|
Chris@16
|
883 PS0,A0
|
Chris@16
|
884 , aux::item<
|
Chris@16
|
885 PS1,A1
|
Chris@16
|
886 >
|
Chris@16
|
887 >
|
Chris@16
|
888 , deduced_list
|
Chris@16
|
889 , aux::tag_keyword_arg
|
Chris@16
|
890 >::type
|
Chris@16
|
891 >::type
|
Chris@16
|
892 operator()(A0& a0, A1& a1) const
|
Chris@16
|
893 {
|
Chris@16
|
894 typedef typename aux::make_arg_list<
|
Chris@16
|
895 aux::item<
|
Chris@16
|
896 PS0,A0
|
Chris@16
|
897 , aux::item<
|
Chris@16
|
898 PS1,A1
|
Chris@16
|
899 >
|
Chris@16
|
900 >
|
Chris@16
|
901 , deduced_list
|
Chris@16
|
902 , aux::tag_keyword_arg
|
Chris@16
|
903 >::type result;
|
Chris@16
|
904
|
Chris@16
|
905 typedef typename mpl::first<result>::type result_type;
|
Chris@16
|
906 typedef typename mpl::second<result>::type error;
|
Chris@16
|
907 error();
|
Chris@16
|
908
|
Chris@16
|
909 return result_type(
|
Chris@16
|
910 a1,a0
|
Chris@16
|
911 // , void_(), void_() ...
|
Chris@16
|
912 BOOST_PP_ENUM_TRAILING_PARAMS(
|
Chris@16
|
913 BOOST_PP_SUB(BOOST_PARAMETER_MAX_ARITY, 2)
|
Chris@16
|
914 , aux::void_reference() BOOST_PP_INTERCEPT)
|
Chris@16
|
915 );
|
Chris@16
|
916 }
|
Chris@16
|
917
|
Chris@16
|
918 // Higher arities are handled by the preprocessor
|
Chris@16
|
919 #define BOOST_PP_ITERATION_PARAMS_1 (3,( \
|
Chris@16
|
920 3,BOOST_PARAMETER_MAX_ARITY,<boost/parameter/aux_/overloads.hpp> \
|
Chris@16
|
921 ))
|
Chris@16
|
922 #include BOOST_PP_ITERATE()
|
Chris@16
|
923
|
Chris@16
|
924 };
|
Chris@16
|
925
|
Chris@16
|
926 } // namespace parameter
|
Chris@16
|
927
|
Chris@16
|
928 } // namespace boost
|
Chris@16
|
929
|
Chris@16
|
930 #endif // BOOST_PARAMETERS_031014_HPP
|
Chris@16
|
931
|