]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/boost/parameter/aux_/arg_list.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / parameter / aux_ / arg_list.hpp
index 721ce040043a66f85a63610af6492fbcf1547167..ffe1bac1849e031d9b9f97331676caf7fae0b92c 100644 (file)
-// Copyright Daniel Wallin, David Abrahams 2005. Use, modification and
-// distribution is subject to the Boost Software License, Version 1.0. (See
-// accompanying file LICENSE_1_0.txt or copy at
+// Copyright Daniel Wallin, David Abrahams 2005.
+// Copyright Cromwell D. Enage 2017.
+// Distributed under 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 ARG_LIST_050329_HPP
 #define ARG_LIST_050329_HPP
 
+namespace boost { namespace parameter { namespace aux {
+
+    //
+    // Structures used to build the tuple of actual arguments.  The tuple is a
+    // nested cons-style list of arg_list specializations terminated by an
+    // empty_arg_list.
+    //
+    // Each specialization of arg_list is derived from its successor in the
+    // list type.  This feature is used along with using declarations to build
+    // member function overload sets that can match against keywords.
+    //
+
+    // MPL sequence support
+    struct arg_list_tag;
+
+    template <typename T>
+    struct get_reference
+    {
+        typedef typename T::reference type;
+    };
+}}} // namespace boost::parameter::aux
+
+#include <boost/parameter/config.hpp>
+
+#if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
+
+namespace boost { namespace parameter { namespace aux {
+
+    struct value_type_is_void
+    {
+    };
+
+    struct value_type_is_not_void
+    {
+    };
+}}} // namespace boost::parameter::aux
+
+#endif
+
 #include <boost/parameter/aux_/void.hpp>
+#include <boost/parameter/aux_/yesno.hpp>
 #include <boost/parameter/aux_/result_of0.hpp>
 #include <boost/parameter/aux_/default.hpp>
-#include <boost/parameter/aux_/parameter_requirements.hpp>
+
+#if defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
+#include <utility>
+
+#if defined(BOOST_PARAMETER_CAN_USE_MP11)
+#include <boost/mp11/integral.hpp>
+#include <boost/mp11/list.hpp>
+#include <boost/mp11/utility.hpp>
+#include <type_traits>
+#endif
+
+namespace boost { namespace parameter { namespace aux {
+
+    // Terminates arg_list<> and represents an empty list.  Since this is just
+    // the terminating case, you might want to look at arg_list first to get a
+    // feel for what's really happening here.
+    struct empty_arg_list
+    {
+        struct tagged_arg
+        {
+            typedef ::boost::parameter::void_ value_type;
+        };
+
+        // Variadic constructor also serves as default constructor.
+        template <typename ...Args>
+        inline BOOST_CONSTEXPR empty_arg_list(Args&&...)
+        {
+        }
+
+        // A metafunction class that, given a keyword and a default type,
+        // returns the appropriate result type for a keyword lookup given
+        // that default.
+        struct binding
+        {
+            template <typename KW, typename Default, typename Reference>
+            struct apply
+            {
+                typedef Default type;
+            };
+
+#if defined(BOOST_PARAMETER_CAN_USE_MP11)
+            template <typename KW, typename Default, typename Reference>
+            using fn = Default;
+#endif
+        };
+
+        // Terminator for has_key, indicating that the keyword is unique.
+        template <typename KW>
+        static ::boost::parameter::aux::no_tag has_key(KW*);
+
+        // If either of these operators are called, it means there is no
+        // argument in the list that matches the supplied keyword.  Just
+        // return the default value.
+        template <typename K, typename Default>
+        inline BOOST_CONSTEXPR Default&
+            operator[](::boost::parameter::aux::default_<K,Default> x) const
+        {
+            return x.value;
+        }
+
+        template <typename K, typename Default>
+        inline BOOST_CONSTEXPR Default&&
+            operator[](::boost::parameter::aux::default_r_<K,Default> x) const
+        {
+            return ::std::forward<Default>(x.value);
+        }
+
+        // If this operator is called, it means there is no argument in the
+        // list that matches the supplied keyword.  Just evaluate and return
+        // the default value.
+        template <typename K, typename F>
+        inline BOOST_CONSTEXPR
+        typename ::boost::parameter::aux::result_of0<F>::type
+            operator[](BOOST_PARAMETER_lazy_default_fallback<K,F> x) const
+        {
+            return x.compute_default();
+        }
+
+        // No argument corresponding to ParameterRequirements::key_type
+        // was found if we match this overload, so unless that parameter
+        // has a default, we indicate that the actual arguments don't
+        // match the function's requirements.
+        template <typename ParameterRequirements, typename ArgPack>
+        static typename ParameterRequirements::has_default
+            satisfies(ParameterRequirements*, ArgPack*);
+
+        // MPL sequence support
+        typedef ::boost::parameter::aux::empty_arg_list type; // convenience
+        // For dispatching to sequence intrinsics
+        typedef ::boost::parameter::aux::arg_list_tag tag;
+    };
+}}} // namespace boost::parameter::aux
+
+#include <boost/parameter/aux_/preprocessor/nullptr.hpp>
 #include <boost/parameter/aux_/yesno.hpp>
 #include <boost/parameter/aux_/is_maybe.hpp>
-#include <boost/parameter/config.hpp>
-
-#include <boost/mpl/apply.hpp>
+#include <boost/parameter/aux_/tagged_argument_fwd.hpp>
+#include <boost/parameter/aux_/parameter_requirements.hpp>
+#include <boost/parameter/aux_/augment_predicate.hpp>
+#include <boost/parameter/keyword_fwd.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/apply_wrap.hpp>
 #include <boost/mpl/assert.hpp>
-#include <boost/mpl/begin.hpp>
-#include <boost/mpl/end.hpp>
-#include <boost/mpl/iterator_tags.hpp>
-
-#include <boost/type_traits/add_reference.hpp>
 #include <boost/type_traits/is_same.hpp>
+#include <boost/core/enable_if.hpp>
+
+namespace boost { namespace parameter { namespace aux {
+
+    // A tuple of tagged arguments, terminated with empty_arg_list.  Every
+    // TaggedArg is an instance of tagged_argument<> or
+    // tagged_argument_rref<>.
+    template <
+        typename TaggedArg
+      , typename Next = ::boost::parameter::aux::empty_arg_list
+#if defined(BOOST_PARAMETER_CAN_USE_MP11)
+      , typename EmitsErrors = ::boost::mp11::mp_true
+#else
+      , typename EmitsErrors = ::boost::mpl::true_
+#endif
+    >
+    class arg_list : public Next
+    {
+#if defined(BOOST_PARAMETER_CAN_USE_MP11)
+        using _holds_maybe = typename ::boost::parameter::aux
+        ::is_maybe<typename TaggedArg::value_type>::type;
+#else
+        typedef typename ::boost::parameter::aux
+        ::is_maybe<typename TaggedArg::value_type>::type _holds_maybe;
+#endif
+
+        TaggedArg arg;      // Stores the argument
+
+     public:
+        typedef TaggedArg tagged_arg;
+        typedef ::boost::parameter::aux::arg_list<TaggedArg,Next> self;
+        typedef typename TaggedArg::key_type key_type;
+
+#if defined(BOOST_PARAMETER_CAN_USE_MP11)
+        using reference = typename ::boost::mp11::mp_if<
+            _holds_maybe
+          , ::boost::parameter::aux
+            ::get_reference<typename TaggedArg::value_type>
+          , ::boost::parameter::aux::get_reference<TaggedArg>
+        >::type;
+
+        using value_type = ::boost::mp11
+        ::mp_if<_holds_maybe,reference,typename TaggedArg::value_type>;
+#else   // !defined(BOOST_PARAMETER_CAN_USE_MP11)
+        typedef typename ::boost::mpl::eval_if<
+            _holds_maybe
+          , ::boost::parameter::aux
+            ::get_reference<typename TaggedArg::value_type>
+          , ::boost::parameter::aux::get_reference<TaggedArg>
+        >::type reference;
+
+        typedef typename ::boost::mpl::if_<
+            _holds_maybe
+          , reference
+          , typename TaggedArg::value_type
+        >::type value_type;
+#endif  // BOOST_PARAMETER_CAN_USE_MP11
+
+        // Create a new list by prepending arg to a copy of tail.  Used when
+        // incrementally building this structure with the comma operator.
+        inline BOOST_CONSTEXPR arg_list(
+            TaggedArg const& head
+          , Next const& tail
+        ) : Next(tail), arg(head)
+        {
+        }
+
+        // Store the arguments in successive nodes of this list.
+        // Use tag dispatching to determine whether to forward all arguments
+        // to the Next constructor, or store the first argument and forward
+        // the rest. -- Cromwell D. Enage
+        template <typename A0>
+        inline BOOST_CONSTEXPR arg_list(
+            ::boost::parameter::aux::value_type_is_not_void
+          , A0&& a0
+        ) : Next(
+#if defined(BOOST_PARAMETER_CAN_USE_MP11)
+                ::boost::mp11::mp_if<
+                    ::std::is_same<
+#else
+                typename ::boost::mpl::if_<
+                    ::boost::is_same<
+#endif
+                        typename Next::tagged_arg::value_type
+                      , ::boost::parameter::void_
+                    >
+                  , ::boost::parameter::aux::value_type_is_void
+                  , ::boost::parameter::aux::value_type_is_not_void
+#if defined(BOOST_PARAMETER_CAN_USE_MP11)
+                >()
+#else
+                >::type()
+#endif
+            )
+          , arg(::std::forward<A0>(a0))
+        {
+        }
+
+        template <typename ...Args>
+        inline BOOST_CONSTEXPR arg_list(
+            ::boost::parameter::aux::value_type_is_void
+          , Args&&... args
+        ) : Next(
+#if defined(BOOST_PARAMETER_CAN_USE_MP11)
+                ::boost::mp11::mp_if<
+                    ::std::is_same<
+#else
+                typename ::boost::mpl::if_<
+                    ::boost::is_same<
+#endif
+                        typename Next::tagged_arg::value_type
+                      , ::boost::parameter::void_
+                    >
+                  , ::boost::parameter::aux::value_type_is_void
+                  , ::boost::parameter::aux::value_type_is_not_void
+#if defined(BOOST_PARAMETER_CAN_USE_MP11)
+                >()
+#else
+                >::type()
+#endif
+              , ::std::forward<Args>(args)...
+            )
+          , arg(::boost::parameter::aux::void_reference())
+        {
+        }
+
+        template <typename A0, typename A1, typename ...Args>
+        inline BOOST_CONSTEXPR arg_list(
+            ::boost::parameter::aux::value_type_is_not_void
+          , A0&& a0
+          , A1&& a1
+          , Args&&... args
+        ) : Next(
+#if defined(BOOST_PARAMETER_CAN_USE_MP11)
+                ::boost::mp11::mp_if<
+                    ::std::is_same<
+#else
+                typename ::boost::mpl::if_<
+                    ::boost::is_same<
+#endif
+                        typename Next::tagged_arg::value_type
+                      , ::boost::parameter::void_
+                    >
+                  , ::boost::parameter::aux::value_type_is_void
+                  , ::boost::parameter::aux::value_type_is_not_void
+#if defined(BOOST_PARAMETER_CAN_USE_MP11)
+                >()
+#else
+                >::type()
+#endif
+              , ::std::forward<A1>(a1)
+              , ::std::forward<Args>(args)...
+            )
+          , arg(::std::forward<A0>(a0))
+        {
+        }
+
+        // A metafunction class that, given a keyword and a default type,
+        // returns the appropriate result type for a keyword lookup given
+        // that default.
+        struct binding
+        {
+            typedef typename Next::binding next_binding;
+
+            template <typename KW, typename Default, typename Reference>
+            struct apply
+            {
+                typedef typename ::boost::mpl::eval_if<
+                    ::boost::is_same<KW,key_type>
+                  , ::boost::mpl::if_<Reference,reference,value_type>
+                  , ::boost::mpl
+                    ::apply_wrap3<next_binding,KW,Default,Reference>
+                >::type type;
+            };
+
+#if defined(BOOST_PARAMETER_CAN_USE_MP11)
+            template <typename KW, typename Default, typename Reference>
+            using fn = ::boost::mp11::mp_if<
+                ::std::is_same<KW,key_type>
+              , ::boost::mp11::mp_if<Reference,reference,value_type>
+              , ::boost::mp11::mp_apply_q<
+                    next_binding
+                  , ::boost::mp11::mp_list<KW,Default,Reference>
+                >
+            >;
+#endif
+        };
+
+        // Overload for key_type, so the assert below will fire
+        // if the same keyword is used again.
+        static ::boost::parameter::aux::yes_tag has_key(key_type*);
+        using Next::has_key;
+
+     private:
+#if defined(BOOST_PARAMETER_CAN_USE_MP11)
+        using _has_unique_key = ::boost::mp11::mp_bool<
+#else
+        typedef ::boost::mpl::bool_<
+#endif
+            sizeof(
+                Next::has_key(
+                    static_cast<key_type*>(BOOST_PARAMETER_AUX_PP_NULLPTR)
+                )
+            ) == sizeof(::boost::parameter::aux::no_tag)
+#if defined(BOOST_PARAMETER_CAN_USE_MP11)
+        >;
+#else
+        > _has_unique_key;
+#endif
+
+#if defined(BOOST_PARAMETER_CAN_USE_MP11)
+        static_assert(
+            !(EmitsErrors::value) || (_has_unique_key::value)
+          , "duplicate keyword"
+        );
+#else
+        BOOST_MPL_ASSERT_MSG(
+            !(EmitsErrors::value) || (_has_unique_key::value)
+          , duplicate_keyword
+          , (key_type)
+        );
+#endif
+
+        //
+        // Begin implementation of indexing operators
+        // for looking up specific arguments by name.
+        //
+
+        // Helpers that handle the case when TaggedArg is empty<T>.
+        template <typename D>
+        inline BOOST_CONSTEXPR reference
+#if defined(BOOST_PARAMETER_CAN_USE_MP11)
+            get_default(D const&, ::boost::mp11::mp_false) const
+#else
+            get_default(D const&, ::boost::mpl::false_) const
+#endif
+        {
+            return this->arg.get_value();
+        }
+
+        template <typename D>
+        inline BOOST_CONSTEXPR reference
+#if defined(BOOST_PARAMETER_CAN_USE_MP11)
+            get_default(D const& d, ::boost::mp11::mp_true) const
+#else
+            get_default(D const& d, ::boost::mpl::true_) const
+#endif
+        {
+            return (
+                this->arg.get_value()
+              ? this->arg.get_value().get()
+              : this->arg.get_value().construct(d.value)
+            );
+        }
+
+     public:
+        inline BOOST_CONSTEXPR reference
+            operator[](::boost::parameter::keyword<key_type> const&) const
+        {
+#if !defined(BOOST_NO_CXX14_CONSTEXPR)
+#if defined(BOOST_PARAMETER_CAN_USE_MP11)
+            static_assert(!_holds_maybe::value, "must not hold maybe");
+#elif !( \
+        BOOST_WORKAROUND(BOOST_GCC, >= 40700) && \
+        BOOST_WORKAROUND(BOOST_GCC, < 40900) \
+    ) && !BOOST_WORKAROUND(BOOST_GCC, >= 50000) && \
+    !BOOST_WORKAROUND(BOOST_MSVC, < 1910)
+            BOOST_MPL_ASSERT_NOT((_holds_maybe));
+#endif
+#endif
+            return this->arg.get_value();
+        }
+
+        template <typename Default>
+        inline BOOST_CONSTEXPR reference
+            operator[](
+                ::boost::parameter::aux::default_<key_type,Default> const& d
+            ) const
+        {
+            return this->get_default(d, _holds_maybe());
+        }
+
+        template <typename Default>
+        inline BOOST_CONSTEXPR reference
+            operator[](
+                ::boost::parameter::aux::default_r_<key_type,Default> const& d
+            ) const
+        {
+            return this->get_default(d, _holds_maybe());
+        }
+
+        template <typename Default>
+        inline BOOST_CONSTEXPR reference
+            operator[](
+                BOOST_PARAMETER_lazy_default_fallback<key_type,Default> const&
+            ) const
+        {
+#if !defined(BOOST_NO_CXX14_CONSTEXPR)
+#if defined(BOOST_PARAMETER_CAN_USE_MP11)
+            static_assert(!_holds_maybe::value, "must not hold maybe");
+#elif !( \
+        BOOST_WORKAROUND(BOOST_GCC, >= 40700) && \
+        BOOST_WORKAROUND(BOOST_GCC, < 40900) \
+    ) && !BOOST_WORKAROUND(BOOST_GCC, >= 50000) && \
+    !BOOST_WORKAROUND(BOOST_MSVC, < 1910)
+            BOOST_MPL_ASSERT_NOT((_holds_maybe));
+#endif
+#endif
+            return this->arg.get_value();
+        }
+
+        // Builds an overload set including operator[]s defined
+        // in base classes.
+        using Next::operator[];
+
+        //
+        // End of indexing support
+        //
+
+        // For parameter_requirements matching this node's key_type, return
+        // a bool constant wrapper indicating whether the requirements are
+        // satisfied by TaggedArg.  Used only for compile-time computation
+        // and never really called, so a declaration is enough.
+        template <typename HasDefault, typename Predicate, typename ArgPack>
+        static typename ::boost::lazy_enable_if<
+#if defined(BOOST_PARAMETER_CAN_USE_MP11)
+            ::boost::mp11::mp_if<
+                EmitsErrors
+              , ::boost::mp11::mp_true
+              , _has_unique_key
+            >
+          , ::boost::parameter::aux::augment_predicate_mp11<
+#else
+            typename ::boost::mpl::if_<
+                EmitsErrors
+              , ::boost::mpl::true_
+              , _has_unique_key
+            >::type
+          , ::boost::parameter::aux::augment_predicate<
+#endif
+                Predicate
+              , reference
+              , key_type
+              , value_type
+              , ArgPack
+            >
+        >::type
+            satisfies(
+                ::boost::parameter::aux::parameter_requirements<
+                    key_type
+                  , Predicate
+                  , HasDefault
+                >*
+              , ArgPack*
+            );
+
+        // Builds an overload set including satisfies functions defined
+        // in base classes.
+        using Next::satisfies;
+
+        // Comma operator to compose argument list without using parameters<>.
+        // Useful for argument lists with undetermined length.
+        template <typename KW, typename T2>
+        inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list<
+            ::boost::parameter::aux::tagged_argument<KW,T2>
+          , self
+        >
+            operator,(
+                ::boost::parameter::aux::tagged_argument<KW,T2> const& x
+            ) const
+        {
+            return ::boost::parameter::aux::arg_list<
+                ::boost::parameter::aux::tagged_argument<KW,T2>
+              , self
+            >(x, *this);
+        }
+
+        template <typename KW, typename T2>
+        inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list<
+            ::boost::parameter::aux::tagged_argument_rref<KW,T2>
+          , self
+        >
+            operator,(
+                ::boost::parameter::aux::tagged_argument_rref<KW,T2> const& x
+            ) const
+        {
+            return ::boost::parameter::aux::arg_list<
+                ::boost::parameter::aux::tagged_argument_rref<KW,T2>
+              , self
+            >(x, *this);
+        }
+
+        // MPL sequence support
+        typedef self type;        // Convenience for users
+        typedef Next tail_type;   // For the benefit of iterators
+        // For dispatching to sequence intrinsics
+        typedef ::boost::parameter::aux::arg_list_tag tag;
+    };
+}}} // namespace boost::parameter::aux
+
+#else   // !defined(BOOST_PARAMETER_HAS_PERFECT_FORWARDING)
+
 #include <boost/preprocessor/repetition/enum_params.hpp>
-#include <boost/preprocessor/repetition/enum_binary_params.hpp>
 #include <boost/preprocessor/facilities/intercept.hpp>
 
-namespace boost { namespace parameter {
+namespace boost { namespace parameter { namespace aux {
 
-// Forward declaration for aux::arg_list, below.
-template<class T> struct keyword;
+    // Terminates arg_list<> and represents an empty list.  Since this is just
+    // the terminating case, you might want to look at arg_list first to get a
+    // feel for what's really happening here.
+    struct empty_arg_list
+    {
+        inline BOOST_CONSTEXPR empty_arg_list()
+        {
+        }
+
+        // Constructor taking BOOST_PARAMETER_COMPOSE_MAX_ARITY empty_arg_list
+        // arguments; this makes initialization.
+        inline BOOST_CONSTEXPR empty_arg_list(
+            BOOST_PP_ENUM_PARAMS(
+                BOOST_PARAMETER_COMPOSE_MAX_ARITY
+              , ::boost::parameter::void_ BOOST_PP_INTERCEPT
+            )
+        )
+        {
+        }
 
-namespace aux {
+        // A metafunction class that, given a keyword and a default type,
+        // returns the appropriate result type for a keyword lookup given
+        // that default.
+        struct binding
+        {
+            template <typename KW, typename Default, typename Reference>
+            struct apply
+            {
+                typedef Default type;
+            };
+        };
 
-// Tag type passed to MPL lambda.
-struct lambda_tag;
+        // Terminator for has_key, indicating that the keyword is unique.
+        template <typename KW>
+        static ::boost::parameter::aux::no_tag has_key(KW*);
 
-//
-// Structures used to build the tuple of actual arguments.  The
-// tuple is a nested cons-style list of arg_list specializations
-// terminated by an empty_arg_list.
-//
-// Each specialization of arg_list is derived from its successor in
-// the list type.  This feature is used along with using
-// declarations to build member function overload sets that can
-// match against keywords.
-//
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+        // The overload set technique doesn't work with these older compilers,
+        // so they need some explicit handholding.
 
-// MPL sequence support
-struct arg_list_tag;
-
-// Terminates arg_list<> and represents an empty list.  Since this
-// is just the terminating case you might want to look at arg_list
-// first, to get a feel for what's really happening here.
-
-struct empty_arg_list
-{
-    empty_arg_list() {}
-
-    // Constructor taking BOOST_PARAMETER_MAX_ARITY empty_arg_list
-    // arguments; this makes initialization
-    empty_arg_list(
-        BOOST_PP_ENUM_PARAMS(
-            BOOST_PARAMETER_MAX_ARITY, void_ BOOST_PP_INTERCEPT
-        ))
-    {}
-
-    // A metafunction class that, given a keyword and a default
-    // type, returns the appropriate result type for a keyword
-    // lookup given that default
-    struct binding
-    {
-        template<class KW, class Default, class Reference>
-        struct apply
+        // A metafunction class that, given a keyword, returns the type of the
+        // base sublist whose get() function can produce the value for that key.
+        struct key_owner
         {
-            typedef Default type;
+            template <typename KW>
+            struct apply
+            {
+                typedef ::boost::parameter::aux::empty_arg_list type;
+            };
         };
+#endif  // Borland workarounds needed
+
+        // If either of these operators are called, it means there is no
+        // argument in the list that matches the supplied keyword.  Just
+        // return the default value.
+        template <typename K, typename Default>
+        inline BOOST_CONSTEXPR Default&
+            operator[](::boost::parameter::aux::default_<K,Default> x) const
+        {
+            return x.value;
+        }
+
+        // If this operator is called, it means there is no argument in the
+        // list that matches the supplied keyword.  Just evaluate and return
+        // the default value.
+        template <typename K, typename F>
+        inline BOOST_CONSTEXPR
+        typename ::boost::parameter::aux::result_of0<F>::type
+            operator[](BOOST_PARAMETER_lazy_default_fallback<K,F> x) const
+        {
+            return x.compute_default();
+        }
+
+        // No argument corresponding to ParameterRequirements::key_type
+        // was found if we match this overload, so unless that parameter
+        // has a default, we indicate that the actual arguments don't
+        // match the function's requirements.
+        template <typename ParameterRequirements, typename ArgPack>
+        static typename ParameterRequirements::has_default
+            satisfies(ParameterRequirements*, ArgPack*);
+
+        // MPL sequence support
+        typedef ::boost::parameter::aux::empty_arg_list type; // convenience
+        // For dispatching to sequence intrinsics
+        typedef ::boost::parameter::aux::arg_list_tag tag;
     };
+}}} // namespace boost::parameter::aux
 
-    // Terminator for has_key, indicating that the keyword is unique
-    template <class KW>
-    static no_tag has_key(KW*);
+#include <boost/parameter/aux_/yesno.hpp>
+#include <boost/parameter/aux_/is_maybe.hpp>
+#include <boost/parameter/aux_/tagged_argument_fwd.hpp>
+#include <boost/parameter/aux_/parameter_requirements.hpp>
+#include <boost/parameter/aux_/augment_predicate.hpp>
+#include <boost/parameter/keyword_fwd.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/apply_wrap.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/preprocessor/repetition/enum_binary_params.hpp>
+#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
 
-#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+#if !defined(BOOST_NO_SFINAE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800)
+#include <boost/core/enable_if.hpp>
+#endif
+
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+#include <boost/parameter/aux_/preprocessor/nullptr.hpp>
+#endif
 
-    // The overload set technique doesn't work with these older
-    // compilers, so they need some explicit handholding.
+namespace boost { namespace parameter { namespace aux {
 
-    // A metafunction class that, given a keyword, returns the type
-    // of the base sublist whose get() function can produce the
-    // value for that key
-    struct key_owner
+    // A tuple of tagged arguments, terminated with empty_arg_list.  Every
+    // TaggedArg is an instance of tagged_argument<>.
+    template <
+        typename TaggedArg
+      , typename Next = ::boost::parameter::aux::empty_arg_list
+      , typename EmitsErrors = ::boost::mpl::true_
+    >
+    class arg_list : public Next
     {
-        template<class KW>
-        struct apply
+        typedef typename ::boost::parameter::aux
+        ::is_maybe<typename TaggedArg::value_type>::type _holds_maybe;
+
+        TaggedArg arg;      // Stores the argument
+
+     public:
+        typedef TaggedArg tagged_arg;
+        typedef ::boost::parameter::aux::arg_list<TaggedArg,Next> self;
+        typedef typename TaggedArg::key_type key_type;
+
+        typedef typename ::boost::mpl::eval_if<
+            _holds_maybe
+          , ::boost::parameter::aux
+            ::get_reference<typename TaggedArg::value_type>
+          , ::boost::parameter::aux::get_reference<TaggedArg>
+        >::type reference;
+
+        typedef typename ::boost::mpl::if_<
+            _holds_maybe
+          , reference
+          , typename TaggedArg::value_type
+        >::type value_type;
+
+        // Create a new list by prepending arg to a copy of tail.  Used when
+        // incrementally building this structure with the comma operator.
+        inline BOOST_CONSTEXPR arg_list(
+            TaggedArg const& head
+          , Next const& tail
+        ) : Next(tail), arg(head)
+        {
+        }
+
+        // Store the arguments in successive nodes of this list.
+        template <
+            // typename A0, typename A1, ...
+            BOOST_PP_ENUM_PARAMS(
+                BOOST_PARAMETER_COMPOSE_MAX_ARITY
+              , typename A
+            )
+        >
+        inline BOOST_CONSTEXPR arg_list(
+            // A0& a0, A1& a1, ...
+            BOOST_PP_ENUM_BINARY_PARAMS(
+                BOOST_PARAMETER_COMPOSE_MAX_ARITY
+              , A
+              , & a
+            )
+        ) : Next(
+                // a1, a2, ...
+                BOOST_PP_ENUM_SHIFTED_PARAMS(
+                    BOOST_PARAMETER_COMPOSE_MAX_ARITY
+                  , a
+                )
+              , ::boost::parameter::aux::void_reference()
+            )
+          , arg(a0)
+        {
+        }
+
+        // A metafunction class that, given a keyword and a default type,
+        // returns the appropriate result type for a keyword lookup given
+        // that default.
+        struct binding
+        {
+            typedef typename Next::binding next_binding;
+
+            template <typename KW, typename Default, typename Reference>
+            struct apply
+            {
+                typedef typename ::boost::mpl::eval_if<
+                    ::boost::is_same<KW,key_type>
+                  , ::boost::mpl::if_<Reference,reference,value_type>
+                  , ::boost::mpl::apply_wrap3<
+                        next_binding
+                      , KW
+                      , Default
+                      , Reference
+                    >
+                >::type type;
+            };
+        };
+
+#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+        // Overload for key_type, so the assert below will fire
+        // if the same keyword is used again.
+        static ::boost::parameter::aux::yes_tag has_key(key_type*);
+        using Next::has_key;
+
+     private:
+#if defined(BOOST_NO_SFINAE) || BOOST_WORKAROUND(BOOST_MSVC, < 1800)
+        BOOST_MPL_ASSERT_MSG(
+            sizeof(
+                Next::has_key(
+                    static_cast<key_type*>(BOOST_PARAMETER_AUX_PP_NULLPTR)
+                )
+            ) == sizeof(::boost::parameter::aux::no_tag)
+          , duplicate_keyword
+          , (key_type)
+        );
+#else
+        typedef ::boost::mpl::bool_<
+            sizeof(
+                Next::has_key(
+                    static_cast<key_type*>(BOOST_PARAMETER_AUX_PP_NULLPTR)
+                )
+            ) == sizeof(::boost::parameter::aux::no_tag)
+        > _has_unique_key;
+
+        BOOST_MPL_ASSERT_MSG(
+            !(EmitsErrors::value) || (_has_unique_key::value)
+          , duplicate_keyword
+          , (key_type)
+        );
+#endif  // SFINAE/MSVC workarounds needed
+#endif  // Borland workarounds not needed
+
+     private:
+        //
+        // Begin implementation of indexing operators
+        // for looking up specific arguments by name.
+        //
+
+        // Helpers that handle the case when TaggedArg is empty<T>.
+        template <typename D>
+        inline BOOST_CONSTEXPR reference
+            get_default(D const&, ::boost::mpl::false_) const
+        {
+            return this->arg.get_value();
+        }
+
+        template <typename D>
+        inline BOOST_CONSTEXPR reference
+            get_default(D const& d, ::boost::mpl::true_) const
+        {
+            return (
+                this->arg.get_value()
+              ? this->arg.get_value().get()
+              : this->arg.get_value().construct(d.value)
+            );
+        }
+
+     public:
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+        // These older compilers don't support the overload set creation
+        // idiom well, so we need to do all the return type calculation
+        // for the compiler and dispatch through an outer function template.
+
+        // A metafunction class that, given a keyword, returns the base
+        // sublist whose get() function can produce the value for that key.
+        struct key_owner
         {
-            typedef empty_arg_list type;
+            typedef typename Next::key_owner next_key_owner;
+
+            template <typename KW>
+            struct apply
+            {
+                typedef typename ::boost::mpl::eval_if<
+                    ::boost::is_same<KW,key_type>
+                  , ::boost::mpl::identity<
+                        ::boost::parameter::aux::arg_list<TaggedArg,Next>
+                    >
+                  , ::boost::mpl::apply_wrap1<next_key_owner,KW>
+                >::type type;
+            };
         };
+
+        // Outer indexing operators that dispatch to the right node's
+        // get() function.
+        template <typename KW>
+        inline BOOST_CONSTEXPR typename ::boost::mpl::apply_wrap3<
+            binding
+          , KW
+          , ::boost::parameter::void_
+          , ::boost::mpl::true_
+        >::type
+            operator[](::boost::parameter::keyword<KW> const& x) const
+        {
+            typename ::boost::mpl::apply_wrap1<key_owner,KW>::type const&
+                sublist = *this;
+            return sublist.get(x);
+        }
+
+        template <typename KW, typename Default>
+        inline BOOST_CONSTEXPR typename ::boost::mpl::apply_wrap3<
+            binding
+          , KW
+          , Default&
+          , ::boost::mpl::true_
+        >::type
+            operator[](
+                ::boost::parameter::aux::default_<KW,Default> const& x
+            ) const
+        {
+            typename ::boost::mpl::apply_wrap1<key_owner,KW>::type const&
+                sublist = *this;
+            return sublist.get(x);
+        }
+
+        template <typename KW, typename F>
+        inline BOOST_CONSTEXPR typename ::boost::mpl::apply_wrap3<
+            binding
+          , KW
+          , typename ::boost::parameter::aux::result_of0<F>::type
+          , ::boost::mpl::true_
+        >::type
+            operator[](
+                BOOST_PARAMETER_lazy_default_fallback<KW,F> const& x
+            ) const
+        {
+            typename ::boost::mpl::apply_wrap1<key_owner,KW>::type const&
+                sublist = *this;
+            return sublist.get(x);
+        }
+
+        // These just return the stored value; when empty_arg_list is reached,
+        // indicating no matching argument was passed, the default is
+        // returned, or if no default_ or lazy_default was passed, compilation
+        // fails.
+        inline BOOST_CONSTEXPR reference
+            get(::boost::parameter::keyword<key_type> const&) const
+        {
+            BOOST_MPL_ASSERT_NOT((_holds_maybe));
+            return this->arg.get_value();
+        }
+
+        template <typename Default>
+        inline BOOST_CONSTEXPR reference
+            get(
+                ::boost::parameter::aux::default_<key_type,Default> const& d
+            ) const
+        {
+            return this->get_default(d, _holds_maybe());
+        }
+
+        template <typename Default>
+        inline BOOST_CONSTEXPR reference
+            get(
+                BOOST_PARAMETER_lazy_default_fallback<key_type,Default> const&
+            ) const
+        {
+            return this->arg.get_value();
+        }
+#else   // !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+        inline BOOST_CONSTEXPR reference
+            operator[](::boost::parameter::keyword<key_type> const&) const
+        {
+            BOOST_MPL_ASSERT_NOT((_holds_maybe));
+            return this->arg.get_value();
+        }
+
+        template <typename Default>
+        inline BOOST_CONSTEXPR reference
+            operator[](
+                ::boost::parameter::aux::default_<key_type,Default> const& d
+            ) const
+        {
+            return this->get_default(d, _holds_maybe());
+        }
+
+        template <typename Default>
+        inline BOOST_CONSTEXPR reference
+            operator[](
+                BOOST_PARAMETER_lazy_default_fallback<key_type,Default> const&
+            ) const
+        {
+            BOOST_MPL_ASSERT_NOT((_holds_maybe));
+            return this->arg.get_value();
+        }
+
+        // Builds an overload set including operator[]s defined
+        // in base classes.
+        using Next::operator[];
+
+        //
+        // End of indexing support
+        //
+
+        // For parameter_requirements matching this node's key_type, return
+        // a bool constant wrapper indicating whether the requirements are
+        // satisfied by TaggedArg.  Used only for compile-time computation
+        // and never really called, so a declaration is enough.
+        template <typename HasDefault, typename Predicate, typename ArgPack>
+        static typename
+#if !defined(BOOST_NO_SFINAE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800)
+        ::boost::lazy_enable_if<
+            typename ::boost::mpl::if_<
+                EmitsErrors
+              , ::boost::mpl::true_
+              , _has_unique_key
+            >::type,
+#endif
+            ::boost::parameter::aux::augment_predicate<
+                Predicate
+              , reference
+              , key_type
+              , value_type
+              , ArgPack
+#if !defined(BOOST_NO_SFINAE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800)
+           >
+#endif
+        >::type
+            satisfies(
+                ::boost::parameter::aux::parameter_requirements<
+                    key_type
+                  , Predicate
+                  , HasDefault
+                >*
+              , ArgPack*
+            );
+
+        // Builds an overload set including satisfies functions defined
+        // in base classes.
+        using Next::satisfies;
+#endif  // Borland workarounds needed
+
+        // Comma operator to compose argument list without using parameters<>.
+        // Useful for argument lists with undetermined length.
+        template <typename KW, typename T2>
+        inline BOOST_CONSTEXPR ::boost::parameter::aux::arg_list<
+            ::boost::parameter::aux::tagged_argument<KW,T2>
+          , self
+        >
+            operator,(
+                ::boost::parameter::aux::tagged_argument<KW,T2> const& x
+            ) const
+        {
+            return ::boost::parameter::aux::arg_list<
+                ::boost::parameter::aux::tagged_argument<KW,T2>
+              , self
+            >(x, *this);
+        }
+
+        // MPL sequence support
+        typedef self type;        // Convenience for users
+        typedef Next tail_type;   // For the benefit of iterators
+        // For dispatching to sequence intrinsics
+        typedef ::boost::parameter::aux::arg_list_tag tag;
     };
+}}} // namespace boost::parameter::aux
+
+#endif  // BOOST_PARAMETER_HAS_PERFECT_FORWARDING
 
-    template <class K, class T>
-    T& get(default_<K,T> x) const
+#if defined(BOOST_PARAMETER_CAN_USE_MP11)
+
+namespace boost { namespace parameter { namespace aux {
+
+    template <typename ...ArgTuples>
+    struct arg_list_cons;
+
+    template <>
+    struct arg_list_cons<>
     {
-        return x.value;
-    }
+        using type = ::boost::parameter::aux::empty_arg_list;
+    };
 
-    template <class K, class F>
-    typename result_of0<F>::type
-    get(lazy_default<K,F> x) const
+    template <typename ArgTuple0, typename ...Tuples>
+    struct arg_list_cons<ArgTuple0,Tuples...>
     {
-        return x.compute_default();
-    }
-#endif
+        using type = ::boost::parameter::aux::arg_list<
+            typename ArgTuple0::tagged_arg
+          , typename ::boost::parameter::aux::arg_list_cons<Tuples...>::type
+          , typename ArgTuple0::emits_errors
+        >;
+    };
 
-    // If this function is called, it means there is no argument
-    // in the list that matches the supplied keyword. Just return
-    // the default value.
-    template <class K, class Default>
-    Default& operator[](default_<K, Default> x) const
+    template <
+        typename Keyword
+      , typename TaggedArg
+      , typename EmitsErrors = ::boost::mp11::mp_true
+    >
+    struct flat_like_arg_tuple
     {
-        return x.value;
-    }
-
-    // If this function is called, it means there is no argument
-    // in the list that matches the supplied keyword. Just evaluate
-    // and return the default value.
-    template <class K, class F>
-    typename result_of0<F>::type
-    operator[](
-        BOOST_PARAMETER_lazy_default_fallback<K,F> x) const
+        using tagged_arg = TaggedArg;
+        using emits_errors = EmitsErrors;
+    };
+
+    template <typename ...ArgTuples>
+    class flat_like_arg_list
+      : public ::boost::parameter::aux::arg_list_cons<ArgTuples...>::type
     {
-        return x.compute_default();
-    }
+        using _base_type = typename ::boost::parameter::aux
+        ::arg_list_cons<ArgTuples...>::type;
+
+     public:
+        inline BOOST_CONSTEXPR flat_like_arg_list(
+            typename _base_type::tagged_arg const& head
+          , typename _base_type::tail_type const& tail
+        ) : _base_type(head, tail)
+        {
+        }
 
-    // No argument corresponding to ParameterRequirements::key_type
-    // was found if we match this overload, so unless that parameter
-    // has a default, we indicate that the actual arguments don't
-    // match the function's requirements.
-    template <class ParameterRequirements, class ArgPack>
-    static typename ParameterRequirements::has_default
-    satisfies(ParameterRequirements*, ArgPack*);
+        template <typename ...Args>
+        inline BOOST_CONSTEXPR flat_like_arg_list(Args&&... args)
+          : _base_type(::std::forward<Args>(args)...)
+        {
+        }
+
+        using _base_type::operator[];
+        using _base_type::satisfies;
+
+        // Comma operator to compose argument list without using parameters<>.
+        // Useful for argument lists with undetermined length.
+        template <typename TaggedArg>
+        inline BOOST_CONSTEXPR ::boost::parameter::aux::flat_like_arg_list<
+            ::boost::parameter::aux::flat_like_arg_tuple<
+                typename TaggedArg::base_type::key_type
+              , typename TaggedArg::base_type
+            >
+          , ArgTuples...
+        >
+            operator,(TaggedArg const& x) const
+        {
+            return ::boost::parameter::aux::flat_like_arg_list<
+                ::boost::parameter::aux::flat_like_arg_tuple<
+                    typename TaggedArg::base_type::key_type
+                  , typename TaggedArg::base_type
+                >
+              , ArgTuples...
+            >(
+                static_cast<typename TaggedArg::base_type const&>(x)
+              , static_cast<_base_type const&>(*this)
+            );
+        }
+    };
 
-    // MPL sequence support
-    typedef empty_arg_list type;   // convenience
-    typedef arg_list_tag tag; // For dispatching to sequence intrinsics
-};
-
-// Forward declaration for arg_list::operator,
-template <class KW, class T>
-struct tagged_argument;
-
-template <class T>
-struct get_reference
-{
-    typedef typename T::reference type;
-};
-
-// A tuple of tagged arguments, terminated with empty_arg_list.
-// Every TaggedArg is an instance of tagged_argument<>.
-template <class TaggedArg, class Next = empty_arg_list>
-struct arg_list : Next
-{
-    typedef arg_list<TaggedArg,Next> self;
-    typedef typename TaggedArg::key_type key_type;
-
-    typedef typename is_maybe<typename TaggedArg::value_type>::type holds_maybe;
-
-    typedef typename mpl::eval_if<
-        holds_maybe
-      , get_reference<typename TaggedArg::value_type>
-      , get_reference<TaggedArg>
-    >::type reference;
-
-    typedef typename mpl::if_<
-        holds_maybe
-      , reference
-      , typename TaggedArg::value_type
-    >::type value_type;
-
-    TaggedArg arg;      // Stores the argument
-
-    // Store the arguments in successive nodes of this list
-    template< // class A0, class A1, ...
-        BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, class A)
-    >
-    arg_list( // A0& a0, A1& a1, ...
-        BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PARAMETER_MAX_ARITY, A, & a)
-    )
-      : Next( // a1, a2, ...
-            BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PARAMETER_MAX_ARITY, a)
-          , void_reference()
-        )
-      , arg(a0)
-    {}
-
-    // Create a new list by prepending arg to a copy of tail.  Used
-    // when incrementally building this structure with the comma
-    // operator.
-    arg_list(TaggedArg head, Next const& tail)
-      : Next(tail)
-      , arg(head)
-    {}
-
-    // A metafunction class that, given a keyword and a default
-    // type, returns the appropriate result type for a keyword
-    // lookup given that default
-    struct binding
+    template <>
+    class flat_like_arg_list<>
+      : public ::boost::parameter::aux::empty_arg_list
     {
-        template <class KW, class Default, class Reference>
-        struct apply
+        using _base_type = ::boost::parameter::aux::empty_arg_list;
+
+     public:
+        template <typename ...Args>
+        inline BOOST_CONSTEXPR flat_like_arg_list(Args&&... args)
+          : _base_type(::std::forward<Args>(args)...)
         {
-          typedef typename mpl::eval_if<
-                boost::is_same<KW, key_type>
-              , mpl::if_<Reference, reference, value_type>
-              , mpl::apply_wrap3<typename Next::binding, KW, Default, Reference>
-          >::type type;
-        };
+        }
+
+        using _base_type::operator[];
+        using _base_type::satisfies;
+
+        // Comma operator to compose argument list without using parameters<>.
+        // Useful for argument lists with undetermined length.
+        template <typename TaggedArg>
+        inline BOOST_CONSTEXPR ::boost::parameter::aux::flat_like_arg_list<
+            ::boost::parameter::aux::flat_like_arg_tuple<
+                typename TaggedArg::base_type::key_type
+              , typename TaggedArg::base_type
+            >
+        >
+            operator,(TaggedArg const& x) const
+        {
+            return ::boost::parameter::aux::flat_like_arg_list<
+                ::boost::parameter::aux::flat_like_arg_tuple<
+                    typename TaggedArg::base_type::key_type
+                  , typename TaggedArg::base_type
+                >
+            >(
+                static_cast<typename TaggedArg::base_type const&>(x)
+              , static_cast<_base_type const&>(*this)
+            );
+        }
     };
+}}} // namespace boost::parameter::aux
 
-#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
-    // Overload for key_type, so the assert below will fire if the
-    // same keyword is used again
-    static yes_tag has_key(key_type*);
-    using Next::has_key;
+#endif  // BOOST_PARAMETER_CAN_USE_MP11
 
-    BOOST_MPL_ASSERT_MSG(
-        sizeof(Next::has_key((key_type*)0)) == sizeof(no_tag)
-      , duplicate_keyword, (key_type)
-    );
+#include <boost/mpl/iterator_tags.hpp>
 
-#endif
-    //
-    // Begin implementation of indexing operators for looking up
-    // specific arguments by name
-    //
+namespace boost { namespace parameter { namespace aux {
 
-    // Helpers that handle the case when TaggedArg is
-    // empty<T>.
-    template <class D>
-    reference get_default(D const&, mpl::false_) const
+    // MPL sequence support
+    template <typename ArgumentPack>
+    struct arg_list_iterator
     {
-        return arg.value;
-    }
+        typedef ::boost::mpl::forward_iterator_tag category;
+
+        // The incremented iterator
+        typedef ::boost::parameter::aux
+        ::arg_list_iterator<typename ArgumentPack::tail_type> next;
 
-    template <class D>
-    reference get_default(D const& d, mpl::true_) const
+        // dereferencing yields the key type
+        typedef typename ArgumentPack::key_type type;
+    };
+
+    template <>
+    struct arg_list_iterator< ::boost::parameter::aux::empty_arg_list>
     {
-        return arg.value ? arg.value.get() : arg.value.construct(d.value);
-    }
+    };
+}}} // namespace boost::parameter::aux
 
-#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
-    // These older compilers don't support the overload set creation
-    // idiom well, so we need to do all the return type calculation
-    // for the compiler and dispatch through an outer function template
-
-    // A metafunction class that, given a keyword, returns the base
-    // sublist whose get() function can produce the value for that
-    // key.
-    struct key_owner
+#include <boost/mpl/begin_end_fwd.hpp>
+
+// MPL sequence support
+namespace boost { namespace mpl {
+
+    template <>
+    struct begin_impl< ::boost::parameter::aux::arg_list_tag>
     {
-        template<class KW>
+        template <typename S>
         struct apply
         {
-          typedef typename mpl::eval_if<
-                boost::is_same<KW, key_type>
-              , mpl::identity<arg_list<TaggedArg,Next> >
-              , mpl::apply_wrap1<typename Next::key_owner,KW>
-          >::type type;
+            typedef ::boost::parameter::aux::arg_list_iterator<S> type;
         };
     };
 
-    // Outer indexing operators that dispatch to the right node's
-    // get() function.
-    template <class KW>
-    typename mpl::apply_wrap3<binding, KW, void_, mpl::true_>::type
-    operator[](keyword<KW> const& x) const
+    template <>
+    struct end_impl< ::boost::parameter::aux::arg_list_tag>
     {
-        typename mpl::apply_wrap1<key_owner, KW>::type const& sublist = *this;
-        return sublist.get(x);
-    }
+        template <typename>
+        struct apply
+        {
+            typedef ::boost::parameter::aux::arg_list_iterator<
+                ::boost::parameter::aux::empty_arg_list
+            > type;
+        };
+    };
+}} // namespace boost::mpl
 
-    template <class KW, class Default>
-    typename mpl::apply_wrap3<binding, KW, Default&, mpl::true_>::type
-    operator[](default_<KW, Default> x) const
-    {
-        typename mpl::apply_wrap1<key_owner, KW>::type const& sublist = *this;
-        return sublist.get(x);
-    }
-
-    template <class KW, class F>
-    typename mpl::apply_wrap3<
-        binding,KW
-      , typename result_of0<F>::type
-      , mpl::true_
-    >::type
-    operator[](lazy_default<KW,F> x) const
-    {
-        typename mpl::apply_wrap1<key_owner, KW>::type const& sublist = *this;
-        return sublist.get(x);
-    }
-
-    // These just return the stored value; when empty_arg_list is
-    // reached, indicating no matching argument was passed, the
-    // default is returned, or if no default_ or lazy_default was
-    // passed, compilation fails.
-    reference get(keyword<key_type> const&) const
-    {
-        BOOST_MPL_ASSERT_NOT((holds_maybe));
-        return arg.value;
-    }
+#include <boost/parameter/value_type.hpp>
+#include <boost/mpl/has_key_fwd.hpp>
+#include <boost/type_traits/is_void.hpp>
 
-    template <class Default>
-    reference get(default_<key_type,Default> const& d) const
-    {
-        return get_default(d, holds_maybe());
-    }
+namespace boost { namespace mpl {
 
-    template <class Default>
-    reference get(lazy_default<key_type, Default>) const
+    template <>
+    struct has_key_impl< ::boost::parameter::aux::arg_list_tag>
     {
-        return arg.value;
-    }
+        template <typename ArgList, typename Keyword>
+        struct apply
+        {
+            typedef typename ::boost::mpl::if_<
+                ::boost::is_void<
+                    typename ::boost::parameter
+                    ::value_type<ArgList,Keyword,void>::type
+                >
+              , ::boost::mpl::false_
+              , ::boost::mpl::true_
+            >::type type;
+        };
+    };
+}} // namespace boost::mpl
 
-#else
+#include <boost/mpl/count_fwd.hpp>
+#include <boost/mpl/int.hpp>
 
-    reference operator[](keyword<key_type> const&) const
-    {
-        BOOST_MPL_ASSERT_NOT((holds_maybe));
-        return arg.value;
-    }
+namespace boost { namespace mpl {
 
-    template <class Default>
-    reference operator[](default_<key_type, Default> const& d) const
+    template <>
+    struct count_impl< ::boost::parameter::aux::arg_list_tag>
     {
-        return get_default(d, holds_maybe());
-    }
+        template <typename ArgList, typename Keyword>
+        struct apply
+        {
+            typedef typename ::boost::mpl::if_<
+                ::boost::is_void<
+                    typename ::boost::parameter
+                    ::value_type<ArgList,Keyword,void>::type
+                >
+              , ::boost::mpl::int_<0>
+              , ::boost::mpl::int_<1>
+            >::type type;
+        };
+    };
+}} // namespace boost::mpl
 
-    template <class Default>
-    reference operator[](lazy_default<key_type, Default>) const
-    {
-        BOOST_MPL_ASSERT_NOT((holds_maybe));
-        return arg.value;
-    }
+#include <boost/mpl/key_type_fwd.hpp>
+#include <boost/mpl/identity.hpp>
 
-    // Builds an overload set including operator[]s defined in base
-    // classes.
-    using Next::operator[];
+namespace boost { namespace mpl {
 
-    //
-    // End of indexing support
-    //
+    template <>
+    struct key_type_impl< ::boost::parameter::aux::arg_list_tag>
+    {
+        template <typename ArgList, typename Keyword>
+        struct apply
+        {
+            typedef typename ::boost::mpl::eval_if<
+                ::boost::is_void<
+                    typename ::boost::parameter
+                    ::value_type<ArgList,Keyword,void>::type
+                >
+              , void
+              , ::boost::mpl::identity<Keyword>
+            >::type type;
+        };
+    };
+}} // namespace boost::mpl
 
+#include <boost/mpl/value_type_fwd.hpp>
 
-    //
-    // For parameter_requirements matching this node's key_type,
-    // return a bool constant wrapper indicating whether the
-    // requirements are satisfied by TaggedArg.  Used only for
-    // compile-time computation and never really called, so a
-    // declaration is enough.
-    //
-    template <class HasDefault, class Predicate, class ArgPack>
-    static typename mpl::apply_wrap2<
-        typename mpl::lambda<Predicate, lambda_tag>::type
-      , value_type, ArgPack
-    >::type
-    satisfies(
-        parameter_requirements<key_type,Predicate,HasDefault>*
-      , ArgPack*
-    );
-
-    // Builds an overload set including satisfies functions defined
-    // in base classes.
-    using Next::satisfies;
-#endif
+namespace boost { namespace mpl {
 
-    // Comma operator to compose argument list without using parameters<>.
-    // Useful for argument lists with undetermined length.
-    template <class KW, class T2>
-    arg_list<tagged_argument<KW, T2>, self>
-    operator,(tagged_argument<KW,T2> x) const
+    template <>
+    struct value_type_impl< ::boost::parameter::aux::arg_list_tag>
+      : ::boost::mpl::key_type_impl< ::boost::parameter::aux::arg_list_tag>
     {
-        return arg_list<tagged_argument<KW,T2>, self>(x, *this);
-    }
+    };
+}} // namespace boost::mpl
 
-    // MPL sequence support
-    typedef self type;             // Convenience for users
-    typedef Next tail_type;        // For the benefit of iterators
-    typedef arg_list_tag tag; // For dispatching to sequence intrinsics
-};
+#include <boost/mpl/at_fwd.hpp>
 
-// MPL sequence support
-template <class ArgumentPack>
-struct arg_list_iterator
-{
-    typedef mpl::forward_iterator_tag category;
+namespace boost { namespace mpl {
 
-    // The incremented iterator
-    typedef arg_list_iterator<typename ArgumentPack::tail_type> next;
+    template <>
+    struct at_impl< ::boost::parameter::aux::arg_list_tag>
+      : ::boost::mpl::key_type_impl< ::boost::parameter::aux::arg_list_tag>
+    {
+    };
+}} // namespace boost::mpl
 
-    // dereferencing yields the key type
-    typedef typename ArgumentPack::key_type type;
-};
+#include <boost/mpl/order_fwd.hpp>
+#include <boost/mpl/void.hpp>
+#include <boost/mpl/find.hpp>
+#include <boost/mpl/distance.hpp>
 
-template <>
-struct arg_list_iterator<empty_arg_list> {};
+namespace boost { namespace mpl {
 
-}} // namespace parameter::aux
+    template <>
+    struct order_impl< ::boost::parameter::aux::arg_list_tag>
+    {
+        template <typename ArgList, typename Keyword>
+        struct apply
+        {
+            typedef typename ::boost::mpl::find<ArgList,Keyword>::type Itr;
+            typedef typename ::boost::mpl::eval_if<
+                ::boost::is_void<
+                    typename ::boost::parameter
+                    ::value_type<ArgList,Keyword,void>::type
+                >
+              , ::boost::mpl::identity< ::boost::mpl::void_>
+              , ::boost::mpl::distance<
+                    Itr
+                  , ::boost::parameter::aux::arg_list_iterator<
+                        ::boost::parameter::aux::empty_arg_list
+                    >
+                >
+            >::type type;
+        };
+    };
+}} // namespace boost::mpl
 
-// MPL sequence support
-namespace mpl
-{
-  template <>
-  struct begin_impl<parameter::aux::arg_list_tag>
-  {
-      template <class S>
-      struct apply
-      {
-          typedef parameter::aux::arg_list_iterator<S> type;
-      };
-  };
-
-  template <>
-  struct end_impl<parameter::aux::arg_list_tag>
-  {
-      template <class>
-      struct apply
-      {
-          typedef parameter::aux::arg_list_iterator<parameter::aux::empty_arg_list> type;
-      };
-  };
-}
-
-} // namespace boost
-
-#endif // ARG_LIST_050329_HPP
+#endif  // include guard