summaryrefslogtreecommitdiff
path: root/boost/parameter/aux_/arg_list.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/parameter/aux_/arg_list.hpp')
-rw-r--r--boost/parameter/aux_/arg_list.hpp1606
1 files changed, 1250 insertions, 356 deletions
diff --git a/boost/parameter/aux_/arg_list.hpp b/boost/parameter/aux_/arg_list.hpp
index 721ce04004..ffe1bac184 100644
--- a/boost/parameter/aux_/arg_list.hpp
+++ b/boost/parameter/aux_/arg_list.hpp
@@ -1,437 +1,1331 @@
-// 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