Compare commits

...

2 Commits

Author SHA1 Message Date
Dave Abrahams
8344c78412 Rob Stewart's edits
[SVN r30164]
2005-07-18 19:59:22 +00:00
nobody
1abfa264f1 This commit was manufactured by cvs2svn to create branch 'robstewart'.
[SVN r30118]
2005-07-15 18:44:00 +00:00
29 changed files with 29 additions and 3626 deletions

View File

@@ -1,17 +0,0 @@
import docutils ;
path-constant docutils-css : ../../iterator/doc/default.css ;
import path ;
sources = [ path.glob . : *.rst ] ;
bases = $(sources:S=) ;
for local b in $(bases)
{
html $(b) : $(b).rst :
<docutils-html>"-gdt --traceback --trim-footnote-reference-space --footnote-references=superscript --embed-stylesheet --stylesheet-path="$(docutils-css)
;
}
alias htmls : $(bases) ;
stage html : $(bases) ;

File diff suppressed because it is too large Load Diff

View File

@@ -25,7 +25,7 @@ __ ../../../../index.htm
:Authors: David Abrahams, Daniel Wallin
:Contact: dave@boost-consulting.com, dalwan01@student.umu.se
:organization: `Boost Consulting`_
:date: $Date: 2005/07/15 16:16:26 $
:date: $Date: 2005/07/15 18:43:59 $
:copyright: Copyright David Abrahams, Daniel Wallin
2005. Distributed under the Boost Software License,
@@ -62,7 +62,7 @@ __ ../../../../index.htm
In C++, arguments are normally given meaning by their positions
with respect to a parameter list. That protocol is fine when there
are one or fewer parameters with default values, but when there are
is at most one parameter with a default value, but when there are
even a few useful defaults, the positional interface becomes
burdensome:
@@ -197,6 +197,11 @@ The Graph library's |dfs| algorithm is a generic function accepting
between one and four arguments by reference, as shown in the table
below:
.. RS -- Seeing the function described via table is harder to
grasp. I suggest showing the function signature first, but omit
the defaults for clarity. That will provide parameter names, in
context, which will make the connection to the table simpler.
.. _`parameter table`:
.. _`default expressions`:
@@ -209,14 +214,14 @@ below:
+----------------+----------+----------------------------------+
|``visitor`` | in |``boost::dfs_visitor<>()`` |
+----------------+----------+----------------------------------+
|``root_vertex`` | in |``*vertices(g).first`` |
|``root_vertex`` | in |``*vertices(graph).first`` |
+----------------+----------+----------------------------------+
|``index_map`` | in |``get(boost::vertex_index,graph)``|
+----------------+----------+----------------------------------+
|``color_map`` | out |an ``iterator_property_map`` |
| | |created from a ``std::vector`` of |
| | |``default_color_type`` of size |
| | |``num_vertices(g)`` and using the |
| | |``num_vertices(graph)`` and using |
| | |``index_map`` for the index map. |
+----------------+----------+----------------------------------+
@@ -300,9 +305,8 @@ the core of ``depth_first_search``::
parameter: a bundle of references to the arguments that the caller
passes to the algorithm, tagged with their keywords. To extract
each parameter, just pass its keyword object to the
|ArgumentPack|\ 's index operator. We'll add some
temporary code to print the arguments, just to get a feel for how
it works:
|ArgumentPack|\ 's subscript operator. Just to get a feel for how
things work, let's add some temporary code to print the arguments:
.. parsed-literal::
@@ -336,7 +340,7 @@ keywords in action, we can write a little test driver:
}
An overloaded comma operator (``operator,``) combines the results
of assigning into each keyword object into a single |ArgumentPack|
of assigning to each keyword object into a single |ArgumentPack|
object that gets passed on to ``core::depth_first_search``. The
extra set of parentheses you see in the example above are required:
without them, each assignment would be interpreted as a separate
@@ -369,7 +373,7 @@ Adding Defaults
Currently, all the arguments to ``depth_first_search`` are
required. If any parameter can't be found, there will be a
compilation error where we try to extract it from the
|ArgumentPack| using the square-brackets operator. To make it
|ArgumentPack| using the subscript operator. To make it
legal to omit an argument we need to give it a default value.
Syntax
@@ -377,7 +381,7 @@ Syntax
We can make any of the parameters optional by following its keyword
with the ``|`` operator and the parameter's default value within
the brackets. In the following example, we've given
the square brackets. In the following example, we've given
``root_vertex`` a default of ``42`` and ``color_map`` a default of
``"hello, world"``.
@@ -414,7 +418,7 @@ The call above would print::
The index expression ``args[…]`` always yields a *reference*
that is bound either to the actual argument passed by the caller
or, if no argument is explicitly specified, to the specified
or, if no argument is passed explicitly, to the specified
default value.
Getting More Realistic
@@ -422,7 +426,7 @@ Getting More Realistic
Now it's time to put some more realistic defaults in place. We'll
have to give up our print statements—at least if we want to see the
defaults work—because as we mentioned, the default values of these
defaults work—since, the default values of these
parameters generally aren't printable.
Instead, we'll connect local variables to the arguments and use
@@ -475,7 +479,7 @@ For example, to declare and initialize ``g`` above, we could write:
As shown in the `parameter table`_, ``graph`` has no default, so
the ``binding`` invocation for *Graph* takes only two arguments.
The default ``visitor`` is ``boost::dfs_visitor<>()``, so the
``binding`` invocation for *Visitor* takes three:
``binding`` invocation for *Visitor* takes three arguments:
.. parsed-literal::
@@ -530,7 +534,7 @@ parameter:
Index i = args[index_map|\ **get(boost::vertex_index,g)**\ ];
We'd like you to notice two capabilities we've gained over what
Notice two capabilities we've gained over what
plain C++ default arguments provide:
1. The default value of the ``index`` parameter depends on the
@@ -600,7 +604,7 @@ Forwarding Functions
Next we need a family of overloaded ``depth_first_search`` function
templates that can be called with anywhere from one to five
arguments. These forwarding functions will invoke an instance of
arguments. These *forwarding functions* will invoke an instance of
``dfs_params`` as a function object, passing their parameters
to its ``operator()`` and forwarding the result on to
``core::depth_first_search``::
@@ -640,8 +644,9 @@ is passed positionally. As you may recall from the
``depth_first_search`` `parameter table`_, ``color_map`` is an
“out” parameter. That means the five-argument
``depth_first_search`` overload should really take its final
argument by non-``const`` reference. On the other hand, assigning
into a keyword object yields a temporary |ArgumentPack| object, and
argument by non-``const`` reference. On the other hand, when
passing arguments by keyword, the keyword object's assignment
operator yields a temporary |ArgumentPack| object, and
a conforming C++ compiler will refuse to bind a non-``const``
reference to a temporary. To support an interface in which the
last argument is passed by keyword, there must be a
@@ -745,12 +750,12 @@ parameters are required, and optionally pass ``Predicate``\ s to
describe the type requirements for each function parameter.
The ``Predicate`` argument must be a unary `MPL
lambda expression`_ that, when applied to the
actual type the argument, indicates whether that argument type
actual type of the argument, indicates whether that argument type
meets the function's requirements for that parameter position.
.. _`MPL lambda expression`: ../../../mpl/doc/refmanual/lambda-expression.html
For example, let's say we want to restrict our ``foo()`` so that
For example, let's say we want to restrict our ``depth_first_search()`` so that
the ``graph`` parameter is required and the ``root_vertex``
parameter is convertible to ``int``. We might write:
@@ -775,8 +780,8 @@ parameter is convertible to ``int``. We might write:
{};
}
Now we can add an additional optional argument to each of our
``depth_first_search`` overloads:
Now we add an additional defaulted argument to each of our
``depth_first_search`` overloads, to trigger SFINAE:
.. parsed-literal::
@@ -814,7 +819,7 @@ These additional parameters are not intended to be used directly
by callers; they merely trigger SFINAE by becoming illegal types
when the ``name`` argument is not convertible to ``const
char*``. The ``BOOST_PARAMETER_FUN`` macro described earlier
actually adds these extra function parameters.
adds these extra function parameters for you.
Efficiency Issues
=================
@@ -838,7 +843,7 @@ Eliminating Copies
------------------
The library has no way to know whether an explicitly-supplied
argument is expensive to copy (or even if it is copiable at all),
argument is expensive to copy (or even if it is copyable at all),
so ``binding<…,k,…>::type`` is always a reference type when the
*k* parameter is supplied by the caller. Since ``args[…]``
yields a reference to the actual argument, ``color`` will be bound
@@ -887,7 +892,7 @@ that—if no argument was supplied by the caller—will be invoked to
construct the default value. Instead of following the keyword with
the ``|`` operator, we'll use ``||`` and follow it with a
nullary (zero-argument) function object that constructs a
default_color_map. The function object is built using
default_color_map. Here, we build the function object using
Boost.Lambda_: [#bind]_
.. _Boost.Lambda: ../../../lambda/index.html

View File

@@ -1,304 +0,0 @@
=========================================
Boost.Parameter Reference Documentation
=========================================
.. contents::
:depth: 1
//////////////////////////////////////////////////////////////////////////////
.. role:: class
:class: class
.. role:: concept
:class: concept
.. role:: function
:class: function
.. class:: reference
class template :class:`keyword`
------------------------------------
TODO Introduction
**Models**
:concept:`IndexExpression`
.. parsed-literal::
template <class Tag>
struct keyword
{
template <class T>
:concept:`KeywordTuple` `operator=`_\(T& value) const;
template <class T>
:concept:`KeywordTuple` `operator=`_\(T const& value) const;
template <class T>
:concept:`IndexDefaultExpression` `operator|`_\(T& default\_) const;
template <class T>
:concept:`IndexDefaultExpression` `operator|`_\(T const& default\_) const;
template <class F>
:concept:`IndexDefaultExpression` `operator||`_\(F const&) const;
};
operator=
~~~~~~~~~
.. parsed-literal::
template <class T> :concept:`KeywordTuple` operator=(T& value) const;
template <class T> :concept:`KeywordTuple` operator=(T const& value) const;
**Requires**
Nothing.
**Returns**
A model of :concept:`KeywordTuple`, holding a *cv* reference to ``value``,
tagged with ``Tag``.
operator|
~~~~~~~~~
.. parsed-literal::
template <class T> :concept:`IndexDefaultExpression` operator|(T& default\_) const;
template <class T> :concept:`IndexDefaultExpression` operator|(T const& default\_) const;
**Requires**
Nothing
**Returns**
An object that models :concept:`IndexDefaultExpression`, that when used as
an argument to ``ArgumentTuple::operator[]`` which doesn't contain
a parameter specified with ``Tag`` returns ``default_``.
operator||
~~~~~~~~~~
.. parsed-literal::
template <class F> :concept:`IndexDefaultExpression` operator|(F const& fn) const;
**Requires**
``F`` is a nullary function object.
**On compilers that support partial specialization:**
+---------------------------------+-----------------------------------------------------+
| Expression | Requirement |
+=================================+=====================================================+
| ``boost::result_of<F()>::type`` | :concept:`CopyConstructible` |
+---------------------------------+-----------------------------------------------------+
| ``fn()`` | Convertible to ``boost::result_of<F()>::type`` |
+---------------------------------+-----------------------------------------------------+
**On compilers that doesn't support partial specialization:**
+------------------------------+-----------------------------------------------------+
| Expression | Requirement |
+==============================+=====================================================+
| ``F::result_type`` | :concept:`CopyConstructible` |
+------------------------------+-----------------------------------------------------+
| ``fn()`` | Convertible to ``F::result_type`` |
+------------------------------+-----------------------------------------------------+
**Returns**
An object that models :concept:`IndexDefaultExpression`, that when used as
an argument to ``ArgumentTuple::operator[]`` which doesn't contain
a parameter specified with ``Tag`` evaluates and returns ``fn()``.
//////////////////////////////////////////////////////////////////////////////
.. class:: reference
class template :class:`parameters`
---------------------------------------------------
.. parsed-literal::
template <class P0, class P1, ..., class PN>
struct parameters
{
template <class T0, class T1, ..., class TN>
struct `restrict`_
{
...
};
template <class A0>
:concept:`KeywordTuple` `operator()`_\(A0 const& a0) const;
template <class A0, class A1>
:concept:`KeywordTuple` `operator()`_\(A0 const& a0, A1 const& a1) const;
template <class A0, class A1, ..., class An>
:concept:`KeywordTuple` `operator()`_\(A0 const& a0, A1 const& a1, ..., An const& an) const;
};
Template Parameter Semantics
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
TODO
restrict
~~~~~~~~
.. parsed-literal::
template <class T0, class T1, ..., class TN> struct restrict { ... };
**Requires**
Nothing
**Returns**
TODO
operator()
~~~~~~~~~~
.. parsed-literal::
template <class A0> :concept:`KeywordTuple` operator()(A0 const& a0) const;
template <class A0, class A1> :concept:`KeywordTuple` operator()(A0 const& a0, A1 const& a1) const;
...
**Requires**
TODO
**Returns**
TODO
//////////////////////////////////////////////////////////////////////////////
.. class:: reference
class template :class:`required`
-------------------------------------------------------------
.. parsed-literal::
template <class Tag, class Predicate = *unspecified*>
struct required;
//////////////////////////////////////////////////////////////////////////////
.. class:: reference
class template :class:`optional`
-------------------------------------------------------------
.. parsed-literal::
template <class Tag, class Predicate = *unspecified*>
struct optional;
//////////////////////////////////////////////////////////////////////////////
.. class:: reference
class template :class:`binding`
-------------------------------------------------------------
A metafunction that, given an :concept:`ArgumentTuple`, returns the reference
type of the parameter identified by ``Keyword``. If no such parameter has been
specified, returns ``Default``.
.. parsed-literal::
template <class Parameters, class Keyword, class Default = *unspecified*>
struct binding
{
typedef ... type;
};
.. class:: reference
//////////////////////////////////////////////////////////////////////////////
class template :class:`lazy_binding`
------------------------------------------------------------------
A metafunction that, given an :concept:`ArgumentTuple`, returns the reference
type of the parameter identified by ``Keyword``. If no such parameter has been
specified, returns the type returned by invoking ``DefaultFn``.
.. parsed-literal::
template <class Parameters, class Keyword, class DefaultFn>
struct lazy_binding
{
typedef ... type;
};
Requirements
~~~~~~~~~~~~
``DefaultFn`` is a nullary function object. The type returned by invoking this
function is determined by ``boost::result_of<DefaultFn()>::type`` on compilers
that support partial specialization. On less compliant compilers a nested
``DefaultFn::result_type`` is used instead.
.. class:: reference
//////////////////////////////////////////////////////////////////////////////
concept :concept:`IndexExpression`, :concept:`IndexDefaultExpression`
---------------------------------------------------------------------
Models of these concepts are used as indices in a :concept:`KeywordTuple`.
.. class:: reference
//////////////////////////////////////////////////////////////////////////////
concept :concept:`KeywordTuple`
-------------------------------
.. Rename this?
Models of this concept are containers of parameters where each parameter
is tagged with a keyword.
Requirements
~~~~~~~~~~~~
* ``x`` and ``z`` are objects that model :concept:`KeywordTuple`.
* ``y`` is a model if :concept:`IndexExpression`.
* ``u`` is a model if :concept:`IndexDefaultExpression`.
* ``X`` is the type of ``x``.
* ``K`` is the tag type used in ``y`` and ``u``.
* ``D`` is the type of the default value in ``u``.
+---------------+-----------------------------+------------------------------------------------+
| Expression | Type | Notes |
+===============+=============================+================================================+
|``x[y]`` | binding<X, K>::type | Returns the bound argument tagged with ``K``. |
+---------------+-----------------------------+------------------------------------------------+
|``x[u]`` | binding<X, K, D>::type | Returns the bound argument tagged with ``K``. |
+---------------+-----------------------------+------------------------------------------------+
|``x, z`` | :concept:`KeywordTuple` | Returns a composite KeywordTuple. |
+---------------+-----------------------------+------------------------------------------------+

View File

@@ -1,16 +0,0 @@
// Copyright David Abrahams, Daniel Wallin 2005. Use, modification and
// distribution is subject to the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_PARAMETER_050401_HPP
#define BOOST_PARAMETER_050401_HPP
#include <boost/parameter/parameters.hpp>
#include <boost/parameter/keyword.hpp>
#include <boost/parameter/binding.hpp>
#include <boost/parameter/macros.hpp>
#include <boost/parameter/match_args.hpp>
#endif // BOOST_PARAMETER_050401_HPP

View File

@@ -1,325 +0,0 @@
// 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/type_traits/add_reference.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/facilities/intercept.hpp>
#include <boost/parameter/aux_/void.hpp>
#include <boost/parameter/aux_/result_of0.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
))
{}
// 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<class KW, class Default>
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<class KW>
struct apply
{
typedef empty_arg_list type;
};
};
template <class K, class T>
T& get(default_<K,T> x) const
{
return x.value;
}
template <class K, class F>
typename result_of0<F>::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 result_of0<F>::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;
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 <class KW, class Default>
struct apply
{
typedef typename mpl::eval_if<
boost::is_same<KW, key_type>
, mpl::identity<reference>
, mpl::apply_wrap2<typename Next::binding, KW, Default>
>::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<class KW>
struct apply
{
typedef typename mpl::eval_if<
boost::is_same<KW, key_type>
, mpl::identity<arg_list<TaggedArg,Next> >
, mpl::apply_wrap1<typename Next::key_owner,KW>
>::type type;
};
};
// Outer indexing operators that dispatch to the right node's
// get() function.
template <class KW>
typename mpl::apply_wrap2<binding, KW, void_>::type
operator[](keyword<KW> const& 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<binding, 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<
binding,KW
, typename result_of0<F>::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.
reference get(keyword<key_type> const& x) const
{
return arg.value;
}
template <class Default>
reference get(default_<key_type,Default> x) const
{
return arg.value;
}
template <class Default>
reference get(lazy_default<key_type, Default> x) const
{
return arg.value;
}
#else
reference operator[](keyword<key_type> const& x) const
{
return arg.value;
}
template <class Default>
reference operator[](default_<key_type, Default> x) const
{
return arg.value;
}
template <class Default>
reference 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
#if !BOOST_WORKAROUND(__BORLANDC__,BOOST_TESTED_AT(0x564))
// 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);
}
#endif
};
#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

@@ -1,67 +0,0 @@
// 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)
: compute_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

@@ -1,70 +0,0 @@
// 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>
// 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 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<aux::empty_arg_list> \
BOOST_PP_REPEAT(N, BOOST_PARAMETER_close_list, _)
template<BOOST_PP_ENUM_PARAMS(N, class A)>
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

View File

@@ -1,25 +0,0 @@
// 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 Keyword keyword;
typedef Predicate predicate;
typedef HasDefault has_default;
};
}}} // namespace boost::parameter::aux
#endif // PARAMETER_REQUIREMENTS_050331_HPP

View File

@@ -1,34 +0,0 @@
// 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
// A metafunction returning the result of invoking a nullary function
// object of the given type.
#if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
# include <boost/utility/result_of.hpp>
namespace boost { namespace parameter { namespace aux {
template <class F>
struct result_of0 : result_of<F()>
{};
}}} // namespace boost::parameter::aux_
#else
namespace boost { namespace parameter { namespace aux {
template <class F>
struct result_of0
{
typedef typename F::result_type type;
};
}}} // namespace boost::parameter::aux_
#endif
#endif // BOOST_PARAMETER_AUX__RESULT_OF0_DWA2005511_HPP

View File

@@ -1,40 +0,0 @@
// 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 <boost/parameter/aux_/unwrap_cv_reference.hpp>
namespace boost { namespace parameter { namespace aux {
template <class Keyword, class Arg>
struct tagged_argument;
template <class Keyword, class ActualArg
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
, class = typename is_cv_reference_wrapper<ActualArg>::type
#endif
>
struct tag
{
typedef tagged_argument<
Keyword
, typename unwrap_cv_reference<ActualArg>::type
> type;
};
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
template <class Keyword, class ActualArg>
struct tag<Keyword,ActualArg,mpl::false_>
{
typedef tagged_argument<
Keyword
, ActualArg
> type;
};
#endif
}}} // namespace boost::parameter::aux_
#endif // BOOST_PARAMETER_AUX_TAG_DWA2005610_HPP

View File

@@ -1,54 +0,0 @@
// 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;
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 <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())
);
}
reference 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

@@ -1,97 +0,0 @@
// 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_<
#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<int>
: 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 <class T>
struct get_type
{
typedef typename T::type type;
};
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
template <class T, class is_reference_wrapper = typename is_cv_reference_wrapper<T>::type>
struct unwrap_cv_reference
{
typedef T type;
};
template <class T>
struct unwrap_cv_reference<T const, mpl::false_>
{
typedef T const type;
};
template <class T>
struct unwrap_cv_reference<T, mpl::true_>
: 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<U> cv
template <class T>
struct unwrap_cv_reference
{
typedef typename mpl::eval_if<
is_cv_reference_wrapper<T>
, get_type<T>
, mpl::identity<T>
>::type type;
};
#endif
}}} // namespace boost::parameter::aux
#endif // UNWRAP_CV_REFERENCE_050328_HPP

View File

@@ -1,18 +0,0 @@
// 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

@@ -1,26 +0,0 @@
// 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

@@ -1,57 +0,0 @@
// 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 <boost/mpl/apply.hpp>
# include <boost/parameter/aux_/result_of0.hpp>
# include <boost/parameter/aux_/void.hpp>
# if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
# include <boost/parameter/aux_/void.hpp>
# include <boost/type_traits/is_same.hpp>
# 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 <class Parameters, class Keyword, class Default = void>
struct binding
: mpl::apply_wrap2<
typename Parameters::binding,Keyword,Default
>
{};
# else
template <class Parameters, class Keyword, class Default = aux::void_>
struct binding
{
typedef typename mpl::apply_wrap2<
typename Parameters::binding,Keyword,
typename mpl::if_<is_same<Default,aux::void_>,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 <class Parameters, class Keyword, class DefaultFn>
struct lazy_binding
{
typedef typename mpl::apply_wrap2<
typename Parameters::binding
, Keyword
, typename aux::result_of0<DefaultFn>::type
>::type type;
};
}} // namespace boost::parameter
#endif // BOOST_PARAMETER_BINDING_DWA200558_HPP

View File

@@ -1,14 +0,0 @@
// 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

@@ -1,119 +0,0 @@
// 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_/tag.hpp>
#include <boost/parameter/aux_/default.hpp>
#include <boost/noncopyable.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 : noncopyable
{
template <class T>
typename aux::tag<Tag, T>::type
operator=(T& x) const
{
typedef typename aux::tag<Tag, T>::type result;
return result(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>
typename aux::tag<Tag, T const>::type
operator=(T const& x) const
{
typedef typename aux::tag<Tag, T const>::type result;
return result(x);
}
#endif
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1200) // avoid partial ordering bugs
template <class Default>
aux::default_<Tag, const Default>
operator|(const Default& default_) const
#if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
volatile
#endif
{
return aux::default_<Tag, const Default>(default_);
}
template <class Default>
aux::lazy_default<Tag, Default>
operator||(Default const& default_) const
#if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
volatile
#endif
{
return aux::lazy_default<Tag, 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<Tag>& get()
{
static keyword<Tag> 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
//
#define BOOST_PARAMETER_KEYWORD(tag_namespace,name) \
namespace tag_namespace { struct name; } \
::boost::parameter::keyword<tag_namespace::name>& name \
= ::boost::parameter::keyword<tag_namespace::name>::get()
}} // namespace boost::parameter
#endif // KEYWORD_050328_HPP

View File

@@ -1,98 +0,0 @@
// 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 <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>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/cat.hpp>
#define BOOST_PARAMETER_FUN_TEMPLATE_HEAD1(n) \
template<BOOST_PP_ENUM_PARAMS(n, class T)>
#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<class Params>
// ret name ## _with_named_params(Params const&);
//
// template<class T0>
// ret name(T0 const& p0, typename parameters::match<T0>::type kw = parameters())
// {
// return name ## _with_named_params(kw(p0));
// }
//
// template<class T0, ..., class TN>
// ret name(T0 const& p0, ..., TN const& PN
// , typename parameters::match<T0, ..., TN>::type kw = parameters())
// {
// return name ## _with_named_params(kw(p0, ..., pN));
// }
//
// template<class Params>
// 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<class Params> \
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<class Params> \
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<class Params> \
ret BOOST_PP_CAT(name, _with_named_params)(Params const& p)
#endif // BOOST_PARAMETER_MACROS_050412_HPP

View File

@@ -1,29 +0,0 @@
// 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_ARGS_DWA2005714_HPP
# define BOOST_PARAMETER_MATCH_ARGS_DWA2005714_HPP
# include <boost/detail/workaround.hpp>
# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
# include <boost/parameter/config.hpp>
# include <boost/parameter/aux_/void.hpp>
# include <boost/preprocessor/arithmetic/sub.hpp>
# include <boost/preprocessor/facilities/intercept.hpp>
# include <boost/preprocessor/repetition/enum_trailing_params.hpp>
# define BOOST_PARAMETER_MATCH_ARGS(N) \
BOOST_PP_ENUM_TRAILING_PARAMS( \
BOOST_PP_SUB(BOOST_PARAMETER_MAX_ARITY,N) \
, ::boost::parameter::aux::void_ BOOST_PP_INTERCEPT \
)
# else
# define BOOST_PARAMETER_MATCH_ARGS(N)
# endif
#endif // BOOST_PARAMETER_MATCH_ARGS_DWA2005714_HPP

View File

@@ -1,456 +0,0 @@
// Copyright David Abrahams, Daniel Wallin 2003. Use, modification and
// distribution is subject to the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_PARAMETERS_031014_HPP
#define BOOST_PARAMETERS_031014_HPP
#include <boost/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/type_traits/remove_reference.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/aux_/tag.hpp>
#include <boost/parameter/config.hpp>
namespace boost {
template<class T> class reference_wrapper;
namespace parameter {
namespace aux { struct use_default {}; }
// These templates can be used to describe the treatment of particular
// named parameters for the purposes of overload elimination with
// SFINAE, by placing specializations in the parameters<...> list. In
// order for a treated function to participate in overload resolution:
//
// - all keyword tags wrapped in required<...> must have a matching
// actual argument
//
// - The actual argument type matched by every keyword tag
// associated with a predicate must satisfy that predicate
//
// If a keyword k is specified without an optional<...> or
// required<...>, wrapper, it is treated as though optional<k> were
// specified.
//
template <class Tag, class Predicate = aux::use_default>
struct required
{
typedef Tag key_type;
typedef Predicate predicate;
};
template <class Tag, class Predicate = aux::use_default>
struct optional
{
typedef Tag key_type;
typedef Predicate predicate;
};
template <class Tag>
struct unnamed
{
typedef Tag key_type;
};
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 get_predicate<...>, below
template <class T>
struct get_predicate_or_default
{
typedef T type;
};
template <>
struct get_predicate_or_default<use_default>
{
typedef mpl::always<mpl::true_> type;
};
// helper for predicate<...>, below
template <class T>
struct get_predicate
{
typedef typename
get_predicate_or_default<typename T::predicate>::type
type;
};
template <class T>
struct predicate
: mpl::eval_if<
mpl::or_<
is_optional<T>
, is_required<T>
>
, get_predicate<T>
, mpl::identity<mpl::always<mpl::true_> >
>
{
};
// Converts a ParameterSpec into a specialization of
// parameter_requirements. We need to do this in order to get the
// 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
: mpl::eval_if<
is_tagged_argument<Arg>
, mpl::identity<Arg>
, tag<typename key_type<DefaultTag>::type, Arg const>
>
{};
#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
{
#if BOOST_WORKAROUND(BOOST_MSVC, == 1310)
// VC7.1 can't handle the sizeof() implementation below,
// so we use this instead.
typedef typename mpl::apply_wrap2<
typename ArgList::binding
, typename ParameterRequirements::keyword
, void_
>::type bound;
typedef typename mpl::eval_if<
is_same<bound, void_>
, typename ParameterRequirements::has_default
, mpl::apply1<
typename ParameterRequirements::predicate
, typename remove_reference<bound>::type
>
>::type type;
#else
BOOST_STATIC_CONSTANT(
bool, value = (
sizeof(
aux::to_yesno(
ArgList::satisfies((ParameterRequirements*)0)
)
) == sizeof(yes_tag)
)
);
typedef mpl::bool_<satisfies::value> type;
#endif
};
// Returns mpl::true_ if the requirements of the given ParameterSpec
// are satisfied by ArgList.
template <class ArgList, class ParameterSpec>
struct satisfies_requirements_of
: satisfies<
ArgList
, typename as_parameter_requirements<ParameterSpec>::type
>
{};
// 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_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 <class NamedList>
struct match_base
: mpl::if_<
// mpl::and_<
// aux::satisfies_requirements_of<NamedList,PS0>
// , mpl::and_<
// aux::satisfies_requirements_of<NamedList,PS1>...
// ..., mpl::true_
// ...> >
# define BOOST_PARAMETER_satisfies(z, n, text) \
mpl::and_< \
aux::satisfies_requirements_of<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<
#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<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/iterator/detail/config_undef.hpp>
#endif // BOOST_PARAMETERS_031014_HPP

View File

@@ -1,12 +0,0 @@
<!-- 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) -->
<html>
<head>
<meta http-equiv="refresh" content="0; URL=doc/html/index.html">
</head>
<body>
Automatically loading index page... if nothing happens, please go to
<a href="doc/html/index.html">doc/html/index.html</a>.
</body>
</html>

View File

@@ -1,14 +0,0 @@
# Boost Parameter Library test Jamfile
subproject libs/parameter/test ;
# bring in rules for testing
import testing ;
test-suite "parameter"
: [ run basics.cpp ]
[ run sfinae.cpp ]
[ run macros.cpp ]
[ compile unwrap_cv_reference.cpp ]
;

View File

@@ -1,8 +0,0 @@
# Boost Parameter Library test Jamfile
test-suite "parameter"
: [ run basics.cpp ]
[ run sfinae.cpp ]
[ run macros.cpp ]
[ compile unwrap_cv_reference.cpp ]
;

View File

@@ -1,112 +0,0 @@
// Copyright David Abrahams, Daniel Wallin 2003. Use, modification and
// distribution is subject to the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/parameter.hpp>
#include <cassert>
#include <string.h>
#include <boost/bind.hpp>
#include <boost/ref.hpp>
#include "basics.hpp"
namespace test
{
// A separate function for getting the "value" key, so we can deduce
// F and use lazy_binding on it.
template <class Params, class F>
typename boost::parameter::lazy_binding<Params,tag::value,F>::type
extract_value(Params const& p, F const& f)
{
typename boost::parameter::lazy_binding<
Params, tag::value, F
>::type v = p[value || f ];
return v;
}
template<class Params>
int f_impl(Params const& p)
{
typename boost::parameter::binding<Params, tag::name>::type
n = p[name];
typename boost::parameter::binding<
Params, tag::value, double
>::type v = extract_value(p, boost::bind(&value_default));
typename boost::parameter::binding<
Params, tag::index, int
>::type i =
#if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042))
p[test::index | 999];
#else
p[index | 999];
#endif
p[tester](n,v,i);
return 1;
}
template<class Tester, class Name, class Value, class Index>
int f(Tester const& t, const Name& name_,
const Value& value_, const Index& index_)
{
return f_impl(f_parameters()(t, name_, value_, index_));
}
template<class Tester, class Name, class Value>
int f(Tester const& t, const Name& name_, const Value& value_)
{
return f_impl(f_parameters()(t, name_, value_));
}
template<class Tester, class Name>
int f(Tester const& t, const Name& name_)
{
return f_impl(f_parameters()(t, name_));
}
template<class Params>
int f_list(Params const& params)
{
return f_impl(params);
}
}
int main()
{
using test::f;
using test::f_list;
using test::name;
using test::value;
using test::index;
using test::tester;
f(
test::values(S("foo"), S("bar"), S("baz"))
, S("foo"), S("bar"), S("baz")
);
int x = 56;
f(
test::values("foo", 666.222, 56)
, index = boost::ref(x), name = "foo"
);
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
// No comma operator available on Borland
f_list((
tester = test::values("foo", 666.222, 56)
, index = boost::ref(x)
, name = "foo"
));
#endif
//f(index = 56, name = 55); // won't compile
return 0;
}

View File

@@ -1,105 +0,0 @@
// Copyright David Abrahams, Daniel Wallin 2005. Use, modification and
// distribution is subject to the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BASICS_050424_HPP
#define BASICS_050424_HPP
#include <boost/static_assert.hpp>
#include <boost/parameter/keyword.hpp>
namespace test {
BOOST_PARAMETER_KEYWORD(tag, name);
BOOST_PARAMETER_KEYWORD(tag, value);
BOOST_PARAMETER_KEYWORD(tag, index);
BOOST_PARAMETER_KEYWORD(tag, tester);
using namespace boost::parameter;
struct f_parameters // vc6 is happier with inheritance than with a typedef
: parameters<
tag::tester
, tag::name
, tag::value
, tag::index
>
{};
inline double value_default()
{
return 666.222;
}
template <class T>
inline bool equal(T const& x, T const& y)
{
return x == y;
}
inline bool equal(char const* s1, char const* s2)
{
return !strcmp(s1,s2);
}
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
inline bool equal(char* s1, char* s2)
{
return !strcmp(s1,s2);
}
#endif
template <class Name, class Value, class Index>
struct values_t
{
values_t(Name const& n, Value const& v, Index const& i)
: n(n), v(v), i(i)
{}
template <class Name_, class Value_, class Index_>
void operator()(Name_ const& n_, Value_ const& v_, Index_ const& i_) const
{
// Only VC and its emulators fail this; they seem to have
// problems with deducing the constness of string literal
// arrays.
#if defined(_MSC_VER) \
&& (BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, <= 700) \
|| BOOST_WORKAROUND(BOOST_MSVC, < 1310)) \
|| BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
# else
BOOST_STATIC_ASSERT((boost::is_same<Index,Index_>::value));
BOOST_STATIC_ASSERT((boost::is_same<Value,Value_>::value));
BOOST_STATIC_ASSERT((boost::is_same<Name,Name_>::value));
#endif
assert(equal(n, n_));
assert(equal(v, v_));
assert(equal(i, i_));
}
Name const& n;
Value const& v;
Index const& i;
};
template <class Name, class Value, class Index>
inline values_t<Name,Value,Index>
values(Name const& n, Value const& v, Index const& i)
{
return values_t<Name,Value,Index>(n,v,i);
}
} // namespace test
// GCC2 has a problem with char (&)[] deduction, so we'll cast string
// literals there.
#undef S
#if BOOST_WORKAROUND(__GNUC__, == 2) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
# define S(s) (char const*)s
#else
# define S(s) s
#endif
#endif // BASICS_050424_HPP

View File

@@ -1,57 +0,0 @@
// Copyright David Abrahams, Daniel Wallin 2003. Use, modification and
// distribution is subject to the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/parameter.hpp>
#include <boost/parameter/macros.hpp>
#include <boost/bind.hpp>
#include <boost/static_assert.hpp>
#include <boost/ref.hpp>
#include <cassert>
#include <string.h>
#include "basics.hpp"
namespace test
{
BOOST_PARAMETER_FUN(int, f, 2, 4, f_parameters)
{
p[tester](
p[name]
, p[value || boost::bind(&value_default) ]
#if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042))
, p[test::index | 999 ]
#else
, p[index | 999 ]
#endif
);
return 1;
}
} // namespace test
int main()
{
using test::f;
using test::name;
using test::value;
using test::index;
using test::tester;
f(
test::values(S("foo"), S("bar"), S("baz"))
, S("foo"), S("bar"), S("baz")
);
int x = 56;
f(
test::values("foo", 666.222, 56)
, index = boost::ref(x), name = "foo"
);
return 0;
}

View File

@@ -1,104 +0,0 @@
// Copyright David Abrahams, Daniel Wallin 2003. Use, modification and
// distribution is subject to the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt
#include <boost/parameter.hpp>
#include <cassert>
#include <string>
#include <boost/type_traits/is_convertible.hpp>
#include <iostream>
#ifndef BOOST_NO_SFINAE
# include <boost/utility/enable_if.hpp>
# include <boost/type_traits/is_same.hpp>
#endif
namespace test
{
BOOST_PARAMETER_KEYWORD(keywords,name);
BOOST_PARAMETER_KEYWORD(keywords,value);
using namespace boost::parameter;
struct f_parameters
: parameters<
optional<
keywords::name
, boost::is_convertible<boost::mpl::_, std::string>
>
, optional<
keywords::value
, boost::is_convertible<boost::mpl::_, float>
>
>
{};
template <class T> struct not_implemented;
template<class P>
void f_impl(P const& p)
{
std::string s = p[name | "bar"];
float v = p[value | 3.f];
assert(s == "foo");
assert(v == 3.f);
}
void f()
{
f_impl(f_parameters()());
}
using boost::parameter::aux::void_;
template<class A0>
void f(
A0 const& a0
, typename f_parameters::match<A0 BOOST_PARAMETER_MATCH_ARGS(1)>::type args = f_parameters())
{
f_impl(args(a0));
}
template<class A0, class A1>
void f(
A0 const& a0, A1 const& a1
, typename f_parameters::match<A0, A1 BOOST_PARAMETER_MATCH_ARGS(2)>::type args = f_parameters())
{
f_impl(args(a0, a1));
}
#ifndef BOOST_NO_SFINAE
// On compilers that actually support SFINAE, add another overload
// that is an equally good match and can only be in the overload set
// when the others are not. This tests that the SFINAE is actually
// working. On all other compilers we're just checking that
// everything about SFINAE-enabled code will work, except of course
// the SFINAE.
template<class A0, class A1>
typename boost::enable_if<boost::is_same<int,A0>, int>::type
f(A0 const& a0, A1 const& a1)
{
return 0;
}
#endif
} // namespace test
int main()
{
using test::name;
using test::value;
using test::f;
f("foo");
f("foo", 3.f);
f(value = 3.f, name = "foo");
#ifndef BOOST_NO_SFINAE
return f(3, 4);
#else
return 0;
#endif
}

View File

@@ -1,30 +0,0 @@
// 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)
#include <boost/parameter/aux_/unwrap_cv_reference.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/ref.hpp>
#include <boost/type_traits/is_same.hpp>
namespace test
{
using namespace boost::parameter::aux;
using namespace boost;
struct foo {};
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<int>::type,int>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<int const>::type,int const>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<int volatile>::type,int volatile>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<int const volatile>::type,int const volatile>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<foo>::type,foo>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<foo const>::type,foo const>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<foo volatile>::type,foo volatile>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<foo const volatile>::type,foo const volatile>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<reference_wrapper<foo> >::type,foo>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<reference_wrapper<foo> const>::type,foo>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<reference_wrapper<foo> volatile>::type,foo>));
BOOST_MPL_ASSERT((is_same<unwrap_cv_reference<reference_wrapper<foo> const volatile>::type,foo>));
}