mirror of
https://github.com/boostorg/functional.git
synced 2025-08-02 22:14:28 +02:00
adds Functional/Forward
[SVN r61597]
This commit is contained in:
19
forward/doc/Jamfile
Normal file
19
forward/doc/Jamfile
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
|
||||||
|
# (C) Copyright Tobias Schwinger
|
||||||
|
#
|
||||||
|
# Use modification and distribution are subject to the boost Software License,
|
||||||
|
# Version 1.0. (See http:/\/www.boost.org/LICENSE_1_0.txt).
|
||||||
|
|
||||||
|
using quickbook ;
|
||||||
|
|
||||||
|
xml forward : forward.qbk ;
|
||||||
|
boostbook standalone : forward
|
||||||
|
:
|
||||||
|
<xsl:param>boost.root=../../../../..
|
||||||
|
<xsl:param>boost.libraries=../../../../libraries.htm
|
||||||
|
<xsl:param>chunk.section.depth=0
|
||||||
|
<xsl:param>chunk.first.sections=0
|
||||||
|
<xsl:param>generate.section.toc.level=2
|
||||||
|
<xsl:param>toc.max.depth=1
|
||||||
|
;
|
||||||
|
|
316
forward/doc/forward.qbk
Normal file
316
forward/doc/forward.qbk
Normal file
@@ -0,0 +1,316 @@
|
|||||||
|
[library Boost.Functional/Forward
|
||||||
|
[quickbook 1.3]
|
||||||
|
[version 1.0]
|
||||||
|
[authors [Schwinger, Tobias]]
|
||||||
|
[copyright 2007 2008 Tobias Schwinger]
|
||||||
|
[license
|
||||||
|
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])
|
||||||
|
]
|
||||||
|
[purpose Function object adapters for generic argument forwarding.]
|
||||||
|
[category higher-order]
|
||||||
|
[category generic]
|
||||||
|
[last-revision $Date: 2008/11/01 19:58:50 $]
|
||||||
|
]
|
||||||
|
|
||||||
|
[def __unspecified__ /unspecified/]
|
||||||
|
[def __boost_ref__ [@http://www.boost.org/doc/html/ref.html Boost.Ref]]
|
||||||
|
[def __boost_result_of__ [@http://www.boost.org/libs/utility/utility.htm#result_of Boost.ResultOf]]
|
||||||
|
[def __boost__result_of__ [@http://www.boost.org/libs/utility/utility.htm#result_of `boost::result_of`]]
|
||||||
|
[def __the_forwarding_problem__ [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm The Forwarding Problem]]
|
||||||
|
[def __boost_fusion__ [@http://www.boost.org/libs/fusion/doc/html/index.html Boost.Fusion]]
|
||||||
|
|
||||||
|
[section Brief Description]
|
||||||
|
|
||||||
|
`boost::forward_adapter` provides a reusable adapter template for function
|
||||||
|
objects. It forwards RValues as references to const, while leaving LValues
|
||||||
|
as-is.
|
||||||
|
|
||||||
|
struct g // function object that only accept LValues
|
||||||
|
{
|
||||||
|
template< typename T0, typename T1, typename T2 >
|
||||||
|
void operator()(T0 & t0, T1 & t1, T2 & t2) const;
|
||||||
|
|
||||||
|
typedef void result_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Adapted version also accepts RValues and forwards
|
||||||
|
// them as references to const, LValues as-is
|
||||||
|
typedef boost::forward_adapter<g> f;
|
||||||
|
|
||||||
|
Another adapter, `boost::lighweight_forward_adapter` allows forwarding with
|
||||||
|
some help from the user accepting and unwrapping reference wrappers (see
|
||||||
|
__boost_ref__) for reference arguments, const qualifying all other arguments.
|
||||||
|
|
||||||
|
The target functions must be compatible with __boost_result_of__, and so are
|
||||||
|
the adapters.
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
|
[section Background]
|
||||||
|
|
||||||
|
Let's suppose we have some function `f` that we can call like this:
|
||||||
|
|
||||||
|
f(123,a_variable);
|
||||||
|
|
||||||
|
Now we want to write another, generic function `g` that can be called the
|
||||||
|
same way and returns some object that calls `f` with the same arguments.
|
||||||
|
|
||||||
|
f(123,a_variable) == g(f,123,a_variable).call_f()
|
||||||
|
|
||||||
|
[heading Why would we want to do it, anyway?]
|
||||||
|
|
||||||
|
Maybe we want to run `f` several times. Or maybe we want to run it within
|
||||||
|
another thread. Maybe we just want to encapsulate the call expression for now,
|
||||||
|
and then use it with other code that allows to compose more complex expressions
|
||||||
|
in order to decompose it with C++ templates and have the compiler generate some
|
||||||
|
machinery that eventually calls `f` at runtime (in other words; apply a
|
||||||
|
technique that is commonly referred to as Expression Templates).
|
||||||
|
|
||||||
|
[heading Now, how do we do it?]
|
||||||
|
|
||||||
|
The bad news is: It's impossible.
|
||||||
|
|
||||||
|
That is so because there is a slight difference between a variable and an
|
||||||
|
expression that evaluates to its value: Given
|
||||||
|
|
||||||
|
int y;
|
||||||
|
int const z = 0;
|
||||||
|
|
||||||
|
and
|
||||||
|
|
||||||
|
template< typename T > void func1(T & x);
|
||||||
|
|
||||||
|
we can call
|
||||||
|
|
||||||
|
func1(y); // x is a reference to a non-const object
|
||||||
|
func1(z); // x is a reference to a const object
|
||||||
|
|
||||||
|
where
|
||||||
|
|
||||||
|
func1(1); // fails to compile.
|
||||||
|
|
||||||
|
This way we can safely have `func1` store its reference argument and the
|
||||||
|
compiler keeps us from storing a reference to an object with temporary lifetime.
|
||||||
|
|
||||||
|
It is important to realize that non-constness and whether an object binds to a
|
||||||
|
non-const reference parameter are two different properties. The latter is the
|
||||||
|
distinction between LValues and RValues. The names stem from the left hand side
|
||||||
|
and the right hand side of assignment expressions, thus LValues are typically
|
||||||
|
the ones you can assign to, and RValues the temporary results from the right
|
||||||
|
hand side expression.
|
||||||
|
|
||||||
|
y = 1+2; // a is LValue, 1+2 is the expression producing the RValue,
|
||||||
|
// 1+2 = a; // usually makes no sense.
|
||||||
|
|
||||||
|
func1(y); // works, because y is an LValue
|
||||||
|
// func1(1+2); // fails to compile, because we only got an RValue.
|
||||||
|
|
||||||
|
If we add const qualification on the parameter, our function also accepts
|
||||||
|
RValues:
|
||||||
|
|
||||||
|
template< typename T > void func2(T const & x);
|
||||||
|
|
||||||
|
// [...] function scope:
|
||||||
|
func2(1); // x is a reference to a const temporary, object,
|
||||||
|
func2(y); // x is a reference to a const object, while y is not const, and
|
||||||
|
func2(z); // x is a reference to a const object, just like z.
|
||||||
|
|
||||||
|
In all cases, the argument `x` in `func2` is a const-qualified LValue.
|
||||||
|
We can use function overloading to identify non-const LValues:
|
||||||
|
|
||||||
|
template< typename T > void func3(T const & x); // #1
|
||||||
|
template< typename T > void func3(T & x); // #2
|
||||||
|
|
||||||
|
// [...] function scope:
|
||||||
|
func3(1); // x is a reference to a const, temporary object in #1,
|
||||||
|
func3(y); // x is a reference to a non-const object in #2, and
|
||||||
|
func3(z); // x is a reference to a const object in #1.
|
||||||
|
|
||||||
|
Note that all arguments `x` in the overloaded function `func3` are LValues.
|
||||||
|
In fact, there is no way to transport RValues into a function as-is in C++98.
|
||||||
|
Also note that we can't distinguish between what used to be a const qualified
|
||||||
|
LValue and an RValue.
|
||||||
|
|
||||||
|
That's as close as we can get to a generic forwarding function `g` as
|
||||||
|
described above by the means of C++ 98. See __the_forwarding_problem__ for a
|
||||||
|
very detailed discussion including solutions that require language changes.
|
||||||
|
|
||||||
|
Now, for actually implementing it, we need 2^N overloads for N parameters
|
||||||
|
(each with and without const qualifier) for each number of arguments
|
||||||
|
(that is 2^(Nmax+1) - 2^Nmin). Right, that means the compile-time complexity
|
||||||
|
is O(2^N), however the factor is low so it works quite well for a reasonable
|
||||||
|
number (< 10) of arguments.
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
|
[section:reference Reference]
|
||||||
|
|
||||||
|
[section forward_adapter]
|
||||||
|
|
||||||
|
[heading Description]
|
||||||
|
|
||||||
|
Function object adapter template whose instances are callable with LValue and
|
||||||
|
RValue arguments. RValue arguments are forwarded as reference-to-const typed
|
||||||
|
LValues.
|
||||||
|
|
||||||
|
An arity can be given as second, numeric non-type template argument to restrict
|
||||||
|
forwarding to a specific arity.
|
||||||
|
If a third, numeric non-type template argument is present, the second and third
|
||||||
|
template argument are treated as minimum and maximum arity, respectively.
|
||||||
|
Specifying an arity can be helpful to improve the readability of diagnostic
|
||||||
|
messages and compile time performance.
|
||||||
|
|
||||||
|
__boost_result_of__ can be used to determine the result types of specific call
|
||||||
|
expressions.
|
||||||
|
|
||||||
|
[heading Header]
|
||||||
|
#include <boost/functional/forward_adapter.hpp>
|
||||||
|
|
||||||
|
[heading Synopsis]
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
template< class Function,
|
||||||
|
int Arity_Or_MinArity = __unspecified__, int MaxArity = __unspecified__ >
|
||||||
|
class forward_adapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
[variablelist Notation
|
||||||
|
[[`F`] [a possibly const qualified function object type or reference type thereof]]
|
||||||
|
[[`f`] [an object convertible to `F`]]
|
||||||
|
[[`FA`] [the type `forward_adapter<F>`]]
|
||||||
|
[[`fa`] [an instance object of `FA`, initialized with `f`]]
|
||||||
|
[[`a0`...`aN`] [arguments to `fa`]]
|
||||||
|
]
|
||||||
|
|
||||||
|
The result type of a target function invocation must be
|
||||||
|
|
||||||
|
__boost__result_of__<F*(TA0 [const]&...TAN [const]&])>::type
|
||||||
|
|
||||||
|
where `TA0`...`TAN` denote the argument types of `a0`...`aN`.
|
||||||
|
|
||||||
|
[heading Expression Semantics]
|
||||||
|
|
||||||
|
[table
|
||||||
|
[[Expression] [Semantics]]
|
||||||
|
[[`FA(f)`] [creates an adapter, initializes the target function with `f`.]]
|
||||||
|
[[`FA()`] [creates an adapter, attempts to use `F`'s default constructor.]]
|
||||||
|
[[`fa(a0`...`aN)`] [calls `f` with with arguments `a0`...`aN`.]]
|
||||||
|
]
|
||||||
|
|
||||||
|
[heading Limits]
|
||||||
|
|
||||||
|
The macro BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY can be defined to set the
|
||||||
|
maximum call arity. It defaults to 6.
|
||||||
|
|
||||||
|
[heading Complexity]
|
||||||
|
|
||||||
|
Preprocessing time: O(2^N), where N is the arity limit.
|
||||||
|
Compile time: O(2^N), where N depends on the arity range.
|
||||||
|
Run time: O(0) if the compiler inlines, O(1) otherwise.
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
|
|
||||||
|
[section lightweight_forward_adapter]
|
||||||
|
|
||||||
|
[heading Description]
|
||||||
|
|
||||||
|
Function object adapter template whose instances are callable with LValue and
|
||||||
|
RValue arguments. All arguments are forwarded as reference-to-const typed
|
||||||
|
LValues, except for reference wrappers which are unwrapped and may yield
|
||||||
|
non-const LValues.
|
||||||
|
|
||||||
|
An arity can be given as second, numeric non-type template argument to restrict
|
||||||
|
forwarding to a specific arity.
|
||||||
|
If a third, numeric non-type template argument is present, the second and third
|
||||||
|
template argument are treated as minimum and maximum arity, respectively.
|
||||||
|
Specifying an arity can be helpful to improve the readability of diagnostic
|
||||||
|
messages and compile time performance.
|
||||||
|
|
||||||
|
__boost_result_of__ can be used to determine the result types of specific call
|
||||||
|
expressions.
|
||||||
|
|
||||||
|
[heading Header]
|
||||||
|
#include <boost/functional/lightweight_forward_adapter.hpp>
|
||||||
|
|
||||||
|
[heading Synopsis]
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
template< class Function,
|
||||||
|
int Arity_Or_MinArity = __unspecified__, int MaxArity = __unspecified__ >
|
||||||
|
struct lightweight_forward_adapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
[variablelist Notation
|
||||||
|
[[`F`] [a possibly const qualified function object type or reference type thereof]]
|
||||||
|
[[`f`] [an object convertible to `F`]]
|
||||||
|
[[`FA`] [the type `lightweight_forward_adapter<F>`]]
|
||||||
|
[[`fa`] [an instance of `FA`, initialized with `f`]]
|
||||||
|
[[`a0`...`aN`] [arguments to `fa`]]
|
||||||
|
]
|
||||||
|
|
||||||
|
The result type of a target function invocation must be
|
||||||
|
|
||||||
|
__boost__result_of__<F*(TA0 [const]&...TAN [const]&])>::type
|
||||||
|
|
||||||
|
where `TA0`...`TAN` denote the argument types of `a0`...`aN`.
|
||||||
|
|
||||||
|
[heading Expression Semantics]
|
||||||
|
|
||||||
|
[table
|
||||||
|
[[Expression] [Semantics]]
|
||||||
|
[[`FA(f)`] [creates an adapter, initializes the target function with `f`.]]
|
||||||
|
[[`FA()`] [creates an adapter, attempts to use `F`'s default constructor.]]
|
||||||
|
[[`fa(a0`...`aN)`] [calls `f` with with const arguments `a0`...`aN`. If `aI` is a
|
||||||
|
reference wrapper it is unwrapped.]]
|
||||||
|
]
|
||||||
|
|
||||||
|
[heading Limits]
|
||||||
|
|
||||||
|
The macro BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY can be defined
|
||||||
|
to set the maximum call arity. It defaults to 10.
|
||||||
|
|
||||||
|
[heading Complexity]
|
||||||
|
|
||||||
|
Preprocessing time: O(N), where N is the arity limit.
|
||||||
|
Compile time: O(N), where N is the effective arity of a call.
|
||||||
|
Run time: O(0) if the compiler inlines, O(1) otherwise.
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
|
|
||||||
|
[section Acknowledgements]
|
||||||
|
|
||||||
|
As these utilities are factored out of the __boost_fusion__ functional module,
|
||||||
|
I want to thank Dan Marsden and Joel de Guzman for letting me participate in the
|
||||||
|
development of that great library in the first place.
|
||||||
|
|
||||||
|
Further, I want to credit the authors of the references below, for their
|
||||||
|
in-depth investigation of the problem and the solution implemented here.
|
||||||
|
|
||||||
|
Last but not least I want to thank Vesa Karnoven and Paul Mensonides for the
|
||||||
|
Boost Preprocessor library. Without it, I would have ended up with an external
|
||||||
|
code generator for this one.
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
||||||
|
|
||||||
|
[section References]
|
||||||
|
|
||||||
|
# [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm The Forwarding Problem],
|
||||||
|
Peter Dimov, Howard E. Hinnant, David Abrahams, 2002
|
||||||
|
|
||||||
|
# [@http://www.boost.org/libs/utility/utility.htm#result_of Boost.ResultOf],
|
||||||
|
Douglas Gregor, 2004
|
||||||
|
|
||||||
|
# [@http://www.boost.org/doc/html/ref.html Boost.Ref],
|
||||||
|
Jaakko Jarvi, Peter Dimov, Douglas Gregor, David Abrahams, 1999-2002
|
||||||
|
|
||||||
|
[endsect]
|
||||||
|
|
528
forward/doc/html/boostbook.css
Normal file
528
forward/doc/html/boostbook.css
Normal file
@@ -0,0 +1,528 @@
|
|||||||
|
/*=============================================================================
|
||||||
|
Copyright (c) 2004 Joel de Guzman
|
||||||
|
http://spirit.sourceforge.net/
|
||||||
|
|
||||||
|
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)
|
||||||
|
=============================================================================*/
|
||||||
|
|
||||||
|
/*=============================================================================
|
||||||
|
Body defaults
|
||||||
|
=============================================================================*/
|
||||||
|
|
||||||
|
body
|
||||||
|
{
|
||||||
|
margin: 1em;
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=============================================================================
|
||||||
|
Paragraphs
|
||||||
|
=============================================================================*/
|
||||||
|
|
||||||
|
p
|
||||||
|
{
|
||||||
|
text-align: left;
|
||||||
|
font-size: 10pt;
|
||||||
|
line-height: 1.15;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=============================================================================
|
||||||
|
Program listings
|
||||||
|
=============================================================================*/
|
||||||
|
|
||||||
|
/* Code on paragraphs */
|
||||||
|
p tt.computeroutput
|
||||||
|
{
|
||||||
|
font-size: 9pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre.synopsis
|
||||||
|
{
|
||||||
|
font-size: 90%;
|
||||||
|
margin: 1pc 4% 0pc 4%;
|
||||||
|
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.programlisting,
|
||||||
|
.screen
|
||||||
|
{
|
||||||
|
font-size: 9pt;
|
||||||
|
display: block;
|
||||||
|
margin: 1pc 4% 0pc 4%;
|
||||||
|
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Program listings in tables don't get borders */
|
||||||
|
td .programlisting,
|
||||||
|
td .screen
|
||||||
|
{
|
||||||
|
margin: 0pc 0pc 0pc 0pc;
|
||||||
|
padding: 0pc 0pc 0pc 0pc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=============================================================================
|
||||||
|
Headings
|
||||||
|
=============================================================================*/
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6
|
||||||
|
{
|
||||||
|
text-align: left;
|
||||||
|
margin: 1em 0em 0.5em 0em;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 { font: 140% }
|
||||||
|
h2 { font: bold 140% }
|
||||||
|
h3 { font: bold 130% }
|
||||||
|
h4 { font: bold 120% }
|
||||||
|
h5 { font: italic 110% }
|
||||||
|
h6 { font: italic 100% }
|
||||||
|
|
||||||
|
/* Top page titles */
|
||||||
|
title,
|
||||||
|
h1.title,
|
||||||
|
h2.title
|
||||||
|
h3.title,
|
||||||
|
h4.title,
|
||||||
|
h5.title,
|
||||||
|
h6.title,
|
||||||
|
.refentrytitle
|
||||||
|
{
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 1pc;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1.title { font-size: 140% }
|
||||||
|
h2.title { font-size: 140% }
|
||||||
|
h3.title { font-size: 130% }
|
||||||
|
h4.title { font-size: 120% }
|
||||||
|
h5.title { font-size: 110% }
|
||||||
|
h6.title { font-size: 100% }
|
||||||
|
|
||||||
|
.section h1
|
||||||
|
{
|
||||||
|
margin: 0em 0em 0.5em 0em;
|
||||||
|
font-size: 140%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section h2 { font-size: 140% }
|
||||||
|
.section h3 { font-size: 130% }
|
||||||
|
.section h4 { font-size: 120% }
|
||||||
|
.section h5 { font-size: 110% }
|
||||||
|
.section h6 { font-size: 100% }
|
||||||
|
|
||||||
|
/* Code on titles */
|
||||||
|
h1 tt.computeroutput { font-size: 140% }
|
||||||
|
h2 tt.computeroutput { font-size: 140% }
|
||||||
|
h3 tt.computeroutput { font-size: 130% }
|
||||||
|
h4 tt.computeroutput { font-size: 120% }
|
||||||
|
h5 tt.computeroutput { font-size: 110% }
|
||||||
|
h6 tt.computeroutput { font-size: 100% }
|
||||||
|
|
||||||
|
/*=============================================================================
|
||||||
|
Author
|
||||||
|
=============================================================================*/
|
||||||
|
|
||||||
|
h3.author
|
||||||
|
{
|
||||||
|
font-size: 100%
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=============================================================================
|
||||||
|
Lists
|
||||||
|
=============================================================================*/
|
||||||
|
|
||||||
|
li
|
||||||
|
{
|
||||||
|
font-size: 10pt;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unordered lists */
|
||||||
|
ul
|
||||||
|
{
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ordered lists */
|
||||||
|
ol
|
||||||
|
{
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=============================================================================
|
||||||
|
Links
|
||||||
|
=============================================================================*/
|
||||||
|
|
||||||
|
a
|
||||||
|
{
|
||||||
|
text-decoration: none; /* no underline */
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover
|
||||||
|
{
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=============================================================================
|
||||||
|
Spirit style navigation
|
||||||
|
=============================================================================*/
|
||||||
|
|
||||||
|
.spirit-nav
|
||||||
|
{
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spirit-nav a
|
||||||
|
{
|
||||||
|
color: white;
|
||||||
|
padding-left: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spirit-nav img
|
||||||
|
{
|
||||||
|
border-width: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=============================================================================
|
||||||
|
Table of contents
|
||||||
|
=============================================================================*/
|
||||||
|
|
||||||
|
.toc
|
||||||
|
{
|
||||||
|
margin: 1pc 4% 0pc 4%;
|
||||||
|
padding: 0.1pc 1pc 0.1pc 1pc;
|
||||||
|
font-size: 80%;
|
||||||
|
line-height: 1.15;
|
||||||
|
}
|
||||||
|
|
||||||
|
.boost-toc
|
||||||
|
{
|
||||||
|
float: right;
|
||||||
|
padding: 0.5pc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=============================================================================
|
||||||
|
Tables
|
||||||
|
=============================================================================*/
|
||||||
|
|
||||||
|
.table-title,
|
||||||
|
div.table p.title
|
||||||
|
{
|
||||||
|
margin-left: 4%;
|
||||||
|
padding-right: 0.5em;
|
||||||
|
padding-left: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.informaltable table,
|
||||||
|
.table table
|
||||||
|
{
|
||||||
|
width: 92%;
|
||||||
|
margin-left: 4%;
|
||||||
|
margin-right: 4%;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.informaltable table,
|
||||||
|
div.table table
|
||||||
|
{
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Table Cells */
|
||||||
|
div.informaltable table tr td,
|
||||||
|
div.table table tr td
|
||||||
|
{
|
||||||
|
padding: 0.5em;
|
||||||
|
text-align: left;
|
||||||
|
font-size: 9pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.informaltable table tr th,
|
||||||
|
div.table table tr th
|
||||||
|
{
|
||||||
|
padding: 0.5em 0.5em 0.5em 0.5em;
|
||||||
|
border: 1pt solid white;
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=============================================================================
|
||||||
|
Blurbs
|
||||||
|
=============================================================================*/
|
||||||
|
|
||||||
|
div.note,
|
||||||
|
div.tip,
|
||||||
|
div.important,
|
||||||
|
div.caution,
|
||||||
|
div.warning,
|
||||||
|
div.sidebar
|
||||||
|
{
|
||||||
|
font-size: 9pt; /* A little bit smaller than the main text */
|
||||||
|
line-height: 1.2;
|
||||||
|
display: block;
|
||||||
|
margin: 1pc 4% 0pc 4%;
|
||||||
|
padding: 0.5pc 0.5pc 0.0pc 0.5pc;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.sidebar img
|
||||||
|
{
|
||||||
|
padding: 1pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=============================================================================
|
||||||
|
Callouts
|
||||||
|
=============================================================================*/
|
||||||
|
.line_callout_bug img
|
||||||
|
{
|
||||||
|
float: left;
|
||||||
|
position:relative;
|
||||||
|
left: 4px;
|
||||||
|
top: -12px;
|
||||||
|
clear: left;
|
||||||
|
margin-left:-22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.callout_bug img
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=============================================================================
|
||||||
|
Variable Lists
|
||||||
|
=============================================================================*/
|
||||||
|
|
||||||
|
/* Make the terms in definition lists bold */
|
||||||
|
div.variablelist dl dt,
|
||||||
|
span.term
|
||||||
|
{
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 10pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.variablelist table tbody tr td
|
||||||
|
{
|
||||||
|
text-align: left;
|
||||||
|
vertical-align: top;
|
||||||
|
padding: 0em 2em 0em 0em;
|
||||||
|
font-size: 10pt;
|
||||||
|
margin: 0em 0em 0.5em 0em;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.variablelist dl dt
|
||||||
|
{
|
||||||
|
margin-bottom: 0.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.variablelist dl dd
|
||||||
|
{
|
||||||
|
margin: 0em 0em 0.5em 2em;
|
||||||
|
font-size: 10pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.variablelist table tbody tr td p,
|
||||||
|
div.variablelist dl dd p
|
||||||
|
{
|
||||||
|
margin: 0em 0em 0.5em 0em;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=============================================================================
|
||||||
|
Misc
|
||||||
|
=============================================================================*/
|
||||||
|
|
||||||
|
/* Title of books and articles in bibliographies */
|
||||||
|
span.title
|
||||||
|
{
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.underline
|
||||||
|
{
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.strikethrough
|
||||||
|
{
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copyright, Legal Notice */
|
||||||
|
div div.legalnotice p
|
||||||
|
{
|
||||||
|
text-align: left
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=============================================================================
|
||||||
|
Colors
|
||||||
|
=============================================================================*/
|
||||||
|
|
||||||
|
@media screen
|
||||||
|
{
|
||||||
|
/* Links */
|
||||||
|
a
|
||||||
|
{
|
||||||
|
color: #005a9c;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:visited
|
||||||
|
{
|
||||||
|
color: #9c5a9c;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 a, h2 a, h3 a, h4 a, h5 a, h6 a,
|
||||||
|
h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover,
|
||||||
|
h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited
|
||||||
|
{
|
||||||
|
text-decoration: none; /* no underline */
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Syntax Highlighting */
|
||||||
|
.keyword { color: #0000AA; }
|
||||||
|
.identifier { color: #000000; }
|
||||||
|
.special { color: #707070; }
|
||||||
|
.preprocessor { color: #402080; }
|
||||||
|
.char { color: teal; }
|
||||||
|
.comment { color: #800000; }
|
||||||
|
.string { color: teal; }
|
||||||
|
.number { color: teal; }
|
||||||
|
.white_bkd { background-color: #FFFFFF; }
|
||||||
|
.dk_grey_bkd { background-color: #999999; }
|
||||||
|
|
||||||
|
/* Copyright, Legal Notice */
|
||||||
|
.copyright
|
||||||
|
{
|
||||||
|
color: #666666;
|
||||||
|
font-size: small;
|
||||||
|
}
|
||||||
|
|
||||||
|
div div.legalnotice p
|
||||||
|
{
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Program listing */
|
||||||
|
pre.synopsis
|
||||||
|
{
|
||||||
|
border: 1px solid #DCDCDC;
|
||||||
|
}
|
||||||
|
|
||||||
|
.programlisting,
|
||||||
|
.screen
|
||||||
|
{
|
||||||
|
border: 1px solid #DCDCDC;
|
||||||
|
}
|
||||||
|
|
||||||
|
td .programlisting,
|
||||||
|
td .screen
|
||||||
|
{
|
||||||
|
border: 0px solid #DCDCDC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Blurbs */
|
||||||
|
div.note,
|
||||||
|
div.tip,
|
||||||
|
div.important,
|
||||||
|
div.caution,
|
||||||
|
div.warning,
|
||||||
|
div.sidebar
|
||||||
|
{
|
||||||
|
border: 1px solid #DCDCDC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Table of contents */
|
||||||
|
.toc
|
||||||
|
{
|
||||||
|
border: 1px solid #DCDCDC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tables */
|
||||||
|
div.informaltable table tr td,
|
||||||
|
div.table table tr td
|
||||||
|
{
|
||||||
|
border: 1px solid #DCDCDC;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.informaltable table tr th,
|
||||||
|
div.table table tr th
|
||||||
|
{
|
||||||
|
background-color: #F0F0F0;
|
||||||
|
border: 1px solid #DCDCDC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Misc */
|
||||||
|
span.highlight
|
||||||
|
{
|
||||||
|
color: #00A000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media print
|
||||||
|
{
|
||||||
|
/* Links */
|
||||||
|
a
|
||||||
|
{
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:visited
|
||||||
|
{
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.spirit-nav
|
||||||
|
{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Program listing */
|
||||||
|
pre.synopsis
|
||||||
|
{
|
||||||
|
border: 1px solid gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.programlisting,
|
||||||
|
.screen
|
||||||
|
{
|
||||||
|
border: 1px solid gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
td .programlisting,
|
||||||
|
td .screen
|
||||||
|
{
|
||||||
|
border: 0px solid #DCDCDC;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Table of contents */
|
||||||
|
.toc
|
||||||
|
{
|
||||||
|
border: 1px solid gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.informaltable table,
|
||||||
|
.table table
|
||||||
|
{
|
||||||
|
border: 1px solid gray;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tables */
|
||||||
|
div.informaltable table tr td,
|
||||||
|
div.table table tr td
|
||||||
|
{
|
||||||
|
border: 1px solid gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.informaltable table tr th,
|
||||||
|
div.table table tr th
|
||||||
|
{
|
||||||
|
border: 1px solid gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Misc */
|
||||||
|
span.highlight
|
||||||
|
{
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
564
forward/doc/html/index.html
Normal file
564
forward/doc/html/index.html
Normal file
@@ -0,0 +1,564 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
|
||||||
|
<title>Chapter<EFBFBD>1.<2E>Boost.Functional/Forward 1.0</title>
|
||||||
|
<link rel="stylesheet" href="boostbook.css" type="text/css">
|
||||||
|
<meta name="generator" content="DocBook XSL Stylesheets V1.68.1">
|
||||||
|
<link rel="start" href="index.html" title="Chapter<65>1.<2E>Boost.Functional/Forward 1.0">
|
||||||
|
</head>
|
||||||
|
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||||
|
<table cellpadding="2" width="100%"><tr>
|
||||||
|
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
|
||||||
|
<td align="center"><a href="../../../../../index.html">Home</a></td>
|
||||||
|
<td align="center"><a href="../../../../libraries.htm">Libraries</a></td>
|
||||||
|
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||||
|
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||||
|
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
|
||||||
|
</tr></table>
|
||||||
|
<hr>
|
||||||
|
<div class="spirit-nav"></div>
|
||||||
|
<div class="chapter" lang="en">
|
||||||
|
<div class="titlepage"><div>
|
||||||
|
<div><h2 class="title">
|
||||||
|
<a name="boost_functional_forward"></a>Chapter<EFBFBD>1.<2E>Boost.Functional/Forward 1.0</h2></div>
|
||||||
|
<div><div class="author"><h3 class="author">
|
||||||
|
<span class="firstname">Tobias</span> <span class="surname">Schwinger</span>
|
||||||
|
</h3></div></div>
|
||||||
|
<div><p class="copyright">Copyright <20> 2007, 2008 Tobias Schwinger</p></div>
|
||||||
|
<div><div class="legalnotice">
|
||||||
|
<a name="id934161"></a><p>
|
||||||
|
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||||
|
</p>
|
||||||
|
</div></div>
|
||||||
|
</div></div>
|
||||||
|
<div class="toc">
|
||||||
|
<p><b>Table of Contents</b></p>
|
||||||
|
<dl>
|
||||||
|
<dt><span class="section"><a href="index.html#boost_functional_forward.brief_description">Brief Description</a></span></dt>
|
||||||
|
<dt><span class="section"><a href="index.html#boost_functional_forward.background">Background</a></span></dt>
|
||||||
|
<dt><span class="section"><a href="index.html#boost_functional_forward.reference"> Reference</a></span></dt>
|
||||||
|
<dt><span class="section"><a href="index.html#boost_functional_forward.acknowledgements">Acknowledgements</a></span></dt>
|
||||||
|
<dt><span class="section"><a href="index.html#boost_functional_forward.references">References</a></span></dt>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
<div class="section" lang="en">
|
||||||
|
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||||
|
<a name="boost_functional_forward.brief_description"></a><a href="index.html#boost_functional_forward.brief_description" title="Brief Description">Brief Description</a></h2></div></div></div>
|
||||||
|
<p>
|
||||||
|
<code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">forward_adapter</span></code> provides a reusable adapter
|
||||||
|
template for function objects. It forwards RValues as references to const,
|
||||||
|
while leaving LValues as-is.
|
||||||
|
</p>
|
||||||
|
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">g</span> <span class="comment">// function object that only accept LValues
|
||||||
|
</span><span class="special">{</span>
|
||||||
|
<span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">T0</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T1</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T2</span> <span class="special">></span>
|
||||||
|
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">T0</span> <span class="special">&</span> <span class="identifier">t0</span><span class="special">,</span> <span class="identifier">T1</span> <span class="special">&</span> <span class="identifier">t1</span><span class="special">,</span> <span class="identifier">T2</span> <span class="special">&</span> <span class="identifier">t2</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
|
||||||
|
|
||||||
|
<span class="keyword">typedef</span> <span class="keyword">void</span> <span class="identifier">result_type</span><span class="special">;</span>
|
||||||
|
<span class="special">};</span>
|
||||||
|
|
||||||
|
<span class="comment">// Adapted version also accepts RValues and forwards
|
||||||
|
</span><span class="comment">// them as references to const, LValues as-is
|
||||||
|
</span><span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">forward_adapter</span><span class="special"><</span><span class="identifier">g</span><span class="special">></span> <span class="identifier">f</span><span class="special">;</span>
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
Another adapter, <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">lighweight_forward_adapter</span></code> allows forwarding
|
||||||
|
with some help from the user accepting and unwrapping reference wrappers (see
|
||||||
|
<a href="http://www.boost.org/doc/html/ref.html" target="_top">Boost.Ref</a>) for
|
||||||
|
reference arguments, const qualifying all other arguments.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The target functions must be compatible with <a href="http://www.boost.org/libs/utility/utility.htm#result_of" target="_top">Boost.ResultOf</a>,
|
||||||
|
and so are the adapters.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="section" lang="en">
|
||||||
|
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||||
|
<a name="boost_functional_forward.background"></a><a href="index.html#boost_functional_forward.background" title="Background">Background</a></h2></div></div></div>
|
||||||
|
<p>
|
||||||
|
Let's suppose we have some function <code class="computeroutput"><span class="identifier">f</span></code>
|
||||||
|
that we can call like this:
|
||||||
|
</p>
|
||||||
|
<pre class="programlisting"><span class="identifier">f</span><span class="special">(</span><span class="number">123</span><span class="special">,</span><span class="identifier">a_variable</span><span class="special">);</span>
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
Now we want to write another, generic function <code class="computeroutput"><span class="identifier">g</span></code>
|
||||||
|
that can be called the same way and returns some object that calls <code class="computeroutput"><span class="identifier">f</span></code> with the same arguments.
|
||||||
|
</p>
|
||||||
|
<pre class="programlisting"><span class="identifier">f</span><span class="special">(</span><span class="number">123</span><span class="special">,</span><span class="identifier">a_variable</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">g</span><span class="special">(</span><span class="identifier">f</span><span class="special">,</span><span class="number">123</span><span class="special">,</span><span class="identifier">a_variable</span><span class="special">).</span><span class="identifier">call_f</span><span class="special">()</span>
|
||||||
|
</pre>
|
||||||
|
<a name="boost_functional_forward.background.why_would_we_want_to_do_it__anyway_"></a><h3>
|
||||||
|
<a name="id934701"></a>
|
||||||
|
<a href="index.html#boost_functional_forward.background.why_would_we_want_to_do_it__anyway_">Why
|
||||||
|
would we want to do it, anyway?</a>
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
Maybe we want to run <code class="computeroutput"><span class="identifier">f</span></code> several
|
||||||
|
times. Or maybe we want to run it within another thread. Maybe we just want
|
||||||
|
to encapsulate the call expression for now, and then use it with other code
|
||||||
|
that allows to compose more complex expressions in order to decompose it with
|
||||||
|
C++ templates and have the compiler generate some machinery that eventually
|
||||||
|
calls <code class="computeroutput"><span class="identifier">f</span></code> at runtime (in other
|
||||||
|
words; apply a technique that is commonly referred to as Expression Templates).
|
||||||
|
</p>
|
||||||
|
<a name="boost_functional_forward.background.now__how_do_we_do_it_"></a><h3>
|
||||||
|
<a name="id934755"></a>
|
||||||
|
<a href="index.html#boost_functional_forward.background.now__how_do_we_do_it_">Now,
|
||||||
|
how do we do it?</a>
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
The bad news is: It's impossible.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
That is so because there is a slight difference between a variable and an expression
|
||||||
|
that evaluates to its value: Given
|
||||||
|
</p>
|
||||||
|
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">y</span><span class="special">;</span>
|
||||||
|
<span class="keyword">int</span> <span class="keyword">const</span> <span class="identifier">z</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
and
|
||||||
|
</p>
|
||||||
|
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">T</span> <span class="special">></span> <span class="keyword">void</span> <span class="identifier">func1</span><span class="special">(</span><span class="identifier">T</span> <span class="special">&</span> <span class="identifier">x</span><span class="special">);</span>
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
we can call
|
||||||
|
</p>
|
||||||
|
<pre class="programlisting"><span class="identifier">func1</span><span class="special">(</span><span class="identifier">y</span><span class="special">);</span> <span class="comment">// x is a reference to a non-const object
|
||||||
|
</span><span class="identifier">func1</span><span class="special">(</span><span class="identifier">z</span><span class="special">);</span> <span class="comment">// x is a reference to a const object
|
||||||
|
</span></pre>
|
||||||
|
<p>
|
||||||
|
where
|
||||||
|
</p>
|
||||||
|
<pre class="programlisting"><span class="identifier">func1</span><span class="special">(</span><span class="number">1</span><span class="special">);</span> <span class="comment">// fails to compile.
|
||||||
|
</span></pre>
|
||||||
|
<p>
|
||||||
|
This way we can safely have <code class="computeroutput"><span class="identifier">func1</span></code>
|
||||||
|
store its reference argument and the compiler keeps us from storing a reference
|
||||||
|
to an object with temporary lifetime.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
It is important to realize that non-constness and whether an object binds to
|
||||||
|
a non-const reference parameter are two different properties. The latter is
|
||||||
|
the distinction between LValues and RValues. The names stem from the left hand
|
||||||
|
side and the right hand side of assignment expressions, thus LValues are typically
|
||||||
|
the ones you can assign to, and RValues the temporary results from the right
|
||||||
|
hand side expression.
|
||||||
|
</p>
|
||||||
|
<pre class="programlisting"><span class="identifier">y</span> <span class="special">=</span> <span class="number">1</span><span class="special">+</span><span class="number">2</span><span class="special">;</span> <span class="comment">// a is LValue, 1+2 is the expression producing the RValue,
|
||||||
|
</span><span class="comment">// 1+2 = a; // usually makes no sense.
|
||||||
|
</span>
|
||||||
|
<span class="identifier">func1</span><span class="special">(</span><span class="identifier">y</span><span class="special">);</span> <span class="comment">// works, because y is an LValue
|
||||||
|
</span><span class="comment">// func1(1+2); // fails to compile, because we only got an RValue.
|
||||||
|
</span></pre>
|
||||||
|
<p>
|
||||||
|
If we add const qualification on the parameter, our function also accepts RValues:
|
||||||
|
</p>
|
||||||
|
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">T</span> <span class="special">></span> <span class="keyword">void</span> <span class="identifier">func2</span><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">x</span><span class="special">);</span>
|
||||||
|
|
||||||
|
<span class="comment">// [...] function scope:
|
||||||
|
</span><span class="identifier">func2</span><span class="special">(</span><span class="number">1</span><span class="special">);</span> <span class="comment">// x is a reference to a const temporary, object,
|
||||||
|
</span><span class="identifier">func2</span><span class="special">(</span><span class="identifier">y</span><span class="special">);</span> <span class="comment">// x is a reference to a const object, while y is not const, and
|
||||||
|
</span><span class="identifier">func2</span><span class="special">(</span><span class="identifier">z</span><span class="special">);</span> <span class="comment">// x is a reference to a const object, just like z.
|
||||||
|
</span></pre>
|
||||||
|
<p>
|
||||||
|
In all cases, the argument <code class="computeroutput"><span class="identifier">x</span></code>
|
||||||
|
in <code class="computeroutput"><span class="identifier">func2</span></code> is a const-qualified
|
||||||
|
LValue. We can use function overloading to identify non-const LValues:
|
||||||
|
</p>
|
||||||
|
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">T</span> <span class="special">></span> <span class="keyword">void</span> <span class="identifier">func3</span><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">x</span><span class="special">);</span> <span class="comment">// #1
|
||||||
|
</span><span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">T</span> <span class="special">></span> <span class="keyword">void</span> <span class="identifier">func3</span><span class="special">(</span><span class="identifier">T</span> <span class="special">&</span> <span class="identifier">x</span><span class="special">);</span> <span class="comment">// #2
|
||||||
|
</span>
|
||||||
|
<span class="comment">// [...] function scope:
|
||||||
|
</span><span class="identifier">func3</span><span class="special">(</span><span class="number">1</span><span class="special">);</span> <span class="comment">// x is a reference to a const, temporary object in #1,
|
||||||
|
</span><span class="identifier">func3</span><span class="special">(</span><span class="identifier">y</span><span class="special">);</span> <span class="comment">// x is a reference to a non-const object in #2, and
|
||||||
|
</span><span class="identifier">func3</span><span class="special">(</span><span class="identifier">z</span><span class="special">);</span> <span class="comment">// x is a reference to a const object in #1.
|
||||||
|
</span></pre>
|
||||||
|
<p>
|
||||||
|
Note that all arguments <code class="computeroutput"><span class="identifier">x</span></code> in
|
||||||
|
the overloaded function <code class="computeroutput"><span class="identifier">func3</span></code>
|
||||||
|
are LValues. In fact, there is no way to transport RValues into a function
|
||||||
|
as-is in C++98. Also note that we can't distinguish between what used to be
|
||||||
|
a const qualified LValue and an RValue.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
That's as close as we can get to a generic forwarding function <code class="computeroutput"><span class="identifier">g</span></code> as described above by the means of C++
|
||||||
|
98. See <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm" target="_top">The
|
||||||
|
Forwarding Problem</a> for a very detailed discussion including solutions
|
||||||
|
that require language changes.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Now, for actually implementing it, we need 2^N overloads for N parameters (each
|
||||||
|
with and without const qualifier) for each number of arguments (that is 2^(Nmax+1)
|
||||||
|
- 2^Nmin). Right, that means the compile-time complexity is O(2^N), however
|
||||||
|
the factor is low so it works quite well for a reasonable number (< 10)
|
||||||
|
of arguments.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="section" lang="en">
|
||||||
|
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||||
|
<a name="boost_functional_forward.reference"></a><a href="index.html#boost_functional_forward.reference" title=" Reference"> Reference</a></h2></div></div></div>
|
||||||
|
<div class="toc"><dl>
|
||||||
|
<dt><span class="section"><a href="index.html#boost_functional_forward.reference.forward_adapter">forward_adapter</a></span></dt>
|
||||||
|
<dt><span class="section"><a href="index.html#boost_functional_forward.reference.lightweight_forward_adapter">lightweight_forward_adapter</a></span></dt>
|
||||||
|
</dl></div>
|
||||||
|
<div class="section" lang="en">
|
||||||
|
<div class="titlepage"><div><div><h3 class="title">
|
||||||
|
<a name="boost_functional_forward.reference.forward_adapter"></a><a href="index.html#boost_functional_forward.reference.forward_adapter" title="forward_adapter">forward_adapter</a></h3></div></div></div>
|
||||||
|
<a name="boost_functional_forward.reference.forward_adapter.description"></a><h4>
|
||||||
|
<a name="id935594"></a>
|
||||||
|
<a href="index.html#boost_functional_forward.reference.forward_adapter.description">Description</a>
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
Function object adapter template whose instances are callable with LValue
|
||||||
|
and RValue arguments. RValue arguments are forwarded as reference-to-const
|
||||||
|
typed LValues.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
An arity can be given as second, numeric non-type template argument to restrict
|
||||||
|
forwarding to a specific arity. If a third, numeric non-type template argument
|
||||||
|
is present, the second and third template argument are treated as minimum
|
||||||
|
and maximum arity, respectively. Specifying an arity can be helpful to improve
|
||||||
|
the readability of diagnostic messages and compile time performance.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a href="http://www.boost.org/libs/utility/utility.htm#result_of" target="_top">Boost.ResultOf</a>
|
||||||
|
can be used to determine the result types of specific call expressions.
|
||||||
|
</p>
|
||||||
|
<a name="boost_functional_forward.reference.forward_adapter.header"></a><h4>
|
||||||
|
<a name="id935646"></a>
|
||||||
|
<a href="index.html#boost_functional_forward.reference.forward_adapter.header">Header</a>
|
||||||
|
</h4>
|
||||||
|
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">functional</span><span class="special">/</span><span class="identifier">forward_adapter</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||||
|
</pre>
|
||||||
|
<a name="boost_functional_forward.reference.forward_adapter.synopsis"></a><h4>
|
||||||
|
<a name="id935721"></a>
|
||||||
|
<a href="index.html#boost_functional_forward.reference.forward_adapter.synopsis">Synopsis</a>
|
||||||
|
</h4>
|
||||||
|
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span>
|
||||||
|
<span class="special">{</span>
|
||||||
|
<span class="keyword">template</span><span class="special"><</span> <span class="keyword">class</span> <span class="identifier">Function</span><span class="special">,</span>
|
||||||
|
<span class="keyword">int</span> <span class="identifier">Arity_Or_MinArity</span> <span class="special">=</span> <span class="emphasis"><em>unspecified</em></span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">MaxArity</span> <span class="special">=</span> <span class="emphasis"><em>unspecified</em></span> <span class="special">></span>
|
||||||
|
<span class="keyword">class</span> <span class="identifier">forward_adapter</span><span class="special">;</span>
|
||||||
|
<span class="special">}</span>
|
||||||
|
</pre>
|
||||||
|
<div class="variablelist">
|
||||||
|
<p class="title"><b>Notation</b></p>
|
||||||
|
<dl>
|
||||||
|
<dt><span class="term"><code class="computeroutput"><span class="identifier">F</span></code></span></dt>
|
||||||
|
<dd><p>
|
||||||
|
a possibly const qualified function object type or reference type thereof
|
||||||
|
</p></dd>
|
||||||
|
<dt><span class="term"><code class="computeroutput"><span class="identifier">f</span></code></span></dt>
|
||||||
|
<dd><p>
|
||||||
|
an object convertible to <code class="computeroutput"><span class="identifier">F</span></code>
|
||||||
|
</p></dd>
|
||||||
|
<dt><span class="term"><code class="computeroutput"><span class="identifier">FA</span></code></span></dt>
|
||||||
|
<dd><p>
|
||||||
|
the type <code class="computeroutput"><span class="identifier">forward_adapter</span><span class="special"><</span><span class="identifier">F</span><span class="special">></span></code>
|
||||||
|
</p></dd>
|
||||||
|
<dt><span class="term"><code class="computeroutput"><span class="identifier">fa</span></code></span></dt>
|
||||||
|
<dd><p>
|
||||||
|
an instance object of <code class="computeroutput"><span class="identifier">FA</span></code>,
|
||||||
|
initialized with <code class="computeroutput"><span class="identifier">f</span></code>
|
||||||
|
</p></dd>
|
||||||
|
<dt><span class="term"><code class="computeroutput"><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span></code></span></dt>
|
||||||
|
<dd><p>
|
||||||
|
arguments to <code class="computeroutput"><span class="identifier">fa</span></code>
|
||||||
|
</p></dd>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
The result type of a target function invocation must be
|
||||||
|
</p>
|
||||||
|
<pre class="programlisting"><a href="http://www.boost.org/libs/utility/utility.htm#result_of" target="_top"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">result_of</span></code></a><span class="special"><</span><span class="identifier">F</span><span class="special">*(</span><span class="identifier">TA0</span> <span class="special">[</span><span class="keyword">const</span><span class="special">]&...</span><span class="identifier">TAN</span> <span class="special">[</span><span class="keyword">const</span><span class="special">]&])>::</span><span class="identifier">type</span>
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
where <code class="computeroutput"><span class="identifier">TA0</span></code>...<code class="computeroutput"><span class="identifier">TAN</span></code> denote the argument types of <code class="computeroutput"><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span></code>.
|
||||||
|
</p>
|
||||||
|
<a name="boost_functional_forward.reference.forward_adapter.expression_semantics"></a><h4>
|
||||||
|
<a name="id936177"></a>
|
||||||
|
<a href="index.html#boost_functional_forward.reference.forward_adapter.expression_semantics">Expression
|
||||||
|
Semantics</a>
|
||||||
|
</h4>
|
||||||
|
<div class="informaltable"><table class="table">
|
||||||
|
<colgroup>
|
||||||
|
<col>
|
||||||
|
<col>
|
||||||
|
</colgroup>
|
||||||
|
<thead><tr>
|
||||||
|
<th>
|
||||||
|
<p>
|
||||||
|
Expression
|
||||||
|
</p>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<p>
|
||||||
|
Semantics
|
||||||
|
</p>
|
||||||
|
</th>
|
||||||
|
</tr></thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<p>
|
||||||
|
<code class="computeroutput"><span class="identifier">FA</span><span class="special">(</span><span class="identifier">f</span><span class="special">)</span></code>
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>
|
||||||
|
creates an adapter, initializes the target function with <code class="computeroutput"><span class="identifier">f</span></code>.
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<p>
|
||||||
|
<code class="computeroutput"><span class="identifier">FA</span><span class="special">()</span></code>
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>
|
||||||
|
creates an adapter, attempts to use <code class="computeroutput"><span class="identifier">F</span></code>'s
|
||||||
|
default constructor.
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<p>
|
||||||
|
<code class="computeroutput"><span class="identifier">fa</span><span class="special">(</span><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span><span class="special">)</span></code>
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>
|
||||||
|
calls <code class="computeroutput"><span class="identifier">f</span></code> with with
|
||||||
|
arguments <code class="computeroutput"><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span></code>.
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table></div>
|
||||||
|
<a name="boost_functional_forward.reference.forward_adapter.limits"></a><h4>
|
||||||
|
<a name="id936405"></a>
|
||||||
|
<a href="index.html#boost_functional_forward.reference.forward_adapter.limits">Limits</a>
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
The macro BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY can be defined to set
|
||||||
|
the maximum call arity. It defaults to 6.
|
||||||
|
</p>
|
||||||
|
<a name="boost_functional_forward.reference.forward_adapter.complexity"></a><h4>
|
||||||
|
<a name="id936434"></a>
|
||||||
|
<a href="index.html#boost_functional_forward.reference.forward_adapter.complexity">Complexity</a>
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
Preprocessing time: O(2^N), where N is the arity limit. Compile time: O(2^N),
|
||||||
|
where N depends on the arity range. Run time: O(0) if the compiler inlines,
|
||||||
|
O(1) otherwise.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="section" lang="en">
|
||||||
|
<div class="titlepage"><div><div><h3 class="title">
|
||||||
|
<a name="boost_functional_forward.reference.lightweight_forward_adapter"></a><a href="index.html#boost_functional_forward.reference.lightweight_forward_adapter" title="lightweight_forward_adapter">lightweight_forward_adapter</a></h3></div></div></div>
|
||||||
|
<a name="boost_functional_forward.reference.lightweight_forward_adapter.description"></a><h4>
|
||||||
|
<a name="id936485"></a>
|
||||||
|
<a href="index.html#boost_functional_forward.reference.lightweight_forward_adapter.description">Description</a>
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
Function object adapter template whose instances are callable with LValue
|
||||||
|
and RValue arguments. All arguments are forwarded as reference-to-const typed
|
||||||
|
LValues, except for reference wrappers which are unwrapped and may yield
|
||||||
|
non-const LValues.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
An arity can be given as second, numeric non-type template argument to restrict
|
||||||
|
forwarding to a specific arity. If a third, numeric non-type template argument
|
||||||
|
is present, the second and third template argument are treated as minimum
|
||||||
|
and maximum arity, respectively. Specifying an arity can be helpful to improve
|
||||||
|
the readability of diagnostic messages and compile time performance.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a href="http://www.boost.org/libs/utility/utility.htm#result_of" target="_top">Boost.ResultOf</a>
|
||||||
|
can be used to determine the result types of specific call expressions.
|
||||||
|
</p>
|
||||||
|
<a name="boost_functional_forward.reference.lightweight_forward_adapter.header"></a><h4>
|
||||||
|
<a name="id936540"></a>
|
||||||
|
<a href="index.html#boost_functional_forward.reference.lightweight_forward_adapter.header">Header</a>
|
||||||
|
</h4>
|
||||||
|
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">functional</span><span class="special">/</span><span class="identifier">lightweight_forward_adapter</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||||
|
</pre>
|
||||||
|
<a name="boost_functional_forward.reference.lightweight_forward_adapter.synopsis"></a><h4>
|
||||||
|
<a name="id936616"></a>
|
||||||
|
<a href="index.html#boost_functional_forward.reference.lightweight_forward_adapter.synopsis">Synopsis</a>
|
||||||
|
</h4>
|
||||||
|
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span>
|
||||||
|
<span class="special">{</span>
|
||||||
|
<span class="keyword">template</span><span class="special"><</span> <span class="keyword">class</span> <span class="identifier">Function</span><span class="special">,</span>
|
||||||
|
<span class="keyword">int</span> <span class="identifier">Arity_Or_MinArity</span> <span class="special">=</span> <span class="emphasis"><em>unspecified</em></span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">MaxArity</span> <span class="special">=</span> <span class="emphasis"><em>unspecified</em></span> <span class="special">></span>
|
||||||
|
<span class="keyword">struct</span> <span class="identifier">lightweight_forward_adapter</span><span class="special">;</span>
|
||||||
|
<span class="special">}</span>
|
||||||
|
</pre>
|
||||||
|
<div class="variablelist">
|
||||||
|
<p class="title"><b>Notation</b></p>
|
||||||
|
<dl>
|
||||||
|
<dt><span class="term"><code class="computeroutput"><span class="identifier">F</span></code></span></dt>
|
||||||
|
<dd><p>
|
||||||
|
a possibly const qualified function object type or reference type thereof
|
||||||
|
</p></dd>
|
||||||
|
<dt><span class="term"><code class="computeroutput"><span class="identifier">f</span></code></span></dt>
|
||||||
|
<dd><p>
|
||||||
|
an object convertible to <code class="computeroutput"><span class="identifier">F</span></code>
|
||||||
|
</p></dd>
|
||||||
|
<dt><span class="term"><code class="computeroutput"><span class="identifier">FA</span></code></span></dt>
|
||||||
|
<dd><p>
|
||||||
|
the type <code class="computeroutput"><span class="identifier">lightweight_forward_adapter</span><span class="special"><</span><span class="identifier">F</span><span class="special">></span></code>
|
||||||
|
</p></dd>
|
||||||
|
<dt><span class="term"><code class="computeroutput"><span class="identifier">fa</span></code></span></dt>
|
||||||
|
<dd><p>
|
||||||
|
an instance of <code class="computeroutput"><span class="identifier">FA</span></code>, initialized
|
||||||
|
with <code class="computeroutput"><span class="identifier">f</span></code>
|
||||||
|
</p></dd>
|
||||||
|
<dt><span class="term"><code class="computeroutput"><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span></code></span></dt>
|
||||||
|
<dd><p>
|
||||||
|
arguments to <code class="computeroutput"><span class="identifier">fa</span></code>
|
||||||
|
</p></dd>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
The result type of a target function invocation must be
|
||||||
|
</p>
|
||||||
|
<pre class="programlisting"><a href="http://www.boost.org/libs/utility/utility.htm#result_of" target="_top"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">result_of</span></code></a><span class="special"><</span><span class="identifier">F</span><span class="special">*(</span><span class="identifier">TA0</span> <span class="special">[</span><span class="keyword">const</span><span class="special">]&...</span><span class="identifier">TAN</span> <span class="special">[</span><span class="keyword">const</span><span class="special">]&])>::</span><span class="identifier">type</span>
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
where <code class="computeroutput"><span class="identifier">TA0</span></code>...<code class="computeroutput"><span class="identifier">TAN</span></code> denote the argument types of <code class="computeroutput"><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span></code>.
|
||||||
|
</p>
|
||||||
|
<a name="boost_functional_forward.reference.lightweight_forward_adapter.expression_semantics"></a><h4>
|
||||||
|
<a name="id937073"></a>
|
||||||
|
<a href="index.html#boost_functional_forward.reference.lightweight_forward_adapter.expression_semantics">Expression
|
||||||
|
Semantics</a>
|
||||||
|
</h4>
|
||||||
|
<div class="informaltable"><table class="table">
|
||||||
|
<colgroup>
|
||||||
|
<col>
|
||||||
|
<col>
|
||||||
|
</colgroup>
|
||||||
|
<thead><tr>
|
||||||
|
<th>
|
||||||
|
<p>
|
||||||
|
Expression
|
||||||
|
</p>
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
<p>
|
||||||
|
Semantics
|
||||||
|
</p>
|
||||||
|
</th>
|
||||||
|
</tr></thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<p>
|
||||||
|
<code class="computeroutput"><span class="identifier">FA</span><span class="special">(</span><span class="identifier">f</span><span class="special">)</span></code>
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>
|
||||||
|
creates an adapter, initializes the target function with <code class="computeroutput"><span class="identifier">f</span></code>.
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<p>
|
||||||
|
<code class="computeroutput"><span class="identifier">FA</span><span class="special">()</span></code>
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>
|
||||||
|
creates an adapter, attempts to use <code class="computeroutput"><span class="identifier">F</span></code>'s
|
||||||
|
default constructor.
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<p>
|
||||||
|
<code class="computeroutput"><span class="identifier">fa</span><span class="special">(</span><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span><span class="special">)</span></code>
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>
|
||||||
|
calls <code class="computeroutput"><span class="identifier">f</span></code> with with
|
||||||
|
const arguments <code class="computeroutput"><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span></code>. If <code class="computeroutput"><span class="identifier">aI</span></code>
|
||||||
|
is a reference wrapper it is unwrapped.
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table></div>
|
||||||
|
<a name="boost_functional_forward.reference.lightweight_forward_adapter.limits"></a><h4>
|
||||||
|
<a name="id937311"></a>
|
||||||
|
<a href="index.html#boost_functional_forward.reference.lightweight_forward_adapter.limits">Limits</a>
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
The macro BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY can be defined
|
||||||
|
to set the maximum call arity. It defaults to 10.
|
||||||
|
</p>
|
||||||
|
<a name="boost_functional_forward.reference.lightweight_forward_adapter.complexity"></a><h4>
|
||||||
|
<a name="id937342"></a>
|
||||||
|
<a href="index.html#boost_functional_forward.reference.lightweight_forward_adapter.complexity">Complexity</a>
|
||||||
|
</h4>
|
||||||
|
<p>
|
||||||
|
Preprocessing time: O(N), where N is the arity limit. Compile time: O(N),
|
||||||
|
where N is the effective arity of a call. Run time: O(0) if the compiler
|
||||||
|
inlines, O(1) otherwise.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="section" lang="en">
|
||||||
|
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||||
|
<a name="boost_functional_forward.acknowledgements"></a><a href="index.html#boost_functional_forward.acknowledgements" title="Acknowledgements">Acknowledgements</a></h2></div></div></div>
|
||||||
|
<p>
|
||||||
|
As these utilities are factored out of the <a href="http://www.boost.org/libs/fusion/doc/html/index.html" target="_top">Boost.Fusion</a>
|
||||||
|
functional module, I want to thank Dan Marsden and Joel de Guzman for letting
|
||||||
|
me participate in the development of that great library in the first place.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Further, I want to credit the authors of the references below, for their in-depth
|
||||||
|
investigation of the problem and the solution implemented here.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Last but not least I want to thank Vesa Karnoven and Paul Mensonides for the
|
||||||
|
Boost Preprocessor library. Without it, I would have ended up with an external
|
||||||
|
code generator for this one.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="section" lang="en">
|
||||||
|
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||||
|
<a name="boost_functional_forward.references"></a><a href="index.html#boost_functional_forward.references" title="References">References</a></h2></div></div></div>
|
||||||
|
<div class="orderedlist"><ol type="1">
|
||||||
|
<li>
|
||||||
|
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm" target="_top">The
|
||||||
|
Forwarding Problem</a>, Peter Dimov, Howard E. Hinnant, David Abrahams,
|
||||||
|
2002
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="http://www.boost.org/libs/utility/utility.htm#result_of" target="_top">Boost.ResultOf</a>,
|
||||||
|
Douglas Gregor, 2004
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="http://www.boost.org/doc/html/ref.html" target="_top">Boost.Ref</a>, Jaakko
|
||||||
|
Jarvi, Peter Dimov, Douglas Gregor, David Abrahams, 1999-2002
|
||||||
|
</li>
|
||||||
|
</ol></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||||
|
<td align="left"><p><small>Last revised: November 01, 2008 at 19:58:50 GMT</small></p></td>
|
||||||
|
<td align="right"><div class="copyright-footer"></div></td>
|
||||||
|
</tr></table>
|
||||||
|
<hr>
|
||||||
|
<div class="spirit-nav"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
15
forward/index.html
Normal file
15
forward/index.html
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="refresh" content="0; URL=doc/html/index.html">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
Automatic redirection failed, click this
|
||||||
|
<a href="doc/html/index.html">link</a> <hr>
|
||||||
|
<p><EFBFBD> Copyright Tobias Schwinger, 2009</p>
|
||||||
|
<p>Distributed under the Boost Software License, Version 1.0. (See
|
||||||
|
accompanying file <a href="../../../LICENSE_1_0.txt">
|
||||||
|
LICENSE_1_0.txt</a> or copy at
|
||||||
|
<a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
17
forward/test/Jamfile
Normal file
17
forward/test/Jamfile
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
# (C) Copyright Tobias Schwinger
|
||||||
|
#
|
||||||
|
# Use modification and distribution are subject to the boost Software License,
|
||||||
|
# Version 1.0. (See http:/\/www.boost.org/LICENSE_1_0.txt).
|
||||||
|
|
||||||
|
import testing ;
|
||||||
|
|
||||||
|
project forward-tests
|
||||||
|
;
|
||||||
|
|
||||||
|
test-suite functional/forward
|
||||||
|
:
|
||||||
|
[ run forward_adapter.cpp ]
|
||||||
|
[ run lightweight_forward_adapter.cpp ]
|
||||||
|
;
|
||||||
|
|
128
forward/test/forward_adapter.cpp
Normal file
128
forward/test/forward_adapter.cpp
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
/*=============================================================================
|
||||||
|
Copyright (c) 2007 Tobias Schwinger
|
||||||
|
|
||||||
|
Use modification and distribution are 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/config.hpp>
|
||||||
|
|
||||||
|
#ifdef BOOST_MSVC
|
||||||
|
# pragma warning(disable: 4244) // no conversion warnings, please
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
#include <boost/functional/forward_adapter.hpp>
|
||||||
|
|
||||||
|
#include <boost/type_traits/is_same.hpp>
|
||||||
|
|
||||||
|
#include <boost/blank.hpp>
|
||||||
|
#include <boost/noncopyable.hpp>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
template <class Base = boost::blank>
|
||||||
|
class test_func : public Base
|
||||||
|
{
|
||||||
|
int val;
|
||||||
|
public:
|
||||||
|
test_func(int v) : val(v) { }
|
||||||
|
|
||||||
|
template<class B>
|
||||||
|
test_func(test_func<B> const & that)
|
||||||
|
: val(that.val)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
template<class B> friend class test_func;
|
||||||
|
|
||||||
|
int operator()(int & l, int const & r) const
|
||||||
|
{
|
||||||
|
return l=r+val;
|
||||||
|
}
|
||||||
|
long operator()(int & l, int const & r)
|
||||||
|
{
|
||||||
|
return -(l=r+val);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Sig>
|
||||||
|
struct result
|
||||||
|
{
|
||||||
|
typedef void type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ensure result_of argument types are what's expected
|
||||||
|
// note: this is *not* how client code should look like
|
||||||
|
template <class Self>
|
||||||
|
struct result< Self const(int&,int const&) > { typedef int type; };
|
||||||
|
|
||||||
|
template <class Self>
|
||||||
|
struct result< Self(int&,int const&) > { typedef long type; };
|
||||||
|
|
||||||
|
template <class Self>
|
||||||
|
struct result< Self(int&,int&) > { typedef char type; };
|
||||||
|
};
|
||||||
|
|
||||||
|
enum { int_, long_, char_ };
|
||||||
|
|
||||||
|
int type_of(int) { return int_; }
|
||||||
|
int type_of(long) { return long_; }
|
||||||
|
int type_of(char) { return char_; }
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
using boost::is_same;
|
||||||
|
using boost::result_of;
|
||||||
|
typedef boost::forward_adapter< test_func<> > f;
|
||||||
|
|
||||||
|
// lvalue,rvalue
|
||||||
|
BOOST_TEST(( is_same<
|
||||||
|
result_of< f(int&, int) >::type, long >::value ));
|
||||||
|
BOOST_TEST(( is_same<
|
||||||
|
result_of< f const (int&, int) >::type, int >::value ));
|
||||||
|
// lvalue,const lvalue
|
||||||
|
BOOST_TEST(( is_same<
|
||||||
|
result_of< f(int&, int const &) >::type, long >::value ));
|
||||||
|
BOOST_TEST(( is_same<
|
||||||
|
result_of< f const (int&, int const &) >::type, int >::value ));
|
||||||
|
// lvalue,lvalue
|
||||||
|
BOOST_TEST(( is_same<
|
||||||
|
result_of< f(int&, int&) >::type, char >::value ));
|
||||||
|
BOOST_TEST(( is_same<
|
||||||
|
result_of< f const (int&, int&) >::type, char >::value ));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
using boost::noncopyable;
|
||||||
|
using boost::forward_adapter;
|
||||||
|
|
||||||
|
int x = 0;
|
||||||
|
test_func<noncopyable> f(7);
|
||||||
|
forward_adapter< test_func<> > func(f);
|
||||||
|
forward_adapter< test_func<noncopyable> & > func_ref(f);
|
||||||
|
forward_adapter< test_func<noncopyable> & > const func_ref_c(f);
|
||||||
|
forward_adapter< test_func<> const > func_c(f);
|
||||||
|
forward_adapter< test_func<> > const func_c2(f);
|
||||||
|
forward_adapter< test_func<noncopyable> const & > func_c_ref(f);
|
||||||
|
|
||||||
|
BOOST_TEST( type_of( func(x,1) ) == long_ );
|
||||||
|
BOOST_TEST( type_of( func_ref(x,1) ) == long_ );
|
||||||
|
BOOST_TEST( type_of( func_ref_c(x,1) ) == long_ );
|
||||||
|
BOOST_TEST( type_of( func_c(x,1) ) == int_ );
|
||||||
|
BOOST_TEST( type_of( func_c2(x,1) ) == int_ );
|
||||||
|
BOOST_TEST( type_of( func_c_ref(x,1) ) == int_ );
|
||||||
|
BOOST_TEST( type_of( func(x,x) ) == char_ );
|
||||||
|
|
||||||
|
BOOST_TEST( func(x,1) == -8 );
|
||||||
|
BOOST_TEST( func_ref(x,1) == -8 );
|
||||||
|
BOOST_TEST( func_ref_c(x,1) == -8 );
|
||||||
|
BOOST_TEST( func_c(x,1) == 8 );
|
||||||
|
BOOST_TEST( func_c2(x,1) == 8 );
|
||||||
|
BOOST_TEST( func_c_ref(x,1) == 8 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
128
forward/test/lightweight_forward_adapter.cpp
Normal file
128
forward/test/lightweight_forward_adapter.cpp
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
/*=============================================================================
|
||||||
|
Copyright (c) 2007 Tobias Schwinger
|
||||||
|
|
||||||
|
Use modification and distribution are 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/config.hpp>
|
||||||
|
|
||||||
|
#ifdef BOOST_MSVC
|
||||||
|
# pragma warning(disable: 4244) // no conversion warnings, please
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/detail/lightweight_test.hpp>
|
||||||
|
#include <boost/functional/lightweight_forward_adapter.hpp>
|
||||||
|
|
||||||
|
#include <boost/type_traits/is_same.hpp>
|
||||||
|
|
||||||
|
#include <boost/blank.hpp>
|
||||||
|
#include <boost/noncopyable.hpp>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
template <class Base = boost::blank>
|
||||||
|
class test_func : public Base
|
||||||
|
{
|
||||||
|
int val;
|
||||||
|
public:
|
||||||
|
test_func(int v) : val(v) { }
|
||||||
|
|
||||||
|
template<class B>
|
||||||
|
test_func(test_func<B> const & that)
|
||||||
|
: val(that.val)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
template<class B> friend class test_func;
|
||||||
|
|
||||||
|
int operator()(int & l, int const & r) const
|
||||||
|
{
|
||||||
|
return l=r+val;
|
||||||
|
}
|
||||||
|
long operator()(int & l, int const & r)
|
||||||
|
{
|
||||||
|
return -(l=r+val);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Sig>
|
||||||
|
struct result
|
||||||
|
{
|
||||||
|
typedef void type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ensure result_of argument types are what's expected
|
||||||
|
// note: this is *not* how client code should look like
|
||||||
|
template <class Self>
|
||||||
|
struct result< Self const(int&,int const&) > { typedef int type; };
|
||||||
|
|
||||||
|
template <class Self>
|
||||||
|
struct result< Self(int&,int const&) > { typedef long type; };
|
||||||
|
|
||||||
|
template <class Self>
|
||||||
|
struct result< Self(int&,int&) > { typedef char type; };
|
||||||
|
};
|
||||||
|
|
||||||
|
enum { int_, long_, char_ };
|
||||||
|
|
||||||
|
int type_of(int) { return int_; }
|
||||||
|
int type_of(long) { return long_; }
|
||||||
|
int type_of(char) { return char_; }
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
using boost::is_same;
|
||||||
|
using boost::result_of;
|
||||||
|
typedef boost::lightweight_forward_adapter< test_func<> > f;
|
||||||
|
typedef boost::reference_wrapper<int> ref;
|
||||||
|
typedef boost::reference_wrapper<int const> cref;
|
||||||
|
|
||||||
|
// lvalue,rvalue
|
||||||
|
BOOST_TEST(( is_same<
|
||||||
|
result_of< f(ref, int) >::type, long >::value ));
|
||||||
|
BOOST_TEST(( is_same<
|
||||||
|
result_of< f const (ref, int) >::type, int >::value ));
|
||||||
|
// lvalue,const lvalue
|
||||||
|
BOOST_TEST(( is_same<
|
||||||
|
result_of< f(ref, cref) >::type, long >::value ));
|
||||||
|
BOOST_TEST(( is_same<
|
||||||
|
result_of< f const (ref, cref) >::type, int >::value ));
|
||||||
|
// lvalue,lvalue
|
||||||
|
BOOST_TEST(( is_same<
|
||||||
|
result_of< f(ref, ref) >::type, char >::value ));
|
||||||
|
BOOST_TEST(( is_same<
|
||||||
|
result_of< f const (ref, ref) >::type, char >::value ));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
using boost::noncopyable;
|
||||||
|
using boost::lightweight_forward_adapter;
|
||||||
|
|
||||||
|
int v = 0; boost::reference_wrapper<int> x(v);
|
||||||
|
test_func<noncopyable> f(7);
|
||||||
|
lightweight_forward_adapter< test_func<> > func(f);
|
||||||
|
lightweight_forward_adapter< test_func<noncopyable> & > func_ref(f);
|
||||||
|
lightweight_forward_adapter< test_func<noncopyable> & > const func_ref_c(f);
|
||||||
|
lightweight_forward_adapter< test_func<> const > func_c(f);
|
||||||
|
lightweight_forward_adapter< test_func<> > const func_c2(f);
|
||||||
|
lightweight_forward_adapter< test_func<noncopyable> const & > func_c_ref(f);
|
||||||
|
|
||||||
|
BOOST_TEST( type_of( func(x,1) ) == long_ );
|
||||||
|
BOOST_TEST( type_of( func_ref(x,1) ) == long_ );
|
||||||
|
BOOST_TEST( type_of( func_ref_c(x,1) ) == long_ );
|
||||||
|
BOOST_TEST( type_of( func_c(x,1) ) == int_ );
|
||||||
|
BOOST_TEST( type_of( func_c2(x,1) ) == int_ );
|
||||||
|
BOOST_TEST( type_of( func_c_ref(x,1) ) == int_ );
|
||||||
|
BOOST_TEST( type_of( func(x,x) ) == char_ );
|
||||||
|
|
||||||
|
BOOST_TEST( func(x,1) == -8 );
|
||||||
|
BOOST_TEST( func_ref(x,1) == -8 );
|
||||||
|
BOOST_TEST( func_ref_c(x,1) == -8 );
|
||||||
|
BOOST_TEST( func_c(x,1) == 8 );
|
||||||
|
BOOST_TEST( func_c2(x,1) == 8 );
|
||||||
|
BOOST_TEST( func_c_ref(x,1) == 8 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
||||||
|
|
472
include/boost/functional/forward_adapter.hpp
Normal file
472
include/boost/functional/forward_adapter.hpp
Normal file
@@ -0,0 +1,472 @@
|
|||||||
|
/*=============================================================================
|
||||||
|
Copyright (c) 2007-2008 Tobias Schwinger
|
||||||
|
|
||||||
|
Use modification and distribution are 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_FUNCTIONAL_FORWARD_ADAPTER_HPP_INCLUDED
|
||||||
|
# ifndef BOOST_PP_IS_ITERATING
|
||||||
|
|
||||||
|
# include <boost/config.hpp>
|
||||||
|
# include <boost/detail/workaround.hpp>
|
||||||
|
|
||||||
|
# include <boost/preprocessor/iteration/iterate.hpp>
|
||||||
|
# include <boost/preprocessor/repetition/enum_params.hpp>
|
||||||
|
# include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||||
|
# include <boost/preprocessor/facilities/intercept.hpp>
|
||||||
|
# include <boost/preprocessor/arithmetic/dec.hpp>
|
||||||
|
|
||||||
|
# include <boost/utility/result_of.hpp>
|
||||||
|
|
||||||
|
# ifndef BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY
|
||||||
|
# define BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY 6
|
||||||
|
# elif BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY < 3
|
||||||
|
# undef BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY
|
||||||
|
# define BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY 3
|
||||||
|
# endif
|
||||||
|
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
template< typename Function, int Arity_Or_MinArity = -1, int MaxArity = -1 >
|
||||||
|
class forward_adapter;
|
||||||
|
|
||||||
|
//----- ---- --- -- - - - -
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template< class MostDerived, typename Function, typename FunctionConst,
|
||||||
|
int Arity, int MinArity >
|
||||||
|
struct forward_adapter_impl;
|
||||||
|
|
||||||
|
struct forward_adapter_result
|
||||||
|
{
|
||||||
|
template< typename Sig > struct apply;
|
||||||
|
|
||||||
|
// Utility metafunction for qualification adjustment on arguments
|
||||||
|
template< typename T > struct q { typedef T const t; };
|
||||||
|
template< typename T > struct q<T const> { typedef T const t; };
|
||||||
|
template< typename T > struct q<T &> { typedef T t; };
|
||||||
|
|
||||||
|
// Utility metafunction to choose target function qualification
|
||||||
|
template< typename T > struct c
|
||||||
|
{ typedef typename T::target_function_t t; };
|
||||||
|
template< typename T > struct c<T& >
|
||||||
|
{ typedef typename T::target_function_t t; };
|
||||||
|
template< typename T > struct c<T const >
|
||||||
|
{ typedef typename T::target_function_const_t t; };
|
||||||
|
template< typename T > struct c<T const&>
|
||||||
|
{ typedef typename T::target_function_const_t t; };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
# define BOOST_TMP_MACRO(f,fn,fc) \
|
||||||
|
boost::detail::forward_adapter_impl< \
|
||||||
|
forward_adapter<f,Arity_Or_MinArity,MaxArity>, fn, fc, \
|
||||||
|
(MaxArity!=-1? MaxArity :Arity_Or_MinArity!=-1? Arity_Or_MinArity \
|
||||||
|
:BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY), \
|
||||||
|
(Arity_Or_MinArity!=-1? Arity_Or_MinArity : 0) >
|
||||||
|
|
||||||
|
template< typename Function, int Arity_Or_MinArity, int MaxArity >
|
||||||
|
class forward_adapter
|
||||||
|
: public BOOST_TMP_MACRO(Function,Function,Function const)
|
||||||
|
, private Function
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
forward_adapter(Function const& f = Function())
|
||||||
|
: Function(f)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
typedef Function target_function_t;
|
||||||
|
typedef Function const target_function_const_t;
|
||||||
|
|
||||||
|
Function & target_function() { return *this; }
|
||||||
|
Function const & target_function() const { return *this; }
|
||||||
|
|
||||||
|
template< typename Sig > struct result
|
||||||
|
: detail::forward_adapter_result::template apply<Sig>
|
||||||
|
{ };
|
||||||
|
|
||||||
|
using BOOST_TMP_MACRO(Function,Function, Function const)::operator();
|
||||||
|
};
|
||||||
|
template< typename Function, int Arity_Or_MinArity, int MaxArity >
|
||||||
|
class forward_adapter< Function const, Arity_Or_MinArity, MaxArity >
|
||||||
|
: public BOOST_TMP_MACRO(Function const, Function const, Function const)
|
||||||
|
, private Function
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
forward_adapter(Function const& f = Function())
|
||||||
|
: Function(f)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
typedef Function const target_function_t;
|
||||||
|
typedef Function const target_function_const_t;
|
||||||
|
|
||||||
|
Function const & target_function() const { return *this; }
|
||||||
|
|
||||||
|
template< typename Sig > struct result
|
||||||
|
: detail::forward_adapter_result::template apply<Sig>
|
||||||
|
{ };
|
||||||
|
|
||||||
|
using BOOST_TMP_MACRO(Function const,Function const, Function const)
|
||||||
|
::operator();
|
||||||
|
};
|
||||||
|
template< typename Function, int Arity_Or_MinArity, int MaxArity >
|
||||||
|
class forward_adapter< Function &, Arity_Or_MinArity, MaxArity >
|
||||||
|
: public BOOST_TMP_MACRO(Function&, Function, Function)
|
||||||
|
{
|
||||||
|
Function& ref_function;
|
||||||
|
public:
|
||||||
|
forward_adapter(Function& f)
|
||||||
|
: ref_function(f)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
typedef Function target_function_t;
|
||||||
|
typedef Function target_function_const_t;
|
||||||
|
|
||||||
|
Function & target_function() const { return this->ref_function; }
|
||||||
|
|
||||||
|
template< typename Sig > struct result
|
||||||
|
: detail::forward_adapter_result::template apply<Sig>
|
||||||
|
{ };
|
||||||
|
|
||||||
|
using BOOST_TMP_MACRO(Function&, Function, Function)::operator();
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef BOOST_TMP_MACRO
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template< class Self >
|
||||||
|
struct forward_adapter_result::apply< Self() >
|
||||||
|
: boost::result_of< typename c<Self>::t() >
|
||||||
|
{ };
|
||||||
|
|
||||||
|
template< class MD, class F, class FC >
|
||||||
|
struct forward_adapter_impl<MD,F,FC,0,0>
|
||||||
|
{
|
||||||
|
inline typename boost::result_of< FC() >::type
|
||||||
|
operator()() const
|
||||||
|
{
|
||||||
|
return static_cast<MD const*>(this)->target_function()();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline typename boost::result_of< F() >::type
|
||||||
|
operator()()
|
||||||
|
{
|
||||||
|
return static_cast<MD*>(this)->target_function()();
|
||||||
|
}
|
||||||
|
|
||||||
|
// closing brace gets generated by preprocessing code, below
|
||||||
|
|
||||||
|
# define BOOST_TMP_MACRO(tpl_params,arg_types,params,args) \
|
||||||
|
template< tpl_params > \
|
||||||
|
inline typename boost::result_of< FC(arg_types) >::type \
|
||||||
|
operator()(params) const \
|
||||||
|
{ \
|
||||||
|
return static_cast<MD const*>(this)->target_function()(args); \
|
||||||
|
} \
|
||||||
|
template< tpl_params > \
|
||||||
|
inline typename boost::result_of< F(arg_types)>::type \
|
||||||
|
operator()(params) \
|
||||||
|
{ \
|
||||||
|
return static_cast<MD*>(this)->target_function()(args); \
|
||||||
|
}
|
||||||
|
|
||||||
|
# // This is the total number of iterations we need
|
||||||
|
# define count ((1 << BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY+1)-2)
|
||||||
|
|
||||||
|
# // Chain file iteration to virtually one loop
|
||||||
|
# if BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY <= 7
|
||||||
|
# define limit1 count
|
||||||
|
# define limit2 0
|
||||||
|
# define limit3 0
|
||||||
|
# else
|
||||||
|
# if BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY <= 15
|
||||||
|
# define limit1 (count >> 8)
|
||||||
|
# define limit2 255
|
||||||
|
# define limit3 0
|
||||||
|
# else
|
||||||
|
# define limit1 (count >> 16)
|
||||||
|
# define limit2 255
|
||||||
|
# define limit3 255
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# define N 0
|
||||||
|
|
||||||
|
# define BOOST_PP_FILENAME_1 <boost/functional/forward_adapter.hpp>
|
||||||
|
# define BOOST_PP_ITERATION_LIMITS (0,limit1)
|
||||||
|
# include BOOST_PP_ITERATE()
|
||||||
|
|
||||||
|
# undef N
|
||||||
|
# undef limit3
|
||||||
|
# undef limit2
|
||||||
|
# undef limit1
|
||||||
|
# undef count
|
||||||
|
# undef BOOST_TMP_MACRO
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class F, int A0, int A1>
|
||||||
|
struct result_of<boost::forward_adapter<F,A0,A1> const ()>
|
||||||
|
: boost::detail::forward_adapter_result::template apply<
|
||||||
|
boost::forward_adapter<F,A0,A1> const () >
|
||||||
|
{ };
|
||||||
|
template<class F, int A0, int A1>
|
||||||
|
struct result_of<boost::forward_adapter<F,A0,A1>()>
|
||||||
|
: boost::detail::forward_adapter_result::template apply<
|
||||||
|
boost::forward_adapter<F,A0,A1>() >
|
||||||
|
{ };
|
||||||
|
template<class F, int A0, int A1>
|
||||||
|
struct result_of<boost::forward_adapter<F,A0,A1> const& ()>
|
||||||
|
: boost::detail::forward_adapter_result::template apply<
|
||||||
|
boost::forward_adapter<F,A0,A1> const () >
|
||||||
|
{ };
|
||||||
|
template<class F, int A0, int A1>
|
||||||
|
struct result_of<boost::forward_adapter<F,A0,A1>& ()>
|
||||||
|
: boost::detail::forward_adapter_result::template apply<
|
||||||
|
boost::forward_adapter<F,A0,A1>() >
|
||||||
|
{ };
|
||||||
|
}
|
||||||
|
|
||||||
|
# define BOOST_FUNCTIONAL_FORWARD_ADAPTER_HPP_INCLUDED
|
||||||
|
|
||||||
|
# elif BOOST_PP_ITERATION_DEPTH() == 1 && limit2
|
||||||
|
# define BOOST_PP_FILENAME_2 <boost/functional/forward_adapter.hpp>
|
||||||
|
# define BOOST_PP_ITERATION_LIMITS (0,limit2)
|
||||||
|
# include BOOST_PP_ITERATE()
|
||||||
|
# elif BOOST_PP_ITERATION_DEPTH() == 2 && limit3
|
||||||
|
# define BOOST_PP_FILENAME_3 <boost/functional/forward_adapter.hpp>
|
||||||
|
# define BOOST_PP_ITERATION_LIMITS (0,limit3)
|
||||||
|
# include BOOST_PP_ITERATE()
|
||||||
|
|
||||||
|
# else
|
||||||
|
|
||||||
|
# // I is the loop counter
|
||||||
|
# if limit2 && limit3
|
||||||
|
# define I (BOOST_PP_ITERATION_1 << 16 | BOOST_PP_ITERATION_2 << 8 | \
|
||||||
|
BOOST_PP_ITERATION_3)
|
||||||
|
# elif limit2
|
||||||
|
# define I (BOOST_PP_ITERATION_1 << 8 | BOOST_PP_ITERATION_2)
|
||||||
|
# else
|
||||||
|
# define I BOOST_PP_ITERATION_1
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if I < count
|
||||||
|
|
||||||
|
# // Done for this arity? Increment N
|
||||||
|
# if (I+2 >> N+1)
|
||||||
|
# if N == 0
|
||||||
|
# undef N
|
||||||
|
# define N 1
|
||||||
|
# elif N == 1
|
||||||
|
# undef N
|
||||||
|
# define N 2
|
||||||
|
# elif N == 2
|
||||||
|
# undef N
|
||||||
|
# define N 3
|
||||||
|
# elif N == 3
|
||||||
|
# undef N
|
||||||
|
# define N 4
|
||||||
|
# elif N == 4
|
||||||
|
# undef N
|
||||||
|
# define N 5
|
||||||
|
# elif N == 5
|
||||||
|
# undef N
|
||||||
|
# define N 6
|
||||||
|
# elif N == 6
|
||||||
|
# undef N
|
||||||
|
# define N 7
|
||||||
|
# elif N == 7
|
||||||
|
# undef N
|
||||||
|
# define N 8
|
||||||
|
# elif N == 8
|
||||||
|
# undef N
|
||||||
|
# define N 9
|
||||||
|
# elif N == 9
|
||||||
|
# undef N
|
||||||
|
# define N 10
|
||||||
|
# elif N == 10
|
||||||
|
# undef N
|
||||||
|
# define N 11
|
||||||
|
# elif N == 11
|
||||||
|
# undef N
|
||||||
|
# define N 12
|
||||||
|
# elif N == 12
|
||||||
|
# undef N
|
||||||
|
# define N 13
|
||||||
|
# elif N == 13
|
||||||
|
# undef N
|
||||||
|
# define N 14
|
||||||
|
# elif N == 14
|
||||||
|
# undef N
|
||||||
|
# define N 15
|
||||||
|
# elif N == 15
|
||||||
|
# undef N
|
||||||
|
# define N 16
|
||||||
|
# endif
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class Self, BOOST_PP_ENUM_PARAMS(N,typename T) >
|
||||||
|
struct forward_adapter_result::apply< Self(BOOST_PP_ENUM_PARAMS(N,T)) >
|
||||||
|
: boost::result_of<
|
||||||
|
typename c<Self>::t(BOOST_PP_ENUM_BINARY_PARAMS(N,
|
||||||
|
typename q<T,>::t& BOOST_PP_INTERCEPT)) >
|
||||||
|
{ };
|
||||||
|
|
||||||
|
template< class MD, class F, class FC >
|
||||||
|
struct forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),N>
|
||||||
|
{
|
||||||
|
template< BOOST_PP_ENUM_PARAMS(N,typename T) >
|
||||||
|
inline typename boost::result_of< F(
|
||||||
|
BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT)) >::type
|
||||||
|
operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT));
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class MD, class F, class FC, int MinArity >
|
||||||
|
struct forward_adapter_impl<MD,F,FC,N,MinArity>
|
||||||
|
: forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),MinArity>
|
||||||
|
{
|
||||||
|
using forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),MinArity>::operator();
|
||||||
|
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# // Zero based count for each arity would be I-(1<<N)+2, but we don't
|
||||||
|
# // need it, unless we need a nicer order.
|
||||||
|
|
||||||
|
# // Macros for the parameter's type modifiers.
|
||||||
|
# if I & 0x000001
|
||||||
|
# define PT0 T0 &
|
||||||
|
# else
|
||||||
|
# define PT0 T0 const &
|
||||||
|
# endif
|
||||||
|
# if I & 0x000002
|
||||||
|
# define PT1 T1 &
|
||||||
|
# else
|
||||||
|
# define PT1 T1 const &
|
||||||
|
# endif
|
||||||
|
# if I & 0x000004
|
||||||
|
# define PT2 T2 &
|
||||||
|
# else
|
||||||
|
# define PT2 T2 const &
|
||||||
|
# endif
|
||||||
|
# if I & 0x000008
|
||||||
|
# define PT3 T3 &
|
||||||
|
# else
|
||||||
|
# define PT3 T3 const &
|
||||||
|
# endif
|
||||||
|
# if I & 0x000010
|
||||||
|
# define PT4 T4 &
|
||||||
|
# else
|
||||||
|
# define PT4 T4 const &
|
||||||
|
# endif
|
||||||
|
# if I & 0x000020
|
||||||
|
# define PT5 T5 &
|
||||||
|
# else
|
||||||
|
# define PT5 T5 const &
|
||||||
|
# endif
|
||||||
|
# if I & 0x000040
|
||||||
|
# define PT6 T6 &
|
||||||
|
# else
|
||||||
|
# define PT6 T6 const &
|
||||||
|
# endif
|
||||||
|
# if I & 0x000080
|
||||||
|
# define PT7 T7 &
|
||||||
|
# else
|
||||||
|
# define PT7 T7 const &
|
||||||
|
# endif
|
||||||
|
# if I & 0x000100
|
||||||
|
# define PT8 T8 &
|
||||||
|
# else
|
||||||
|
# define PT8 T8 const &
|
||||||
|
# endif
|
||||||
|
# if I & 0x000200
|
||||||
|
# define PT9 T9 &
|
||||||
|
# else
|
||||||
|
# define PT9 T9 const &
|
||||||
|
# endif
|
||||||
|
# if I & 0x000400
|
||||||
|
# define PT10 T10 &
|
||||||
|
# else
|
||||||
|
# define PT10 T10 const &
|
||||||
|
# endif
|
||||||
|
# if I & 0x000800
|
||||||
|
# define PT11 T11 &
|
||||||
|
# else
|
||||||
|
# define PT11 T11 const &
|
||||||
|
# endif
|
||||||
|
# if I & 0x001000
|
||||||
|
# define PT12 T12 &
|
||||||
|
# else
|
||||||
|
# define PT12 T12 const &
|
||||||
|
# endif
|
||||||
|
# if I & 0x002000
|
||||||
|
# define PT13 T13 &
|
||||||
|
# else
|
||||||
|
# define PT13 T13 const &
|
||||||
|
# endif
|
||||||
|
# if I & 0x004000
|
||||||
|
# define PT14 T14 &
|
||||||
|
# else
|
||||||
|
# define PT14 T14 const &
|
||||||
|
# endif
|
||||||
|
# if I & 0x008000
|
||||||
|
# define PT15 T15 &
|
||||||
|
# else
|
||||||
|
# define PT15 T15 const &
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if BOOST_WORKAROUND(BOOST_MSVC,BOOST_TESTED_AT(1400))
|
||||||
|
template< BOOST_PP_ENUM_PARAMS(N,typename T) >
|
||||||
|
inline typename boost::result_of< FC(BOOST_PP_ENUM_PARAMS(N,PT))
|
||||||
|
>::type
|
||||||
|
operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a)) const
|
||||||
|
{
|
||||||
|
return static_cast<MD const* const>(this)
|
||||||
|
->target_function()(BOOST_PP_ENUM_PARAMS(N,a));
|
||||||
|
}
|
||||||
|
template< BOOST_PP_ENUM_PARAMS(N,typename T) >
|
||||||
|
inline typename boost::result_of< F(BOOST_PP_ENUM_PARAMS(N,PT))
|
||||||
|
>::type
|
||||||
|
operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a))
|
||||||
|
{
|
||||||
|
return static_cast<MD* const>(this)
|
||||||
|
->target_function()(BOOST_PP_ENUM_PARAMS(N,a));
|
||||||
|
}
|
||||||
|
# else
|
||||||
|
BOOST_TMP_MACRO(BOOST_PP_ENUM_PARAMS(N,typename T),
|
||||||
|
BOOST_PP_ENUM_PARAMS(N,PT), BOOST_PP_ENUM_BINARY_PARAMS(N,PT,a),
|
||||||
|
BOOST_PP_ENUM_PARAMS(N,a) )
|
||||||
|
// ...generates uglier code but is faster - it caches ENUM_*
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# undef PT0
|
||||||
|
# undef PT1
|
||||||
|
# undef PT2
|
||||||
|
# undef PT3
|
||||||
|
# undef PT4
|
||||||
|
# undef PT5
|
||||||
|
# undef PT6
|
||||||
|
# undef PT7
|
||||||
|
# undef PT8
|
||||||
|
# undef PT9
|
||||||
|
# undef PT10
|
||||||
|
# undef PT11
|
||||||
|
# undef PT12
|
||||||
|
# undef PT13
|
||||||
|
# undef PT14
|
||||||
|
# undef PT15
|
||||||
|
|
||||||
|
# endif // I < count
|
||||||
|
|
||||||
|
# undef I
|
||||||
|
# endif // defined(BOOST_PP_IS_ITERATING)
|
||||||
|
|
||||||
|
#endif // include guard
|
||||||
|
|
259
include/boost/functional/lightweight_forward_adapter.hpp
Normal file
259
include/boost/functional/lightweight_forward_adapter.hpp
Normal file
@@ -0,0 +1,259 @@
|
|||||||
|
/*=============================================================================
|
||||||
|
Copyright (c) 2007 Tobias Schwinger
|
||||||
|
|
||||||
|
Use modification and distribution are 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_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_HPP_INCLUDED
|
||||||
|
# ifndef BOOST_PP_IS_ITERATING
|
||||||
|
|
||||||
|
# include <boost/config.hpp>
|
||||||
|
# include <boost/detail/workaround.hpp>
|
||||||
|
|
||||||
|
# include <boost/preprocessor/cat.hpp>
|
||||||
|
# include <boost/preprocessor/iteration/iterate.hpp>
|
||||||
|
# include <boost/preprocessor/repetition/enum.hpp>
|
||||||
|
# include <boost/preprocessor/repetition/enum_params.hpp>
|
||||||
|
# include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||||
|
# include <boost/preprocessor/facilities/intercept.hpp>
|
||||||
|
|
||||||
|
# include <boost/utility/result_of.hpp>
|
||||||
|
# include <boost/ref.hpp>
|
||||||
|
|
||||||
|
# ifndef BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY
|
||||||
|
# define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY 10
|
||||||
|
# elif BOOST_FUNCTIONAL_FORDWARD_ADAPTER_MAX_ARITY < 3
|
||||||
|
# undef BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY
|
||||||
|
# define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY 3
|
||||||
|
# endif
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
template< typename Function, int Arity_Or_MinArity = -1, int MaxArity = -1 >
|
||||||
|
class lightweight_forward_adapter;
|
||||||
|
|
||||||
|
//----- ---- --- -- - - - -
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template< class MostDerived, typename Function, typename FunctionConst,
|
||||||
|
int Arity, int MinArity >
|
||||||
|
struct lightweight_forward_adapter_impl;
|
||||||
|
|
||||||
|
struct lightweight_forward_adapter_result
|
||||||
|
{
|
||||||
|
template< typename Sig > struct apply;
|
||||||
|
|
||||||
|
// Utility metafunction for argument transform
|
||||||
|
template< typename T > struct x { typedef T const& t; };
|
||||||
|
template< typename T > struct x< boost::reference_wrapper<T> >
|
||||||
|
{ typedef T& t; };
|
||||||
|
template< typename T > struct x<T&> : x<T> { };
|
||||||
|
template< typename T > struct x<T const&> : x<T> { };
|
||||||
|
template< typename T > struct x<T const> : x<T> { };
|
||||||
|
|
||||||
|
// Utility metafunction to choose target function qualification
|
||||||
|
template< typename T > struct c
|
||||||
|
{ typedef typename T::target_function_t t; };
|
||||||
|
template< typename T > struct c<T& >
|
||||||
|
{ typedef typename T::target_function_t t; };
|
||||||
|
template< typename T > struct c<T const >
|
||||||
|
{ typedef typename T::target_function_const_t t; };
|
||||||
|
template< typename T > struct c<T const&>
|
||||||
|
{ typedef typename T::target_function_const_t t; };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
# define BOOST_TMP_MACRO(f,fn,fc) \
|
||||||
|
boost::detail::lightweight_forward_adapter_impl< \
|
||||||
|
lightweight_forward_adapter<f,Arity_Or_MinArity,MaxArity>, fn, fc, \
|
||||||
|
(MaxArity!=-1? MaxArity :Arity_Or_MinArity!=-1? Arity_Or_MinArity \
|
||||||
|
:BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY), \
|
||||||
|
(Arity_Or_MinArity!=-1? Arity_Or_MinArity : 0) >
|
||||||
|
|
||||||
|
template< typename Function, int Arity_Or_MinArity, int MaxArity >
|
||||||
|
class lightweight_forward_adapter
|
||||||
|
: public BOOST_TMP_MACRO(Function,Function,Function const)
|
||||||
|
, private Function
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
lightweight_forward_adapter(Function const& f = Function())
|
||||||
|
: Function(f)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
typedef Function target_function_t;
|
||||||
|
typedef Function const target_function_const_t;
|
||||||
|
|
||||||
|
Function & target_function() { return *this; }
|
||||||
|
Function const & target_function() const { return *this; }
|
||||||
|
|
||||||
|
template< typename Sig > struct result
|
||||||
|
: detail::lightweight_forward_adapter_result::template apply<Sig>
|
||||||
|
{ };
|
||||||
|
|
||||||
|
using BOOST_TMP_MACRO(Function,Function, Function const)::operator();
|
||||||
|
};
|
||||||
|
template< typename Function, int Arity_Or_MinArity, int MaxArity >
|
||||||
|
class lightweight_forward_adapter< Function const, Arity_Or_MinArity,
|
||||||
|
MaxArity >
|
||||||
|
: public BOOST_TMP_MACRO(Function const, Function const, Function const)
|
||||||
|
, private Function
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
lightweight_forward_adapter(Function const& f = Function())
|
||||||
|
: Function(f)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
typedef Function const target_function_t;
|
||||||
|
typedef Function const target_function_const_t;
|
||||||
|
|
||||||
|
Function const & target_function() const { return *this; }
|
||||||
|
|
||||||
|
template< typename Sig > struct result
|
||||||
|
: detail::lightweight_forward_adapter_result::template apply<Sig>
|
||||||
|
{ };
|
||||||
|
|
||||||
|
using BOOST_TMP_MACRO(Function const,Function const, Function const)
|
||||||
|
::operator();
|
||||||
|
};
|
||||||
|
template< typename Function, int Arity_Or_MinArity, int MaxArity >
|
||||||
|
class lightweight_forward_adapter< Function &, Arity_Or_MinArity, MaxArity >
|
||||||
|
: public BOOST_TMP_MACRO(Function&, Function, Function)
|
||||||
|
{
|
||||||
|
Function& ref_function;
|
||||||
|
public:
|
||||||
|
lightweight_forward_adapter(Function& f)
|
||||||
|
: ref_function(f)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
typedef Function target_function_t;
|
||||||
|
typedef Function target_function_const_t;
|
||||||
|
|
||||||
|
Function & target_function() const { return this->ref_function; }
|
||||||
|
|
||||||
|
template< typename Sig > struct result
|
||||||
|
: detail::lightweight_forward_adapter_result::template apply<Sig>
|
||||||
|
{ };
|
||||||
|
|
||||||
|
using BOOST_TMP_MACRO(Function&, Function, Function)::operator();
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef BOOST_TMP_MACRO
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
template< class Self >
|
||||||
|
struct lightweight_forward_adapter_result::apply< Self() >
|
||||||
|
: boost::result_of< typename c<Self>::t() >
|
||||||
|
{ };
|
||||||
|
|
||||||
|
template< class MD, class F, class FC >
|
||||||
|
struct lightweight_forward_adapter_impl<MD,F,FC,0,0>
|
||||||
|
: lightweight_forward_adapter_result
|
||||||
|
{
|
||||||
|
inline typename boost::result_of< FC() >::type
|
||||||
|
operator()() const
|
||||||
|
{
|
||||||
|
return static_cast<MD const*>(this)->target_function()();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline typename boost::result_of< F() >::type
|
||||||
|
operator()()
|
||||||
|
{
|
||||||
|
return static_cast<MD*>(this)->target_function()();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
# define BOOST_PP_FILENAME_1 \
|
||||||
|
<boost/functional/lightweight_forward_adapter.hpp>
|
||||||
|
# define BOOST_PP_ITERATION_LIMITS \
|
||||||
|
(1,BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY)
|
||||||
|
# include BOOST_PP_ITERATE()
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<class F, int A0, int A1>
|
||||||
|
struct result_of<boost::lightweight_forward_adapter<F,A0,A1> const ()>
|
||||||
|
: boost::detail::lightweight_forward_adapter_result::template apply<
|
||||||
|
boost::lightweight_forward_adapter<F,A0,A1> const () >
|
||||||
|
{ };
|
||||||
|
template<class F, int A0, int A1>
|
||||||
|
struct result_of<boost::lightweight_forward_adapter<F,A0,A1>()>
|
||||||
|
: boost::detail::lightweight_forward_adapter_result::template apply<
|
||||||
|
boost::lightweight_forward_adapter<F,A0,A1>() >
|
||||||
|
{ };
|
||||||
|
template<class F, int A0, int A1>
|
||||||
|
struct result_of<boost::lightweight_forward_adapter<F,A0,A1> const& ()>
|
||||||
|
: boost::detail::lightweight_forward_adapter_result::template apply<
|
||||||
|
boost::lightweight_forward_adapter<F,A0,A1> const () >
|
||||||
|
{ };
|
||||||
|
template<class F, int A0, int A1>
|
||||||
|
struct result_of<boost::lightweight_forward_adapter<F,A0,A1>& ()>
|
||||||
|
: boost::detail::lightweight_forward_adapter_result::template apply<
|
||||||
|
boost::lightweight_forward_adapter<F,A0,A1>() >
|
||||||
|
{ };
|
||||||
|
}
|
||||||
|
|
||||||
|
# define BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_HPP_INCLUDED
|
||||||
|
|
||||||
|
# else // defined(BOOST_PP_IS_ITERATING)
|
||||||
|
# define N BOOST_PP_ITERATION()
|
||||||
|
|
||||||
|
template< class Self, BOOST_PP_ENUM_PARAMS(N,typename T) >
|
||||||
|
struct lightweight_forward_adapter_result::apply<
|
||||||
|
Self (BOOST_PP_ENUM_PARAMS(N,T)) >
|
||||||
|
: boost::result_of<
|
||||||
|
typename c<Self>::t (BOOST_PP_ENUM_BINARY_PARAMS(N,
|
||||||
|
typename x<T,>::t BOOST_PP_INTERCEPT)) >
|
||||||
|
{ };
|
||||||
|
|
||||||
|
template< class MD, class F, class FC >
|
||||||
|
struct lightweight_forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),N>
|
||||||
|
: lightweight_forward_adapter_result
|
||||||
|
{
|
||||||
|
template< BOOST_PP_ENUM_PARAMS(N,typename T) >
|
||||||
|
inline typename boost::result_of< F(BOOST_PP_ENUM_BINARY_PARAMS(N,
|
||||||
|
T,const& BOOST_PP_INTERCEPT)) >::type
|
||||||
|
operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,& BOOST_PP_INTERCEPT));
|
||||||
|
};
|
||||||
|
|
||||||
|
template< class MD, class F, class FC, int MinArity >
|
||||||
|
struct lightweight_forward_adapter_impl<MD,F,FC,N,MinArity>
|
||||||
|
: lightweight_forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),MinArity>
|
||||||
|
{
|
||||||
|
using lightweight_forward_adapter_impl<MD,F,FC,BOOST_PP_DEC(N),
|
||||||
|
MinArity>::operator();
|
||||||
|
|
||||||
|
# define M(z,i,d) \
|
||||||
|
static_cast<typename d::template x<T##i>::t>(a##i)
|
||||||
|
|
||||||
|
template< BOOST_PP_ENUM_PARAMS(N,typename T) >
|
||||||
|
inline typename lightweight_forward_adapter_result::template apply<
|
||||||
|
MD const (BOOST_PP_ENUM_BINARY_PARAMS(N,
|
||||||
|
T,const& BOOST_PP_INTERCEPT)) >::type
|
||||||
|
operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const& a)) const
|
||||||
|
{
|
||||||
|
typedef lightweight_forward_adapter_result _;
|
||||||
|
return static_cast<MD const*>(this)->target_function()(
|
||||||
|
BOOST_PP_ENUM(N,M,_));
|
||||||
|
}
|
||||||
|
template< BOOST_PP_ENUM_PARAMS(N,typename T) >
|
||||||
|
inline typename lightweight_forward_adapter_result::template apply<
|
||||||
|
MD (BOOST_PP_ENUM_BINARY_PARAMS(N,
|
||||||
|
T,const& BOOST_PP_INTERCEPT)) >::type
|
||||||
|
operator()(BOOST_PP_ENUM_BINARY_PARAMS(N,T,const& a))
|
||||||
|
{
|
||||||
|
typedef lightweight_forward_adapter_result _;
|
||||||
|
return static_cast<MD*>(this)->target_function()(
|
||||||
|
BOOST_PP_ENUM(N,M,_));
|
||||||
|
}
|
||||||
|
# undef M
|
||||||
|
};
|
||||||
|
|
||||||
|
# undef N
|
||||||
|
# endif // defined(BOOST_PP_IS_ITERATING)
|
||||||
|
|
||||||
|
#endif // include guard
|
||||||
|
|
Reference in New Issue
Block a user