Boost Parameter Library initial check in

[SVN r27964]
This commit is contained in:
Daniel Wallin
2005-04-04 21:53:56 +00:00
commit d0c5ddc28b
12 changed files with 1289 additions and 0 deletions

96
.gitattributes vendored Normal file
View File

@@ -0,0 +1,96 @@
* text=auto !eol svneol=native#text/plain
*.gitattributes text svneol=native#text/plain
# Scriptish formats
*.bat text svneol=native#text/plain
*.bsh text svneol=native#text/x-beanshell
*.cgi text svneol=native#text/plain
*.cmd text svneol=native#text/plain
*.js text svneol=native#text/javascript
*.php text svneol=native#text/x-php
*.pl text svneol=native#text/x-perl
*.pm text svneol=native#text/x-perl
*.py text svneol=native#text/x-python
*.sh eol=lf svneol=LF#text/x-sh
configure eol=lf svneol=LF#text/x-sh
# Image formats
*.bmp binary svneol=unset#image/bmp
*.gif binary svneol=unset#image/gif
*.ico binary svneol=unset#image/ico
*.jpeg binary svneol=unset#image/jpeg
*.jpg binary svneol=unset#image/jpeg
*.png binary svneol=unset#image/png
*.tif binary svneol=unset#image/tiff
*.tiff binary svneol=unset#image/tiff
*.svg text svneol=native#image/svg%2Bxml
# Data formats
*.pdf binary svneol=unset#application/pdf
*.avi binary svneol=unset#video/avi
*.doc binary svneol=unset#application/msword
*.dsp text svneol=crlf#text/plain
*.dsw text svneol=crlf#text/plain
*.eps binary svneol=unset#application/postscript
*.gz binary svneol=unset#application/gzip
*.mov binary svneol=unset#video/quicktime
*.mp3 binary svneol=unset#audio/mpeg
*.ppt binary svneol=unset#application/vnd.ms-powerpoint
*.ps binary svneol=unset#application/postscript
*.psd binary svneol=unset#application/photoshop
*.rdf binary svneol=unset#text/rdf
*.rss text svneol=unset#text/xml
*.rtf binary svneol=unset#text/rtf
*.sln text svneol=native#text/plain
*.swf binary svneol=unset#application/x-shockwave-flash
*.tgz binary svneol=unset#application/gzip
*.vcproj text svneol=native#text/xml
*.vcxproj text svneol=native#text/xml
*.vsprops text svneol=native#text/xml
*.wav binary svneol=unset#audio/wav
*.xls binary svneol=unset#application/vnd.ms-excel
*.zip binary svneol=unset#application/zip
# Text formats
.htaccess text svneol=native#text/plain
*.bbk text svneol=native#text/xml
*.cmake text svneol=native#text/plain
*.css text svneol=native#text/css
*.dtd text svneol=native#text/xml
*.htm text svneol=native#text/html
*.html text svneol=native#text/html
*.ini text svneol=native#text/plain
*.log text svneol=native#text/plain
*.mak text svneol=native#text/plain
*.qbk text svneol=native#text/plain
*.rst text svneol=native#text/plain
*.sql text svneol=native#text/x-sql
*.txt text svneol=native#text/plain
*.xhtml text svneol=native#text/xhtml%2Bxml
*.xml text svneol=native#text/xml
*.xsd text svneol=native#text/xml
*.xsl text svneol=native#text/xml
*.xslt text svneol=native#text/xml
*.xul text svneol=native#text/xul
*.yml text svneol=native#text/plain
boost-no-inspect text svneol=native#text/plain
CHANGES text svneol=native#text/plain
COPYING text svneol=native#text/plain
INSTALL text svneol=native#text/plain
Jamfile text svneol=native#text/plain
Jamroot text svneol=native#text/plain
Jamfile.v2 text svneol=native#text/plain
Jamrules text svneol=native#text/plain
Makefile* text svneol=native#text/plain
README text svneol=native#text/plain
TODO text svneol=native#text/plain
# Code formats
*.c text svneol=native#text/plain
*.cpp text svneol=native#text/plain
*.h text svneol=native#text/plain
*.hpp text svneol=native#text/plain
*.ipp text svneol=native#text/plain
*.tpp text svneol=native#text/plain
*.jam text svneol=native#text/plain
*.java text svneol=native#text/plain

View File

@@ -0,0 +1,309 @@
// 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
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef ARG_LIST_050329_HPP
#define ARG_LIST_050329_HPP
#include <boost/mpl/apply.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/facilities/intercept.hpp>
#include <boost/parameter/aux_/void.hpp>
#include <boost/parameter/aux_/default.hpp>
#include <boost/parameter/aux_/parameter_requirements.hpp>
#include <boost/parameter/config.hpp>
namespace boost { namespace parameter {
// Forward declaration for aux::arg_list, below.
template<class T> struct keyword;
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.
//
// 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
))
{}
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) || BOOST_WORKAROUND(__GNUC__, < 3)
// 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<class KW>
struct apply
{
typedef empty_arg_list type;
};
};
// A metafunction class that, given a keyword and a default
// type, returns the appropriate result type for a keyword
// lookup given that default
struct key_value_type
{
template<class KW, class Default>
struct apply
{
typedef Default type;
};
};
template <class K, class T>
T& get(default_<K,T> x) const
{
return x.value;
}
template <class K, class F>
typename F::result_type get(lazy_default<K,F> x) const
{
return x.compute_default();
}
#endif
// 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
{
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 F::result_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 <class ParameterRequirements>
static typename ParameterRequirements::has_default
satisfies(ParameterRequirements*);
};
// Forward declaration for arg_list::operator,
template <class KW, class T>
struct tagged_argument;
// 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 typename TaggedArg::key_type key_type;
typedef typename TaggedArg::value_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 const& a0, A1 const& a1, ...
BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PARAMETER_MAX_ARITY, A, const & a)
)
: Next( // a1, a2, ...
BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PARAMETER_MAX_ARITY, a)
, void_()
)
, 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 arg, Next const& tail)
: Next(tail)
, arg(arg)
{}
//
// Begin implementation of indexing operators for looking up
// specific arguments by name
//
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) || BOOST_WORKAROUND(__GNUC__, < 3)
// 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
{
template<class KW>
struct apply
: mpl::eval_if<
boost::is_same<KW, key_type>
, mpl::identity<arg_list<TaggedArg,Next> >
, mpl::apply_wrap1<typename Next::key_owner,KW>
>
{};
};
// A metafunction class that, given a keyword and a default
// type, returns the appropriate result type for a keyword
// lookup given that default
struct key_value_type
{
template <class KW, class Default>
struct apply
: mpl::eval_if<
boost::is_same<KW, key_type>
, mpl::identity<value_type>
, mpl::apply_wrap2<typename Next::key_value_type, KW, Default>
>
{};
};
// Outer indexing operators that dispatch to the right node's
// get() function.
template <class KW>
typename mpl::apply_wrap2<key_value_type, KW, void_>::type&
operator[](keyword<KW> x) const
{
typename mpl::apply_wrap1<key_owner, KW>::type const& sublist = *this;
return sublist.get(x);
}
template <class KW, class Default>
typename mpl::apply_wrap2<key_value_type, KW, Default>::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_wrap2<
key_value_type,KW
, typename F::result_type
>::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.
value_type& get(keyword<key_type> x) const
{
return arg.value;
}
template <class Default>
value_type& get(default_<key_type,Default> x) const
{
return arg.value;
}
template <class Default>
value_type& get(lazy_default<key_type, Default> x) const
{
return arg.value;
}
#else
value_type& operator[](keyword<key_type> x) const
{
return arg.value;
}
template <class Default>
value_type& operator[](default_<key_type, Default> x) const
{
return arg.value;
}
template <class Default>
value_type& operator[](lazy_default<key_type, Default> x) const
{
return arg.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 <class HasDefault, class Predicate>
static typename mpl::apply1<Predicate, value_type>::type
satisfies(
parameter_requirements<key_type,Predicate,HasDefault>*
);
// Builds an overload set including satisfies functions defined
// in base classes.
using Next::satisfies;
#endif
// 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>, arg_list>
operator,(tagged_argument<KW, T2> x) const
{
return arg_list<tagged_argument<KW, T2>, arg_list>(x, *this);
}
};
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) // ETI workaround
template <> struct arg_list<int,int> {};
#endif
}}} // namespace boost::parameter::aux
#endif // ARG_LIST_050329_HPP

View File

@@ -0,0 +1,67 @@
// 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
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef DEFAULT_050329_HPP
#define DEFAULT_050329_HPP
namespace boost { namespace parameter { namespace aux {
// A wrapper for the default value passed by the user when resolving
// the value of the parameter with the given Keyword
template <class Keyword, class Value>
struct default_
{
default_(Value& x)
: value(x)
{}
Value& value;
};
//
// lazy_default --
//
// A wrapper for the default value computation function passed by
// the user when resolving the value of the parameter with the
// given keyword
//
#if BOOST_WORKAROUND(__EDG_VERSION__, <= 300)
// These compilers need a little extra help with overload
// resolution; we have empty_arg_list's operator[] accept a base
// class to make that overload less preferable.
template <class KW, class DefaultComputer>
struct lazy_default_base
{
lazy_default_base(DefaultComputer const& x)
: default_(x)
{}
DefaultComputer const& compute_default;
};
template <class KW, class DefaultComputer>
struct lazy_default
: lazy_default_base<KW,DefaultComputer>
{
lazy_default(DefaultComputer const & x)
: lazy_default_base<KW,DefaultComputer>(x)
{}
};
# define BOOST_PARAMETER_lazy_default_fallback lazy_default_base
#else
template <class KW, class DefaultComputer>
struct lazy_default
{
lazy_default(const DefaultComputer& x)
: compute_default(x)
{}
DefaultComputer const& compute_default;
};
# define BOOST_PARAMETER_lazy_default_fallback lazy_default
#endif
}}} // namespace boost::parameter::aux
#endif // DEFAULT_050329_HPP

View File

@@ -0,0 +1,81 @@
// 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)
// This file generates overloads in this format:
//
// template<class A0, class A1>
// detail::arg_list<
// BOOST_DEDUCED_TYPENAME aux::as_tagged_argument<PS0, A0>::type
// , detail::arg_list<
// BOOST_DEDUCED_TYPENAME aux::as_tagged_argument<PS1, A1>::type
// >
// >
// operator()(const A0& a0, const A1& a1) const
// {
// typedef arg_list<
// BOOST_DEDUCED_TYPENAME aux::as_tagged_argument<PS0, A0>::type
// , arg_list<
// BOOST_DEDUCED_TYPENAME aux::as_tagged_argument<PS1, A1>::type
// ...
// >
// > arg_tuple;
//
// typename aux::as_tagged_argument<PS0, A0>::type tagged0(a0);
// typename aux::as_tagged_argument<PS1, A1>::type tagged1(a1);
//
// return arg_tuple(
// tagged0
// , tagged1
// , aux::void_()
// ...
// );
// }
//
#if !defined(BOOST_PP_IS_ITERATING)
# error Boost.Parameters - do not include this file!
#endif
#define N BOOST_PP_ITERATION()
#define BOOST_PARAMETER_open_list(z, n, text) \
aux::arg_list< \
BOOST_DEDUCED_TYPENAME aux::as_tagged_argument< \
BOOST_PP_CAT(PS, n), BOOST_PP_CAT(A, n) \
>::type
#define BOOST_PARAMETER_close_list(z, n, text) >
#define BOOST_PARAMETER_tagged_argument(z, n, text) \
typename aux::as_tagged_argument< \
BOOST_PP_CAT(PS, n), BOOST_PP_CAT(A, n) \
>::type BOOST_PP_CAT(tagged, n)(BOOST_PP_CAT(a, n));
#define BOOST_PARAMETER_arg_list(n) \
BOOST_PP_ENUM(N, BOOST_PARAMETER_open_list, _) \
BOOST_PP_REPEAT(N, BOOST_PARAMETER_close_list, _)
template<BOOST_PP_ENUM_PARAMS(N, class A)>
BOOST_PARAMETER_arg_list(N)
operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& a)) const
{
typedef BOOST_PARAMETER_arg_list(N) arg_tuple;
BOOST_PP_REPEAT(N, BOOST_PARAMETER_tagged_argument, _)
return arg_tuple(
BOOST_PP_ENUM_PARAMS(N, tagged)
BOOST_PP_ENUM_TRAILING_PARAMS(
BOOST_PP_SUB(BOOST_PARAMETER_MAX_ARITY, N)
, aux::void_() BOOST_PP_INTERCEPT
));
}
#undef BOOST_PARAMETER_arg_list
#undef BOOST_PARAMETER_open_list
#undef BOOST_PARAMETER_close_list
#undef BOOST_PARAMETER_tagged_argument
#undef N

View File

@@ -0,0 +1,24 @@
// 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
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef PARAMETER_REQUIREMENTS_050331_HPP
#define PARAMETER_REQUIREMENTS_050331_HPP
namespace boost { namespace parameter { namespace aux {
// Used to pass static information about parameter requirements
// through the satisfies() overload set (below). The
// matched function is never invoked, but its type indicates whether
// a parameter matches at compile-time
template <class Keyword, class Predicate, class HasDefault>
struct parameter_requirements
{
typedef HasDefault has_default;
};
}}} // namespace boost::parameter::aux
#endif // PARAMETER_REQUIREMENTS_050331_HPP

View File

@@ -0,0 +1,53 @@
// 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
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef TAGGED_ARGUMENT_050328_HPP
#define TAGGED_ARGUMENT_050328_HPP
#include <boost/parameter/aux_/void.hpp>
#include <boost/parameter/aux_/arg_list.hpp>
namespace boost { namespace parameter { namespace aux {
// Holds a reference to an argument of type Arg associated with
// keyword Keyword
template <class Keyword, class Arg>
struct tagged_argument
{
typedef Keyword key_type;
typedef Arg value_type;
tagged_argument(Arg& x) : value(x) {}
// Comma operator to compose argument list without using parameters<>.
// Useful for argument lists with undetermined length.
template <class Keyword2, class Arg2>
arg_list<
tagged_argument<Keyword, Arg>
, arg_list<tagged_argument<Keyword2, Arg2> >
>
operator,(tagged_argument<Keyword2, Arg2> x) const
{
return arg_list<
tagged_argument<Keyword, Arg>
, arg_list<tagged_argument<Keyword2, Arg2> >
>(
*this
, arg_list<tagged_argument<Keyword2, Arg2> >(x, empty_arg_list())
);
}
Arg& value;
};
// Defines a metafunction, is_tagged_argument, that identifies
// tagged_argument specializations.
BOOST_PYTHON_IS_XXX_DEF(tagged_argument,tagged_argument,2)
}}} // namespace boost::parameter::aux
#endif // TAGGED_ARGUMENT_050328_HPP

View File

@@ -0,0 +1,59 @@
// 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
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef UNWRAP_CV_REFERENCE_050328_HPP
#define UNWRAP_CV_REFERENCE_050328_HPP
#include <boost/parameter/aux_/yesno.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/eval_if.hpp>
namespace boost { template<class T> class reference_wrapper; }
namespace boost { namespace parameter { namespace aux {
//
// reference_wrapper support -- because of the forwarding problem,
// when passing arguments positionally by non-const reference, we
// ask users of named parameter interfaces to use ref(x) to wrap
// them.
//
// is_cv_reference_wrapper returns mpl::true_ if T is of type
// reference_wrapper<U> cv
template <class U>
yes_tag is_cv_reference_wrapper_check(reference_wrapper<U> const volatile*);
no_tag is_cv_reference_wrapper_check(...);
template <class T>
struct is_cv_reference_wrapper
{
BOOST_STATIC_CONSTANT(
bool, value = (
sizeof(is_cv_reference_wrapper_check((T*)0)) == sizeof(yes_tag)
)
);
typedef mpl::bool_<value> type;
};
// Produces the unwrapped type to hold a reference to in named<>
// Can't use boost::unwrap_reference<> here because it
// doesn't handle the case where T = reference_wrapper<U> cv
template <class T>
struct unwrap_cv_reference
{
typedef typename mpl::eval_if<
is_cv_reference_wrapper<T>
, T
, mpl::identity<T>
>::type type;
};
}}} // namespace boost::parameter::aux
#endif // UNWRAP_CV_REFERENCE_050328_HPP

View File

@@ -0,0 +1,18 @@
// 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
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef VOID_050329_HPP
#define VOID_050329_HPP
namespace boost { namespace parameter { namespace aux {
// A placemarker for "no argument passed."
// MAINTAINER NOTE: Do not make this into a metafunction
struct void_ {};
}}} // namespace boost::parameter::aux
#endif // VOID_050329_HPP

View File

@@ -0,0 +1,26 @@
// 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
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef YESNO_050328_HPP
#define YESNO_050328_HPP
#include <boost/mpl/bool.hpp>
namespace boost { namespace parameter { namespace aux {
// types used with the "sizeof trick" to capture the results of
// overload resolution at compile-time.
typedef char yes_tag;
typedef char (&no_tag)[2];
// mpl::true_ and mpl::false_ are not distinguishable by sizeof(),
// so we pass them through these functions to get a type that is.
yes_tag to_yesno(mpl::true_);
no_tag to_yesno(mpl::false_);
}}} // namespace boost::parameter::aux
#endif // YESNO_050328_HPP

View File

@@ -0,0 +1,14 @@
// 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
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_PARAMETER_CONFIG_050403_HPP
#define BOOST_PARAMETER_CONFIG_050403_HPP
#ifndef BOOST_PARAMETER_MAX_ARITY
# define BOOST_PARAMETER_MAX_ARITY 5
#endif
#endif // BOOST_PARAMETER_CONFIG_050403_HPP

View File

@@ -0,0 +1,93 @@
// 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
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef KEYWORD_050328_HPP
#define KEYWORD_050328_HPP
#include <boost/parameter/aux_/unwrap_cv_reference.hpp>
#include <boost/parameter/aux_/tagged_argument.hpp>
#include <boost/parameter/aux_/default.hpp>
namespace boost { namespace parameter {
// Instances of unique specializations of keyword<...> serve to
// associate arguments with parameter names. For example:
//
// struct rate_; // parameter names
// struct skew_;
// namespace
// {
// keyword<rate_> rate; // keywords
// keyword<skew_> skew;
// }
//
// ...
//
// f(rate = 1, skew = 2.4);
//
template <class Tag>
struct keyword
{
template <class T>
aux::tagged_argument<
Tag
, typename aux::unwrap_cv_reference<T>::type
>
operator=(T& x) const
{
return aux::tagged_argument<
Tag
, BOOST_DEDUCED_TYPENAME aux::unwrap_cv_reference<T>::type
>(x);
}
template <class Default>
aux::default_<Tag, Default>
operator|(Default& default_) const
{
return aux::default_<Tag, Default>(default_);
}
template <class Default>
aux::lazy_default<Tag, Default>
operator||(Default& default_) const
{
return aux::lazy_default<Tag, Default>(default_);
}
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1200) // avoid partial ordering bugs
template <class T>
aux::tagged_argument<
Tag
, typename aux::unwrap_cv_reference<T const>::type
>
operator=(T const& x) const
{
return aux::tagged_argument<
Tag
, BOOST_DEDUCED_TYPENAME aux::unwrap_cv_reference<T const>::type
>(x);
}
template <class Default>
aux::default_<Tag, const Default>
operator|(const Default& default_) const
{
return aux::default_<Tag, const Default>(default_);
}
template <class Default>
aux::lazy_default<Tag, Default>
operator||(Default const& default_) const
{
return aux::lazy_default<Tag, Default>(default_);
}
#endif
};
}} // namespace boost::parameter
#endif // KEYWORD_050328_HPP

View File

@@ -0,0 +1,449 @@
// 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_PARAMETER_031014_HPP
#define BOOST_PARAMETER_031014_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/type_traits/is_same.hpp>
#include <boost/iterator/detail/config_def.hpp>
#include <boost/python/detail/is_xxx.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/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/keyword.hpp>
#include <boost/parameter/config.hpp>
namespace boost {
template<class T> class reference_wrapper;
namespace parameter {
// 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.
//
template <class Tag, class Predicate = mpl::always<mpl::true_> >
struct required
{
typedef Tag key_type;
typedef Predicate predicate;
};
template <class Tag, class Predicate = mpl::always<mpl::true_> >
struct optional
{
typedef Tag key_type;
typedef Predicate predicate;
};
namespace aux
{
// Defines metafunctions, is_required and is_optional, that
// identify required<...> and optional<...> specializations.
BOOST_PYTHON_IS_XXX_DEF(required, required, 2)
BOOST_PYTHON_IS_XXX_DEF(optional, optional, 2)
//
// 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<...> or optional<...>.
//
// helper for key_type<...>, below.
template <class T>
struct get_key_type
{ typedef typename T::key_type type; };
template <class T>
struct key_type
: mpl::eval_if<
mpl::or_<
is_optional<T>
, is_required<T>
>
, get_key_type<T>
, mpl::identity<T>
>
{
};
template <class T>
struct has_default
: mpl::not_<typename is_required<T>::type>
{
};
// helper for predicate<...>, below
template <class T>
struct get_predicate
{
typedef typename T::predicate 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
// key_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 key_type<ParameterSpec>::type
, typename predicate<ParameterSpec>::type
, typename has_default<ParameterSpec>::type
> type;
};
// Labels Arg with default keyword tag DefaultTag if it is not
// already a tagged_argument
template <class DefaultTag, class Arg>
struct as_tagged_argument
{
typedef typename mpl::if_<
is_tagged_argument<Arg>
, Arg
, tagged_argument<
typename key_type<DefaultTag>::type
, typename unwrap_cv_reference<Arg const>::type
>
>::type type;
};
#if BOOST_WORKAROUND(BOOST_MSVC, == 1200) // ETI workaround
template <>
struct as_tagged_argument<int,int>
{
typedef int type;
};
#endif
// Returns mpl::true_ iff the given ParameterRequirements are
// satisfied by ArgList.
template <class ArgList, class ParameterRequirements>
struct satisfies
{
BOOST_STATIC_CONSTANT(
bool, value = (
sizeof(
aux::to_yesno(
ArgList::satisfies((ParameterRequirements*)0)
)
) == sizeof(yes_tag)
)
);
typedef mpl::bool_<value> type;
};
// 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
>
{};
// 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>
struct make_arg_list
{
typedef arg_list<
typename as_tagged_argument<ParameterSpec,ArgumentType>::type
, typename TailFn::type
> type;
};
// Just like make_arg_list, except if ArgumentType is void_, the
// result is empty_arg_list. Used to build arg_lists whose length
// depends on the number of non-default (void_) arguments passed to
// a class template.
template <
class ParameterSpec
, class ArgumentType
, 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>
>
{};
// 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<aux::empty_arg_list> \
BOOST_PP_REPEAT(n, BOOST_PARAMETER_right_angle, _)
} // namespace aux
#define BOOST_PARAMETERS_TEMPLATE_ARGS(z, n, text) class BOOST_PP_CAT(PS, n) = aux::void_
template<
class PS0
, BOOST_PP_ENUM_SHIFTED(BOOST_PARAMETER_MAX_ARITY, BOOST_PARAMETERS_TEMPLATE_ARGS, _)
>
struct parameters
{
typedef parameters self;
#undef BOOST_PARAMETERS_TEMPLATE_ARGS
// 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).
#ifndef BOOST_NO_SFINAE
// If NamedList satisfies the PS0, PS1, ..., this is a
// metafunction returning parameters. Otherwise it
// has no nested ::type.
template <class NamedList>
struct restrict_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<NamedList, BOOST_PP_CAT(PS, n)> ,
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>
, aux::void_
>
{};
#endif
// Specializations are to be used as an optional argument to
// eliminate overloads via SFINAE
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
)::type
>::type
{};
#else
{ typedef parameters type; };
#endif
//
// 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.
//
aux::empty_arg_list operator()() const
{
return aux::empty_arg_list();
}
template<class A0>
typename
aux::make_arg_list<PS0,A0, 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> >
::type result_type;
return result_type(
a0
// , void_(), void_(), void_() ...
BOOST_PP_ENUM_TRAILING_PARAMS(
BOOST_PP_SUB(BOOST_PARAMETER_MAX_ARITY, 1)
, aux::void_() BOOST_PP_INTERCEPT)
);
}
template<class A0, class A1>
typename
aux::make_arg_list<
PS0,A0
, aux::make_arg_list<
PS1,A1
, mpl::identity<aux::empty_arg_list>
>
>
::type
operator()(A0 const& a0, A1 const& a1) const
{
typedef typename
aux::make_arg_list<
PS0,A0
, aux::make_arg_list<
PS1,A1
, mpl::identity<aux::empty_arg_list>
>
>
::type result_type;
return result_type(
a0, a1
// , void_(), void_() ...
BOOST_PP_ENUM_TRAILING_PARAMS(
BOOST_PP_SUB(BOOST_PARAMETER_MAX_ARITY, 2)
, aux::void_() 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()
#undef BOOST_PARAMETER_build_arg_list
#undef BOOST_PARAMETER_make_arg_list
#undef BOOST_PARAMETER_right_angle
};
} // namespace parameter
} // namespace boost
#include <boost/preprocessor/tuple/elem.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/logical/bool.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/control/expr_if.hpp>
#define BOOST_PARAMETER_FUN_TEMPLATE_HEAD1(n) \
template<BOOST_PP_ENUM_PARAMS(n, class T)>
#define BOOST_PARAMETER_FUN_TEMPLATE_HEAD0(n)
#define BOOST_PARAMETER_FUN_DECL(z, n, params) \
\
BOOST_PP_CAT(BOOST_PARAMETER_FUN_TEMPLATE_HEAD, BOOST_PP_BOOL(n))(n) \
\
BOOST_PP_TUPLE_ELEM(3, 0, params) \
BOOST_PP_TUPLE_ELEM(3, 1, params)( \
BOOST_PP_ENUM_BINARY_PARAMS(n, const T, &p) \
BOOST_PP_COMMA_IF(n) \
BOOST_PP_EXPR_IF(n, typename) BOOST_PP_TUPLE_ELEM(3, 2, params)::restrict \
< \
BOOST_PP_ENUM_PARAMS(n, T) \
>::type kw = BOOST_PP_TUPLE_ELEM(3, 2, params)() \
) \
{ \
return BOOST_PP_CAT(BOOST_PP_TUPLE_ELEM(3, 1, params), _with_named_params)( \
kw(BOOST_PP_ENUM_PARAMS(n, p)) \
); \
}
#define BOOST_PARAMETER_FUN(ret, name, lo, hi, keywords) \
\
template<class Params> \
ret BOOST_PP_CAT(name, _with_named_params)(const Params&); \
\
BOOST_PP_REPEAT_FROM_TO( \
lo, BOOST_PP_INC(hi), BOOST_PARAMETER_FUN_DECL, (ret, name, keywords)) \
\
template<class Params> \
ret BOOST_PP_CAT(name, _with_named_params)(const Params& p)
#include <boost/iterator/detail/config_undef.hpp>
#endif // BOOST_PARAMETER_031014_HPP