mirror of
https://github.com/boostorg/bind.git
synced 2026-04-14 05:36:01 +02:00
Compare commits
15 Commits
boost-1.28
...
boost-1.29
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5bca8bb195 | ||
|
|
c4a96abfa6 | ||
|
|
55dbef0000 | ||
|
|
b63a6a5d99 | ||
|
|
52cc55329b | ||
|
|
5db80e9a33 | ||
|
|
3cbc321fa5 | ||
|
|
2f97add842 | ||
|
|
5345f14829 | ||
|
|
0053801ad2 | ||
|
|
ad043d1fff | ||
|
|
35ee2f3a52 | ||
|
|
5b1528f3f4 | ||
|
|
2277238db7 | ||
|
|
bdde6cd8b2 |
251
bind.html
251
bind.html
@@ -10,7 +10,7 @@
|
||||
<td width="277">
|
||||
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" width="277" height="86">
|
||||
</td>
|
||||
<td align="middle">
|
||||
<td align="center">
|
||||
<h1>bind.hpp</h1>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -24,8 +24,8 @@
|
||||
function pointers</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#with_function_objects">Using bind with function
|
||||
objects</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#with_member_functions">Using bind with member
|
||||
function pointers</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#with_member_pointers">Using bind with pointers
|
||||
to members</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#nested_binds">Using nested binds for function
|
||||
composition</a></h4>
|
||||
<h3 style="MARGIN-LEFT: 20pt"><a href="#Examples">Examples</a></h3>
|
||||
@@ -45,6 +45,8 @@
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#Q_com">Does <b>bind</b> work with COM methods?</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#Q_mac">Does <b>bind</b> work with Mac toolbox
|
||||
functions?</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#Q_extern_C">Does <b>bind</b> work with extern
|
||||
"C" functions?</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#Q_auto_stdcall">Why doesn't <b>bind</b> automatically
|
||||
recognize nonstandard functions?</a></h4>
|
||||
<h3 style="MARGIN-LEFT: 20pt"><a href="#Troubleshooting">Troubleshooting</a></h3>
|
||||
@@ -70,11 +72,13 @@
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#CommonRequirements">Common requirements</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#CommonDefinitions">Common definitions</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#bind">bind</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#AdditionalOverloads">Additional overloads</a></h4>
|
||||
<h3 style="MARGIN-LEFT: 20pt"><a href="#Implementation">Implementation</a></h3>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#Files">Files</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#Dependencies">Dependencies</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#NumberOfArguments">Number of Arguments</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#stdcall">"__stdcall" and "pascal" Support</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#stdcall">"__stdcall", "__fastcall", and
|
||||
"pascal" Support</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#BOOST_BIND">Using the BOOST_BIND macro</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#visit_each"><b>visit_each</b> support</a></h4>
|
||||
<h3 style="MARGIN-LEFT: 20pt"><a href="#Acknowledgements">Acknowledgements</a></h3>
|
||||
@@ -198,13 +202,13 @@ bind(std::less<int>(), _1, 9)(x); // x < 9
|
||||
<p>
|
||||
[Note: the ability to omit the return type is not available on all compilers.]
|
||||
</p>
|
||||
<h3><a name="with_member_functions">Using bind with member function pointers</a></h3>
|
||||
<h3><a name="with_member_pointers">Using bind with pointers to members</a></h3>
|
||||
<p>
|
||||
Pointers to member functions are not function objects, because they do not
|
||||
support <tt>operator()</tt>. For convenience, <b>bind</b> accepts member
|
||||
function pointers as its first argument, and the behavior is as if <a href="mem_fn.html">
|
||||
boost::mem_fn</a> has been used to convert the member function pointer into
|
||||
a function object. In other words, the expression
|
||||
Pointers to member functions and pointers to data members are not function
|
||||
objects, because they do not support <tt>operator()</tt>. For convenience, <b>bind</b>
|
||||
accepts member pointers as its first argument, and the behavior is as if <a href="mem_fn.html">
|
||||
boost::mem_fn</a> has been used to convert the member pointer into a
|
||||
function object. In other words, the expression
|
||||
</p>
|
||||
<pre>
|
||||
bind(&X::f, <i>args</i>)
|
||||
@@ -216,7 +220,8 @@ bind(&X::f, <i>args</i>)
|
||||
bind<R>(<a href="mem_fn.html">mem_fn</a>(&X::f), <i>args</i>)
|
||||
</pre>
|
||||
<p>
|
||||
where <b>R</b> is the return type of <b>X::f</b>.
|
||||
where <b>R</b> is the return type of <b>X::f</b> (for member functions) or a
|
||||
const reference to the type of the member (for data members.)
|
||||
</p>
|
||||
<p>
|
||||
[Note: <b>mem_fn</b> creates function objects that are able to accept a
|
||||
@@ -260,13 +265,13 @@ bind(&X::f, p, _1)(i); // (<i>internal copy of p</i>)->f(i)
|
||||
bind(f, bind(g, _1))(x); // f(g(x))
|
||||
</pre>
|
||||
<p>
|
||||
The inner <STRONG>bind</STRONG> expressions are evaluated, in
|
||||
unspecified order, before the outer <STRONG>bind</STRONG> when the
|
||||
function object is called; the results of the evaluation are then substituted
|
||||
in their place when the outer <STRONG>bind</STRONG> is evaluated. In the
|
||||
example above, when the function object is called with the argument list <tt>(x)</tt>,
|
||||
<tt>bind(g, _1)(x)</tt> is evaluated first, yielding <tt>g(x)</tt>, and then <tt>bind(f,
|
||||
g(x))(x)</tt> is evaluated, yielding the final result <tt>f(g(x))</tt>.
|
||||
The inner <STRONG>bind</STRONG> expressions are evaluated, in unspecified
|
||||
order, before the outer <STRONG>bind</STRONG> when the function object is
|
||||
called; the results of the evaluation are then substituted in their place when
|
||||
the outer <STRONG>bind</STRONG> is evaluated. In the example above, when the
|
||||
function object is called with the argument list <tt>(x)</tt>, <tt>bind(g, _1)(x)</tt>
|
||||
is evaluated first, yielding <tt>g(x)</tt>, and then <tt>bind(f, g(x))(x)</tt> is
|
||||
evaluated, yielding the final result <tt>f(g(x))</tt>.
|
||||
</p>
|
||||
<P>
|
||||
This feature of <b>bind</b> can be used to perform function composition. See <a href="bind_as_compose.cpp">
|
||||
@@ -289,8 +294,8 @@ std::for_each(v.begin(), v.end(), bind(_1, 5));
|
||||
The desired effect can be achieved via a helper function object <STRONG>apply</STRONG>
|
||||
that applies its first argument, as a function object, to the rest of its
|
||||
argument list. For convenience, an implementation of <STRONG>apply</STRONG> is
|
||||
provided in the <STRONG>boost/bind/apply.hpp</STRONG> header file. Here is
|
||||
how the modified version of the previous example looks like:
|
||||
provided in the <STRONG>boost/bind/apply.hpp</STRONG> header file. Here is how
|
||||
the modified version of the previous example looks like:
|
||||
</p>
|
||||
<pre>
|
||||
typedef void (*pf)(int);
|
||||
@@ -305,9 +310,9 @@ std::for_each(v.begin(), v.end(), bind(apply<void>(), _1, 5));
|
||||
protect</STRONG>, that masks the type so that <STRONG>bind</STRONG> does
|
||||
not recognize and evaluate it. When called, <STRONG>protect</STRONG> simply
|
||||
forwards the argument list to the other function object unmodified.</P>
|
||||
<P>The header <STRONG>boost/bind/protect.hpp</STRONG> contains an
|
||||
implementation of <STRONG>protect</STRONG>. To protect a <STRONG>bind</STRONG>
|
||||
function object from evaluation, use <tt>protect(bind(f, ...))</tt>.</P>
|
||||
<P>The header <STRONG>boost/bind/protect.hpp</STRONG> contains an implementation of <STRONG>
|
||||
protect</STRONG>. To protect a <STRONG>bind</STRONG> function object from
|
||||
evaluation, use <tt>protect(bind(f, ...))</tt>.</P>
|
||||
<h2><a name="Examples">Examples</a></h2>
|
||||
<h3><a name="with_algorithms">Using bind with standard algorithms</a></h3>
|
||||
<pre>
|
||||
@@ -451,6 +456,15 @@ template<class T> void f(T const & t);
|
||||
alternative is to treat the function as a <a href="#with_function_objects">generic
|
||||
function object</a> and use the bind<R>(f, ...) syntax.
|
||||
</p>
|
||||
<h3><a name="Q_extern_C">Does <b>bind</b> work with extern "C" functions?</a></h3>
|
||||
<p>
|
||||
Sometimes. On some platforms, pointers to extern "C" functions are equivalent
|
||||
to "ordinary" function pointers, so they work fine. Other platforms treat them
|
||||
as different types. A platform-specific implementation of <b>bind</b> is
|
||||
expected to handle the problem transparently; this implementation does not. As
|
||||
usual, the workaround is to treat the function as a <a href="#with_function_objects">
|
||||
generic function object</a> and use the bind<R>(f, ...) syntax.
|
||||
</p>
|
||||
<h3><a name="Q_auto_stdcall">Why doesn't <b>bind</b> automatically recognize
|
||||
nonstandard functions?</a></h3>
|
||||
<p>
|
||||
@@ -458,8 +472,9 @@ template<class T> void f(T const & t);
|
||||
lock-in. Had the <a href="#stdcall">appropriate macros</a> been defined
|
||||
automatically, you could have accidentally taken advantage of them without
|
||||
realizing that your code is, perhaps, no longer portable. In addition, some
|
||||
compilers have the option to make <b>__stdcall</b> their default calling
|
||||
convention, in which case no separate support would be necessary.
|
||||
compilers have the option to make <b>__stdcall</b> (<STRONG>__fastcall</STRONG>)
|
||||
their default calling convention, in which case no separate support would be
|
||||
necessary.
|
||||
</p>
|
||||
<h2><a name="Troubleshooting">Troubleshooting</a></h2>
|
||||
<h3><a name="err_num_args">Incorrect number of arguments</a></h3>
|
||||
@@ -570,10 +585,14 @@ int main()
|
||||
<h3><a name="err_nonstd">Binding a nonstandard function</a></h3>
|
||||
<p>
|
||||
By default, the bind(f, a1, a2, ..., aN) <A href="#Q_forms">form</A> recognizes
|
||||
"ordinary" C++ functions and function pointers. <A href="#stdcall">Functions that use
|
||||
a different calling convention</A>, or variable-argument functions
|
||||
such as <STRONG>std::printf</STRONG>, do not work. The general bind<R>(f,
|
||||
a1, a2, ..., aN) <A href="#Q_forms">form</A> works with nonstandard functions.
|
||||
"ordinary" C++ functions and function pointers. <A href="#stdcall">Functions that
|
||||
use a different calling convention</A>, or variable-argument functions such
|
||||
as <STRONG>std::printf</STRONG>, do not work. The general bind<R>(f, a1,
|
||||
a2, ..., aN) <A href="#Q_forms">form</A> works with nonstandard functions.
|
||||
</p>
|
||||
<p>
|
||||
On some platforms, extern "C" functions, like <b>std::strcmp</b>, are not
|
||||
recognized by the short form of bind.
|
||||
</p>
|
||||
<P>
|
||||
See also <A href="#stdcall" name="stdcall">"__stdcall" and "pascal" Support</A>.</P>
|
||||
@@ -641,35 +660,37 @@ namespace boost
|
||||
|
||||
// no arguments
|
||||
|
||||
template<class R, class F> <i>implementation-defined-1</i> <a href="#bind_1">bind</a>(F f);
|
||||
template<class R, class F> <i>unspecified-1</i> <a href="#bind_1">bind</a>(F f);
|
||||
|
||||
template<class F> <i>implementation-defined-1-1</i> <a href="#bind_1_1">bind</a>(F f);
|
||||
template<class F> <i>unspecified-1-1</i> <a href="#bind_1_1">bind</a>(F f);
|
||||
|
||||
template<class R> <i>implementation-defined-2</i> <a href="#bind_2">bind</a>(R (*f) ());
|
||||
template<class R> <i>unspecified-2</i> <a href="#bind_2">bind</a>(R (*f) ());
|
||||
|
||||
// one argument
|
||||
|
||||
template<class R, class F, class A1> <i>implementation-defined-3</i> <a href="#bind_3">bind</a>(F f, A1 a1);
|
||||
template<class R, class F, class A1> <i>unspecified-3</i> <a href="#bind_3">bind</a>(F f, A1 a1);
|
||||
|
||||
template<class F, class A1> <i>implementation-defined-3-1</i> <a href="#bind_3_1">bind</a>(F f, A1 a1);
|
||||
template<class F, class A1> <i>unspecified-3-1</i> <a href="#bind_3_1">bind</a>(F f, A1 a1);
|
||||
|
||||
template<class R, class B1, class A1> <i>implementation-defined-4</i> <a href="#bind_4">bind</a>(R (*f) (B1), A1 a1);
|
||||
template<class R, class B1, class A1> <i>unspecified-4</i> <a href="#bind_4">bind</a>(R (*f) (B1), A1 a1);
|
||||
|
||||
template<class R, class T, class A1> <i>implementation-defined-5</i> <a href="#bind_5">bind</a>(R (T::*f) (), A1 a1);
|
||||
template<class R, class T, class A1> <i>unspecified-5</i> <a href="#bind_5">bind</a>(R (T::*f) (), A1 a1);
|
||||
|
||||
template<class R, class T, class A1> <i>implementation-defined-6</i> <a href="#bind_6">bind</a>(R (T::*f) () const, A1 a1);
|
||||
template<class R, class T, class A1> <i>unspecified-6</i> <a href="#bind_6">bind</a>(R (T::*f) () const, A1 a1);
|
||||
|
||||
template<class R, class T, class A1> <i>unspecified-6-1</i> <a href="#bind_6_1">bind</a>(R T::*f, A1 a1);
|
||||
|
||||
// two arguments
|
||||
|
||||
template<class R, class F, class A1, class A2> <i>implementation-defined-7</i> <a href="#bind_7">bind</a>(F f, A1 a1, A2 a2);
|
||||
template<class R, class F, class A1, class A2> <i>unspecified-7</i> <a href="#bind_7">bind</a>(F f, A1 a1, A2 a2);
|
||||
|
||||
template<class F, class A1, class A2> <i>implementation-defined-7-1</i> <a href="#bind_7_1">bind</a>(F f, A1 a1, A2 a2);
|
||||
template<class F, class A1, class A2> <i>unspecified-7-1</i> <a href="#bind_7_1">bind</a>(F f, A1 a1, A2 a2);
|
||||
|
||||
template<class R, class B1, class B2, class A1, class A2> <i>implementation-defined-8</i> <a href="#bind_8">bind</a>(R (*f) (B1, B2), A1 a1, A2 a2);
|
||||
template<class R, class B1, class B2, class A1, class A2> <i>unspecified-8</i> <a href="#bind_8">bind</a>(R (*f) (B1, B2), A1 a1, A2 a2);
|
||||
|
||||
template<class R, class T, class B1, class A1, class A2> <i>implementation-defined-9</i> <a href="#bind_9">bind</a>(R (T::*f) (B1), A1 a1, A2 a2);
|
||||
template<class R, class T, class B1, class A1, class A2> <i>unspecified-9</i> <a href="#bind_9">bind</a>(R (T::*f) (B1), A1 a1, A2 a2);
|
||||
|
||||
template<class R, class T, class B1, class A1, class A2> <i>implementation-defined-10</i> <a href="#bind_10">bind</a>(R (T::*f) (B1) const, A1 a1, A2 a2);
|
||||
template<class R, class T, class B1, class A1, class A2> <i>unspecified-10</i> <a href="#bind_10">bind</a>(R (T::*f) (B1) const, A1 a1, A2 a2);
|
||||
|
||||
// implementation defined number of additional overloads for more arguments
|
||||
|
||||
@@ -678,11 +699,11 @@ template<class R, class T, class B1, class A1, class A2> <i>implementation
|
||||
namespace
|
||||
{
|
||||
|
||||
<i>implementation-defined-placeholder-type-1</i> _1;
|
||||
<i>unspecified-placeholder-type-1</i> _1;
|
||||
|
||||
<i>implementation-defined-placeholder-type-2</i> _2;
|
||||
<i>unspecified-placeholder-type-2</i> _2;
|
||||
|
||||
<i>implementation-defined-placeholder-type-3</i> _3;
|
||||
<i>unspecified-placeholder-type-3</i> _3;
|
||||
|
||||
// implementation defined number of additional placeholder definitions
|
||||
|
||||
@@ -690,12 +711,11 @@ namespace
|
||||
</pre>
|
||||
<h3><a name="CommonRequirements">Common requirements</a></h3>
|
||||
<p>
|
||||
All <tt><i>implementation-defined-N</i></tt> types returned by <b>bind</b> are <b>CopyConstructible</b>.
|
||||
<tt><i>implementation-defined-N</i>::result_type</tt> is defined as the return
|
||||
type of <tt><i>implementation-defined-N</i>::operator()</tt>.
|
||||
All <tt><i>unspecified-N</i></tt> types returned by <b>bind</b> are <b>CopyConstructible</b>.
|
||||
<tt><i>unspecified-N</i>::result_type</tt> is defined as the return type of <tt><i>unspecified-N</i>::operator()</tt>.
|
||||
</p>
|
||||
<p>
|
||||
All <tt><i>implementation-defined-placeholder-N</i></tt> types are <b>CopyConstructible</b>.
|
||||
All <tt><i>unspecified-placeholder-N</i></tt> types are <b>CopyConstructible</b>.
|
||||
Their copy constructors do not throw exceptions.
|
||||
</p>
|
||||
<h3><a name="CommonDefinitions">Common definitions</a></h3>
|
||||
@@ -717,11 +737,10 @@ namespace
|
||||
<tt>x</tt> otherwise.</li>
|
||||
</ul>
|
||||
<h3><a name="bind">bind</a></h3>
|
||||
<h4><a name="bind_1">template<class R, class F> <i>implementation-defined-1</i> bind(F
|
||||
f)</a></h4>
|
||||
<h4><a name="bind_1">template<class R, class F> <i>unspecified-1</i> bind(F f)</a></h4>
|
||||
<blockquote>
|
||||
<p>
|
||||
<b>Returns:</b> a function object <i>λ</i> such that the expression <tt>λ(v<sub>1</sub>,
|
||||
<b>Returns:</b> A function object <i>λ</i> such that the expression <tt>λ(v<sub>1</sub>,
|
||||
v<sub>2</sub>, ..., v<sub>m</sub>)</tt> is equivalent to <tt><b>f</b>()</tt>,
|
||||
implicitly converted to <b>R</b>.
|
||||
</p>
|
||||
@@ -730,29 +749,31 @@ namespace
|
||||
exception.
|
||||
</p>
|
||||
</blockquote>
|
||||
<h4><a name="bind_1_1">template<class F> <i>implementation-defined-1-1</i> bind(F
|
||||
f)</a></h4>
|
||||
<h4><a name="bind_1_1">template<class F> <i>unspecified-1-1</i> bind(F f)</a></h4>
|
||||
<blockquote>
|
||||
<p>
|
||||
<b>Effects:</b> equivalent to <tt>bind<typename F::result_type, F>(f);</tt>
|
||||
<b>Effects:</b> Equivalent to <tt>bind<typename F::result_type, F>(f);</tt>
|
||||
</p>
|
||||
<p>
|
||||
<b>Notes:</b> Implementations are allowed to infer the return type of <b>f</b> via
|
||||
other means as an extension, without relying on the <tt>result_type</tt> member.
|
||||
</p>
|
||||
</blockquote>
|
||||
<h4><a name="bind_2">template<class R> <i>implementation-defined-2</i> bind(R
|
||||
(*f) ())</a></h4>
|
||||
<h4><a name="bind_2">template<class R> <i>unspecified-2</i> bind(R (*f) ())</a></h4>
|
||||
<blockquote>
|
||||
<p>
|
||||
<b>Returns:</b> a function object <i>λ</i> such that the expression <tt>λ(v<sub>1</sub>,
|
||||
<b>Returns:</b> A function object <i>λ</i> such that the expression <tt>λ(v<sub>1</sub>,
|
||||
v<sub>2</sub>, ..., v<sub>m</sub>)</tt> is equivalent to <tt><b>f</b>()</tt>.
|
||||
</p>
|
||||
<p>
|
||||
<b>Throws:</b> Nothing.
|
||||
</p>
|
||||
</blockquote>
|
||||
<h4><a name="bind_3">template<class R, class F, class A1> <i>implementation-defined-3</i>
|
||||
bind(F f, A1 a1)</a></h4>
|
||||
<h4><a name="bind_3">template<class R, class F, class A1> <i>unspecified-3</i> bind(F
|
||||
f, A1 a1)</a></h4>
|
||||
<blockquote>
|
||||
<p>
|
||||
<b>Returns:</b> a function object <i>λ</i> such that the expression <tt>λ(v<sub>1</sub>,
|
||||
<b>Returns:</b> A function object <i>λ</i> such that the expression <tt>λ(v<sub>1</sub>,
|
||||
v<sub>2</sub>, ..., v<sub>m</sub>)</tt> is equivalent to <tt><b>f</b>(µ(<b>a1</b>,
|
||||
v<sub>1</sub>, v<sub>2</sub>, ..., v<sub>m</sub>))</tt>, implicitly
|
||||
converted to <b>R</b>.
|
||||
@@ -762,19 +783,23 @@ namespace
|
||||
an exception.
|
||||
</p>
|
||||
</blockquote>
|
||||
<h4><a name="bind_3_1">template<class F, class A1> <i>implementation-defined-3-1</i>
|
||||
bind(F f, A1 a1)</a></h4>
|
||||
<h4><a name="bind_3_1">template<class F, class A1> <i>unspecified-3-1</i> bind(F
|
||||
f, A1 a1)</a></h4>
|
||||
<blockquote>
|
||||
<p>
|
||||
<b>Effects:</b> equivalent to <tt>bind<typename F::result_type, F, A1>(f,
|
||||
<b>Effects:</b> Equivalent to <tt>bind<typename F::result_type, F, A1>(f,
|
||||
a1);</tt>
|
||||
</p>
|
||||
<p>
|
||||
<b>Notes:</b> Implementations are allowed to infer the return type of <b>f</b> via
|
||||
other means as an extension, without relying on the <tt>result_type</tt> member.
|
||||
</p>
|
||||
</blockquote>
|
||||
<h4><a name="bind_4">template<class R, class B1, class A1> <i>implementation-defined-4</i>
|
||||
bind(R (*f) (B1), A1 a1)</a></h4>
|
||||
<h4><a name="bind_4">template<class R, class B1, class A1> <i>unspecified-4</i> bind(R
|
||||
(*f) (B1), A1 a1)</a></h4>
|
||||
<blockquote>
|
||||
<p>
|
||||
<b>Returns:</b> a function object <i>λ</i> such that the expression <tt>λ(v<sub>1</sub>,
|
||||
<b>Returns:</b> A function object <i>λ</i> such that the expression <tt>λ(v<sub>1</sub>,
|
||||
v<sub>2</sub>, ..., v<sub>m</sub>)</tt> is equivalent to <tt><b>f</b>(µ(<b>a1</b>,
|
||||
v<sub>1</sub>, v<sub>2</sub>, ..., v<sub>m</sub>))</tt>.
|
||||
</p>
|
||||
@@ -783,27 +808,35 @@ namespace
|
||||
exception.
|
||||
</p>
|
||||
</blockquote>
|
||||
<h4><a name="bind_5">template<class R, class T, class A1> <i>implementation-defined-5</i>
|
||||
bind(R (T::*f) (), A1 a1)</a></h4>
|
||||
<h4><a name="bind_5">template<class R, class T, class A1> <i>unspecified-5</i> bind(R
|
||||
(T::*f) (), A1 a1)</a></h4>
|
||||
<blockquote>
|
||||
<p>
|
||||
<b>Effects:</b> equivalent to <tt>bind<R>(<a href="mem_fn.html">boost::mem_fn</a>(f),
|
||||
<b>Effects:</b> Equivalent to <tt>bind<R>(<a href="mem_fn.html">boost::mem_fn</a>(f),
|
||||
a1);</tt>
|
||||
</p>
|
||||
</blockquote>
|
||||
<h4><a name="bind_6">template<class R, class T, class A1> <i>implementation-defined-6</i>
|
||||
bind(R (T::*f) () const, A1 a1)</a></h4>
|
||||
<h4><a name="bind_6">template<class R, class T, class A1> <i>unspecified-6</i> bind(R
|
||||
(T::*f) () const, A1 a1)</a></h4>
|
||||
<blockquote>
|
||||
<p>
|
||||
<b>Effects:</b> equivalent to <tt>bind<R>(<a href="mem_fn.html">boost::mem_fn</a>(f),
|
||||
<b>Effects:</b> Equivalent to <tt>bind<R>(<a href="mem_fn.html">boost::mem_fn</a>(f),
|
||||
a1);</tt>
|
||||
</p>
|
||||
</blockquote>
|
||||
<h4><a name="bind_7">template<class R, class F, class A1, class A2> <i>implementation-defined-7</i>
|
||||
<h4><a name="bind_6_1">template<class R, class T, class A1> <i>unspecified-6-1</i>
|
||||
bind(R T::*f, A1 a1)</a></h4>
|
||||
<blockquote>
|
||||
<p>
|
||||
<b>Effects:</b> Equivalent to <tt>bind<R const &>(<a href="mem_fn.html">boost::mem_fn</a>(f),
|
||||
a1);</tt>
|
||||
</p>
|
||||
</blockquote>
|
||||
<h4><a name="bind_7">template<class R, class F, class A1, class A2> <i>unspecified-7</i>
|
||||
bind(F f, A1 a1, A2 a2)</a></h4>
|
||||
<blockquote>
|
||||
<p>
|
||||
<b>Returns:</b> a function object <i>λ</i> such that the expression <tt>λ(v<sub>1</sub>,
|
||||
<b>Returns:</b> A function object <i>λ</i> such that the expression <tt>λ(v<sub>1</sub>,
|
||||
v<sub>2</sub>, ..., v<sub>m</sub>)</tt> is equivalent to <tt><b>f</b>(µ(<b>a1</b>,
|
||||
v<sub>1</sub>, v<sub>2</sub>, ..., v<sub>m</sub>), µ(<b>a2</b>, v<sub>1</sub>,
|
||||
v<sub>2</sub>, ..., v<sub>m</sub>))</tt>, implicitly converted to <b>R</b>.
|
||||
@@ -813,19 +846,23 @@ namespace
|
||||
throw an exception.
|
||||
</p>
|
||||
</blockquote>
|
||||
<h4><a name="bind_7_1">template<class F, class A1, class A2> <i>implementation-defined-7-1</i>
|
||||
<h4><a name="bind_7_1">template<class F, class A1, class A2> <i>unspecified-7-1</i>
|
||||
bind(F f, A1 a1, A2 a2)</a></h4>
|
||||
<blockquote>
|
||||
<p>
|
||||
<b>Effects:</b> equivalent to <tt>bind<typename F::result_type, F, A1, A2>(f,
|
||||
<b>Effects:</b> Equivalent to <tt>bind<typename F::result_type, F, A1, A2>(f,
|
||||
a1, a2);</tt>
|
||||
</p>
|
||||
<p>
|
||||
<b>Notes:</b> Implementations are allowed to infer the return type of <b>f</b> via
|
||||
other means as an extension, without relying on the <tt>result_type</tt> member.
|
||||
</p>
|
||||
</blockquote>
|
||||
<h4><a name="bind_8">template<class R, class B1, class B2, class A1, class A2> <i>implementation-defined-8</i>
|
||||
<h4><a name="bind_8">template<class R, class B1, class B2, class A1, class A2> <i>unspecified-8</i>
|
||||
bind(R (*f) (B1, B2), A1 a1, A2 a2)</a></h4>
|
||||
<blockquote>
|
||||
<p>
|
||||
<b>Returns:</b> a function object <i>λ</i> such that the expression <tt>λ(v<sub>1</sub>,
|
||||
<b>Returns:</b> A function object <i>λ</i> such that the expression <tt>λ(v<sub>1</sub>,
|
||||
v<sub>2</sub>, ..., v<sub>m</sub>)</tt> is equivalent to <tt><b>f</b>(µ(<b>a1</b>,
|
||||
v<sub>1</sub>, v<sub>2</sub>, ..., v<sub>m</sub>), µ(<b>a2</b>, v<sub>1</sub>,
|
||||
v<sub>2</sub>, ..., v<sub>m</sub>))</tt>.
|
||||
@@ -835,22 +872,27 @@ namespace
|
||||
an exception.
|
||||
</p>
|
||||
</blockquote>
|
||||
<h4><a name="bind_9">template<class R, class T, class B1, class A1, class A2> <i>implementation-defined-9</i>
|
||||
<h4><a name="bind_9">template<class R, class T, class B1, class A1, class A2> <i>unspecified-9</i>
|
||||
bind(R (T::*f) (B1), A1 a1, A2 a2)</a></h4>
|
||||
<blockquote>
|
||||
<p>
|
||||
<b>Effects:</b> equivalent to <tt>bind<R>(<a href="mem_fn.html">boost::mem_fn</a>(f),
|
||||
<b>Effects:</b> Equivalent to <tt>bind<R>(<a href="mem_fn.html">boost::mem_fn</a>(f),
|
||||
a1, a2);</tt>
|
||||
</p>
|
||||
</blockquote>
|
||||
<h4><a name="bind_10">template<class R, class T, class B1, class A1, class A2> <i>implementation-defined-10</i>
|
||||
<h4><a name="bind_10">template<class R, class T, class B1, class A1, class A2> <i>unspecified-10</i>
|
||||
bind(R (T::*f) (B1) const, A1 a1, A2 a2)</a></h4>
|
||||
<blockquote>
|
||||
<p>
|
||||
<b>Effects:</b> equivalent to <tt>bind<R>(<a href="mem_fn.html">boost::mem_fn</a>(f),
|
||||
<b>Effects:</b> Equivalent to <tt>bind<R>(<a href="mem_fn.html">boost::mem_fn</a>(f),
|
||||
a1, a2);</tt>
|
||||
</p>
|
||||
</blockquote>
|
||||
<h3><a name="AdditionalOverloads">Additional overloads</a></h3>
|
||||
<p>
|
||||
Implementations are allowed to provide additional <b>bind</b> overloads in
|
||||
order to support more arguments or different function pointer variations.
|
||||
</p>
|
||||
<h2><a name="Implementation">Implementation</a></h2>
|
||||
<h3><a name="Files">Files</a></h3>
|
||||
<ul>
|
||||
@@ -867,19 +909,20 @@ namespace
|
||||
<a href="../../boost/bind/bind_template.hpp">boost/bind/bind_template.hpp</a>
|
||||
(used by bind.hpp, do not include directly)
|
||||
<LI>
|
||||
<A href="../../boost/bind/bind_template.hpp">boost/bind/arg.hpp</A>
|
||||
(defines the type of the placeholder arguments)
|
||||
<A href="../../boost/bind/arg.hpp">boost/bind/arg.hpp</A>
|
||||
(defines the type of the placeholder arguments)
|
||||
<LI>
|
||||
<A href="../../boost/bind/bind_template.hpp">boost/bind/placeholders.hpp</A>
|
||||
<A href="../../boost/bind/placeholders.hpp">boost/bind/placeholders.hpp</A>
|
||||
(defines the _1, _2, ... _9 placeholders)
|
||||
<LI>
|
||||
<A href="../../boost/bind/bind_template.hpp">boost/bind/apply.hpp</A> (<STRONG>apply</STRONG>
|
||||
<A href="../../boost/bind/apply.hpp">boost/bind/apply.hpp</A> (<STRONG>apply</STRONG>
|
||||
helper function object)
|
||||
<LI>
|
||||
<A href="../../boost/bind/bind_template.hpp">boost/bind/protect.hpp</A> (<STRONG>protect</STRONG>
|
||||
<A href="../../boost/bind/protect.hpp">boost/bind/protect.hpp</A> (<STRONG>protect</STRONG>
|
||||
helper function)
|
||||
<LI>
|
||||
<A href="../../boost/bind/bind_template.hpp">boost/bind/make_adaptable.hpp</A> (<STRONG>make_adaptable</STRONG>
|
||||
<A href="../../boost/bind/make_adaptable.hpp">boost/bind/make_adaptable.hpp</A>
|
||||
(<STRONG>make_adaptable</STRONG>
|
||||
helper function)
|
||||
<li>
|
||||
<a href="bind_test.cpp">libs/bind/bind_test.cpp</a>
|
||||
@@ -896,6 +939,12 @@ namespace
|
||||
<li>
|
||||
<a href="bind_stdcall_mf_test.cpp">libs/bind/bind_stdcall_mf_test.cpp</a> (test
|
||||
with __stdcall member functions)</li>
|
||||
<li>
|
||||
<a href="bind_fastcall_test.cpp">libs/bind/bind_fastcall_test.cpp</a>
|
||||
(test with __fastcall functions)
|
||||
<li>
|
||||
<a href="bind_fastcall_mf_test.cpp">libs/bind/bind_fastcall_mf_test.cpp</a> (test
|
||||
with __fastcall member functions)</li>
|
||||
</ul>
|
||||
<h3><a name="Dependencies">Dependencies</a></h3>
|
||||
<ul>
|
||||
@@ -911,7 +960,7 @@ namespace
|
||||
This implementation supports function objects with up to nine arguments. This
|
||||
is an implementation detail, not an inherent limitation of the design.
|
||||
</p>
|
||||
<h3><a name="stdcall">"__stdcall" and "pascal" Support</a></h3>
|
||||
<h3><a name="stdcall">"__stdcall", "__fastcall", and "pascal" Support</a></h3>
|
||||
<p>
|
||||
Some platforms allow several types of (member) functions that differ by their <b>calling
|
||||
convention</b> (the rules by which the function is invoked: how are
|
||||
@@ -920,8 +969,8 @@ namespace
|
||||
</p>
|
||||
<p>
|
||||
For example, Windows API functions and COM interface member functions use a
|
||||
calling convention known as <b>__stdcall</b>. Mac toolbox functions use a <b>pascal</b>
|
||||
calling convention.
|
||||
calling convention known as <b>__stdcall</b>.Borland VCL components use <STRONG>__fastcall</STRONG>.
|
||||
Mac toolbox functions use a <b>pascal</b> calling convention.
|
||||
</p>
|
||||
<p>
|
||||
To use <b>bind</b> with <b>__stdcall</b> functions, <b>#define</b> the macro <b>BOOST_BIND_ENABLE_STDCALL</b>
|
||||
@@ -931,10 +980,16 @@ namespace
|
||||
To use <b>bind</b> with <b>__stdcall</b> <b>member</b> functions, <b>#define</b>
|
||||
the macro <b>BOOST_MEM_FN_ENABLE_STDCALL</b> before including <b><boost/bind.hpp></b>.
|
||||
</p>
|
||||
<p>
|
||||
<P>To use <B>bind</B> with <B>__fastcall</B> functions, <B>#define</B> the macro <B>BOOST_BIND_ENABLE_FASTCALL</B>
|
||||
before including <B><boost/bind.hpp></B>.
|
||||
</P>
|
||||
<P>To use <B>bind</B> with <B>__fastcall</B> <B>member</B> functions, <B>#define</B>
|
||||
the macro <B>BOOST_MEM_FN_ENABLE_FASTCALL</B> before including <B><boost/bind.hpp></B>.
|
||||
</P>
|
||||
<P>
|
||||
To use <b>bind</b> with <b>pascal</b> functions, <b>#define</b> the macro <b>BOOST_BIND_ENABLE_PASCAL</b>
|
||||
before including <b><boost/bind.hpp></b>.
|
||||
</p>
|
||||
</P>
|
||||
<p>
|
||||
[Note: this is a non-portable extension. It is not part of the interface.]
|
||||
</p>
|
||||
@@ -995,7 +1050,7 @@ namespace
|
||||
Järvi.
|
||||
</p>
|
||||
<p>
|
||||
Dave Abrahams fixed a MSVC-specific conflict between <b>bind</b> and the <a href="../utility\iterator_adaptors.htm">
|
||||
Dave Abrahams fixed a MSVC-specific conflict between <b>bind</b> and the <a href="../utility/iterator_adaptors.htm">
|
||||
iterator adaptors library</a>.
|
||||
</p>
|
||||
<p>
|
||||
@@ -1009,9 +1064,9 @@ namespace
|
||||
<p><br>
|
||||
<br>
|
||||
<br>
|
||||
<small>Copyright © 2001, 2002 by Peter Dimov and Multi Media Ltd. Permission
|
||||
to copy, use, modify, sell and distribute this document is granted provided
|
||||
this copyright notice appears in all copies. This document is provided "as is"
|
||||
<small>Copyright © 2001, 2002 by Peter Dimov and Multi Media Ltd. Permission to
|
||||
copy, use, modify, sell and distribute this document is granted provided this
|
||||
copyright notice appears in all copies. This document is provided "as is"
|
||||
without express or implied warranty, and with no claim as to its suitability
|
||||
for any purpose.</small></p>
|
||||
</body>
|
||||
|
||||
163
bind_fastcall_mf_test.cpp
Normal file
163
bind_fastcall_mf_test.cpp
Normal file
@@ -0,0 +1,163 @@
|
||||
#if defined(_MSC_VER) && !defined(__ICL)
|
||||
#pragma warning(disable: 4786) // identifier truncated in debug info
|
||||
#pragma warning(disable: 4710) // function not inlined
|
||||
#pragma warning(disable: 4711) // function selected for automatic inline expansion
|
||||
#pragma warning(disable: 4514) // unreferenced inline removed
|
||||
#endif
|
||||
|
||||
//
|
||||
// bind_stdcall_mf_test.cpp - test for bind.hpp + __stdcall (member functions)
|
||||
//
|
||||
// Copyright (c) 2001 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
|
||||
#define BOOST_MEM_FN_ENABLE_FASTCALL
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
|
||||
#pragma warning(push, 3)
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
struct X
|
||||
{
|
||||
mutable unsigned int hash;
|
||||
|
||||
X(): hash(0) {}
|
||||
|
||||
void __fastcall f0() { f1(17); }
|
||||
void __fastcall g0() const { g1(17); }
|
||||
|
||||
void __fastcall f1(int a1) { hash = (hash * 17041 + a1) % 32768; }
|
||||
void __fastcall g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; }
|
||||
|
||||
void __fastcall f2(int a1, int a2) { f1(a1); f1(a2); }
|
||||
void __fastcall g2(int a1, int a2) const { g1(a1); g1(a2); }
|
||||
|
||||
void __fastcall f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); }
|
||||
void __fastcall g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); }
|
||||
|
||||
void __fastcall f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); }
|
||||
void __fastcall g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); }
|
||||
|
||||
void __fastcall f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); }
|
||||
void __fastcall g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); }
|
||||
|
||||
void __fastcall f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); }
|
||||
void __fastcall g6(int a1, int a2, int a3, int a4, int a5, int a6) const { g5(a1, a2, a3, a4, a5); g1(a6); }
|
||||
|
||||
void __fastcall f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { f6(a1, a2, a3, a4, a5, a6); f1(a7); }
|
||||
void __fastcall g7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) const { g6(a1, a2, a3, a4, a5, a6); g1(a7); }
|
||||
|
||||
void __fastcall f8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { f7(a1, a2, a3, a4, a5, a6, a7); f1(a8); }
|
||||
void __fastcall g8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) const { g7(a1, a2, a3, a4, a5, a6, a7); g1(a8); }
|
||||
};
|
||||
|
||||
void member_function_test()
|
||||
{
|
||||
using namespace boost;
|
||||
|
||||
X x;
|
||||
|
||||
// 0
|
||||
|
||||
bind(&X::f0, &x)();
|
||||
bind(&X::f0, ref(x))();
|
||||
|
||||
bind(&X::g0, &x)();
|
||||
bind(&X::g0, x)();
|
||||
bind(&X::g0, ref(x))();
|
||||
|
||||
// 1
|
||||
|
||||
bind(&X::f1, &x, 1)();
|
||||
bind(&X::f1, ref(x), 1)();
|
||||
|
||||
bind(&X::g1, &x, 1)();
|
||||
bind(&X::g1, x, 1)();
|
||||
bind(&X::g1, ref(x), 1)();
|
||||
|
||||
// 2
|
||||
|
||||
bind(&X::f2, &x, 1, 2)();
|
||||
bind(&X::f2, ref(x), 1, 2)();
|
||||
|
||||
bind(&X::g2, &x, 1, 2)();
|
||||
bind(&X::g2, x, 1, 2)();
|
||||
bind(&X::g2, ref(x), 1, 2)();
|
||||
|
||||
// 3
|
||||
|
||||
bind(&X::f3, &x, 1, 2, 3)();
|
||||
bind(&X::f3, ref(x), 1, 2, 3)();
|
||||
|
||||
bind(&X::g3, &x, 1, 2, 3)();
|
||||
bind(&X::g3, x, 1, 2, 3)();
|
||||
bind(&X::g3, ref(x), 1, 2, 3)();
|
||||
|
||||
// 4
|
||||
|
||||
bind(&X::f4, &x, 1, 2, 3, 4)();
|
||||
bind(&X::f4, ref(x), 1, 2, 3, 4)();
|
||||
|
||||
bind(&X::g4, &x, 1, 2, 3, 4)();
|
||||
bind(&X::g4, x, 1, 2, 3, 4)();
|
||||
bind(&X::g4, ref(x), 1, 2, 3, 4)();
|
||||
|
||||
// 5
|
||||
|
||||
bind(&X::f5, &x, 1, 2, 3, 4, 5)();
|
||||
bind(&X::f5, ref(x), 1, 2, 3, 4, 5)();
|
||||
|
||||
bind(&X::g5, &x, 1, 2, 3, 4, 5)();
|
||||
bind(&X::g5, x, 1, 2, 3, 4, 5)();
|
||||
bind(&X::g5, ref(x), 1, 2, 3, 4, 5)();
|
||||
|
||||
// 6
|
||||
|
||||
bind(&X::f6, &x, 1, 2, 3, 4, 5, 6)();
|
||||
bind(&X::f6, ref(x), 1, 2, 3, 4, 5, 6)();
|
||||
|
||||
bind(&X::g6, &x, 1, 2, 3, 4, 5, 6)();
|
||||
bind(&X::g6, x, 1, 2, 3, 4, 5, 6)();
|
||||
bind(&X::g6, ref(x), 1, 2, 3, 4, 5, 6)();
|
||||
|
||||
// 7
|
||||
|
||||
bind(&X::f7, &x, 1, 2, 3, 4, 5, 6, 7)();
|
||||
bind(&X::f7, ref(x), 1, 2, 3, 4, 5, 6, 7)();
|
||||
|
||||
bind(&X::g7, &x, 1, 2, 3, 4, 5, 6, 7)();
|
||||
bind(&X::g7, x, 1, 2, 3, 4, 5, 6, 7)();
|
||||
bind(&X::g7, ref(x), 1, 2, 3, 4, 5, 6, 7)();
|
||||
|
||||
// 8
|
||||
|
||||
bind(&X::f8, &x, 1, 2, 3, 4, 5, 6, 7, 8)();
|
||||
bind(&X::f8, ref(x), 1, 2, 3, 4, 5, 6, 7, 8)();
|
||||
|
||||
bind(&X::g8, &x, 1, 2, 3, 4, 5, 6, 7, 8)();
|
||||
bind(&X::g8, x, 1, 2, 3, 4, 5, 6, 7, 8)();
|
||||
bind(&X::g8, ref(x), 1, 2, 3, 4, 5, 6, 7, 8)();
|
||||
|
||||
BOOST_TEST( x.hash == 23558 );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
member_function_test();
|
||||
return boost::report_errors();
|
||||
}
|
||||
109
bind_fastcall_test.cpp
Normal file
109
bind_fastcall_test.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
#if defined(_MSC_VER) && !defined(__ICL)
|
||||
#pragma warning(disable: 4786) // identifier truncated in debug info
|
||||
#pragma warning(disable: 4710) // function not inlined
|
||||
#pragma warning(disable: 4711) // function selected for automatic inline expansion
|
||||
#pragma warning(disable: 4514) // unreferenced inline removed
|
||||
#endif
|
||||
|
||||
//
|
||||
// bind_fastcall_test.cpp - test for bind.hpp + __fastcall (free functions)
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
|
||||
#define BOOST_BIND_ENABLE_FASTCALL
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
|
||||
#pragma warning(push, 3)
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
//
|
||||
|
||||
long __fastcall f_0()
|
||||
{
|
||||
return 17041L;
|
||||
}
|
||||
|
||||
long __fastcall f_1(long a)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
long __fastcall f_2(long a, long b)
|
||||
{
|
||||
return a + 10 * b;
|
||||
}
|
||||
|
||||
long __fastcall f_3(long a, long b, long c)
|
||||
{
|
||||
return a + 10 * b + 100 * c;
|
||||
}
|
||||
|
||||
long __fastcall f_4(long a, long b, long c, long d)
|
||||
{
|
||||
return a + 10 * b + 100 * c + 1000 * d;
|
||||
}
|
||||
|
||||
long __fastcall f_5(long a, long b, long c, long d, long e)
|
||||
{
|
||||
return a + 10 * b + 100 * c + 1000 * d + 10000 * e;
|
||||
}
|
||||
|
||||
long __fastcall f_6(long a, long b, long c, long d, long e, long f)
|
||||
{
|
||||
return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f;
|
||||
}
|
||||
|
||||
long __fastcall f_7(long a, long b, long c, long d, long e, long f, long g)
|
||||
{
|
||||
return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f + 1000000 * g;
|
||||
}
|
||||
|
||||
long __fastcall f_8(long a, long b, long c, long d, long e, long f, long g, long h)
|
||||
{
|
||||
return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f + 1000000 * g + 10000000 * h;
|
||||
}
|
||||
|
||||
long __fastcall f_9(long a, long b, long c, long d, long e, long f, long g, long h, long i)
|
||||
{
|
||||
return a + 10 * b + 100 * c + 1000 * d + 10000 * e + 100000 * f + 1000000 * g + 10000000 * h + 100000000 * i;
|
||||
}
|
||||
|
||||
void function_test()
|
||||
{
|
||||
using namespace boost;
|
||||
|
||||
int const i = 1;
|
||||
|
||||
BOOST_TEST( bind(f_0)(i) == 17041L );
|
||||
BOOST_TEST( bind(f_1, _1)(i) == 1L );
|
||||
BOOST_TEST( bind(f_2, _1, 2)(i) == 21L );
|
||||
BOOST_TEST( bind(f_3, _1, 2, 3)(i) == 321L );
|
||||
BOOST_TEST( bind(f_4, _1, 2, 3, 4)(i) == 4321L );
|
||||
BOOST_TEST( bind(f_5, _1, 2, 3, 4, 5)(i) == 54321L );
|
||||
BOOST_TEST( bind(f_6, _1, 2, 3, 4, 5, 6)(i) == 654321L );
|
||||
BOOST_TEST( bind(f_7, _1, 2, 3, 4, 5, 6, 7)(i) == 7654321L );
|
||||
BOOST_TEST( bind(f_8, _1, 2, 3, 4, 5, 6, 7, 8)(i) == 87654321L );
|
||||
BOOST_TEST( bind(f_9, _1, 2, 3, 4, 5, 6, 7, 8, 9)(i) == 987654321L );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
function_test();
|
||||
return boost::report_errors();
|
||||
}
|
||||
@@ -30,9 +30,7 @@
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
#define BOOST_INCLUDE_MAIN
|
||||
#include <boost/test/test_tools.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
struct X
|
||||
{
|
||||
@@ -158,8 +156,8 @@ void member_function_test()
|
||||
BOOST_TEST( x.hash == 23558 );
|
||||
}
|
||||
|
||||
int test_main(int, char * [])
|
||||
int main()
|
||||
{
|
||||
member_function_test();
|
||||
return 0;
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
@@ -30,8 +30,7 @@
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#define BOOST_INCLUDE_MAIN
|
||||
#include <boost/test/test_tools.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
//
|
||||
|
||||
@@ -103,8 +102,8 @@ void function_test()
|
||||
BOOST_TEST( bind(f_9, _1, 2, 3, 4, 5, 6, 7, 8, 9)(i) == 987654321L );
|
||||
}
|
||||
|
||||
int test_main(int, char * [])
|
||||
int main()
|
||||
{
|
||||
function_test();
|
||||
return 0;
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
@@ -30,9 +30,7 @@
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
#define BOOST_INCLUDE_MAIN
|
||||
#include <boost/test/test_tools.hpp>
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
//
|
||||
|
||||
@@ -485,7 +483,7 @@ void nested_bind_test()
|
||||
BOOST_TEST( (bind(fv_1, bind(f_0))(), (global_result == 17041L)) );
|
||||
}
|
||||
|
||||
int test_main(int, char * [])
|
||||
int main()
|
||||
{
|
||||
function_test();
|
||||
function_object_test();
|
||||
@@ -498,5 +496,5 @@ int test_main(int, char * [])
|
||||
member_function_void_test();
|
||||
nested_bind_test();
|
||||
|
||||
return 0;
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
@@ -59,6 +59,11 @@ template<class F> struct result_traits<unspecified, F>
|
||||
typedef typename F::result_type type;
|
||||
};
|
||||
|
||||
template<class F> struct result_traits< unspecified, reference_wrapper<F> >
|
||||
{
|
||||
typedef typename F::result_type type;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// bind_t forward declaration for listN
|
||||
@@ -85,6 +90,23 @@ private:
|
||||
|
||||
template<class T> class type {};
|
||||
|
||||
// unwrap
|
||||
|
||||
template<class F> inline F & unwrap(F & f, long)
|
||||
{
|
||||
return f;
|
||||
}
|
||||
|
||||
template<class F> inline F & unwrap(reference_wrapper<F> & f, int)
|
||||
{
|
||||
return f;
|
||||
}
|
||||
|
||||
template<class F> inline F & unwrap(reference_wrapper<F> const & f, int)
|
||||
{
|
||||
return f;
|
||||
}
|
||||
|
||||
// listN
|
||||
|
||||
#ifdef BOOST_NO_VOID_RETURNS
|
||||
@@ -120,7 +142,7 @@ public:
|
||||
|
||||
template<class R, class F, class A> R operator()(type<R>, F f, A &) const
|
||||
{
|
||||
return f();
|
||||
return unwrap(f, 0)();
|
||||
}
|
||||
|
||||
template<class V> void accept(V &) const
|
||||
@@ -144,9 +166,9 @@ public:
|
||||
|
||||
explicit list1(A1 a1): a1_(a1) {}
|
||||
|
||||
A1 operator[] (arg<1>) const { return a1_; }
|
||||
A1 operator[] (boost::arg<1>) const { return a1_; }
|
||||
|
||||
A1 operator[] (arg<1> (*) ()) const { return a1_; }
|
||||
A1 operator[] (boost::arg<1> (*) ()) const { return a1_; }
|
||||
|
||||
template<class T> T & operator[] (value<T> & v) const { return v.get(); }
|
||||
|
||||
@@ -160,7 +182,7 @@ public:
|
||||
|
||||
template<class R, class F, class A> R operator()(type<R>, F f, A & a) const
|
||||
{
|
||||
return f(a[a1_]);
|
||||
return unwrap(f, 0)(a[a1_]);
|
||||
}
|
||||
|
||||
template<class V> void accept(V & v) const
|
||||
@@ -190,11 +212,11 @@ public:
|
||||
|
||||
list2(A1 a1, A2 a2): a1_(a1), a2_(a2) {}
|
||||
|
||||
A1 operator[] (arg<1>) const { return a1_; }
|
||||
A2 operator[] (arg<2>) const { return a2_; }
|
||||
A1 operator[] (boost::arg<1>) const { return a1_; }
|
||||
A2 operator[] (boost::arg<2>) const { return a2_; }
|
||||
|
||||
A1 operator[] (arg<1> (*) ()) const { return a1_; }
|
||||
A2 operator[] (arg<2> (*) ()) const { return a2_; }
|
||||
A1 operator[] (boost::arg<1> (*) ()) const { return a1_; }
|
||||
A2 operator[] (boost::arg<2> (*) ()) const { return a2_; }
|
||||
|
||||
template<class T> T & operator[] (value<T> & v) const { return v.get(); }
|
||||
|
||||
@@ -208,7 +230,7 @@ public:
|
||||
|
||||
template<class R, class F, class A> R operator()(type<R>, F f, A & a) const
|
||||
{
|
||||
return f(a[a1_], a[a2_]);
|
||||
return unwrap(f, 0)(a[a1_], a[a2_]);
|
||||
}
|
||||
|
||||
template<class V> void accept(V & v) const
|
||||
@@ -240,13 +262,13 @@ public:
|
||||
|
||||
list3(A1 a1, A2 a2, A3 a3): a1_(a1), a2_(a2), a3_(a3) {}
|
||||
|
||||
A1 operator[] (arg<1>) const { return a1_; }
|
||||
A2 operator[] (arg<2>) const { return a2_; }
|
||||
A3 operator[] (arg<3>) const { return a3_; }
|
||||
A1 operator[] (boost::arg<1>) const { return a1_; }
|
||||
A2 operator[] (boost::arg<2>) const { return a2_; }
|
||||
A3 operator[] (boost::arg<3>) const { return a3_; }
|
||||
|
||||
A1 operator[] (arg<1> (*) ()) const { return a1_; }
|
||||
A2 operator[] (arg<2> (*) ()) const { return a2_; }
|
||||
A3 operator[] (arg<3> (*) ()) const { return a3_; }
|
||||
A1 operator[] (boost::arg<1> (*) ()) const { return a1_; }
|
||||
A2 operator[] (boost::arg<2> (*) ()) const { return a2_; }
|
||||
A3 operator[] (boost::arg<3> (*) ()) const { return a3_; }
|
||||
|
||||
template<class T> T & operator[] (value<T> & v) const { return v.get(); }
|
||||
|
||||
@@ -260,7 +282,7 @@ public:
|
||||
|
||||
template<class R, class F, class A> R operator()(type<R>, F f, A & a) const
|
||||
{
|
||||
return f(a[a1_], a[a2_], a[a3_]);
|
||||
return unwrap(f, 0)(a[a1_], a[a2_], a[a3_]);
|
||||
}
|
||||
|
||||
template<class V> void accept(V & v) const
|
||||
@@ -294,15 +316,15 @@ public:
|
||||
|
||||
list4(A1 a1, A2 a2, A3 a3, A4 a4): a1_(a1), a2_(a2), a3_(a3), a4_(a4) {}
|
||||
|
||||
A1 operator[] (arg<1>) const { return a1_; }
|
||||
A2 operator[] (arg<2>) const { return a2_; }
|
||||
A3 operator[] (arg<3>) const { return a3_; }
|
||||
A4 operator[] (arg<4>) const { return a4_; }
|
||||
A1 operator[] (boost::arg<1>) const { return a1_; }
|
||||
A2 operator[] (boost::arg<2>) const { return a2_; }
|
||||
A3 operator[] (boost::arg<3>) const { return a3_; }
|
||||
A4 operator[] (boost::arg<4>) const { return a4_; }
|
||||
|
||||
A1 operator[] (arg<1> (*) ()) const { return a1_; }
|
||||
A2 operator[] (arg<2> (*) ()) const { return a2_; }
|
||||
A3 operator[] (arg<3> (*) ()) const { return a3_; }
|
||||
A4 operator[] (arg<4> (*) ()) const { return a4_; }
|
||||
A1 operator[] (boost::arg<1> (*) ()) const { return a1_; }
|
||||
A2 operator[] (boost::arg<2> (*) ()) const { return a2_; }
|
||||
A3 operator[] (boost::arg<3> (*) ()) const { return a3_; }
|
||||
A4 operator[] (boost::arg<4> (*) ()) const { return a4_; }
|
||||
|
||||
template<class T> T & operator[] (value<T> & v) const { return v.get(); }
|
||||
|
||||
@@ -316,7 +338,7 @@ public:
|
||||
|
||||
template<class R, class F, class A> R operator()(type<R>, F f, A & a) const
|
||||
{
|
||||
return f(a[a1_], a[a2_], a[a3_], a[a4_]);
|
||||
return unwrap(f, 0)(a[a1_], a[a2_], a[a3_], a[a4_]);
|
||||
}
|
||||
|
||||
template<class V> void accept(V & v) const
|
||||
@@ -352,17 +374,17 @@ public:
|
||||
|
||||
list5(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5): a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5) {}
|
||||
|
||||
A1 operator[] (arg<1>) const { return a1_; }
|
||||
A2 operator[] (arg<2>) const { return a2_; }
|
||||
A3 operator[] (arg<3>) const { return a3_; }
|
||||
A4 operator[] (arg<4>) const { return a4_; }
|
||||
A5 operator[] (arg<5>) const { return a5_; }
|
||||
A1 operator[] (boost::arg<1>) const { return a1_; }
|
||||
A2 operator[] (boost::arg<2>) const { return a2_; }
|
||||
A3 operator[] (boost::arg<3>) const { return a3_; }
|
||||
A4 operator[] (boost::arg<4>) const { return a4_; }
|
||||
A5 operator[] (boost::arg<5>) const { return a5_; }
|
||||
|
||||
A1 operator[] (arg<1> (*) ()) const { return a1_; }
|
||||
A2 operator[] (arg<2> (*) ()) const { return a2_; }
|
||||
A3 operator[] (arg<3> (*) ()) const { return a3_; }
|
||||
A4 operator[] (arg<4> (*) ()) const { return a4_; }
|
||||
A5 operator[] (arg<5> (*) ()) const { return a5_; }
|
||||
A1 operator[] (boost::arg<1> (*) ()) const { return a1_; }
|
||||
A2 operator[] (boost::arg<2> (*) ()) const { return a2_; }
|
||||
A3 operator[] (boost::arg<3> (*) ()) const { return a3_; }
|
||||
A4 operator[] (boost::arg<4> (*) ()) const { return a4_; }
|
||||
A5 operator[] (boost::arg<5> (*) ()) const { return a5_; }
|
||||
|
||||
template<class T> T & operator[] (value<T> & v) const { return v.get(); }
|
||||
|
||||
@@ -376,7 +398,7 @@ public:
|
||||
|
||||
template<class R, class F, class A> R operator()(type<R>, F f, A & a) const
|
||||
{
|
||||
return f(a[a1_], a[a2_], a[a3_], a[a4_], a[a5_]);
|
||||
return unwrap(f, 0)(a[a1_], a[a2_], a[a3_], a[a4_], a[a5_]);
|
||||
}
|
||||
|
||||
template<class V> void accept(V & v) const
|
||||
@@ -414,19 +436,19 @@ public:
|
||||
|
||||
list6(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6): a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6) {}
|
||||
|
||||
A1 operator[] (arg<1>) const { return a1_; }
|
||||
A2 operator[] (arg<2>) const { return a2_; }
|
||||
A3 operator[] (arg<3>) const { return a3_; }
|
||||
A4 operator[] (arg<4>) const { return a4_; }
|
||||
A5 operator[] (arg<5>) const { return a5_; }
|
||||
A6 operator[] (arg<6>) const { return a6_; }
|
||||
A1 operator[] (boost::arg<1>) const { return a1_; }
|
||||
A2 operator[] (boost::arg<2>) const { return a2_; }
|
||||
A3 operator[] (boost::arg<3>) const { return a3_; }
|
||||
A4 operator[] (boost::arg<4>) const { return a4_; }
|
||||
A5 operator[] (boost::arg<5>) const { return a5_; }
|
||||
A6 operator[] (boost::arg<6>) const { return a6_; }
|
||||
|
||||
A1 operator[] (arg<1> (*) ()) const { return a1_; }
|
||||
A2 operator[] (arg<2> (*) ()) const { return a2_; }
|
||||
A3 operator[] (arg<3> (*) ()) const { return a3_; }
|
||||
A4 operator[] (arg<4> (*) ()) const { return a4_; }
|
||||
A5 operator[] (arg<5> (*) ()) const { return a5_; }
|
||||
A6 operator[] (arg<6> (*) ()) const { return a6_; }
|
||||
A1 operator[] (boost::arg<1> (*) ()) const { return a1_; }
|
||||
A2 operator[] (boost::arg<2> (*) ()) const { return a2_; }
|
||||
A3 operator[] (boost::arg<3> (*) ()) const { return a3_; }
|
||||
A4 operator[] (boost::arg<4> (*) ()) const { return a4_; }
|
||||
A5 operator[] (boost::arg<5> (*) ()) const { return a5_; }
|
||||
A6 operator[] (boost::arg<6> (*) ()) const { return a6_; }
|
||||
|
||||
template<class T> T & operator[] (value<T> & v) const { return v.get(); }
|
||||
|
||||
@@ -440,7 +462,7 @@ public:
|
||||
|
||||
template<class R, class F, class A> R operator()(type<R>, F f, A & a) const
|
||||
{
|
||||
return f(a[a1_], a[a2_], a[a3_], a[a4_], a[a5_], a[a6_]);
|
||||
return unwrap(f, 0)(a[a1_], a[a2_], a[a3_], a[a4_], a[a5_], a[a6_]);
|
||||
}
|
||||
|
||||
template<class V> void accept(V & v) const
|
||||
@@ -480,21 +502,21 @@ public:
|
||||
|
||||
list7(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7): a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7) {}
|
||||
|
||||
A1 operator[] (arg<1>) const { return a1_; }
|
||||
A2 operator[] (arg<2>) const { return a2_; }
|
||||
A3 operator[] (arg<3>) const { return a3_; }
|
||||
A4 operator[] (arg<4>) const { return a4_; }
|
||||
A5 operator[] (arg<5>) const { return a5_; }
|
||||
A6 operator[] (arg<6>) const { return a6_; }
|
||||
A7 operator[] (arg<7>) const { return a7_; }
|
||||
A1 operator[] (boost::arg<1>) const { return a1_; }
|
||||
A2 operator[] (boost::arg<2>) const { return a2_; }
|
||||
A3 operator[] (boost::arg<3>) const { return a3_; }
|
||||
A4 operator[] (boost::arg<4>) const { return a4_; }
|
||||
A5 operator[] (boost::arg<5>) const { return a5_; }
|
||||
A6 operator[] (boost::arg<6>) const { return a6_; }
|
||||
A7 operator[] (boost::arg<7>) const { return a7_; }
|
||||
|
||||
A1 operator[] (arg<1> (*) ()) const { return a1_; }
|
||||
A2 operator[] (arg<2> (*) ()) const { return a2_; }
|
||||
A3 operator[] (arg<3> (*) ()) const { return a3_; }
|
||||
A4 operator[] (arg<4> (*) ()) const { return a4_; }
|
||||
A5 operator[] (arg<5> (*) ()) const { return a5_; }
|
||||
A6 operator[] (arg<6> (*) ()) const { return a6_; }
|
||||
A7 operator[] (arg<7> (*) ()) const { return a7_; }
|
||||
A1 operator[] (boost::arg<1> (*) ()) const { return a1_; }
|
||||
A2 operator[] (boost::arg<2> (*) ()) const { return a2_; }
|
||||
A3 operator[] (boost::arg<3> (*) ()) const { return a3_; }
|
||||
A4 operator[] (boost::arg<4> (*) ()) const { return a4_; }
|
||||
A5 operator[] (boost::arg<5> (*) ()) const { return a5_; }
|
||||
A6 operator[] (boost::arg<6> (*) ()) const { return a6_; }
|
||||
A7 operator[] (boost::arg<7> (*) ()) const { return a7_; }
|
||||
|
||||
template<class T> T & operator[] (value<T> & v) const { return v.get(); }
|
||||
|
||||
@@ -508,7 +530,7 @@ public:
|
||||
|
||||
template<class R, class F, class A> R operator()(type<R>, F f, A & a) const
|
||||
{
|
||||
return f(a[a1_], a[a2_], a[a3_], a[a4_], a[a5_], a[a6_], a[a7_]);
|
||||
return unwrap(f, 0)(a[a1_], a[a2_], a[a3_], a[a4_], a[a5_], a[a6_], a[a7_]);
|
||||
}
|
||||
|
||||
template<class V> void accept(V & v) const
|
||||
@@ -550,23 +572,23 @@ public:
|
||||
|
||||
list8(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8): a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8) {}
|
||||
|
||||
A1 operator[] (arg<1>) const { return a1_; }
|
||||
A2 operator[] (arg<2>) const { return a2_; }
|
||||
A3 operator[] (arg<3>) const { return a3_; }
|
||||
A4 operator[] (arg<4>) const { return a4_; }
|
||||
A5 operator[] (arg<5>) const { return a5_; }
|
||||
A6 operator[] (arg<6>) const { return a6_; }
|
||||
A7 operator[] (arg<7>) const { return a7_; }
|
||||
A8 operator[] (arg<8>) const { return a8_; }
|
||||
A1 operator[] (boost::arg<1>) const { return a1_; }
|
||||
A2 operator[] (boost::arg<2>) const { return a2_; }
|
||||
A3 operator[] (boost::arg<3>) const { return a3_; }
|
||||
A4 operator[] (boost::arg<4>) const { return a4_; }
|
||||
A5 operator[] (boost::arg<5>) const { return a5_; }
|
||||
A6 operator[] (boost::arg<6>) const { return a6_; }
|
||||
A7 operator[] (boost::arg<7>) const { return a7_; }
|
||||
A8 operator[] (boost::arg<8>) const { return a8_; }
|
||||
|
||||
A1 operator[] (arg<1> (*) ()) const { return a1_; }
|
||||
A2 operator[] (arg<2> (*) ()) const { return a2_; }
|
||||
A3 operator[] (arg<3> (*) ()) const { return a3_; }
|
||||
A4 operator[] (arg<4> (*) ()) const { return a4_; }
|
||||
A5 operator[] (arg<5> (*) ()) const { return a5_; }
|
||||
A6 operator[] (arg<6> (*) ()) const { return a6_; }
|
||||
A7 operator[] (arg<7> (*) ()) const { return a7_; }
|
||||
A8 operator[] (arg<8> (*) ()) const { return a8_; }
|
||||
A1 operator[] (boost::arg<1> (*) ()) const { return a1_; }
|
||||
A2 operator[] (boost::arg<2> (*) ()) const { return a2_; }
|
||||
A3 operator[] (boost::arg<3> (*) ()) const { return a3_; }
|
||||
A4 operator[] (boost::arg<4> (*) ()) const { return a4_; }
|
||||
A5 operator[] (boost::arg<5> (*) ()) const { return a5_; }
|
||||
A6 operator[] (boost::arg<6> (*) ()) const { return a6_; }
|
||||
A7 operator[] (boost::arg<7> (*) ()) const { return a7_; }
|
||||
A8 operator[] (boost::arg<8> (*) ()) const { return a8_; }
|
||||
|
||||
template<class T> T & operator[] (value<T> & v) const { return v.get(); }
|
||||
|
||||
@@ -580,7 +602,7 @@ public:
|
||||
|
||||
template<class R, class F, class A> R operator()(type<R>, F f, A & a) const
|
||||
{
|
||||
return f(a[a1_], a[a2_], a[a3_], a[a4_], a[a5_], a[a6_], a[a7_], a[a8_]);
|
||||
return unwrap(f, 0)(a[a1_], a[a2_], a[a3_], a[a4_], a[a5_], a[a6_], a[a7_], a[a8_]);
|
||||
}
|
||||
|
||||
template<class V> void accept(V & v) const
|
||||
@@ -624,25 +646,25 @@ public:
|
||||
|
||||
list9(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9): a1_(a1), a2_(a2), a3_(a3), a4_(a4), a5_(a5), a6_(a6), a7_(a7), a8_(a8), a9_(a9) {}
|
||||
|
||||
A1 operator[] (arg<1>) const { return a1_; }
|
||||
A2 operator[] (arg<2>) const { return a2_; }
|
||||
A3 operator[] (arg<3>) const { return a3_; }
|
||||
A4 operator[] (arg<4>) const { return a4_; }
|
||||
A5 operator[] (arg<5>) const { return a5_; }
|
||||
A6 operator[] (arg<6>) const { return a6_; }
|
||||
A7 operator[] (arg<7>) const { return a7_; }
|
||||
A8 operator[] (arg<8>) const { return a8_; }
|
||||
A9 operator[] (arg<9>) const { return a9_; }
|
||||
A1 operator[] (boost::arg<1>) const { return a1_; }
|
||||
A2 operator[] (boost::arg<2>) const { return a2_; }
|
||||
A3 operator[] (boost::arg<3>) const { return a3_; }
|
||||
A4 operator[] (boost::arg<4>) const { return a4_; }
|
||||
A5 operator[] (boost::arg<5>) const { return a5_; }
|
||||
A6 operator[] (boost::arg<6>) const { return a6_; }
|
||||
A7 operator[] (boost::arg<7>) const { return a7_; }
|
||||
A8 operator[] (boost::arg<8>) const { return a8_; }
|
||||
A9 operator[] (boost::arg<9>) const { return a9_; }
|
||||
|
||||
A1 operator[] (arg<1> (*) ()) const { return a1_; }
|
||||
A2 operator[] (arg<2> (*) ()) const { return a2_; }
|
||||
A3 operator[] (arg<3> (*) ()) const { return a3_; }
|
||||
A4 operator[] (arg<4> (*) ()) const { return a4_; }
|
||||
A5 operator[] (arg<5> (*) ()) const { return a5_; }
|
||||
A6 operator[] (arg<6> (*) ()) const { return a6_; }
|
||||
A7 operator[] (arg<7> (*) ()) const { return a7_; }
|
||||
A8 operator[] (arg<8> (*) ()) const { return a8_; }
|
||||
A9 operator[] (arg<9> (*) ()) const { return a9_; }
|
||||
A1 operator[] (boost::arg<1> (*) ()) const { return a1_; }
|
||||
A2 operator[] (boost::arg<2> (*) ()) const { return a2_; }
|
||||
A3 operator[] (boost::arg<3> (*) ()) const { return a3_; }
|
||||
A4 operator[] (boost::arg<4> (*) ()) const { return a4_; }
|
||||
A5 operator[] (boost::arg<5> (*) ()) const { return a5_; }
|
||||
A6 operator[] (boost::arg<6> (*) ()) const { return a6_; }
|
||||
A7 operator[] (boost::arg<7> (*) ()) const { return a7_; }
|
||||
A8 operator[] (boost::arg<8> (*) ()) const { return a8_; }
|
||||
A9 operator[] (boost::arg<9> (*) ()) const { return a9_; }
|
||||
|
||||
template<class T> T & operator[] (value<T> & v) const { return v.get(); }
|
||||
|
||||
@@ -656,7 +678,7 @@ public:
|
||||
|
||||
template<class R, class F, class A> R operator()(type<R>, F f, A & a) const
|
||||
{
|
||||
return f(a[a1_], a[a2_], a[a3_], a[a4_], a[a5_], a[a6_], a[a7_], a[a8_], a[a9_]);
|
||||
return unwrap(f, 0)(a[a1_], a[a2_], a[a3_], a[a4_], a[a5_], a[a6_], a[a7_], a[a8_], a[a9_]);
|
||||
}
|
||||
|
||||
template<class V> void accept(V & v) const
|
||||
@@ -703,7 +725,7 @@ template <class R> struct evaluator0
|
||||
template<class L, class F, class A>
|
||||
static R eval(L const&, F f, A &)
|
||||
{
|
||||
return f();
|
||||
return unwrap(f, 0)();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -712,7 +734,7 @@ template <> struct evaluator0<void>
|
||||
template<class L, class F, class A>
|
||||
static void eval(L const&, F f, A &)
|
||||
{
|
||||
f();
|
||||
unwrap(f, 0)();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -721,7 +743,7 @@ template <class R> struct evaluator1
|
||||
template<class L, class F, class A>
|
||||
static R eval(L const& l, F f, A & a)
|
||||
{
|
||||
return f(a[l.a1_]);
|
||||
return unwrap(f, 0)(a[l.a1_]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -730,7 +752,7 @@ template <> struct evaluator1<void>
|
||||
template<class L, class F, class A>
|
||||
static void eval(L const& l, F f, A & a)
|
||||
{
|
||||
f(a[l.a1_]);
|
||||
unwrap(f, 0)(a[l.a1_]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -739,7 +761,7 @@ template <class R> struct evaluator2
|
||||
template<class L, class F, class A>
|
||||
static R eval(L const& l, F f, A & a)
|
||||
{
|
||||
return f(a[l.a1_], a[l.a2_]);
|
||||
return unwrap(f, 0)(a[l.a1_], a[l.a2_]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -748,7 +770,7 @@ template <> struct evaluator2<void>
|
||||
template<class L, class F, class A>
|
||||
static void eval(L const& l, F f, A & a)
|
||||
{
|
||||
f(a[l.a1_], a[l.a2_]);
|
||||
unwrap(f, 0)(a[l.a1_], a[l.a2_]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -757,7 +779,7 @@ template <class R> struct evaluator3
|
||||
template<class L, class F, class A>
|
||||
static R eval(L const& l, F f, A & a)
|
||||
{
|
||||
return f(a[l.a1_], a[l.a2_], a[l.a3_]);
|
||||
return unwrap(f, 0)(a[l.a1_], a[l.a2_], a[l.a3_]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -766,7 +788,7 @@ template <> struct evaluator3<void>
|
||||
template<class L, class F, class A>
|
||||
static void eval(L const& l, F f, A & a)
|
||||
{
|
||||
f(a[l.a1_], a[l.a2_], a[l.a3_]);
|
||||
unwrap(f, 0)(a[l.a1_], a[l.a2_], a[l.a3_]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -775,7 +797,7 @@ template <class R> struct evaluator4
|
||||
template<class L, class F, class A>
|
||||
static R eval(L const& l, F f, A & a)
|
||||
{
|
||||
return f(a[l.a1_], a[l.a2_], a[l.a3_], a[l.a4_]);
|
||||
return unwrap(f, 0)(a[l.a1_], a[l.a2_], a[l.a3_], a[l.a4_]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -784,7 +806,7 @@ template <> struct evaluator4<void>
|
||||
template<class L, class F, class A>
|
||||
static void eval(L const& l, F f, A & a)
|
||||
{
|
||||
f(a[l.a1_], a[l.a2_], a[l.a3_], a[l.a4_]);
|
||||
unwrap(f, 0)(a[l.a1_], a[l.a2_], a[l.a3_], a[l.a4_]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -793,7 +815,7 @@ template <class R> struct evaluator5
|
||||
template<class L, class F, class A>
|
||||
static R eval(L const& l, F f, A & a)
|
||||
{
|
||||
return f(a[l.a1_], a[l.a2_], a[l.a3_], a[l.a4_], a[l.a5_]);
|
||||
return unwrap(f, 0)(a[l.a1_], a[l.a2_], a[l.a3_], a[l.a4_], a[l.a5_]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -802,7 +824,7 @@ template <> struct evaluator5<void>
|
||||
template<class L, class F, class A>
|
||||
static void eval(L const& l, F f, A & a)
|
||||
{
|
||||
f(a[l.a1_], a[l.a2_], a[l.a3_], a[l.a4_], a[l.a5_]);
|
||||
unwrap(f, 0)(a[l.a1_], a[l.a2_], a[l.a3_], a[l.a4_], a[l.a5_]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -811,7 +833,7 @@ template <class R> struct evaluator6
|
||||
template<class L, class F, class A>
|
||||
static R eval(L const& l, F f, A & a)
|
||||
{
|
||||
return f(a[l.a1_], a[l.a2_], a[l.a3_], a[l.a4_], a[l.a5_], a[l.a6_]);
|
||||
return unwrap(f, 0)(a[l.a1_], a[l.a2_], a[l.a3_], a[l.a4_], a[l.a5_], a[l.a6_]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -820,7 +842,7 @@ template <> struct evaluator6<void>
|
||||
template<class L, class F, class A>
|
||||
static void eval(L const& l, F f, A & a)
|
||||
{
|
||||
f(a[l.a1_], a[l.a2_], a[l.a3_], a[l.a4_], a[l.a5_], a[l.a6_]);
|
||||
unwrap(f, 0)(a[l.a1_], a[l.a2_], a[l.a3_], a[l.a4_], a[l.a5_], a[l.a6_]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -829,7 +851,7 @@ template <class R> struct evaluator7
|
||||
template<class L, class F, class A>
|
||||
static R eval(L const& l, F f, A & a)
|
||||
{
|
||||
return f(a[l.a1_], a[l.a2_], a[l.a3_], a[l.a4_], a[l.a5_], a[l.a6_], a[l.a7_]);
|
||||
return unwrap(f, 0)(a[l.a1_], a[l.a2_], a[l.a3_], a[l.a4_], a[l.a5_], a[l.a6_], a[l.a7_]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -838,7 +860,7 @@ template <> struct evaluator7<void>
|
||||
template<class L, class F, class A>
|
||||
static void eval(L const& l, F f, A & a)
|
||||
{
|
||||
f(a[l.a1_], a[l.a2_], a[l.a3_], a[l.a4_], a[l.a5_], a[l.a6_], a[l.a7_]);
|
||||
unwrap(f, 0)(a[l.a1_], a[l.a2_], a[l.a3_], a[l.a4_], a[l.a5_], a[l.a6_], a[l.a7_]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -847,7 +869,7 @@ template <class R> struct evaluator8
|
||||
template<class L, class F, class A>
|
||||
static R eval(L const& l, F f, A & a)
|
||||
{
|
||||
return f(a[l.a1_], a[l.a2_], a[l.a3_], a[l.a4_], a[l.a5_], a[l.a6_], a[l.a7_], a[l.a8_]);
|
||||
return unwrap(f, 0)(a[l.a1_], a[l.a2_], a[l.a3_], a[l.a4_], a[l.a5_], a[l.a6_], a[l.a7_], a[l.a8_]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -856,7 +878,7 @@ template <> struct evaluator8<void>
|
||||
template<class L, class F, class A>
|
||||
static void eval(L const& l, F f, A & a)
|
||||
{
|
||||
f(a[l.a1_], a[l.a2_], a[l.a3_], a[l.a4_], a[l.a5_], a[l.a6_], a[l.a7_], a[l.a8_]);
|
||||
unwrap(f, 0)(a[l.a1_], a[l.a2_], a[l.a3_], a[l.a4_], a[l.a5_], a[l.a6_], a[l.a7_], a[l.a8_]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -865,7 +887,7 @@ template <class R> struct evaluator9
|
||||
template<class L, class F, class A>
|
||||
static R eval(L const& l, F f, A & a)
|
||||
{
|
||||
return f(a[l.a1_], a[l.a2_], a[l.a3_], a[l.a4_], a[l.a5_], a[l.a6_], a[l.a7_], a[l.a8_], a[l.a9_]);
|
||||
return unwrap(f, 0)(a[l.a1_], a[l.a2_], a[l.a3_], a[l.a4_], a[l.a5_], a[l.a6_], a[l.a7_], a[l.a8_], a[l.a9_]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -874,7 +896,7 @@ template <> struct evaluator9<void>
|
||||
template<class L, class F, class A>
|
||||
static void eval(L const& l, F f, A & a)
|
||||
{
|
||||
f(a[l.a1_], a[l.a2_], a[l.a3_], a[l.a4_], a[l.a5_], a[l.a6_], a[l.a7_], a[l.a8_], a[l.a9_]);
|
||||
unwrap(f, 0)(a[l.a1_], a[l.a2_], a[l.a3_], a[l.a4_], a[l.a5_], a[l.a6_], a[l.a7_], a[l.a8_], a[l.a9_]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -967,12 +989,12 @@ template<class T> struct add_value< reference_wrapper<T> >
|
||||
|
||||
template<int I> struct add_value< arg<I> >
|
||||
{
|
||||
typedef arg<I> type;
|
||||
typedef boost::arg<I> type;
|
||||
};
|
||||
|
||||
template<int I> struct add_value< arg<I> (*) () >
|
||||
{
|
||||
typedef arg<I> (*type) ();
|
||||
typedef boost::arg<I> (*type) ();
|
||||
};
|
||||
|
||||
template<class R, class F, class L> struct add_value< bind_t<R, F, L> >
|
||||
@@ -1321,6 +1343,18 @@ template<class F, class A1, class A2, class A3, class A4, class A5, class A6, cl
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_BIND_ENABLE_FASTCALL
|
||||
|
||||
#define BOOST_BIND_CC __fastcall
|
||||
#define BOOST_BIND_ST
|
||||
|
||||
#include <boost/bind/bind_cc.hpp>
|
||||
|
||||
#undef BOOST_BIND_CC
|
||||
#undef BOOST_BIND_ST
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_BIND_ENABLE_PASCAL
|
||||
|
||||
#define BOOST_BIND_ST pascal
|
||||
@@ -1355,15 +1389,27 @@ template<class F, class A1, class A2, class A3, class A4, class A5, class A6, cl
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_MEM_FN_ENABLE_FASTCALL
|
||||
|
||||
#define BOOST_BIND_MF_NAME(X) X##_fastcall
|
||||
#define BOOST_BIND_MF_CC __fastcall
|
||||
|
||||
#include <boost/bind/bind_mf_cc.hpp>
|
||||
|
||||
#undef BOOST_BIND_MF_NAME
|
||||
#undef BOOST_BIND_MF_CC
|
||||
|
||||
#endif
|
||||
|
||||
// data member pointers
|
||||
|
||||
template<class R, class T, class A1>
|
||||
_bi::bind_t< R, _mfi::dm<R, T>, typename _bi::list_av_1<A1>::type >
|
||||
_bi::bind_t< R const &, _mfi::dm<R, T>, typename _bi::list_av_1<A1>::type >
|
||||
BOOST_BIND(R T::*f, A1 a1)
|
||||
{
|
||||
typedef _mfi::dm<R, T> F;
|
||||
typedef typename _bi::list_av_1<A1>::type list_type;
|
||||
return _bi::bind_t<R, F, list_type>(F(f), list_type(a1));
|
||||
return _bi::bind_t<R const &, F, list_type>(F(f), list_type(a1));
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
@@ -36,7 +36,7 @@ static inline boost::arg<7> _7() { return boost::arg<7>(); }
|
||||
static inline boost::arg<8> _8() { return boost::arg<8>(); }
|
||||
static inline boost::arg<9> _9() { return boost::arg<9>(); }
|
||||
|
||||
#elif defined(BOOST_MSVC)
|
||||
#elif defined(BOOST_MSVC) && BOOST_MSVC <= 1300
|
||||
|
||||
static boost::arg<1> _1;
|
||||
static boost::arg<2> _2;
|
||||
|
||||
@@ -66,6 +66,18 @@ template<class V> struct mf
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_MEM_FN_ENABLE_FASTCALL
|
||||
|
||||
#define BOOST_MEM_FN_NAME(X) inner_##X##_fastcall
|
||||
#define BOOST_MEM_FN_CC __fastcall
|
||||
|
||||
#include <boost/bind/mem_fn_template.hpp>
|
||||
|
||||
#undef BOOST_MEM_FN_CC
|
||||
#undef BOOST_MEM_FN_NAME
|
||||
|
||||
#endif
|
||||
|
||||
#undef BOOST_MEM_FN_RETURN
|
||||
|
||||
}; // struct mf<V>
|
||||
@@ -95,6 +107,18 @@ template<> struct mf<void>
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_MEM_FN_ENABLE_FASTCALL
|
||||
|
||||
#define BOOST_MEM_FN_NAME(X) inner_##X##_fastcall
|
||||
#define BOOST_MEM_FN_CC __fastcall
|
||||
|
||||
#include <boost/bind/mem_fn_template.hpp>
|
||||
|
||||
#undef BOOST_MEM_FN_CC
|
||||
#undef BOOST_MEM_FN_NAME
|
||||
|
||||
#endif
|
||||
|
||||
#undef BOOST_MEM_FN_RETURN
|
||||
|
||||
}; // struct mf<void>
|
||||
@@ -126,6 +150,20 @@ template<> struct mf<void>
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_MEM_FN_ENABLE_FASTCALL
|
||||
|
||||
#define BOOST_MEM_FN_NAME(X) X##_fastcall
|
||||
#define BOOST_MEM_FN_NAME2(X) inner_##X##_fastcall
|
||||
#define BOOST_MEM_FN_CC __fastcall
|
||||
|
||||
#include <boost/bind/mem_fn_vw.hpp>
|
||||
|
||||
#undef BOOST_MEM_FN_NAME
|
||||
#undef BOOST_MEM_FN_NAME2
|
||||
#undef BOOST_MEM_FN_CC
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace _mfi
|
||||
|
||||
#else // #ifdef BOOST_NO_VOID_RETURNS
|
||||
@@ -158,6 +196,18 @@ namespace _mfi
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_MEM_FN_ENABLE_FASTCALL
|
||||
|
||||
#define BOOST_MEM_FN_NAME(X) X##_fastcall
|
||||
#define BOOST_MEM_FN_CC __fastcall
|
||||
|
||||
#include <boost/bind/mem_fn_template.hpp>
|
||||
|
||||
#undef BOOST_MEM_FN_CC
|
||||
#undef BOOST_MEM_FN_NAME
|
||||
|
||||
#endif
|
||||
|
||||
#undef BOOST_MEM_FN_RETURN
|
||||
|
||||
} // namespace _mfi
|
||||
@@ -187,6 +237,18 @@ namespace _mfi
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_MEM_FN_ENABLE_FASTCALL
|
||||
|
||||
#define BOOST_MEM_FN_NAME(X) X##_fastcall
|
||||
#define BOOST_MEM_FN_CC __fastcall
|
||||
|
||||
#include <boost/bind/mem_fn_cc.hpp>
|
||||
|
||||
#undef BOOST_MEM_FN_NAME
|
||||
#undef BOOST_MEM_FN_CC
|
||||
|
||||
#endif
|
||||
|
||||
// data member support
|
||||
|
||||
namespace _mfi
|
||||
|
||||
10
index.html
Normal file
10
index.html
Normal file
@@ -0,0 +1,10 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="refresh" content="0; URL=bind.html">
|
||||
</head>
|
||||
<body>
|
||||
Automatic redirection failed, please go to
|
||||
<a href="bind.html">bind.html</a> or
|
||||
<a href="mem_fn.html">mem_fn.html</a>.
|
||||
</body>
|
||||
</html>
|
||||
86
mem_fn.html
86
mem_fn.html
@@ -37,14 +37,17 @@
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#Files">Files</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#Dependencies">Dependencies</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#NumberOfArguments">Number of Arguments</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#stdcall">"__stdcall" Support</a></h4>
|
||||
<h4 style="MARGIN-LEFT: 40pt"><a href="#stdcall">"__stdcall" and
|
||||
"__fastcall" Support</a></h4>
|
||||
<h3 style="MARGIN-LEFT: 20pt"><a href="#Acknowledgements">Acknowledgements</a></h3>
|
||||
<h2><a name="Purpose">Purpose</a></h2>
|
||||
<p>
|
||||
<b>boost::mem_fn</b> is a generalization of the standard functions <b>std::mem_fun</b>
|
||||
and <b>std::mem_fun_ref</b>. It supports member function pointers with more
|
||||
than one argument, and the returned function object can take a pointer, a
|
||||
reference, or a smart pointer to an object instance as its first argument.
|
||||
reference, or a smart pointer to an object instance as its first argument. <STRONG>mem_fn</STRONG>
|
||||
also supports pointers to data members by treating them as functions taking no
|
||||
arguments and returning a (const) reference to the member.
|
||||
</p>
|
||||
<p>
|
||||
The purpose of <b>mem_fn</b> is twofold. First, it allows users to invoke a
|
||||
@@ -86,8 +89,8 @@ template<class It, class R, class T> void for_each(It first, It last, R (T
|
||||
documentation of <b>bind</b></a> for an example.
|
||||
</p>
|
||||
<p>
|
||||
<b>mem_fn</b> takes one argument, a pointer to a member function, and returns a
|
||||
function object suitable for use with standard or user-defined algorithms:
|
||||
<b>mem_fn</b> takes one argument, a pointer to a member, and returns a function
|
||||
object suitable for use with standard or user-defined algorithms:
|
||||
</p>
|
||||
<pre>
|
||||
struct X
|
||||
@@ -135,7 +138,8 @@ void k(std::vector<boost::shared_ptr<X> > const & v)
|
||||
</p>
|
||||
<p>
|
||||
All function objects returned by <b>mem_fn</b> expose a <b>result_type</b> typedef
|
||||
that represents the return type of the member function.
|
||||
that represents the return type of the member function. For data members, <STRONG>result_type</STRONG>
|
||||
is defined as a const reference to the type of the member.
|
||||
</p>
|
||||
<h2><a name="FAQ">Frequently Asked Questions</a></h2>
|
||||
<h3><a name="Q1">Can <b>mem_fn</b> be used instead of the standard <b>std::mem_fun[_ref]</b>
|
||||
@@ -175,19 +179,21 @@ void k(std::vector<boost::shared_ptr<X> > const & v)
|
||||
namespace boost
|
||||
{
|
||||
|
||||
template<class T> T * <a href="#get_pointer_1">get_pointer</a> (T * p);
|
||||
template<class T> T * <a href="#get_pointer_1">get_pointer</a>(T * p);
|
||||
|
||||
template<class R, class T> <i>implementation-defined-1</i> <a href="#mem_fn_1">mem_fn</a>(R (T::*pmf) ());
|
||||
template<class R, class T> <i>unspecified-1</i> <a href="#mem_fn_1">mem_fn</a>(R (T::*pmf) ());
|
||||
|
||||
template<class R, class T> <i>implementation-defined-2</i> <a href="#mem_fn_2">mem_fn</a>(R (T::*pmf) () const);
|
||||
template<class R, class T> <i>unspecified-2</i> <a href="#mem_fn_2">mem_fn</a>(R (T::*pmf) () const);
|
||||
|
||||
template<class R, class T, class A1> <i>implementation-defined-3</i> <a href="#mem_fn_3">mem_fn</a>(R (T::*pmf) (A1));
|
||||
template<class R, class T> <i>unspecified-2-1</i> <a href="#mem_fn_2_1">mem_fn</a>(R T::*pm);
|
||||
|
||||
template<class R, class T, class A1> <i>implementation-defined-4</i> <a href="#mem_fn_4">mem_fn</a>(R (T::*pmf) (A1) const);
|
||||
template<class R, class T, class A1> <i>unspecified-3</i> <a href="#mem_fn_3">mem_fn</a>(R (T::*pmf) (A1));
|
||||
|
||||
template<class R, class T, class A1, class A2> <i>implementation-defined-5</i> <a href="#mem_fn_5">mem_fn</a>(R (T::*pmf) (A1, A2));
|
||||
template<class R, class T, class A1> <i>unspecified-4</i> <a href="#mem_fn_4">mem_fn</a>(R (T::*pmf) (A1) const);
|
||||
|
||||
template<class R, class T, class A1, class A2> <i>implementation-defined-6</i> <a href="#mem_fn_6">mem_fn</a>(R (T::*pmf) (A1, A2) const);
|
||||
template<class R, class T, class A1, class A2> <i>unspecified-5</i> <a href="#mem_fn_5">mem_fn</a>(R (T::*pmf) (A1, A2));
|
||||
|
||||
template<class R, class T, class A1, class A2> <i>unspecified-6</i> <a href="#mem_fn_6">mem_fn</a>(R (T::*pmf) (A1, A2) const);
|
||||
|
||||
// implementation defined number of additional overloads for more arguments
|
||||
|
||||
@@ -195,11 +201,12 @@ template<class R, class T, class A1, class A2> <i>implementation-defined-6
|
||||
</pre>
|
||||
<h3><a name="CommonRequirements">Common requirements</a></h3>
|
||||
<p>
|
||||
All <tt><i>implementation-defined-N</i></tt> types mentioned in the Synopsis
|
||||
are <b>CopyConstructible</b> and <b>Assignable</b>. Their copy constructors and
|
||||
assignment operators do not throw exceptions. <tt><i>implementation-defined-N</i>::result_type</tt>
|
||||
is defined as the return type of the member function pointer passed as an
|
||||
argument to <b>mem_fn</b> (<b>R</b> in the Synopsis.)
|
||||
All <tt><i>unspecified-N</i></tt> types mentioned in the Synopsis are <b>CopyConstructible</b>
|
||||
and <b>Assignable</b>. Their copy constructors and assignment operators do not
|
||||
throw exceptions. <tt><i>unspecified-N</i>::result_type</tt> is defined as the
|
||||
return type of the member function pointer passed as an argument to <b>mem_fn</b>
|
||||
(<b>R</b> in the Synopsis.) <tt><i>unspecified-2-1</i>::result_type</tt> is
|
||||
defined as <tt>R const &</tt>.
|
||||
</p>
|
||||
<h3><a name="get_pointer">get_pointer</a></h3>
|
||||
<h4><a name="get_pointer_1">template<class T> T * get_pointer(T * p)</a></h4>
|
||||
@@ -212,8 +219,8 @@ template<class R, class T, class A1, class A2> <i>implementation-defined-6
|
||||
</p>
|
||||
</blockquote>
|
||||
<h3><a name="mem_fn">mem_fn</a></h3>
|
||||
<h4><a name="mem_fn_1">template<class R, class T> <i>implementation-defined-1</i>
|
||||
mem_fn(R (T::*pmf) ())</a></h4>
|
||||
<h4><a name="mem_fn_1">template<class R, class T> <i>unspecified-1</i> mem_fn(R
|
||||
(T::*pmf) ())</a></h4>
|
||||
<blockquote>
|
||||
<p>
|
||||
<b>Returns:</b> a function object <i>f</i> such that the expression <tt><i>f(t)</i></tt>
|
||||
@@ -224,8 +231,8 @@ template<class R, class T, class A1, class A2> <i>implementation-defined-6
|
||||
<b>Throws:</b> Nothing.
|
||||
</p>
|
||||
</blockquote>
|
||||
<h4><a name="mem_fn_2">template<class R, class T> <i>implementation-defined-2</i>
|
||||
mem_fn(R (T::*pmf) () const)</a></h4>
|
||||
<h4><a name="mem_fn_2">template<class R, class T> <i>unspecified-2</i> mem_fn(R
|
||||
(T::*pmf) () const)</a></h4>
|
||||
<blockquote>
|
||||
<p>
|
||||
<b>Returns:</b> a function object <i>f</i> such that the expression <tt><i>f(t)</i></tt>
|
||||
@@ -237,8 +244,20 @@ template<class R, class T, class A1, class A2> <i>implementation-defined-6
|
||||
<b>Throws:</b> Nothing.
|
||||
</p>
|
||||
</blockquote>
|
||||
<h4><a name="mem_fn_3">template<class R, class T, class A1> <i>implementation-defined-3</i>
|
||||
mem_fn(R (T::*pmf) (A1))</a></h4>
|
||||
<h4><a name="mem_fn_2_1">template<class R, class T> <i>unspecified-2-1</i> mem_fn(R
|
||||
T::*pm)</a></h4>
|
||||
<blockquote>
|
||||
<p>
|
||||
<b>Returns:</b> a function object <i>f</i> such that the expression <tt><i>f(t)</i></tt>
|
||||
is equivalent to <tt>t.*pm</tt> when <i>t</i> is of type <STRONG>T</STRONG> <EM>[const]<STRONG>
|
||||
</STRONG></EM>or derived, <tt>get_pointer(t)->*pm</tt> otherwise.
|
||||
</p>
|
||||
<p>
|
||||
<b>Throws:</b> Nothing.
|
||||
</p>
|
||||
</blockquote>
|
||||
<h4><a name="mem_fn_3">template<class R, class T, class A1> <i>unspecified-3</i> mem_fn(R
|
||||
(T::*pmf) (A1))</a></h4>
|
||||
<blockquote>
|
||||
<p>
|
||||
<b>Returns:</b> a function object <i>f</i> such that the expression <tt><i>f(t, a1)</i></tt>
|
||||
@@ -249,8 +268,8 @@ template<class R, class T, class A1, class A2> <i>implementation-defined-6
|
||||
<b>Throws:</b> Nothing.
|
||||
</p>
|
||||
</blockquote>
|
||||
<h4><a name="mem_fn_4">template<class R, class T, class A1> <i>implementation-defined-4</i>
|
||||
mem_fn(R (T::*pmf) (A1) const)</a></h4>
|
||||
<h4><a name="mem_fn_4">template<class R, class T, class A1> <i>unspecified-4</i> mem_fn(R
|
||||
(T::*pmf) (A1) const)</a></h4>
|
||||
<blockquote>
|
||||
<p>
|
||||
<b>Returns:</b> a function object <i>f</i> such that the expression <tt><i>f(t, a1)</i></tt>
|
||||
@@ -262,7 +281,7 @@ template<class R, class T, class A1, class A2> <i>implementation-defined-6
|
||||
<b>Throws:</b> Nothing.
|
||||
</p>
|
||||
</blockquote>
|
||||
<h4><a name="mem_fn_5">template<class R, class T, class A1, class A2> <i>implementation-defined-5</i>
|
||||
<h4><a name="mem_fn_5">template<class R, class T, class A1, class A2> <i>unspecified-5</i>
|
||||
mem_fn(R (T::*pmf) (A1, A2))</a></h4>
|
||||
<blockquote>
|
||||
<p>
|
||||
@@ -274,7 +293,7 @@ template<class R, class T, class A1, class A2> <i>implementation-defined-6
|
||||
<b>Throws:</b> Nothing.
|
||||
</p>
|
||||
</blockquote>
|
||||
<h4><a name="mem_fn_6">template<class R, class T, class A1, class A2> <i>implementation-defined-6</i>
|
||||
<h4><a name="mem_fn_6">template<class R, class T, class A1, class A2> <i>unspecified-6</i>
|
||||
mem_fn(R (T::*pmf) (A1, A2) const)</a></h4>
|
||||
<blockquote>
|
||||
<p>
|
||||
@@ -321,7 +340,7 @@ template<class R, class T, class A1, class A2> <i>implementation-defined-6
|
||||
This implementation supports member functions with up to eight arguments. This
|
||||
is not an inherent limitation of the design, but an implementation detail.
|
||||
</p>
|
||||
<h3><a name="stdcall">"__stdcall" Support</a></h3>
|
||||
<h3><a name="stdcall">"__stdcall" and "__fastcall" Support</a></h3>
|
||||
<p>
|
||||
Some platforms allow several types of member functions that differ by their <b>calling
|
||||
convention</b> (the rules by which the function is invoked: how are
|
||||
@@ -330,16 +349,19 @@ template<class R, class T, class A1, class A2> <i>implementation-defined-6
|
||||
</p>
|
||||
<p>
|
||||
For example, Windows API functions and COM interface member functions use a
|
||||
calling convention known as <b>__stdcall</b>.
|
||||
calling convention known as <b>__stdcall</b>. Borland VCL components use <STRONG>__fastcall</STRONG>.
|
||||
</p>
|
||||
<p>
|
||||
To use <b>mem_fn</b> with <b>__stdcall</b> member functions, <b>#define</b> the
|
||||
macro <b>BOOST_MEM_FN_ENABLE_STDCALL</b> before including, directly or
|
||||
indirectly, <b><boost/mem_fn.hpp></b>.
|
||||
</p>
|
||||
<p>
|
||||
[Note: this is a non-portable extension. It is not part of the interface.]
|
||||
</p>
|
||||
<P>To use <B>mem_fn</B> with <B>__fastcall</B> member functions, <B>#define</B> the
|
||||
macro <B>BOOST_MEM_FN_ENABLE_FASTCALL</B> before including, directly or
|
||||
indirectly, <B><boost/mem_fn.hpp></B>.
|
||||
</P>
|
||||
<P>[Note: this is a non-portable extension. It is not part of the interface.]
|
||||
</P>
|
||||
<p>
|
||||
[Note: Some compilers provide only minimal support for the <b>__stdcall</b> keyword.]
|
||||
</p>
|
||||
|
||||
185
mem_fn_fastcall_test.cpp
Normal file
185
mem_fn_fastcall_test.cpp
Normal file
@@ -0,0 +1,185 @@
|
||||
#if defined(_MSC_VER) && !defined(__ICL)
|
||||
#pragma warning(disable: 4786) // identifier truncated in debug info
|
||||
#pragma warning(disable: 4710) // function not inlined
|
||||
#pragma warning(disable: 4711) // function selected for automatic inline expansion
|
||||
#pragma warning(disable: 4514) // unreferenced inline removed
|
||||
#endif
|
||||
|
||||
//
|
||||
// mem_fn_fastcall_test.cpp - a test for mem_fn.hpp + __fastcall
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
|
||||
#define BOOST_MEM_FN_ENABLE_FASTCALL
|
||||
|
||||
#include <boost/mem_fn.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
|
||||
#pragma warning(push, 3)
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
struct X
|
||||
{
|
||||
mutable unsigned int hash;
|
||||
|
||||
X(): hash(0) {}
|
||||
|
||||
void __fastcall f0() { f1(17); }
|
||||
void __fastcall g0() const { g1(17); }
|
||||
|
||||
void __fastcall f1(int a1) { hash = (hash * 17041 + a1) % 32768; }
|
||||
void __fastcall g1(int a1) const { hash = (hash * 17041 + a1 * 2) % 32768; }
|
||||
|
||||
void __fastcall f2(int a1, int a2) { f1(a1); f1(a2); }
|
||||
void __fastcall g2(int a1, int a2) const { g1(a1); g1(a2); }
|
||||
|
||||
void __fastcall f3(int a1, int a2, int a3) { f2(a1, a2); f1(a3); }
|
||||
void __fastcall g3(int a1, int a2, int a3) const { g2(a1, a2); g1(a3); }
|
||||
|
||||
void __fastcall f4(int a1, int a2, int a3, int a4) { f3(a1, a2, a3); f1(a4); }
|
||||
void __fastcall g4(int a1, int a2, int a3, int a4) const { g3(a1, a2, a3); g1(a4); }
|
||||
|
||||
void __fastcall f5(int a1, int a2, int a3, int a4, int a5) { f4(a1, a2, a3, a4); f1(a5); }
|
||||
void __fastcall g5(int a1, int a2, int a3, int a4, int a5) const { g4(a1, a2, a3, a4); g1(a5); }
|
||||
|
||||
void __fastcall f6(int a1, int a2, int a3, int a4, int a5, int a6) { f5(a1, a2, a3, a4, a5); f1(a6); }
|
||||
void __fastcall g6(int a1, int a2, int a3, int a4, int a5, int a6) const { g5(a1, a2, a3, a4, a5); g1(a6); }
|
||||
|
||||
void __fastcall f7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) { f6(a1, a2, a3, a4, a5, a6); f1(a7); }
|
||||
void __fastcall g7(int a1, int a2, int a3, int a4, int a5, int a6, int a7) const { g6(a1, a2, a3, a4, a5, a6); g1(a7); }
|
||||
|
||||
void __fastcall f8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) { f7(a1, a2, a3, a4, a5, a6, a7); f1(a8); }
|
||||
void __fastcall g8(int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8) const { g7(a1, a2, a3, a4, a5, a6, a7); g1(a8); }
|
||||
};
|
||||
|
||||
int detect_errors(bool x)
|
||||
{
|
||||
if(x)
|
||||
{
|
||||
std::cerr << "no errors detected.\n";
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "test failed.\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
using boost::mem_fn;
|
||||
|
||||
X x;
|
||||
|
||||
X const & rcx = x;
|
||||
X const * pcx = &x;
|
||||
|
||||
boost::shared_ptr<X> sp(new X);
|
||||
|
||||
mem_fn(&X::f0)(x);
|
||||
mem_fn(&X::f0)(&x);
|
||||
mem_fn(&X::f0)(sp);
|
||||
|
||||
mem_fn(&X::g0)(x);
|
||||
mem_fn(&X::g0)(rcx);
|
||||
mem_fn(&X::g0)(&x);
|
||||
mem_fn(&X::g0)(pcx);
|
||||
mem_fn(&X::g0)(sp);
|
||||
|
||||
mem_fn(&X::f1)(x, 1);
|
||||
mem_fn(&X::f1)(&x, 1);
|
||||
mem_fn(&X::f1)(sp, 1);
|
||||
|
||||
mem_fn(&X::g1)(x, 1);
|
||||
mem_fn(&X::g1)(rcx, 1);
|
||||
mem_fn(&X::g1)(&x, 1);
|
||||
mem_fn(&X::g1)(pcx, 1);
|
||||
mem_fn(&X::g1)(sp, 1);
|
||||
|
||||
mem_fn(&X::f2)(x, 1, 2);
|
||||
mem_fn(&X::f2)(&x, 1, 2);
|
||||
mem_fn(&X::f2)(sp, 1, 2);
|
||||
|
||||
mem_fn(&X::g2)(x, 1, 2);
|
||||
mem_fn(&X::g2)(rcx, 1, 2);
|
||||
mem_fn(&X::g2)(&x, 1, 2);
|
||||
mem_fn(&X::g2)(pcx, 1, 2);
|
||||
mem_fn(&X::g2)(sp, 1, 2);
|
||||
|
||||
mem_fn(&X::f3)(x, 1, 2, 3);
|
||||
mem_fn(&X::f3)(&x, 1, 2, 3);
|
||||
mem_fn(&X::f3)(sp, 1, 2, 3);
|
||||
|
||||
mem_fn(&X::g3)(x, 1, 2, 3);
|
||||
mem_fn(&X::g3)(rcx, 1, 2, 3);
|
||||
mem_fn(&X::g3)(&x, 1, 2, 3);
|
||||
mem_fn(&X::g3)(pcx, 1, 2, 3);
|
||||
mem_fn(&X::g3)(sp, 1, 2, 3);
|
||||
|
||||
mem_fn(&X::f4)(x, 1, 2, 3, 4);
|
||||
mem_fn(&X::f4)(&x, 1, 2, 3, 4);
|
||||
mem_fn(&X::f4)(sp, 1, 2, 3, 4);
|
||||
|
||||
mem_fn(&X::g4)(x, 1, 2, 3, 4);
|
||||
mem_fn(&X::g4)(rcx, 1, 2, 3, 4);
|
||||
mem_fn(&X::g4)(&x, 1, 2, 3, 4);
|
||||
mem_fn(&X::g4)(pcx, 1, 2, 3, 4);
|
||||
mem_fn(&X::g4)(sp, 1, 2, 3, 4);
|
||||
|
||||
mem_fn(&X::f5)(x, 1, 2, 3, 4, 5);
|
||||
mem_fn(&X::f5)(&x, 1, 2, 3, 4, 5);
|
||||
mem_fn(&X::f5)(sp, 1, 2, 3, 4, 5);
|
||||
|
||||
mem_fn(&X::g5)(x, 1, 2, 3, 4, 5);
|
||||
mem_fn(&X::g5)(rcx, 1, 2, 3, 4, 5);
|
||||
mem_fn(&X::g5)(&x, 1, 2, 3, 4, 5);
|
||||
mem_fn(&X::g5)(pcx, 1, 2, 3, 4, 5);
|
||||
mem_fn(&X::g5)(sp, 1, 2, 3, 4, 5);
|
||||
|
||||
mem_fn(&X::f6)(x, 1, 2, 3, 4, 5, 6);
|
||||
mem_fn(&X::f6)(&x, 1, 2, 3, 4, 5, 6);
|
||||
mem_fn(&X::f6)(sp, 1, 2, 3, 4, 5, 6);
|
||||
|
||||
mem_fn(&X::g6)(x, 1, 2, 3, 4, 5, 6);
|
||||
mem_fn(&X::g6)(rcx, 1, 2, 3, 4, 5, 6);
|
||||
mem_fn(&X::g6)(&x, 1, 2, 3, 4, 5, 6);
|
||||
mem_fn(&X::g6)(pcx, 1, 2, 3, 4, 5, 6);
|
||||
mem_fn(&X::g6)(sp, 1, 2, 3, 4, 5, 6);
|
||||
|
||||
mem_fn(&X::f7)(x, 1, 2, 3, 4, 5, 6, 7);
|
||||
mem_fn(&X::f7)(&x, 1, 2, 3, 4, 5, 6, 7);
|
||||
mem_fn(&X::f7)(sp, 1, 2, 3, 4, 5, 6, 7);
|
||||
|
||||
mem_fn(&X::g7)(x, 1, 2, 3, 4, 5, 6, 7);
|
||||
mem_fn(&X::g7)(rcx, 1, 2, 3, 4, 5, 6, 7);
|
||||
mem_fn(&X::g7)(&x, 1, 2, 3, 4, 5, 6, 7);
|
||||
mem_fn(&X::g7)(pcx, 1, 2, 3, 4, 5, 6, 7);
|
||||
mem_fn(&X::g7)(sp, 1, 2, 3, 4, 5, 6, 7);
|
||||
|
||||
mem_fn(&X::f8)(x, 1, 2, 3, 4, 5, 6, 7, 8);
|
||||
mem_fn(&X::f8)(&x, 1, 2, 3, 4, 5, 6, 7, 8);
|
||||
mem_fn(&X::f8)(sp, 1, 2, 3, 4, 5, 6, 7, 8);
|
||||
|
||||
mem_fn(&X::g8)(x, 1, 2, 3, 4, 5, 6, 7, 8);
|
||||
mem_fn(&X::g8)(rcx, 1, 2, 3, 4, 5, 6, 7, 8);
|
||||
mem_fn(&X::g8)(&x, 1, 2, 3, 4, 5, 6, 7, 8);
|
||||
mem_fn(&X::g8)(pcx, 1, 2, 3, 4, 5, 6, 7, 8);
|
||||
mem_fn(&X::g8)(sp, 1, 2, 3, 4, 5, 6, 7, 8);
|
||||
|
||||
return detect_errors(x.hash == 17610 && sp->hash == 2155);
|
||||
}
|
||||
Reference in New Issue
Block a user