mirror of
https://github.com/boostorg/parameter.git
synced 2026-01-19 16:32:13 +00:00
Compare commits
3 Commits
master
...
svn-branch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0071292388 | ||
|
|
d3677ce156 | ||
|
|
73afdad1e5 |
@@ -1,14 +0,0 @@
|
||||
// Copyright David Abrahams, Daniel Wallin 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
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_PARAMETER_050401_HPP
|
||||
#define BOOST_PARAMETER_050401_HPP
|
||||
|
||||
#include <boost/parameter/parameters.hpp>
|
||||
#include <boost/parameter/keyword.hpp>
|
||||
#include <boost/parameter/binding.hpp>
|
||||
|
||||
#endif // BOOST_PARAMETER_050401_HPP
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
#define BOOST_PARAMETER_open_list(z, n, text) \
|
||||
aux::make_arg_list< \
|
||||
BOOST_PP_CAT(PS, n), BOOST_PP_CAT(A, n) \
|
||||
BOOST_PP_CAT(PS, n), BOOST_PP_CAT(A, n), unnamed_specs \
|
||||
|
||||
#define BOOST_PARAMETER_close_list(z, n, text) >
|
||||
|
||||
|
||||
@@ -15,10 +15,11 @@ namespace boost { namespace parameter { namespace aux {
|
||||
template <class Keyword, class Predicate, class HasDefault>
|
||||
struct parameter_requirements
|
||||
{
|
||||
typedef Keyword keyword;
|
||||
typedef Predicate predicate;
|
||||
typedef HasDefault has_default;
|
||||
};
|
||||
|
||||
}}} // namespace boost::parameter::aux
|
||||
|
||||
#endif // PARAMETER_REQUIREMENTS_050331_HPP
|
||||
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
#include <boost/mpl/identity.hpp>
|
||||
#include <boost/mpl/not.hpp>
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/iterator/detail/config_def.hpp>
|
||||
#include <boost/python/detail/is_xxx.hpp>
|
||||
|
||||
@@ -76,18 +78,21 @@ struct optional
|
||||
typedef Predicate predicate;
|
||||
};
|
||||
|
||||
template <class Tag>
|
||||
template <class Tag, class Predicate>
|
||||
struct unnamed
|
||||
{
|
||||
typedef Tag key_type;
|
||||
typedef Predicate predicate;
|
||||
};
|
||||
|
||||
namespace aux
|
||||
{
|
||||
// Defines metafunctions, is_required and is_optional, that
|
||||
// identify required<...> and optional<...> specializations.
|
||||
namespace aux {
|
||||
|
||||
// Defines metafunctions, is_required, is_optional and is_unnamed,
|
||||
// that identify required<...>, optional<...> and unnamed<>
|
||||
// specializations.
|
||||
BOOST_PYTHON_IS_XXX_DEF(required, required, 2)
|
||||
BOOST_PYTHON_IS_XXX_DEF(optional, optional, 2)
|
||||
BOOST_PYTHON_IS_XXX_DEF(unnamed, unnamed, 2)
|
||||
|
||||
//
|
||||
// key_type, has_default, and predicate --
|
||||
@@ -100,11 +105,16 @@ namespace aux
|
||||
// a ParameterSpec is a specialization of either keyword<...>,
|
||||
// required<...> or optional<...>.
|
||||
//
|
||||
|
||||
|
||||
// helper for key_type<...>, below.
|
||||
template <class T>
|
||||
struct get_key_type
|
||||
{ typedef typename T::key_type type; };
|
||||
: mpl::if_<
|
||||
is_unnamed<typename T::key_type>
|
||||
, get_key_type<typename T::key_type>
|
||||
, mpl::identity<typename T::key_type>
|
||||
>::type
|
||||
{};
|
||||
|
||||
template <class T>
|
||||
struct key_type
|
||||
@@ -112,6 +122,7 @@ namespace aux
|
||||
mpl::or_<
|
||||
is_optional<T>
|
||||
, is_required<T>
|
||||
, is_unnamed<T>
|
||||
>
|
||||
, get_key_type<T>
|
||||
, mpl::identity<T>
|
||||
@@ -141,11 +152,12 @@ namespace aux
|
||||
// helper for predicate<...>, below
|
||||
template <class T>
|
||||
struct get_predicate
|
||||
{
|
||||
typedef typename
|
||||
get_predicate_or_default<typename T::predicate>::type
|
||||
type;
|
||||
};
|
||||
: mpl::if_<
|
||||
is_unnamed<typename T::key_type>
|
||||
, get_predicate<typename T::key_type>
|
||||
, get_predicate_or_default<typename T::predicate>
|
||||
>::type
|
||||
{};
|
||||
|
||||
template <class T>
|
||||
struct predicate
|
||||
@@ -153,6 +165,7 @@ namespace aux
|
||||
mpl::or_<
|
||||
is_optional<T>
|
||||
, is_required<T>
|
||||
, is_unnamed<T>
|
||||
>
|
||||
, get_predicate<T>
|
||||
, mpl::identity<mpl::always<mpl::true_> >
|
||||
@@ -175,24 +188,21 @@ namespace aux
|
||||
> type;
|
||||
};
|
||||
|
||||
// Labels Arg with default keyword tag DefaultTag if it is not
|
||||
// already a tagged_argument
|
||||
template <class DefaultTag, class Arg>
|
||||
// Labels Arg with default keyword tag from ParameterSpec
|
||||
// if it is not already a tagged_argument
|
||||
template <class ParameterSpec, class Arg, class Unnamed>
|
||||
struct as_tagged_argument
|
||||
{
|
||||
typedef typename mpl::if_<
|
||||
typedef typename mpl::eval_if<
|
||||
is_tagged_argument<Arg>
|
||||
, Arg
|
||||
, tagged_argument<
|
||||
typename key_type<DefaultTag>::type
|
||||
, typename unwrap_cv_reference<Arg const>::type
|
||||
>
|
||||
, mpl::identity<Arg>
|
||||
, mpl::apply_wrap2<Unnamed, Arg, typename key_type<ParameterSpec>::type>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, == 1200) // ETI workaround
|
||||
template <>
|
||||
struct as_tagged_argument<int,int>
|
||||
struct as_tagged_argument<int,int,int>
|
||||
{
|
||||
typedef int type;
|
||||
};
|
||||
@@ -203,6 +213,24 @@ namespace aux
|
||||
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_wrap2<
|
||||
typename ArgList::binding
|
||||
, typename ParameterRequirements::keyword
|
||||
, void_
|
||||
>::type bound;
|
||||
|
||||
typedef typename mpl::eval_if<
|
||||
is_same<bound, void_>
|
||||
, typename ParameterRequirements::has_default
|
||||
, mpl::apply1<
|
||||
typename ParameterRequirements::predicate
|
||||
, typename remove_reference<bound>::type
|
||||
>
|
||||
>::type type;
|
||||
#else
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool, value = (
|
||||
sizeof(
|
||||
@@ -214,6 +242,7 @@ namespace aux
|
||||
);
|
||||
|
||||
typedef mpl::bool_<satisfies::value> type;
|
||||
#endif
|
||||
};
|
||||
|
||||
// Returns mpl::true_ if the requirements of the given ParameterSpec
|
||||
@@ -229,11 +258,11 @@ namespace aux
|
||||
// Helper for make_partial_arg_list, below. Produce an arg_list
|
||||
// node for the given ParameterSpec and ArgumentType, whose tail is
|
||||
// determined by invoking the nullary metafunction TailFn.
|
||||
template <class ParameterSpec, class ArgumentType, class TailFn>
|
||||
template <class ParameterSpec, class ArgumentType, class Unnamed, class TailFn>
|
||||
struct make_arg_list
|
||||
{
|
||||
typedef arg_list<
|
||||
typename as_tagged_argument<ParameterSpec,ArgumentType>::type
|
||||
typename as_tagged_argument<ParameterSpec,ArgumentType,Unnamed>::type
|
||||
, typename TailFn::type
|
||||
> type;
|
||||
};
|
||||
@@ -245,13 +274,14 @@ namespace aux
|
||||
template <
|
||||
class ParameterSpec
|
||||
, class ArgumentType
|
||||
, class Unnamed
|
||||
, class TailFn
|
||||
>
|
||||
struct make_partial_arg_list
|
||||
: mpl::eval_if<
|
||||
is_same<ArgumentType,void_>
|
||||
, mpl::identity<empty_arg_list>
|
||||
, make_arg_list<ParameterSpec, ArgumentType, TailFn>
|
||||
, make_arg_list<ParameterSpec, ArgumentType, Unnamed, TailFn>
|
||||
>
|
||||
{};
|
||||
|
||||
@@ -267,14 +297,127 @@ namespace aux
|
||||
#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),
|
||||
|
||||
BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(2,names), n), \
|
||||
BOOST_PP_SEQ_ELEM(3,names),
|
||||
|
||||
#define BOOST_PARAMETER_right_angle(z, n, text) >
|
||||
|
||||
#define BOOST_PARAMETER_build_arg_list(n, make, parameter_spec, argument_type) \
|
||||
|
||||
#define BOOST_PARAMETER_build_arg_list(n, make, parameter_spec, argument_type, unnamed) \
|
||||
BOOST_PP_REPEAT( \
|
||||
n, BOOST_PARAMETER_make_arg_list, (make)(parameter_spec)(argument_type)(unnamed)) \
|
||||
mpl::identity<aux::empty_arg_list> \
|
||||
BOOST_PP_REPEAT(n, BOOST_PARAMETER_right_angle, _)
|
||||
|
||||
// Metafunctions used to determine if a ParameterSpec is
|
||||
// either unnamed<something, something> or
|
||||
// [required/optional]<unnamed<something, something> >
|
||||
|
||||
template <class T>
|
||||
struct is_nested_unnamed_aux
|
||||
: is_unnamed<typename T::key_type>
|
||||
{};
|
||||
|
||||
template <class T>
|
||||
struct is_nested_unnamed
|
||||
: mpl::if_<
|
||||
mpl::or_<
|
||||
is_optional<T>
|
||||
, is_required<T>
|
||||
>
|
||||
, is_nested_unnamed_aux<T>
|
||||
, mpl::false_
|
||||
>::type
|
||||
{};
|
||||
|
||||
template <class T>
|
||||
struct is_unnamed_spec
|
||||
: mpl::or_<
|
||||
is_unnamed<T>
|
||||
, is_nested_unnamed<T>
|
||||
>
|
||||
{};
|
||||
|
||||
// List of unnamed keywords with the associated predicate.
|
||||
template <class Keyword, class Predicate, class Tail>
|
||||
struct unnamed_list
|
||||
{
|
||||
// If the Predicate applies; tag the argument with
|
||||
// Keyword. Otherwise, try the tail.
|
||||
template <class Arg, class DefaultTag>
|
||||
struct apply
|
||||
{
|
||||
typedef typename mpl::eval_if<
|
||||
typename mpl::apply1<Predicate, Arg>::type
|
||||
, mpl::identity<tagged_argument<
|
||||
Keyword
|
||||
, typename unwrap_cv_reference<Arg const>::type
|
||||
> >
|
||||
, mpl::apply_wrap2<Tail, Arg, DefaultTag>
|
||||
>::type type;
|
||||
};
|
||||
};
|
||||
|
||||
// Terminates an unnamed_list<>.
|
||||
struct empty_unnamed_list
|
||||
{
|
||||
// Default case. No unnamed predicates matched the Arg.
|
||||
// Tag argument with the DefaultTag.
|
||||
template <class Arg, class DefaultTag>
|
||||
struct apply
|
||||
{
|
||||
typedef tagged_argument<
|
||||
DefaultTag
|
||||
, typename unwrap_cv_reference<Arg const>::type
|
||||
> type;
|
||||
};
|
||||
};
|
||||
|
||||
template <class ParameterSpec, class TailFn>
|
||||
struct make_unnamed_list_aux
|
||||
{
|
||||
typedef typename mpl::if_<
|
||||
is_unnamed_spec<ParameterSpec>
|
||||
, unnamed_list<
|
||||
typename key_type<ParameterSpec>::type
|
||||
, typename predicate<ParameterSpec>::type
|
||||
, typename TailFn::type
|
||||
>
|
||||
, typename TailFn::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <class ParameterSpec, class TailFn>
|
||||
struct make_unnamed_list
|
||||
{
|
||||
typedef typename mpl::eval_if<
|
||||
is_same<ParameterSpec, void_>
|
||||
, mpl::identity<empty_unnamed_list>
|
||||
, make_unnamed_list_aux<ParameterSpec, TailFn>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
// Generates:
|
||||
//
|
||||
// make<
|
||||
// parameter_spec#0
|
||||
// , make<
|
||||
// parameter_spec#1
|
||||
// , make<
|
||||
// parameter_spec#2
|
||||
// , mpl::identity<mpl::vector0<> >
|
||||
// >
|
||||
// >
|
||||
// >
|
||||
//
|
||||
|
||||
#define BOOST_PARAMETER_make_unnamed_list(z, n, names) \
|
||||
BOOST_PP_SEQ_ELEM(0,names)< \
|
||||
BOOST_PP_CAT(BOOST_PP_SEQ_ELEM(1,names), n),
|
||||
|
||||
#define BOOST_PARAMETER_build_unnamed_list(n, make, parameter_spec) \
|
||||
BOOST_PP_REPEAT( \
|
||||
n, BOOST_PARAMETER_make_arg_list, (make)(parameter_spec)(argument_type)) \
|
||||
mpl::identity<aux::empty_arg_list> \
|
||||
n, BOOST_PARAMETER_make_unnamed_list, (make)(parameter_spec)) \
|
||||
mpl::identity<aux::empty_unnamed_list> \
|
||||
BOOST_PP_REPEAT(n, BOOST_PARAMETER_right_angle, _)
|
||||
|
||||
} // namespace aux
|
||||
@@ -289,6 +432,12 @@ struct parameters
|
||||
{
|
||||
#undef BOOST_PARAMETER_TEMPLATE_ARGS
|
||||
|
||||
typedef typename BOOST_PARAMETER_build_unnamed_list(
|
||||
BOOST_PARAMETER_MAX_ARITY
|
||||
, aux::make_unnamed_list
|
||||
, PS
|
||||
)::type unnamed_specs;
|
||||
|
||||
// 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
|
||||
@@ -319,12 +468,15 @@ struct parameters
|
||||
|
||||
# undef BOOST_PARAMETER_satisfies
|
||||
|
||||
, mpl::identity<parameters>
|
||||
, mpl::identity<
|
||||
parameters<BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, PS)>
|
||||
>
|
||||
, aux::void_
|
||||
>
|
||||
{};
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
|
||||
@@ -333,13 +485,13 @@ struct parameters
|
||||
template<
|
||||
BOOST_PP_ENUM_BINARY_PARAMS(
|
||||
BOOST_PARAMETER_MAX_ARITY, class A, = aux::void_ BOOST_PP_INTERCEPT
|
||||
)
|
||||
)
|
||||
>
|
||||
struct restrict
|
||||
# ifndef BOOST_NO_SFINAE
|
||||
: restrict_base<
|
||||
typename BOOST_PARAMETER_build_arg_list(
|
||||
BOOST_PARAMETER_MAX_ARITY, aux::make_partial_arg_list, PS, A
|
||||
BOOST_PARAMETER_MAX_ARITY, aux::make_partial_arg_list, PS, A, unnamed_specs
|
||||
)::type
|
||||
>::type
|
||||
{};
|
||||
@@ -365,12 +517,12 @@ struct parameters
|
||||
|
||||
template<class A0>
|
||||
typename
|
||||
aux::make_arg_list<PS0,A0, mpl::identity<aux::empty_arg_list> >
|
||||
aux::make_arg_list<PS0,A0,unnamed_specs, mpl::identity<aux::empty_arg_list> >
|
||||
::type
|
||||
operator()( A0 const& a0) const
|
||||
{
|
||||
typedef typename
|
||||
aux::make_arg_list<PS0, A0, mpl::identity<aux::empty_arg_list> >
|
||||
aux::make_arg_list<PS0, A0, unnamed_specs, mpl::identity<aux::empty_arg_list> >
|
||||
::type result_type;
|
||||
|
||||
return result_type(
|
||||
@@ -385,9 +537,9 @@ struct parameters
|
||||
template<class A0, class A1>
|
||||
typename
|
||||
aux::make_arg_list<
|
||||
PS0,A0
|
||||
PS0,A0,unnamed_specs
|
||||
, aux::make_arg_list<
|
||||
PS1,A1
|
||||
PS1,A1,unnamed_specs
|
||||
, mpl::identity<aux::empty_arg_list>
|
||||
>
|
||||
>
|
||||
@@ -396,9 +548,9 @@ struct parameters
|
||||
{
|
||||
typedef typename
|
||||
aux::make_arg_list<
|
||||
PS0,A0
|
||||
PS0,A0,unnamed_specs
|
||||
, aux::make_arg_list<
|
||||
PS1,A1
|
||||
PS1,A1,unnamed_specs
|
||||
, mpl::identity<aux::empty_arg_list>
|
||||
>
|
||||
>
|
||||
|
||||
@@ -10,6 +10,7 @@ import testing ;
|
||||
: [ run basics.cpp ]
|
||||
[ run sfinae.cpp ]
|
||||
[ run macros.cpp ]
|
||||
[ run unnamed.cpp ]
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
71
test/unnamed.cpp
Executable file
71
test/unnamed.cpp
Executable file
@@ -0,0 +1,71 @@
|
||||
// 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)
|
||||
|
||||
#include <boost/parameter.hpp>
|
||||
#include <cassert>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace test
|
||||
{
|
||||
using namespace boost::parameter;
|
||||
namespace mpl = boost::mpl;
|
||||
|
||||
struct g_parameters
|
||||
: parameters<
|
||||
unnamed<struct name_, boost::is_convertible<mpl::_, std::string> >
|
||||
, unnamed<struct value_, boost::is_convertible<mpl::_, float> >
|
||||
>
|
||||
{};
|
||||
|
||||
keyword<struct name_> name;
|
||||
keyword<struct value_> value;
|
||||
|
||||
template<class Params>
|
||||
int g_(Params const& p)
|
||||
{
|
||||
assert(p[name] == std::string("foo"));
|
||||
assert(p[value] == 3.14f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
template<class A0>
|
||||
int g(A0 const& a0)
|
||||
{
|
||||
return g_(g_parameters()(a0));
|
||||
}
|
||||
|
||||
template<class A0, class A1>
|
||||
int g(A0 const& a0, A1 const& a1)
|
||||
{
|
||||
return g_(g_parameters()(a0, a1));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#include <typeinfo>
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{
|
||||
using test::g;
|
||||
using test::name;
|
||||
using test::value;
|
||||
|
||||
g("foo", 3.14f);
|
||||
g(3.14f, "foo");
|
||||
|
||||
g(value = 3.14f, "foo");
|
||||
g(name = "foo", 3.14f);
|
||||
g(3.14f, name = "foo");
|
||||
g(name = "foo", value = 3.14f);
|
||||
// g((void*)0, (void*)0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user