Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/boost/parameter/parameters.hpp @ 49

Last change on this file since 49 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 26.3 KB
Line 
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#ifndef BOOST_NO_SFINAE
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# ifndef BOOST_NO_SFINAE
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 it's 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
Note: See TracBrowser for help on using the repository browser.