1332 lines
43 KiB
C++
1332 lines
43 KiB
C++
// 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 BOOST_PARAMETER_AUX_ARG_LIST_HPP
|
|
#define BOOST_PARAMETER_AUX_ARG_LIST_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>
|
|
|
|
#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/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/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/facilities/intercept.hpp>
|
|
|
|
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
|
|
{
|
|
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
|
|
)
|
|
)
|
|
{
|
|
}
|
|
|
|
// 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;
|
|
};
|
|
};
|
|
|
|
// Terminator for has_key, indicating that the keyword is unique.
|
|
template <typename KW>
|
|
static ::boost::parameter::aux::no_tag has_key(KW*);
|
|
|
|
#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
|
|
// The overload set technique doesn't work with these older compilers,
|
|
// so they need some explicit handholding.
|
|
|
|
// 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
|
|
{
|
|
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
|
|
|
|
#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 !defined(BOOST_NO_SFINAE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800)
|
|
#include <boost/core/enable_if.hpp>
|
|
#endif
|
|
|
|
#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564))
|
|
#include <boost/parameter/aux_/preprocessor/nullptr.hpp>
|
|
#endif
|
|
|
|
namespace boost { namespace parameter { namespace aux {
|
|
|
|
// 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
|
|
{
|
|
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(BOOST_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(BOOST_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 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(BOOST_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
|
|
|
|
#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<>
|
|
{
|
|
using type = ::boost::parameter::aux::empty_arg_list;
|
|
};
|
|
|
|
template <typename ArgTuple0, typename ...Tuples>
|
|
struct arg_list_cons<ArgTuple0,Tuples...>
|
|
{
|
|
using type = ::boost::parameter::aux::arg_list<
|
|
typename ArgTuple0::tagged_arg
|
|
, typename ::boost::parameter::aux::arg_list_cons<Tuples...>::type
|
|
, typename ArgTuple0::emits_errors
|
|
>;
|
|
};
|
|
|
|
template <
|
|
typename Keyword
|
|
, typename TaggedArg
|
|
, typename EmitsErrors = ::boost::mp11::mp_true
|
|
>
|
|
struct flat_like_arg_tuple
|
|
{
|
|
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
|
|
{
|
|
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)
|
|
{
|
|
}
|
|
|
|
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)
|
|
);
|
|
}
|
|
};
|
|
|
|
template <>
|
|
class flat_like_arg_list<>
|
|
: public ::boost::parameter::aux::empty_arg_list
|
|
{
|
|
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)...)
|
|
{
|
|
}
|
|
|
|
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
|
|
|
|
#endif // BOOST_PARAMETER_CAN_USE_MP11
|
|
|
|
#include <boost/mpl/iterator_tags.hpp>
|
|
|
|
namespace boost { namespace parameter { namespace aux {
|
|
|
|
// MPL sequence support
|
|
template <typename ArgumentPack>
|
|
struct arg_list_iterator
|
|
{
|
|
typedef ::boost::mpl::forward_iterator_tag category;
|
|
|
|
// The incremented iterator
|
|
typedef ::boost::parameter::aux
|
|
::arg_list_iterator<typename ArgumentPack::tail_type> next;
|
|
|
|
// dereferencing yields the key type
|
|
typedef typename ArgumentPack::key_type type;
|
|
};
|
|
|
|
template <>
|
|
struct arg_list_iterator< ::boost::parameter::aux::empty_arg_list>
|
|
{
|
|
};
|
|
}}} // namespace boost::parameter::aux
|
|
|
|
#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 <typename S>
|
|
struct apply
|
|
{
|
|
typedef ::boost::parameter::aux::arg_list_iterator<S> type;
|
|
};
|
|
};
|
|
|
|
template <>
|
|
struct end_impl< ::boost::parameter::aux::arg_list_tag>
|
|
{
|
|
template <typename>
|
|
struct apply
|
|
{
|
|
typedef ::boost::parameter::aux::arg_list_iterator<
|
|
::boost::parameter::aux::empty_arg_list
|
|
> type;
|
|
};
|
|
};
|
|
}} // namespace boost::mpl
|
|
|
|
#include <boost/parameter/value_type.hpp>
|
|
#include <boost/mpl/has_key_fwd.hpp>
|
|
#include <boost/type_traits/is_void.hpp>
|
|
|
|
namespace boost { namespace mpl {
|
|
|
|
template <>
|
|
struct has_key_impl< ::boost::parameter::aux::arg_list_tag>
|
|
{
|
|
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
|
|
|
|
#include <boost/mpl/count_fwd.hpp>
|
|
#include <boost/mpl/int.hpp>
|
|
|
|
namespace boost { namespace mpl {
|
|
|
|
template <>
|
|
struct count_impl< ::boost::parameter::aux::arg_list_tag>
|
|
{
|
|
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
|
|
|
|
#include <boost/mpl/key_type_fwd.hpp>
|
|
#include <boost/mpl/identity.hpp>
|
|
|
|
namespace boost { namespace mpl {
|
|
|
|
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>
|
|
|
|
namespace boost { namespace mpl {
|
|
|
|
template <>
|
|
struct value_type_impl< ::boost::parameter::aux::arg_list_tag>
|
|
: ::boost::mpl::key_type_impl< ::boost::parameter::aux::arg_list_tag>
|
|
{
|
|
};
|
|
}} // namespace boost::mpl
|
|
|
|
#include <boost/mpl/at_fwd.hpp>
|
|
|
|
namespace boost { namespace mpl {
|
|
|
|
template <>
|
|
struct at_impl< ::boost::parameter::aux::arg_list_tag>
|
|
: ::boost::mpl::key_type_impl< ::boost::parameter::aux::arg_list_tag>
|
|
{
|
|
};
|
|
}} // namespace boost::mpl
|
|
|
|
#include <boost/mpl/order_fwd.hpp>
|
|
#include <boost/mpl/void.hpp>
|
|
#include <boost/mpl/find.hpp>
|
|
#include <boost/mpl/distance.hpp>
|
|
|
|
namespace boost { namespace mpl {
|
|
|
|
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
|
|
|
|
#endif // include guard
|
|
|