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