commit d0c5ddc28b915c639804f532a2aa0fab98ca177c Author: Daniel Wallin Date: Mon Apr 4 21:53:56 2005 +0000 Boost Parameter Library initial check in [SVN r27964] diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..3e84d7c --- /dev/null +++ b/.gitattributes @@ -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 diff --git a/include/boost/parameter/aux_/arg_list.hpp b/include/boost/parameter/aux_/arg_list.hpp new file mode 100755 index 0000000..737e9f8 --- /dev/null +++ b/include/boost/parameter/aux_/arg_list.hpp @@ -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 + +#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 + )) + {} + +#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 + 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 + struct apply + { + typedef Default type; + }; + }; + + template + T& get(default_ x) const + { + return x.value; + } + + template + typename F::result_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 F::result_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 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 + struct apply + : mpl::eval_if< + boost::is_same + , mpl::identity > + , mpl::apply_wrap1 + > + {}; + }; + + // 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 + struct apply + : mpl::eval_if< + boost::is_same + , mpl::identity + , mpl::apply_wrap2 + > + {}; + }; + + // Outer indexing operators that dispatch to the right node's + // get() function. + template + typename mpl::apply_wrap2::type& + operator[](keyword 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< + key_value_type,KW + , typename F::result_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. + value_type& get(keyword x) const + { + return arg.value; + } + + template + value_type& get(default_ x) const + { + return arg.value; + } + + template + value_type& get(lazy_default x) const + { + return arg.value; + } +#else + value_type& operator[](keyword x) const + { + return arg.value; + } + + template + value_type& operator[](default_ x) const + { + return arg.value; + } + + template + value_type& operator[](lazy_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 + 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, arg_list> + operator,(tagged_argument x) const + { + return arg_list, arg_list>(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/include/boost/parameter/aux_/default.hpp b/include/boost/parameter/aux_/default.hpp new file mode 100755 index 0000000..db26488 --- /dev/null +++ b/include/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) + : 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/include/boost/parameter/aux_/overloads.hpp b/include/boost/parameter/aux_/overloads.hpp new file mode 100755 index 0000000..06450c9 --- /dev/null +++ b/include/boost/parameter/aux_/overloads.hpp @@ -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 +// detail::arg_list< +// BOOST_DEDUCED_TYPENAME aux::as_tagged_argument::type +// , detail::arg_list< +// BOOST_DEDUCED_TYPENAME aux::as_tagged_argument::type +// > +// > +// operator()(const A0& a0, const A1& a1) const +// { +// typedef arg_list< +// BOOST_DEDUCED_TYPENAME aux::as_tagged_argument::type +// , arg_list< +// BOOST_DEDUCED_TYPENAME aux::as_tagged_argument::type +// ... +// > +// > arg_tuple; +// +// typename aux::as_tagged_argument::type tagged0(a0); +// typename aux::as_tagged_argument::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_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 + diff --git a/include/boost/parameter/aux_/parameter_requirements.hpp b/include/boost/parameter/aux_/parameter_requirements.hpp new file mode 100755 index 0000000..8a61464 --- /dev/null +++ b/include/boost/parameter/aux_/parameter_requirements.hpp @@ -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 +struct parameter_requirements +{ + typedef HasDefault has_default; +}; + +}}} // namespace boost::parameter::aux + +#endif // PARAMETER_REQUIREMENTS_050331_HPP + diff --git a/include/boost/parameter/aux_/tagged_argument.hpp b/include/boost/parameter/aux_/tagged_argument.hpp new file mode 100755 index 0000000..077160d --- /dev/null +++ b/include/boost/parameter/aux_/tagged_argument.hpp @@ -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 +#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; + + tagged_argument(Arg& 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()) + ); + } + + 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 + diff --git a/include/boost/parameter/aux_/unwrap_cv_reference.hpp b/include/boost/parameter/aux_/unwrap_cv_reference.hpp new file mode 100755 index 0000000..8841124 --- /dev/null +++ b/include/boost/parameter/aux_/unwrap_cv_reference.hpp @@ -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 +#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_ 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 cv +template +struct unwrap_cv_reference +{ + typedef typename mpl::eval_if< + is_cv_reference_wrapper + , T + , mpl::identity + >::type type; +}; + +}}} // namespace boost::parameter::aux + +#endif // UNWRAP_CV_REFERENCE_050328_HPP + diff --git a/include/boost/parameter/aux_/void.hpp b/include/boost/parameter/aux_/void.hpp new file mode 100755 index 0000000..0716e34 --- /dev/null +++ b/include/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/include/boost/parameter/aux_/yesno.hpp b/include/boost/parameter/aux_/yesno.hpp new file mode 100755 index 0000000..13fa545 --- /dev/null +++ b/include/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/include/boost/parameter/config.hpp b/include/boost/parameter/config.hpp new file mode 100755 index 0000000..e4fcc29 --- /dev/null +++ b/include/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/include/boost/parameter/keyword.hpp b/include/boost/parameter/keyword.hpp new file mode 100755 index 0000000..8ab5c86 --- /dev/null +++ b/include/boost/parameter/keyword.hpp @@ -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 +#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 +{ + template + aux::tagged_argument< + Tag + , typename aux::unwrap_cv_reference::type + > + operator=(T& x) const + { + return aux::tagged_argument< + Tag + , BOOST_DEDUCED_TYPENAME aux::unwrap_cv_reference::type + >(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, == 1200) // avoid partial ordering bugs + template + aux::tagged_argument< + Tag + , typename aux::unwrap_cv_reference::type + > + operator=(T const& x) const + { + return aux::tagged_argument< + Tag + , BOOST_DEDUCED_TYPENAME aux::unwrap_cv_reference::type + >(x); + } + + template + aux::default_ + operator|(const Default& default_) const + { + return aux::default_(default_); + } + + template + aux::lazy_default + operator||(Default const& default_) const + { + return aux::lazy_default(default_); + } +#endif +}; + +}} // namespace boost::parameter + +#endif // KEYWORD_050328_HPP + diff --git a/include/boost/parameter/parameter.hpp b/include/boost/parameter/parameter.hpp new file mode 100755 index 0000000..b6bd493 --- /dev/null +++ b/include/boost/parameter/parameter.hpp @@ -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 +#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 { + +// 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; +}; + +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 + 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 predicate<...>, below + template + struct get_predicate + { + typedef typename T::predicate 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 + { + typedef typename mpl::if_< + is_tagged_argument + , Arg + , tagged_argument< + typename key_type::type + , typename unwrap_cv_reference::type + > + >::type type; + }; + +#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 + { + BOOST_STATIC_CONSTANT( + bool, value = ( + sizeof( + aux::to_yesno( + ArgList::satisfies((ParameterRequirements*)0) + ) + ) == sizeof(yes_tag) + ) + ); + + typedef mpl::bool_ type; + }; + + // 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_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 + struct restrict_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< + 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 + 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 + +#include +#include +#include +#include +#include +#include + +#define BOOST_PARAMETER_FUN_TEMPLATE_HEAD1(n) \ + template + +#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 \ + 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 \ + ret BOOST_PP_CAT(name, _with_named_params)(const Params& p) + +#include + +#endif // BOOST_PARAMETER_031014_HPP +