From: g0dil Date: Thu, 10 Apr 2008 09:23:14 +0000 (+0000) Subject: Add Boost.Parameter Version 1.33.1 to senf repository X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=a66abf9858a3bf29816432f95f2faf74337b6f4f;p=senf.git Add Boost.Parameter Version 1.33.1 to senf repository git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@799 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/boost/parameter/aux_/arg_list.hpp b/boost/parameter/aux_/arg_list.hpp new file mode 100644 index 0000000..2def8e9 --- /dev/null +++ b/boost/parameter/aux_/arg_list.hpp @@ -0,0 +1,326 @@ +// 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 +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include + +namespace boost { namespace parameter { + +// Forward declaration for aux::arg_list, below. +template 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 + )) + {} + + // 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 + struct apply + { + typedef Default type; + }; + }; + +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \ + || (BOOST_WORKAROUND(__GNUC__, < 3)) \ + || BOOST_WORKAROUND(__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 + struct apply + { + typedef empty_arg_list type; + }; + }; + + template + T& get(default_ x) const + { + return x.value; + } + + template + typename result_of0::type + get(lazy_default 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 + Default& operator[](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 + typename result_of0::type + operator[]( + BOOST_PARAMETER_lazy_default_fallback 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 + static typename ParameterRequirements::has_default + satisfies(ParameterRequirements*); +}; + +// Forward declaration for arg_list::operator, +template +struct tagged_argument; + +// A tuple of tagged arguments, terminated with empty_arg_list. +// Every TaggedArg is an instance of tagged_argument<>. +template +struct arg_list : Next +{ + typedef arg_list self; + typedef typename TaggedArg::key_type key_type; + typedef typename TaggedArg::value_type value_type; + typedef typename TaggedArg::reference reference; + + 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) + {} + + + // 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 + struct apply + { + typedef typename mpl::eval_if< + boost::is_same + , mpl::identity + , mpl::apply_wrap2 + >::type type; + }; + }; + + // + // Begin implementation of indexing operators for looking up + // specific arguments by name + // + +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) \ + || BOOST_WORKAROUND(__GNUC__, < 3) \ + || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + // These older compilers don't support the overload set creation + // idiom well, so we need to do all the return type calculation + // for the compiler and dispatch through an outer function template + + // A metafunction class that, given a keyword, returns the base + // sublist whose get() function can produce the value for that + // key. + struct key_owner + { + template + struct apply + { + typedef typename mpl::eval_if< + boost::is_same + , mpl::identity > + , mpl::apply_wrap1 + >::type type; + }; + }; + + // Outer indexing operators that dispatch to the right node's + // get() function. + template + typename mpl::apply_wrap2::type + operator[](keyword const& x) const + { + typename mpl::apply_wrap1::type const& sublist = *this; + return sublist.get(x); + } + + template + typename mpl::apply_wrap2::type + operator[](default_ x) const + { + typename mpl::apply_wrap1::type const& sublist = *this; + return sublist.get(x); + } + + template + typename mpl::apply_wrap2< + binding,KW + , typename result_of0::type + >::type + operator[](lazy_default x) const + { + typename mpl::apply_wrap1::type const& sublist = *this; + return sublist.get(x); + } + + // These just return the stored value; when empty_arg_list is + // reached, indicating no matching argument was passed, the + // default is returned, or if no default_ or lazy_default was + // passed, compilation fails. + reference get(keyword const&) const + { + return arg.value; + } + + template + reference get(default_) const + { + return arg.value; + } + + template + reference get(lazy_default) const + { + return arg.value; + } + +#else + + reference operator[](keyword const&) const + { + return arg.value; + } + + template + reference operator[](default_) const + { + return arg.value; + } + + template + reference operator[](lazy_default) 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 + static typename mpl::apply1::type + satisfies( + parameter_requirements* + ); + + // 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 + arg_list, self> + operator,(tagged_argument x) + { + return arg_list, self>(x, *this); + } +}; + +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) // ETI workaround +template <> struct arg_list {}; +#endif + +}}} // namespace boost::parameter::aux + +#endif // ARG_LIST_050329_HPP + diff --git a/boost/parameter/aux_/default.hpp b/boost/parameter/aux_/default.hpp new file mode 100644 index 0000000..ee90b95 --- /dev/null +++ b/boost/parameter/aux_/default.hpp @@ -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 +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 +struct lazy_default_base +{ + lazy_default_base(DefaultComputer const& x) + : compute_default(x) + {} + DefaultComputer const& compute_default; +}; + +template +struct lazy_default + : lazy_default_base + { + lazy_default(DefaultComputer const & x) + : lazy_default_base(x) + {} + }; +# define BOOST_PARAMETER_lazy_default_fallback lazy_default_base +#else +template +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 + diff --git a/boost/parameter/aux_/overloads.hpp b/boost/parameter/aux_/overloads.hpp new file mode 100644 index 0000000..6ca1dd0 --- /dev/null +++ b/boost/parameter/aux_/overloads.hpp @@ -0,0 +1,70 @@ +// 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 +// typename aux::make_arg_list< +// PS0,A0 +// , aux::make_arg_list< +// PS1,A1 +// , mpl::identity +// > +// >::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 +// > +// >::type arg_tuple; +// +// return arg_tuple( +// a0 +// , a1 +// , 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::make_arg_list< \ + BOOST_PP_CAT(PS, n), BOOST_PP_CAT(A, n) \ + +#define BOOST_PARAMETER_close_list(z, n, text) > + +#define BOOST_PARAMETER_arg_list(n) \ + BOOST_PP_ENUM(N, BOOST_PARAMETER_open_list, _) \ + , mpl::identity \ + BOOST_PP_REPEAT(N, BOOST_PARAMETER_close_list, _) + +template +typename BOOST_PARAMETER_arg_list(N)::type +operator()(BOOST_PP_ENUM_BINARY_PARAMS(N, A, const& a)) const +{ + typedef typename BOOST_PARAMETER_arg_list(N)::type arg_tuple; + + return arg_tuple( + BOOST_PP_ENUM_PARAMS(N, a) + 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 N + diff --git a/boost/parameter/aux_/parameter_requirements.hpp b/boost/parameter/aux_/parameter_requirements.hpp new file mode 100644 index 0000000..ad7a129 --- /dev/null +++ b/boost/parameter/aux_/parameter_requirements.hpp @@ -0,0 +1,25 @@ +// 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 +struct parameter_requirements +{ + typedef Keyword keyword; + typedef Predicate predicate; + typedef HasDefault has_default; +}; + +}}} // namespace boost::parameter::aux + +#endif // PARAMETER_REQUIREMENTS_050331_HPP diff --git a/boost/parameter/aux_/result_of0.hpp b/boost/parameter/aux_/result_of0.hpp new file mode 100644 index 0000000..e009614 --- /dev/null +++ b/boost/parameter/aux_/result_of0.hpp @@ -0,0 +1,36 @@ +// Copyright David Abrahams 2005. 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_RESULT_OF0_DWA2005511_HPP +# define BOOST_PARAMETER_AUX_RESULT_OF0_DWA2005511_HPP + +# include + +// A metafunction returning the result of invoking a nullary function +// object of the given type. + +#ifndef BOOST_NO_RESULT_OF + +# include +namespace boost { namespace parameter { namespace aux { +template +struct result_of0 : result_of +{}; + +}}} // namespace boost::parameter::aux_ + +#else + +namespace boost { namespace parameter { namespace aux { +template +struct result_of0 +{ + typedef typename F::result_type type; +}; + +}}} // namespace boost::parameter::aux_ + +#endif + + +#endif // BOOST_PARAMETER_AUX_RESULT_OF0_DWA2005511_HPP diff --git a/boost/parameter/aux_/tag.hpp b/boost/parameter/aux_/tag.hpp new file mode 100644 index 0000000..475efb9 --- /dev/null +++ b/boost/parameter/aux_/tag.hpp @@ -0,0 +1,38 @@ +// Copyright David Abrahams 2005. 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_TAG_DWA2005610_HPP +# define BOOST_PARAMETER_AUX_TAG_DWA2005610_HPP + +# include +# include + +namespace boost { namespace parameter { namespace aux { + +template ::type +#endif + > +struct tag +{ + typedef tagged_argument< + Keyword + , typename unwrap_cv_reference::type + > type; +}; + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +template +struct tag +{ + typedef tagged_argument< + Keyword + , ActualArg + > type; +}; +#endif + +}}} // namespace boost::parameter::aux_ + +#endif // BOOST_PARAMETER_AUX_TAG_DWA2005610_HPP diff --git a/boost/parameter/aux_/tagged_argument.hpp b/boost/parameter/aux_/tagged_argument.hpp new file mode 100644 index 0000000..ed679d7 --- /dev/null +++ b/boost/parameter/aux_/tagged_argument.hpp @@ -0,0 +1,55 @@ +// 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 +#include +#include + +namespace boost { namespace parameter { namespace aux { + +// Holds a reference to an argument of type Arg associated with +// keyword Keyword + +template +struct tagged_argument +{ + typedef Keyword key_type; + typedef Arg value_type; + typedef Arg& reference; + + tagged_argument(reference x) : value(x) {} + + // Comma operator to compose argument list without using parameters<>. + // Useful for argument lists with undetermined length. + template + arg_list< + tagged_argument + , arg_list > + > + operator,(tagged_argument x) const + { + return arg_list< + tagged_argument + , arg_list > + >( + *this + , arg_list >(x, empty_arg_list()) + ); + } + + reference value; +}; + +// Defines a metafunction, is_tagged_argument, that identifies +// tagged_argument specializations. +BOOST_DETAIL_IS_XXX_DEF(tagged_argument,tagged_argument,2) + +}}} // namespace boost::parameter::aux + +#endif // TAGGED_ARGUMENT_050328_HPP + diff --git a/boost/parameter/aux_/unwrap_cv_reference.hpp b/boost/parameter/aux_/unwrap_cv_reference.hpp new file mode 100644 index 0000000..e7aa0c1 --- /dev/null +++ b/boost/parameter/aux_/unwrap_cv_reference.hpp @@ -0,0 +1,97 @@ +// 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 +#include +#include +#include + +namespace boost { template 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 cv +template +yes_tag is_cv_reference_wrapper_check(reference_wrapper const volatile*); +no_tag is_cv_reference_wrapper_check(...); + +template +struct is_cv_reference_wrapper +{ + BOOST_STATIC_CONSTANT( + bool, value = ( + sizeof(is_cv_reference_wrapper_check((T*)0)) == sizeof(yes_tag) + ) + ); + + typedef mpl::bool_< +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + is_cv_reference_wrapper:: +#endif + value> type; +}; + +#if BOOST_WORKAROUND(MSVC, == 1200) +template <> +struct is_cv_reference_wrapper + : mpl::false_ {}; +#endif + +// Needed for unwrap_cv_reference below. T might be const, so +// eval_if might fail because of deriving from T const on EDG. +template +struct get_type +{ + typedef typename T::type type; +}; + +#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) +template ::type> +struct unwrap_cv_reference +{ + typedef T type; +}; + +template +struct unwrap_cv_reference +{ + typedef T const type; +}; + +template +struct unwrap_cv_reference + : T +{}; + +#else +// 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 cv +template +struct unwrap_cv_reference +{ + typedef typename mpl::eval_if< + is_cv_reference_wrapper + , get_type + , mpl::identity + >::type type; +}; +#endif + +}}} // namespace boost::parameter::aux + +#endif // UNWRAP_CV_REFERENCE_050328_HPP + diff --git a/boost/parameter/aux_/void.hpp b/boost/parameter/aux_/void.hpp new file mode 100644 index 0000000..0716e34 --- /dev/null +++ b/boost/parameter/aux_/void.hpp @@ -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 + diff --git a/boost/parameter/aux_/yesno.hpp b/boost/parameter/aux_/yesno.hpp new file mode 100644 index 0000000..13fa545 --- /dev/null +++ b/boost/parameter/aux_/yesno.hpp @@ -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 + +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 + diff --git a/boost/parameter/binding.hpp b/boost/parameter/binding.hpp new file mode 100644 index 0000000..b7082aa --- /dev/null +++ b/boost/parameter/binding.hpp @@ -0,0 +1,57 @@ +// Copyright David Abrahams 2005. 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_BINDING_DWA200558_HPP +# define BOOST_PARAMETER_BINDING_DWA200558_HPP + +# include +# include + +# include + +# if BOOST_WORKAROUND(BOOST_MSVC, < 1300) +# include +# include +# endif + +namespace boost { namespace parameter { + +// A metafunction that, given an argument pack, returns the type of +// the parameter identified by the given keyword. If no such +// parameter has been specified, returns Default +# if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) +template +struct binding + : mpl::apply_wrap2< + typename Parameters::binding,Keyword,Default + > +{}; +# else +template +struct binding +{ + typedef typename mpl::apply_wrap2< + typename Parameters::binding,Keyword, + typename mpl::if_,void,Default>::type + >::type type; +}; +# endif + +// A metafunction that, given an argument pack, returns the type of +// the parameter identified by the given keyword. If no such +// parameter has been specified, returns the type returned by invoking +// DefaultFn +template +struct lazy_binding +{ + typedef typename mpl::apply_wrap2< + typename Parameters::binding + , Keyword + , typename aux::result_of0::type + >::type type; +}; + + +}} // namespace boost::parameter + +#endif // BOOST_PARAMETER_BINDING_DWA200558_HPP diff --git a/boost/parameter/config.hpp b/boost/parameter/config.hpp new file mode 100644 index 0000000..e4fcc29 --- /dev/null +++ b/boost/parameter/config.hpp @@ -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 + diff --git a/boost/parameter/keyword.hpp b/boost/parameter/keyword.hpp new file mode 100644 index 0000000..6b69b78 --- /dev/null +++ b/boost/parameter/keyword.hpp @@ -0,0 +1,134 @@ +// 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 +#include +#include +#include + +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; // keywords +// keyword skew; +// } +// +// ... +// +// f(rate = 1, skew = 2.4); +// +template +struct keyword : noncopyable +{ + template + typename aux::tag::type + operator=(T& x) const + { + typedef typename aux::tag::type result; + return result(x); + } + + template + aux::default_ + operator|(Default& default_) const + { + return aux::default_(default_); + } + + template + aux::lazy_default + operator||(Default& default_) const + { + return aux::lazy_default(default_); + } + +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) // avoid partial ordering bugs + template + typename aux::tag::type + operator=(T const& x) const + { + typedef typename aux::tag::type result; + return result(x); + } +#endif + +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) // avoid partial ordering bugs + template + aux::default_ + operator|(const Default& default_) const +#if BOOST_WORKAROUND(BOOST_MSVC, == 1300) + volatile +#endif + { + return aux::default_(default_); + } + + template + aux::lazy_default + operator||(Default const& default_) const +#if BOOST_WORKAROUND(BOOST_MSVC, == 1300) + volatile +#endif + { + return aux::lazy_default(default_); + } +#endif + + public: // Insurance against ODR violations + + // People will need to define these keywords in header files. To + // prevent ODR violations, it's important that the keyword used in + // every instantiation of a function template is the same object. + // We provide a reference to a common instance of each keyword + // object and prevent construction by users. + + static keyword& get() + { + static keyword result; + return result; + } + + private: + keyword() {} +}; + +// Reduces boilerplate required to declare and initialize keywords +// without violating ODR. Declares a keyword tag type with the given +// name in namespace tag_namespace, and declares and initializes a +// reference in an anonymous namespace to a singleton instance of that +// type. + +#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) + +# define BOOST_PARAMETER_KEYWORD(tag_namespace,name) \ + namespace tag_namespace { struct name; } \ + static ::boost::parameter::keyword& name \ + = ::boost::parameter::keyword::get(); + +#else + +#define BOOST_PARAMETER_KEYWORD(tag_namespace,name) \ + namespace tag_namespace { struct name; } \ + namespace \ + { \ + ::boost::parameter::keyword& name \ + = ::boost::parameter::keyword::get(); \ + } + +#endif + +}} // namespace boost::parameter + +#endif // KEYWORD_050328_HPP + diff --git a/boost/parameter/macros.hpp b/boost/parameter/macros.hpp new file mode 100644 index 0000000..add6643 --- /dev/null +++ b/boost/parameter/macros.hpp @@ -0,0 +1,98 @@ +// 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_MACROS_050412_HPP +#define BOOST_PARAMETER_MACROS_050412_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BOOST_PARAMETER_FUN_TEMPLATE_HEAD1(n) \ + template + +#define BOOST_PARAMETER_FUN_TEMPLATE_HEAD0(n) + +#ifndef BOOST_NO_SFINAE + +# define BOOST_PARAMETER_MATCH_TYPE(n, param) \ + BOOST_PP_EXPR_IF(n, typename) param::match \ + < \ + BOOST_PP_ENUM_PARAMS(n, T) \ + >::type + +#else + +# define BOOST_PARAMETER_MATCH_TYPE(n, param) param + +#endif + +#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, T, const& p) \ + BOOST_PP_COMMA_IF(n) \ + BOOST_PARAMETER_MATCH_TYPE(n,BOOST_PP_TUPLE_ELEM(3, 2, params)) \ + 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)) \ + ); \ + } + +// Generates: +// +// template +// ret name ## _with_named_params(Params const&); +// +// template +// ret name(T0 const& p0, typename parameters::match::type kw = parameters()) +// { +// return name ## _with_named_params(kw(p0)); +// } +// +// template +// ret name(T0 const& p0, ..., TN const& PN +// , typename parameters::match::type kw = parameters()) +// { +// return name ## _with_named_params(kw(p0, ..., pN)); +// } +// +// template +// ret name ## _with_named_params(Params const&) +// +// lo and hi determines the min and max arity of the generated functions. + +#define BOOST_PARAMETER_FUN(ret, name, lo, hi, parameters) \ + \ + template \ + ret BOOST_PP_CAT(name, _with_named_params)(Params const&); \ + \ + BOOST_PP_REPEAT_FROM_TO( \ + lo, BOOST_PP_INC(hi), BOOST_PARAMETER_FUN_DECL, (ret, name, parameters)) \ + \ + template \ + ret BOOST_PP_CAT(name, _with_named_params)(Params const& p) + +#define BOOST_PARAMETER_MEMFUN(ret, name, lo, hi, parameters) \ + \ + BOOST_PP_REPEAT_FROM_TO( \ + lo, BOOST_PP_INC(hi), BOOST_PARAMETER_FUN_DECL, (ret, name, parameters)) \ + \ + template \ + ret BOOST_PP_CAT(name, _with_named_params)(Params const& p) + +#endif // BOOST_PARAMETER_MACROS_050412_HPP + diff --git a/boost/parameter/match.hpp b/boost/parameter/match.hpp new file mode 100644 index 0000000..81b4cba --- /dev/null +++ b/boost/parameter/match.hpp @@ -0,0 +1,55 @@ +// Copyright David Abrahams 2005. 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_MATCH_DWA2005714_HPP +# define BOOST_PARAMETER_MATCH_DWA2005714_HPP + +# include +# include + +# if BOOST_WORKAROUND(__MWERKS__, <= 0x3003) +// Temporary version of BOOST_PP_SEQ_ENUM until Paul M. integrates the workaround. +# define BOOST_PARAMETER_SEQ_ENUM_I(size,seq) BOOST_PP_CAT(BOOST_PP_SEQ_ENUM_, size) seq +# define BOOST_PARAMETER_SEQ_ENUM(seq) BOOST_PARAMETER_SEQ_ENUM_I(BOOST_PP_SEQ_SIZE(seq), seq) +# else +# define BOOST_PARAMETER_SEQ_ENUM(seq) BOOST_PP_SEQ_ENUM(seq) +# endif + +# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) + +# include +# include +# include +# include +# include + +# define BOOST_PARAMETER_MATCH_DEFAULTS(ArgTypes) \ + BOOST_PP_ENUM_TRAILING_PARAMS( \ + BOOST_PP_SUB( \ + BOOST_PARAMETER_MAX_ARITY \ + , BOOST_PP_SEQ_SIZE(ArgTypes) \ + ) \ + , ::boost::parameter::aux::void_ BOOST_PP_INTERCEPT \ + ) + +# else + +# define BOOST_PARAMETER_MATCH_DEFAULTS(ArgTypes) + +# endif + +// +// Generates, e.g. +// +// typename dfs_params::match::type name = dfs_params() +// +// with workarounds for Borland compatibility. +// + +# define BOOST_PARAMETER_MATCH(ParameterSpec, ArgTypes, name) \ + typename ParameterSpec ::match< \ + BOOST_PARAMETER_SEQ_ENUM(ArgTypes) \ + BOOST_PARAMETER_MATCH_DEFAULTS(ArgTypes) \ + >::type name = ParameterSpec () + +#endif // BOOST_PARAMETER_MATCH_DWA2005714_HPP diff --git a/boost/parameter/parameters.hpp b/boost/parameter/parameters.hpp new file mode 100644 index 0000000..7787b9c --- /dev/null +++ b/boost/parameter/parameters.hpp @@ -0,0 +1,455 @@ +// 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace boost { + +template 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 were +// specified. +// +template +struct required +{ + typedef Tag key_type; + typedef Predicate predicate; +}; + +template +struct optional +{ + typedef Tag key_type; + typedef Predicate predicate; +}; + +template +struct unnamed +{ + typedef Tag key_type; +}; + +namespace aux +{ + // Defines metafunctions, is_required and is_optional, that + // identify required<...> and optional<...> specializations. + BOOST_DETAIL_IS_XXX_DEF(required, required, 2) + BOOST_DETAIL_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 + struct get_key_type + { typedef typename T::key_type type; }; + + template + struct key_type + : mpl::eval_if< + mpl::or_< + is_optional + , is_required + > + , get_key_type + , mpl::identity + > + { + }; + + template + struct has_default + : mpl::not_::type> + { + }; + + // helper for get_predicate<...>, below + template + struct get_predicate_or_default + { + typedef T type; + }; + + template <> + struct get_predicate_or_default + { + typedef mpl::always type; + }; + + // helper for predicate<...>, below + template + struct get_predicate + { + typedef typename + get_predicate_or_default::type + type; + }; + + template + struct predicate + : mpl::eval_if< + mpl::or_< + is_optional + , is_required + > + , get_predicate + , mpl::identity > + > + { + }; + + + // 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 + struct as_parameter_requirements + { + typedef parameter_requirements< + typename key_type::type + , typename predicate::type + , typename has_default::type + > type; + }; + + // Labels Arg with default keyword tag DefaultTag if it is not + // already a tagged_argument + template + struct as_tagged_argument + : mpl::eval_if< + is_tagged_argument + , mpl::identity + , tag::type, Arg const> + > + {}; + +#if BOOST_WORKAROUND(BOOST_MSVC, == 1200) // ETI workaround + template <> + struct as_tagged_argument + { + typedef int type; + }; +#endif + + // Returns mpl::true_ iff the given ParameterRequirements are + // satisfied by ArgList. + template + 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 + , typename ParameterRequirements::has_default + , mpl::apply1< + typename ParameterRequirements::predicate + , typename remove_reference::type + > + >::type type; +#else + BOOST_STATIC_CONSTANT( + bool, value = ( + sizeof( + aux::to_yesno( + ArgList::satisfies((ParameterRequirements*)0) + ) + ) == sizeof(yes_tag) + ) + ); + + typedef mpl::bool_ type; +#endif + }; + + // Returns mpl::true_ if the requirements of the given ParameterSpec + // are satisfied by ArgList. + template + struct satisfies_requirements_of + : satisfies< + ArgList + , typename as_parameter_requirements::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 + struct make_arg_list + { + typedef arg_list< + typename as_tagged_argument::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 + , mpl::identity + , make_arg_list + > + {}; + + // Generates: + // + // make< + // parameter_spec#0, argument_type#0 + // , make< + // parameter_spec#1, argument_type#1 + // , ... mpl::identity + // ...> + // > +#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 \ + BOOST_PP_REPEAT(n, BOOST_PARAMETER_right_angle, _) + +} // namespace aux + +#define BOOST_PARAMETER_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_PARAMETER_TEMPLATE_ARGS, _) +> +struct parameters +{ +#undef BOOST_PARAMETER_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 + struct match_base + : mpl::if_< + // mpl::and_< + // aux::satisfies_requirements_of + // , mpl::and_< + // aux::satisfies_requirements_of... + // ..., mpl::true_ + // ...> > + +# define BOOST_PARAMETER_satisfies(z, n, text) \ + mpl::and_< \ + aux::satisfies_requirements_of , + + 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 + , aux::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, = aux::void_ BOOST_PP_INTERCEPT + ) +#endif + > + struct match +# ifndef BOOST_NO_SFINAE + : match_base< + typename BOOST_PARAMETER_build_arg_list( + BOOST_PARAMETER_MAX_ARITY, aux::make_partial_arg_list, PS, A + )::type + >::type + {}; +# else + { + typedef parameters< + BOOST_PP_ENUM_PARAMS(BOOST_PARAMETER_MAX_ARITY, PS) + > 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 + typename + aux::make_arg_list > + ::type + operator()( A0 const& a0) const + { + typedef typename + aux::make_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 + typename + aux::make_arg_list< + PS0,A0 + , aux::make_arg_list< + PS1,A1 + , mpl::identity + > + > + ::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 + > + > + ::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, \ + )) +#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 + +#endif // BOOST_PARAMETERS_031014_HPP +