ossrv_pub/boost_apis/boost/parameter/parameters.hpp
changeset 0 e4d67989cc36
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ossrv_pub/boost_apis/boost/parameter/parameters.hpp	Tue Feb 02 02:01:42 2010 +0200
@@ -0,0 +1,931 @@
+// Copyright David Abrahams, Daniel Wallin 2003. Use, modification and 
+// distribution is subject to the Boost Software License, Version 1.0. 
+// (See accompanying file LICENSE_1_0.txt or copy at 
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PARAMETERS_031014_HPP
+#define BOOST_PARAMETERS_031014_HPP
+
+#include <boost/detail/is_xxx.hpp>
+
+#include <boost/type_traits/is_const.hpp>
+
+#include <boost/mpl/lambda.hpp>
+#include <boost/mpl/apply.hpp>
+#include <boost/mpl/always.hpp>
+#include <boost/mpl/and.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/not.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/pair.hpp>
+
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+#include <boost/preprocessor/repetition/enum.hpp>
+#include <boost/preprocessor/repetition/enum_params.hpp>
+#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
+#include <boost/preprocessor/arithmetic/sub.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
+#include <boost/preprocessor/repetition/enum_shifted.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
+#include <boost/preprocessor/seq/elem.hpp>
+#include <boost/preprocessor/iteration/iterate.hpp>
+#include <boost/preprocessor/facilities/intercept.hpp>
+#include <boost/preprocessor/cat.hpp>
+
+#include <boost/parameter/aux_/arg_list.hpp>
+#include <boost/parameter/aux_/yesno.hpp>
+#include <boost/parameter/aux_/void.hpp>
+#include <boost/parameter/aux_/default.hpp>
+#include <boost/parameter/aux_/unwrap_cv_reference.hpp>
+#include <boost/parameter/aux_/tagged_argument.hpp>
+#include <boost/parameter/aux_/tag.hpp>
+#include <boost/parameter/aux_/template_keyword.hpp>
+#include <boost/parameter/aux_/set.hpp>
+#include <boost/parameter/config.hpp>
+
+namespace parameter_
+{
+  template <class T>
+  struct unmatched_argument
+  {
+      BOOST_MPL_ASSERT((boost::is_same<T,void>));
+      typedef int type;
+  }; 
+} // namespace parameter_
+
+namespace boost {
+
+template<class T> class reference_wrapper;
+
+namespace parameter {
+
+namespace aux { struct use_default {}; }
+
+// These templates can be used to describe the treatment of particular
+// named parameters for the purposes of overload elimination with
+// SFINAE, by placing specializations in the parameters<...> list.  In
+// order for a treated function to participate in overload resolution:
+//
+//   - all keyword tags wrapped in required<...> must have a matching
+//     actual argument
+//
+//   - The actual argument type matched by every keyword tag
+//     associated with a predicate must satisfy that predicate
+//
+// If a keyword k is specified without an optional<...> or
+// required<...>, wrapper, it is treated as though optional<k> were
+// specified.
+//
+// If a keyword k is specified with deduced<...>, that keyword
+// will be automatically deduced from the argument list.
+//
+template <class Tag, class Predicate = aux::use_default>
+struct required
+{
+    typedef Tag key_type;
+    typedef Predicate predicate;
+};
+
+template <class Tag, class Predicate = aux::use_default>
+struct optional
+{
+    typedef Tag key_type;
+    typedef Predicate predicate;
+};
+
+template <class Tag>
+struct deduced
+{
+    typedef Tag key_type;
+};
+
+namespace aux
+{
+  // Defines metafunctions, is_required and is_optional, that
+  // identify required<...>, optional<...> and deduced<...> specializations.
+  BOOST_DETAIL_IS_XXX_DEF(required, required, 2)
+  BOOST_DETAIL_IS_XXX_DEF(optional, optional, 2)
+  BOOST_DETAIL_IS_XXX_DEF(deduced_aux, deduced, 1)
+
+  template <class S>
+  struct is_deduced0
+    : is_deduced_aux<
+          typename S::key_type
+      >::type
+  {};
+
+  template <class S>
+  struct is_deduced
+    : mpl::eval_if<
+          mpl::or_<
+              is_optional<S>, is_required<S>
+          >
+        , is_deduced0<S>
+        , mpl::false_
+      >::type
+  {};
+
+  //
+  // key_type, has_default, and predicate --
+  //
+  // These metafunctions accept a ParameterSpec and extract the
+  // keyword tag, whether or not a default is supplied for the
+  // parameter, and the predicate that the corresponding actual
+  // argument type is required match.
+  //
+  // a ParameterSpec is a specialization of either keyword<...>,
+  // required<...>, optional<...>
+  //
+
+  // helper for key_type<...>, below.
+  template <class T>
+  struct get_tag_type0
+  {
+      typedef typename T::key_type type;
+  };
+
+  template <class T>
+  struct get_tag_type
+    : mpl::eval_if<
+          is_deduced_aux<typename T::key_type>
+        , get_tag_type0<typename T::key_type>
+        , mpl::identity<typename T::key_type>
+      >
+  {};
+
+  template <class T>
+  struct tag_type
+    : mpl::eval_if<
+          mpl::or_<
+              is_optional<T>
+            , is_required<T>
+          >
+        , get_tag_type<T>
+        , mpl::identity<T>
+      >
+  {};
+
+  template <class T>
+  struct has_default
+    : mpl::not_<is_required<T> >
+  {};
+
+  // helper for get_predicate<...>, below
+  template <class T>
+  struct get_predicate_or_default
+  {
+      typedef T type;
+  };
+
+  template <>
+  struct get_predicate_or_default<use_default>
+  {
+      typedef mpl::always<mpl::true_> type;
+  };
+
+  // helper for predicate<...>, below
+  template <class T>
+  struct get_predicate
+  {
+      typedef typename
+          get_predicate_or_default<typename T::predicate>::type
+      type;
+  };
+
+  template <class T>
+  struct predicate
+    : mpl::eval_if<
+         mpl::or_<
+              is_optional<T>
+            , is_required<T>
+          >
+        , get_predicate<T>
+        , mpl::identity<mpl::always<mpl::true_> >
+      >
+  {
+  };
+
+
+  // Converts a ParameterSpec into a specialization of
+  // parameter_requirements.  We need to do this in order to get the
+  // tag_type into the type in a way that can be conveniently matched
+  // by a satisfies(...) member function in arg_list.
+  template <class ParameterSpec>
+  struct as_parameter_requirements
+  {
+      typedef parameter_requirements<
+          typename tag_type<ParameterSpec>::type
+        , typename predicate<ParameterSpec>::type
+        , typename has_default<ParameterSpec>::type
+      > type;
+  };
+
+  template <class T>
+  struct is_named_argument
+    : mpl::or_<
+          is_template_keyword<T>
+        , is_tagged_argument<T>
+      >
+  {};
+  
+  // Returns mpl::true_ iff the given ParameterRequirements are
+  // satisfied by ArgList.
+  template <class ArgList, class ParameterRequirements>
+  struct satisfies
+  {
+#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
+      // VC7.1 can't handle the sizeof() implementation below,
+      // so we use this instead.
+      typedef typename mpl::apply_wrap3<
+          typename ArgList::binding
+        , typename ParameterRequirements::keyword
+        , void_
+        , mpl::false_
+      >::type bound;
+
+      typedef typename mpl::eval_if<
+          is_same<bound, void_>
+        , typename ParameterRequirements::has_default
+        , mpl::apply_wrap2<
+              typename mpl::lambda<
+                  typename ParameterRequirements::predicate, lambda_tag
+              >::type
+            , bound
+            , ArgList
+          >
+      >::type type;
+#else
+      BOOST_STATIC_CONSTANT(
+          bool, value = (
+              sizeof(
+                  aux::to_yesno(
+                      ArgList::satisfies((ParameterRequirements*)0, (ArgList*)0)
+                  )
+              ) == sizeof(yes_tag)
+          )
+      );
+
+      typedef mpl::bool_<satisfies::value> type;
+#endif
+  };
+
+  // Returns mpl::true_ if the requirements of the given ParameterSpec
+  // are satisfied by ArgList.
+  template <class ArgList, class ParameterSpec>
+  struct satisfies_requirements_of
+    : satisfies<
+          ArgList
+        , typename as_parameter_requirements<ParameterSpec>::type
+      >
+  {};
+
+  // Tags a deduced argument Arg with the keyword tag of Spec using TagFn.
+  // Returns the tagged argument and the mpl::set<> UsedArgs with the
+  // tag of Spec inserted.
+  template <class UsedArgs, class Spec, class Arg, class TagFn>
+  struct tag_deduced
+  {
+      typedef mpl::pair<
+          typename mpl::apply_wrap2<TagFn, typename tag_type<Spec>::type, Arg>::type
+        , typename aux::insert_<UsedArgs, typename tag_type<Spec>::type>::type
+      > type;
+  };
+
+  template <
+      class Argument
+    , class ArgumentPack
+    , class DeducedArgs
+    , class UsedArgs
+    , class TagFn
+  >
+  struct deduce_tag;
+
+  // Tag type passed to MPL lambda.
+  struct lambda_tag;
+
+  // Helper for deduce_tag<> below.
+  template <
+      class Argument
+    , class ArgumentPack
+    , class DeducedArgs
+    , class UsedArgs
+    , class TagFn
+  >
+  struct deduce_tag0
+  {
+      typedef typename DeducedArgs::spec spec;
+
+      typedef typename mpl::apply_wrap2<
+          typename mpl::lambda<
+              typename spec::predicate, lambda_tag
+          >::type
+        , Argument
+        , ArgumentPack
+      >::type condition;
+
+      // Deduced parameter matches several arguments.
+
+      BOOST_MPL_ASSERT((
+          mpl::not_<mpl::and_<
+              condition
+            , aux::has_key_<UsedArgs, typename tag_type<spec>::type>
+          > >
+      ));
+
+      typedef typename mpl::eval_if<
+          condition
+        , tag_deduced<UsedArgs, spec, Argument, TagFn>
+        , deduce_tag<Argument, ArgumentPack, typename DeducedArgs::tail, UsedArgs, TagFn>
+      >::type type;
+  };
+
+  // Tries to deduced a keyword tag for a given Argument.
+  // Returns an mpl::pair<> consisting of the tagged_argument<>, 
+  // and an mpl::set<> where the new tag has been inserted.
+  //
+  //  Argument: The argument type to be tagged.
+  //
+  //  ArgumentPack: The ArgumentPack built so far.
+  //
+  //  DeducedArgs: A specialization of deduced_item<> (see below).
+  //               A list containing only the deduced ParameterSpecs.
+  //
+  //  UsedArgs: An mpl::set<> containing the keyword tags used so far.
+  //
+  //  TagFn: A metafunction class used to tag positional or deduced
+  //         arguments with a keyword tag.
+
+  template <
+      class Argument
+    , class ArgumentPack
+    , class DeducedArgs
+    , class UsedArgs
+    , class TagFn
+  >
+  struct deduce_tag
+  {
+      typedef typename mpl::eval_if<
+          is_same<DeducedArgs, void_>
+        , mpl::pair<void_, UsedArgs>
+        , deduce_tag0<Argument, ArgumentPack, DeducedArgs, UsedArgs, TagFn>
+      >::type type;
+  };
+
+  template <
+      class List
+    , class DeducedArgs
+    , class TagFn
+    , class Positional
+    , class UsedArgs
+    , class ArgumentPack
+    , class Error
+  >
+  struct make_arg_list_aux;
+
+  // Inserts Tagged::key_type into the UserArgs set.
+  // Extra indirection to lazily evaluate Tagged::key_type.
+  template <class UsedArgs, class Tagged>
+  struct insert_tagged
+  {
+      typedef typename aux::insert_<
+          UsedArgs, typename Tagged::key_type
+      >::type type;
+  };
+
+  // Borland needs the insane extra-indirection workaround below
+  // so that it doesn't magically drop the const qualifier from
+  // the argument type.
+
+  template <
+      class List
+    , class DeducedArgs
+    , class TagFn
+    , class Positional
+    , class UsedArgs
+    , class ArgumentPack
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+    , class argument
+#endif
+    , class Error
+  >
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+  struct make_arg_list00
+#else
+  struct make_arg_list0
+#endif
+  {
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+      typedef typename List::arg argument;
+#endif
+      typedef typename List::spec parameter_spec;
+      typedef typename tag_type<parameter_spec>::type tag_;
+
+      typedef is_named_argument<argument> is_tagged;
+
+      // If this argument is either explicitly tagged or a deduced
+      // parameter, we turn off positional matching.
+      typedef mpl::and_<
+          mpl::not_<
+              mpl::or_<is_deduced<parameter_spec>, is_tagged> 
+          > 
+        , Positional
+      > positional;
+
+      // If this parameter is explicitly tagged we add it to the
+      // used-parmeters set. We only really need to add parameters
+      // that are deduced, but we would need a way to check if
+      // a given tag corresponds to a deduced parameter spec.
+      typedef typename mpl::eval_if<
+          is_tagged
+        , insert_tagged<UsedArgs, argument>
+        , mpl::identity<UsedArgs>
+      >::type used_args;
+
+      // If this parameter is neither explicitly tagged, nor
+      // positionally matched; deduce the tag from the deduced
+      // parameter specs.
+      typedef typename mpl::eval_if<
+          mpl::or_<is_tagged, positional>
+        , mpl::pair<void_, used_args>
+        , deduce_tag<argument, ArgumentPack, DeducedArgs, used_args, TagFn>
+      >::type deduced_data;
+
+      // If this parameter is explicitly tagged..
+      typedef typename mpl::eval_if<
+          is_tagged
+        , mpl::identity<argument>                        // .. just use it
+        , mpl::eval_if<                                  // .. else, if positional matching is turned on..
+                positional
+              , mpl::apply_wrap2<TagFn, tag_, argument>  // .. tag it positionally
+              , mpl::first<deduced_data>                 // .. else, use the deduced tag
+          >
+      >::type tagged;
+
+      // We build the arg_list incrementally as we go, prepending new
+      // nodes.
+
+      typedef typename mpl::if_<
+          mpl::and_<
+              is_same<Error, void_>
+            , is_same<tagged, void_>
+          >
+        , parameter_::unmatched_argument<argument>
+        , void_
+      >::type error;
+
+      typedef typename mpl::if_<
+          is_same<tagged, void_>
+        , ArgumentPack
+        , arg_list<tagged, ArgumentPack>
+      >::type argument_pack;
+
+      typedef typename make_arg_list_aux<
+          typename List::tail
+        , DeducedArgs
+        , TagFn
+        , positional
+        , typename deduced_data::second
+        , argument_pack
+        , error
+      >::type type;
+  };
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+  template <
+      class List
+    , class DeducedArgs
+    , class TagFn
+    , class Positional
+    , class UsedArgs
+    , class ArgumentPack
+    , class Error
+  >
+  struct make_arg_list0
+  {
+      typedef typename mpl::eval_if<
+          typename List::is_arg_const
+        , make_arg_list00<
+              List
+            , DeducedArgs
+            , TagFn
+            , Positional
+            , UsedArgs
+            , ArgumentPack
+            , typename List::arg const
+            , Error
+          >
+        , make_arg_list00<
+              List
+            , DeducedArgs
+            , TagFn
+            , Positional
+            , UsedArgs
+            , ArgumentPack
+            , typename List::arg
+            , Error
+          >
+      >::type type;
+  };
+#endif
+
+  // Returns an ArgumentPack where the list of arguments has
+  // been tagged with keyword tags.
+  //
+  //   List: A specialization of item<> (see below). Contains
+  //         both the ordered ParameterSpecs, and the given arguments.
+  //
+  //   DeducedArgs: A specialization of deduced_item<> (see below).
+  //                A list containing only the deduced ParameterSpecs.
+  //
+  //   TagFn: A metafunction class used to tag positional or deduced
+  //          arguments with a keyword tag.
+  //
+  //   Position: An mpl::bool_<> specialization indicating if positional
+  //             matching is to be performed.
+  //
+  //   DeducedSet: An mpl::set<> containing the keyword tags used so far.
+  //
+  //   ArgumentPack: The ArgumentPack built so far. This is initially an
+  //                 empty_arg_list and is built incrementally.
+  //
+
+  template <
+      class List
+    , class DeducedArgs
+    , class TagFn
+    , class Positional
+    , class DeducedSet
+    , class ArgumentPack
+    , class Error
+  >
+  struct make_arg_list_aux
+  {
+      typedef typename mpl::eval_if<
+          is_same<List, void_>
+        , mpl::identity<mpl::pair<ArgumentPack, Error> >
+        , make_arg_list0<List, DeducedArgs, TagFn, Positional, DeducedSet, ArgumentPack, Error>
+      >::type type;
+  };
+
+  // VC6.5 was choking on the default parameters for make_arg_list_aux, so
+  // this just forwards to that adding in the defaults.
+  template <
+      class List
+    , class DeducedArgs
+    , class TagFn
+    , class EmitErrors = mpl::true_
+  >
+  struct make_arg_list
+  {
+      typedef typename make_arg_list_aux<
+          List, DeducedArgs, TagFn, mpl::true_, aux::set0, empty_arg_list, void_
+      >::type type;
+  };
+
+  // A parameter spec item typelist.
+  template <class Spec, class Arg, class Tail = void_>
+  struct item
+  {
+      typedef Spec spec;
+
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+      typedef is_const<Arg> is_arg_const;
+#endif
+
+      typedef Arg arg;
+      typedef Tail tail;
+  };
+
+  template <class Spec, class Arg, class Tail>
+  struct make_item
+  {
+      typedef item<Spec, Arg, typename Tail::type> type;
+  };
+
+  // Creates a item typelist.
+  template <class Spec, class Arg, class Tail>
+  struct make_items
+  {
+      typedef typename mpl::eval_if<
+          is_same<Arg, void_>
+        , mpl::identity<void_>
+        , make_item<Spec, Arg, Tail>
+      >::type type;
+  };
+
+  // A typelist that stored deduced parameter specs.
+  template <class ParameterSpec, class Tail = void_>
+  struct deduced_item
+  {
+      typedef ParameterSpec spec;
+      typedef Tail tail;
+  };
+
+  // Evaluate Tail and construct deduced_item list.
+  template <class Spec, class Tail>
+  struct make_deduced_item
+  {
+      typedef deduced_item<Spec, typename Tail::type> type;
+  };
+
+  template <class Spec, class Tail>
+  struct make_deduced_items
+  {
+      typedef typename mpl::eval_if<
+          is_same<Spec, void_>
+        , mpl::identity<void_>
+        , mpl::eval_if<
+              is_deduced<Spec>
+            , make_deduced_item<Spec, Tail>
+            , Tail
+          >
+      >::type type;
+  };
+
+  // Generates:
+  //
+  //   make<
+  //       parameter_spec#0, argument_type#0
+  //     , make<
+  //           parameter_spec#1, argument_type#1
+  //         , ... mpl::identity<aux::empty_arg_list>
+  //    ...>
+  //   >
+#define BOOST_PARAMETER_make_arg_list(z, n, names)      \
+      BOOST_PP_SEQ_ELEM(0,names)<                       \
+          BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(1,names), n),  \
+          BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(2,names), n), 
+
+#define BOOST_PARAMETER_right_angle(z, n, text) >
+
+#define BOOST_PARAMETER_build_arg_list(n, make, parameter_spec, argument_type)      \
+  BOOST_PP_REPEAT(                                                                  \
+      n, BOOST_PARAMETER_make_arg_list, (make)(parameter_spec)(argument_type))      \
+      mpl::identity<void_>                                                          \
+  BOOST_PP_REPEAT(n, BOOST_PARAMETER_right_angle, _)
+
+#define BOOST_PARAMETER_make_deduced_list(z, n, names)  \
+      BOOST_PP_SEQ_ELEM(0,names)<                       \
+          BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(1,names), n),
+
+#define BOOST_PARAMETER_build_deduced_list(n, make, parameter_spec)                 \
+  BOOST_PP_REPEAT(                                                                  \
+      n, BOOST_PARAMETER_make_deduced_list, (make)(parameter_spec))                 \
+  mpl::identity<void_>                                                              \
+  BOOST_PP_REPEAT(n, BOOST_PARAMETER_right_angle, _)
+
+  struct tag_keyword_arg
+  {
+      template <class K, class T>
+      struct apply
+        : tag<K,T>
+      {};
+  };
+
+  struct tag_template_keyword_arg
+  {
+      template <class K, class T>
+      struct apply
+      {
+          typedef template_keyword<K,T> type;
+      };
+  };
+
+} // namespace aux
+
+#define BOOST_PARAMETER_FORWARD_TYPEDEF(z, i, names) \
+    typedef BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(0,names),i) BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(1,names),i);
+
+#define BOOST_PARAMETER_FORWARD_TYPEDEFS(n, src, dest) \
+    BOOST_PP_REPEAT(n, BOOST_PARAMETER_FORWARD_TYPEDEF, (src)(dest))
+
+
+#define BOOST_PARAMETER_TEMPLATE_ARGS(z, n, text) class BOOST_PP_CAT(PS, n) = void_
+
+template<
+     class PS0
+   , BOOST_PP_ENUM_SHIFTED(BOOST_PARAMETER_MAX_ARITY, BOOST_PARAMETER_TEMPLATE_ARGS, _)
+>
+struct parameters
+{
+#undef BOOST_PARAMETER_TEMPLATE_ARGS
+
+    typedef typename BOOST_PARAMETER_build_deduced_list(
+        BOOST_PARAMETER_MAX_ARITY, aux::make_deduced_items, PS
+    )::type deduced_list;
+
+    // if the elements of NamedList match the criteria of overload
+    // resolution, returns a type which can be constructed from
+    // parameters.  Otherwise, this is not a valid metafunction (no nested
+    // ::type).
+
+
+#ifndef BOOST_NO_SFINAE
+    // If NamedList satisfies the PS0, PS1, ..., this is a
+    // metafunction returning parameters.  Otherwise it 
+    // has no nested ::type.
+    template <class ArgumentPackAndError>
+    struct match_base
+      : mpl::if_<
+            // mpl::and_<
+            //    aux::satisfies_requirements_of<NamedList,PS0>
+            //  , mpl::and_<
+            //       aux::satisfies_requirements_of<NamedList,PS1>...
+            //           ..., mpl::true_
+            // ...> >
+            
+# define BOOST_PARAMETER_satisfies(z, n, text)                                      \
+            mpl::and_<                                                              \
+                aux::satisfies_requirements_of<                                     \
+                    typename mpl::first<ArgumentPackAndError>::type                 \
+                  , BOOST_PP_CAT(PS, n)>                                            \
+                  ,
+            mpl::and_<
+                is_same<typename mpl::second<ArgumentPackAndError>::type, void_>
+              , BOOST_PP_REPEAT(BOOST_PARAMETER_MAX_ARITY, BOOST_PARAMETER_satisfies, _)
+                mpl::true_
+                BOOST_PP_REPEAT(BOOST_PARAMETER_MAX_ARITY, BOOST_PARAMETER_right_angle, _)
+            >
+
+# undef BOOST_PARAMETER_satisfies
+
+          , mpl::identity<parameters>
+          , void_
+        >
+    {};
+#endif
+    
+    // Specializations are to be used as an optional argument to
+    // eliminate overloads via SFINAE
+    template<
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+        // Borland simply can't handle default arguments in member
+        // class templates.  People wishing to write portable code can
+        // explicitly specify BOOST_PARAMETER_MAX_ARITY arguments
+        BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, class A)
+#else 
+        BOOST_PP_ENUM_BINARY_PARAMS(
+            BOOST_PARAMETER_MAX_ARITY, class A, = void_ BOOST_PP_INTERCEPT
+        )
+#endif
+    >
+    struct match
+# ifndef BOOST_NO_SFINAE
+      : match_base<
+            typename aux::make_arg_list<
+                typename BOOST_PARAMETER_build_arg_list(
+                    BOOST_PARAMETER_MAX_ARITY, aux::make_items, PS, A
+                )::type
+              , deduced_list
+              , aux::tag_keyword_arg
+              , mpl::false_ // Don't emit errors when doing SFINAE
+            >::type
+        >::type
+    {};
+# else
+    { 
+        typedef parameters<
+            BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, PS)
+        > type; 
+    };
+# endif
+
+    // Metafunction that returns an ArgumentPack.
+
+    // TODO, bind has to instantiate the error type in the result
+    // of make_arg_list.
+
+    template <
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+        // Borland simply can't handle default arguments in member
+        // class templates.  People wishing to write portable code can
+        // explicitly specify BOOST_PARAMETER_MAX_ARITY arguments
+        BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, class A)
+#else 
+        BOOST_PP_ENUM_BINARY_PARAMS(
+            BOOST_PARAMETER_MAX_ARITY, class A, = void_ BOOST_PP_INTERCEPT
+        )
+#endif            
+    >
+    struct bind
+    {
+        typedef typename aux::make_arg_list<
+            typename BOOST_PARAMETER_build_arg_list(
+                BOOST_PARAMETER_MAX_ARITY, aux::make_items, PS, A
+            )::type
+          , deduced_list
+          , aux::tag_template_keyword_arg
+        >::type result;
+
+        typedef typename mpl::first<result>::type type;
+    };
+
+    BOOST_PARAMETER_FORWARD_TYPEDEFS(BOOST_PARAMETER_MAX_ARITY, PS, parameter_spec)
+
+    //
+    // The function call operator is used to build an arg_list that
+    // labels the positional parameters and maintains whatever other
+    // tags may have been specified by the caller.
+    //
+    // !!!NOTE!!!
+    //
+    // The make_arg_list<> produces a reversed arg_list, so
+    // we need to pass the arguments to it's constructor
+    // reversed.
+    //
+    aux::empty_arg_list operator()() const
+    {
+       return aux::empty_arg_list();
+    }
+
+    template<class A0>
+    typename mpl::first<
+        typename aux::make_arg_list<
+            aux::item<
+                PS0,A0
+            >
+          , deduced_list
+          , aux::tag_keyword_arg
+        >::type
+    >::type
+    operator()(A0& a0) const
+    {
+        typedef typename aux::make_arg_list<
+            aux::item<
+                PS0,A0
+            >
+          , deduced_list
+          , aux::tag_keyword_arg
+        >::type result;
+
+        typedef typename mpl::first<result>::type result_type;
+        typedef typename mpl::second<result>::type error;
+        error();
+
+        return result_type(
+            a0
+            // , void_(), void_(), void_() ...
+            BOOST_PP_ENUM_TRAILING_PARAMS(
+                BOOST_PP_SUB(BOOST_PARAMETER_MAX_ARITY, 1)
+              , aux::void_reference() BOOST_PP_INTERCEPT)
+        );
+    }
+
+    template<class A0, class A1>
+    typename mpl::first<
+        typename aux::make_arg_list<
+            aux::item<
+                PS0,A0
+              , aux::item<
+                    PS1,A1
+                >
+            >
+          , deduced_list
+          , aux::tag_keyword_arg
+        >::type
+    >::type
+    operator()(A0& a0, A1& a1) const
+    {
+        typedef typename aux::make_arg_list<
+            aux::item<
+                PS0,A0
+              , aux::item<
+                    PS1,A1
+                >
+            >
+          , deduced_list
+          , aux::tag_keyword_arg
+        >::type result;
+
+        typedef typename mpl::first<result>::type result_type;
+        typedef typename mpl::second<result>::type error;
+        error();
+
+        return result_type(
+            a1,a0
+            // , void_(), void_() ...
+            BOOST_PP_ENUM_TRAILING_PARAMS(
+                BOOST_PP_SUB(BOOST_PARAMETER_MAX_ARITY, 2)
+              , aux::void_reference() BOOST_PP_INTERCEPT)
+        );
+    }
+
+    // Higher arities are handled by the preprocessor
+#define BOOST_PP_ITERATION_PARAMS_1 (3,( \
+        3,BOOST_PARAMETER_MAX_ARITY,<boost/parameter/aux_/overloads.hpp> \
+    ))
+#include BOOST_PP_ITERATE()
+
+};
+
+} // namespace parameter
+
+} // namespace boost
+
+#endif // BOOST_PARAMETERS_031014_HPP
+