diff options
Diffstat (limited to 'boost/parameter/aux_/arg_list.hpp')
-rw-r--r-- | boost/parameter/aux_/arg_list.hpp | 1606 |
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 |