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

source code of boost/boost/parameter/parameters.hpp