mirror of
https://github.com/boostorg/function.git
synced 2026-01-30 07:52:08 +00:00
Compare commits
41 Commits
boost-1.26
...
svn-branch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5d7f4aae46 | ||
|
|
9a4d7447a7 | ||
|
|
83481662bb | ||
|
|
64b6e85a94 | ||
|
|
57ee7e962a | ||
|
|
48943fec83 | ||
|
|
a0b89d0a30 | ||
|
|
82226cb9d6 | ||
|
|
28984e4f23 | ||
|
|
02f5d9d0e0 | ||
|
|
1774c0646d | ||
|
|
4b430a5414 | ||
|
|
7b0f465f33 | ||
|
|
6882358627 | ||
|
|
39f6d34db8 | ||
|
|
812ef599bd | ||
|
|
8c198b1c90 | ||
|
|
5a07d4b262 | ||
|
|
11187bcf3a | ||
|
|
aaa7f61b9e | ||
|
|
a250f9c140 | ||
|
|
4f33ea7665 | ||
|
|
51c376c4ee | ||
|
|
8e123d2a97 | ||
|
|
58656b40b1 | ||
|
|
2fa9ee040b | ||
|
|
8635632937 | ||
|
|
96f7184528 | ||
|
|
647693dfc9 | ||
|
|
d48fa26030 | ||
|
|
d3daf6db42 | ||
|
|
fb26630e37 | ||
|
|
794b728603 | ||
|
|
ce68cb8999 | ||
|
|
47599fb625 | ||
|
|
1a7478bbd1 | ||
|
|
db5399d447 | ||
|
|
083767f67a | ||
|
|
8cbd121969 | ||
|
|
2e67e2126b | ||
|
|
1512df77b1 |
@@ -32,7 +32,7 @@
|
|||||||
<b>typename</b> Allocator = std::allocator<function_base> >
|
<b>typename</b> Allocator = std::allocator<function_base> >
|
||||||
<b>class</b> <a href="#functionN">function<i>N</i></a> : <b>public</b> <a href="#function_base">function_base</a>, <b>public</b> Mixin
|
<b>class</b> <a href="#functionN">function<i>N</i></a> : <b>public</b> <a href="#function_base">function_base</a>, <b>public</b> Mixin
|
||||||
{
|
{
|
||||||
<b>typedef</b> ResultType result_type;
|
<b>typedef</b> ResultType result_type; <em>// <a href="#novoid">[1]</a></em>
|
||||||
<b>typedef</b> Policy policy_type;
|
<b>typedef</b> Policy policy_type;
|
||||||
<b>typedef</b> Mixin mixin_type;
|
<b>typedef</b> Mixin mixin_type;
|
||||||
<b>typedef</b> Allocator allocator_type;
|
<b>typedef</b> Allocator allocator_type;
|
||||||
@@ -45,13 +45,15 @@
|
|||||||
<i>// Construction</i>
|
<i>// Construction</i>
|
||||||
<a href="#functionN_default"><b>explicit</b> function<i>N</i>(<b>const</b> Mixin<b>&</b> = Mixin())</a>;
|
<a href="#functionN_default"><b>explicit</b> function<i>N</i>(<b>const</b> Mixin<b>&</b> = Mixin())</a>;
|
||||||
<a href="#functionN_copy">function<i>N</i>(<b>const</b> function<i>N</i><b>&</b>)</a>;
|
<a href="#functionN_copy">function<i>N</i>(<b>const</b> function<i>N</i><b>&</b>)</a>;
|
||||||
<a href="#functionN_target"><b>template</b><<b>typename</b> F> function<i>N</i>(<b>const</b> F<b>&</b>, <b>const</b> Mixin<b>&</b> = Mixin())</a>;
|
<a href="#functionN_target"><b>template</b><<b>typename</b> F> function<i>N</i>(F, <b>const</b> Mixin<b>&</b> = Mixin())</a>;
|
||||||
|
<a href="#functionN_target_ref"><b>template</b><<b>typename</b> F> function<i>N</i>(reference_wrapper<F>)</a>;
|
||||||
|
|
||||||
<i>// Assignment</i>
|
<i>// Assignment</i>
|
||||||
<a href="#functionN_copy_assn">function<i>N</i><b>&</b> <b>operator</b>=(<b>const</b> function<i>N</i><b>&</b>)</a>;
|
<a href="#functionN_copy_assn">function<i>N</i><b>&</b> <b>operator</b>=(<b>const</b> function<i>N</i><b>&</b>)</a>;
|
||||||
<a href="#functionN_target_assn"><b>template</b><<b>typename</b> F> function<i>N</i><b>&</b> <b>operator</b>=(<b>const</b> F<b>&</b>)</a>;
|
<a href="#functionN_target_assn"><b>template</b><<b>typename</b> F> function<i>N</i><b>&</b> <b>operator</b>=(F)</a>;
|
||||||
|
<a href="#functionN_target_ref_assn"><b>template</b><<b>typename</b> F> function<i>N</i><b>&</b> <b>operator</b>=(reference_wrapper<F>)</a>;
|
||||||
<a href="#functionN_copy_set"><b>void</b> set(<b>const</b> function<i>N</i><b>&</b>)</a>;
|
<a href="#functionN_copy_set"><b>void</b> set(<b>const</b> function<i>N</i><b>&</b>)</a>;
|
||||||
<a href="#functionN_target_set"><b>template</b><<b>typename</b> F> <b>void</b> set(<b>const</b> F<b>&</b>)</a>;
|
<a href="#functionN_target_set"><b>template</b><<b>typename</b> F> <b>void</b> set(F)</a>;
|
||||||
<a href="#functionN_swap"><b>void</b> swap(function<i>N</i><b>&</b>)</a>;
|
<a href="#functionN_swap"><b>void</b> swap(function<i>N</i><b>&</b>)</a>;
|
||||||
<a href="#functionN_clear"><b>void</b> clear()</a>;
|
<a href="#functionN_clear"><b>void</b> clear()</a>;
|
||||||
|
|
||||||
@@ -67,8 +69,8 @@
|
|||||||
<b>typename</b> Policy,
|
<b>typename</b> Policy,
|
||||||
<b>typename</b> Mixin,
|
<b>typename</b> Mixin,
|
||||||
<b>typename</b> Allocator>
|
<b>typename</b> Allocator>
|
||||||
<b>void</b> <a href="#swap_functionN">swap</a>(<b>const</b> function<em>N</em><Arg1, Arg2, <i>...</i>, Arg<i>N</i>, Policy, Mixin, Allocator><b>&</b>,
|
<b>void</b> <a href="#swap_functionN">swap</a>(function<em>N</em><ResultType, Arg1, Arg2, <i>...</i>, Arg<i>N</i>, Policy, Mixin, Allocator><b>&</b>,
|
||||||
<b>const</b> function<em>N</em><Arg1, Arg2, <i>...</i>, Arg<i>N</i>, Policy, Mixin, Allocator><b>&</b>);
|
function<em>N</em><ResultType, Arg1, Arg2, <i>...</i>, Arg<i>N</i>, Policy, Mixin, Allocator><b>&</b>);
|
||||||
|
|
||||||
// For any <i>N</i> in [0, <i>MAX_ARGS</i>]
|
// For any <i>N</i> in [0, <i>MAX_ARGS</i>]
|
||||||
<b>template</b><<b>typename</b> ResultType,
|
<b>template</b><<b>typename</b> ResultType,
|
||||||
@@ -80,21 +82,21 @@
|
|||||||
<b>typename</b> Arg<i>N+2</i> = <i>implementation-defined</i>,
|
<b>typename</b> Arg<i>N+2</i> = <i>implementation-defined</i>,
|
||||||
<i>...</i>
|
<i>...</i>
|
||||||
<b>typename</b> Arg<i>MAX_ARGS</i> = <i>implementation-defined</i>>
|
<b>typename</b> Arg<i>MAX_ARGS</i> = <i>implementation-defined</i>>
|
||||||
<b>class</b> <a href="#function">function</a> : <b>public</b> <a href="#functionN">function<i>N</i></a><Arg1, Arg2, <i>...</i>, Arg<i>N</i>>
|
<b>class</b> <a href="#function">function</a> : <b>public</b> <a href="#functionN">function<i>N</i></a><ResultType, Arg1, Arg2, <i>...</i>, Arg<i>N</i>>
|
||||||
{
|
{
|
||||||
<i>// Construction</i>
|
<i>// Construction</i>
|
||||||
function();
|
function();
|
||||||
function(<b>const</b> function<b>&</b>);
|
function(<b>const</b> function<b>&</b>);
|
||||||
function<i>N</i>(<b>const</b> function<i>N</i><b>&</b>);
|
function(<b>const</b> function<i>N</i><ResultType, Arg1, Arg2, ..., Arg<i>N</i>><b>&</b>);
|
||||||
<b>template</b><<b>typename</b> F> function<i>N</i>(<b>const</b> F<b>&</b>);
|
<b>template</b><<b>typename</b> F> function<i>N</i>(F);
|
||||||
|
|
||||||
<i>// Assignment</i>
|
<i>// Assignment</i>
|
||||||
function<b>&</b> <b>operator</b>=(<b>const</b> function<b>&</b>);
|
function<b>&</b> <b>operator</b>=(<b>const</b> function<b>&</b>);
|
||||||
function<i>N</i><b>&</b> <b>operator</b>=(<b>const</b> function<i>N</i><b>&</b>);
|
function<b>&</b> <b>operator</b>=(<b>const</b> function<i>N</i><ResultType, Arg1, Arg2, ..., Arg<i>N</i>><b>&</b>);
|
||||||
<b>template</b><<b>typename</b> F> function<b>&</b> <b>operator</b>=(<b>const</b> F<b>&</b>);
|
<b>template</b><<b>typename</b> F> function<b>&</b> <b>operator</b>=(F);
|
||||||
<b>void</b> set(<b>const</b> function<b>&</b>);
|
<b>void</b> set(<b>const</b> function<b>&</b>);
|
||||||
<b>void</b> set(<b>const</b> function<i>N</i><b>&</b>);
|
<b>void</b> set(<b>const</b> function<i>N</i><ResultType, Arg1, Arg2, ..., Arg<i>N</i>><b>&</b>);
|
||||||
<b>template</b><<b>typename</b> F> <b>void</b> set(<b>const</b> F<b>&</b>);
|
<b>template</b><<b>typename</b> F> <b>void</b> set(F);
|
||||||
};
|
};
|
||||||
|
|
||||||
<b>template</b><<b>typename</b> ResultType,
|
<b>template</b><<b>typename</b> ResultType,
|
||||||
@@ -102,8 +104,8 @@
|
|||||||
<b>typename</b> Arg2,
|
<b>typename</b> Arg2,
|
||||||
<i>...</i>
|
<i>...</i>
|
||||||
<b>typename</b> Arg<i>MAX_ARGS</i>>
|
<b>typename</b> Arg<i>MAX_ARGS</i>>
|
||||||
<b>void</b> <a href="#swap_function">swap</a>(<b>const</b> function<Arg1, Arg2, <i>...</i>, Arg<i>MAX_ARGS</i>><b>&</b>,
|
<b>void</b> <a href="#swap_function">swap</a>(function<ResultType, Arg1, Arg2, <i>...</i>, Arg<i>MAX_ARGS</i>><b>&</b>,
|
||||||
<b>const</b> function<Arg1, Arg2, <i>...</i>, Arg<i>MAX_ARGS</i>><b>&</b>);
|
function<ResultType, Arg1, Arg2, <i>...</i>, Arg<i>MAX_ARGS</i>><b>&</b>);
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
@@ -126,22 +128,13 @@
|
|||||||
</pre>
|
</pre>
|
||||||
<p> A special provision is made for pointers to member functions. Though they are not function objects, Boost.Function will adapt them internally to function objects. This requires that a pointer to member function of the form <code>R (X::*mf)(Arg1, Arg2, ..., Arg<em>N</em>) <em>cv-quals</em></code> be adapted to a function object with the following function call operator overloads:
|
<p> A special provision is made for pointers to member functions. Though they are not function objects, Boost.Function will adapt them internally to function objects. This requires that a pointer to member function of the form <code>R (X::*mf)(Arg1, Arg2, ..., Arg<em>N</em>) <em>cv-quals</em></code> be adapted to a function object with the following function call operator overloads:
|
||||||
<pre>
|
<pre>
|
||||||
R <b>operator</b>()(<em>cv-quals</em> X& x, Arg1 arg1, Arg2 arg2, ..., Arg<em>N</em> arg<em>N</em>) <b>const</b>
|
|
||||||
{
|
|
||||||
<b>return</b> x.*mf(arg1, arg2, ..., arg<em>N</em>);
|
|
||||||
}
|
|
||||||
|
|
||||||
R <b>operator</b>()(<em>cv-quals</em> X* x, Arg1 arg1, Arg2 arg2, ..., Arg<em>N</em> arg<em>N</em>) <b>const</b>
|
|
||||||
{
|
|
||||||
<b>return</b> x->*mf(arg1, arg2, ..., arg<em>N</em>);
|
|
||||||
}
|
|
||||||
|
|
||||||
<b>template</b><<b>typename P</b>>
|
<b>template</b><<b>typename P</b>>
|
||||||
R <b>operator</b>()(<em>cv-quals</em> P& x, Arg1 arg1, Arg2 arg2, ..., Arg<em>N</em> arg<em>N</em>) <b>const</b>
|
R <b>operator</b>()(<em>cv-quals</em> P& x, Arg1 arg1, Arg2 arg2, ..., Arg<em>N</em> arg<em>N</em>) <b>const</b>
|
||||||
{
|
{
|
||||||
<b>return</b> (*x).*mf(arg1, arg2, ..., arg<em>N</em>);
|
<b>return</b> (*x).*mf(arg1, arg2, ..., arg<em>N</em>);
|
||||||
}
|
}
|
||||||
</pre>
|
</pre>
|
||||||
|
<li><a name="stateless"></a>A function object <code>f</code> of type <code>F</code> is <em>stateless</em> if it is a function pointer or if <a href="../../type_traits/index.htm#properties"><code>boost::is_stateless<T></code></a> is true. The construction of or copy to a Boost.Function object from a stateless function object will not cause exceptions to be thrown and will not allocate any storage.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h2><a name="function_base">Class <code>function_base</code></a></h2>
|
<h2><a name="function_base">Class <code>function_base</code></a></h2>
|
||||||
@@ -174,34 +167,52 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li><b>Effects</b>: Constructs the <code>Mixin</code> subobject with the given mixin.</li>
|
<li><b>Effects</b>: Constructs the <code>Mixin</code> subobject with the given mixin.</li>
|
||||||
<li><b>Postconditions</b>: <code>f.<a href="#empty">empty</a>()</code>.</li>
|
<li><b>Postconditions</b>: <code>f.<a href="#empty">empty</a>()</code>.</li>
|
||||||
<li><b>Throws</b>: will not throw.</li>
|
<li><b>Throws</b>: will not throw unless construction of the <code>Mixin</code> subobject throws.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p> <a name="functionN_copy"><code>function<i>N</i>(<b>const</b> function<i>N</i><b>&</b> g);</code></a>
|
<p> <a name="functionN_copy"><code>function<i>N</i>(<b>const</b> function<i>N</i><b>&</b> g);</code></a>
|
||||||
<ul>
|
<ul>
|
||||||
<li><b>Postconditions</b>: <code>f</code> contains a copy of the <code>g</code>'s target, if it has one, or is empty if <code>g.<a href="#empty">empty</a>()</code>. The mixin for the <code>f</code> is copy-constructed from the mixin of <code>g</code>.</li>
|
<li><b>Postconditions</b>: <code>f</code> contains a copy of the <code>g</code>'s target, if it has one, or is empty if <code>g.<a href="#empty">empty</a>()</code>. The mixin for the <code>f</code> is copy-constructed from the mixin of <code>g</code>.</li>
|
||||||
|
<li><b>Throws</b>: will not throw unless copying the target of <code>g</code> or construction of the <code>Mixin</code> subobject throws.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p> <a name="functionN_target"><code><b>template</b><<b>typename</b> F> function<i>N</i>(<b>const</b> F<b>&</b> g, <b>const</b> Mixin<b>&</b> = Mixin());</code></a>
|
<p> <a name="functionN_target"><code><b>template</b><<b>typename</b> F> function<i>N</i>(F g, <b>const</b> Mixin<b>&</b> = Mixin());</code></a>
|
||||||
<ul>
|
<ul>
|
||||||
<li><b>Requires</b>: <code>g</code> is a <a href="#compatible">compatible</a> function object.</li>
|
<li><b>Requires</b>: <code>g</code> is a <a href="#compatible">compatible</a> function object.</li>
|
||||||
<li><b>Effects</b>: Constructs the <code>Mixin</code> subobject from the given mixin.</li>
|
<li><b>Effects</b>: Constructs the <code>Mixin</code> subobject from the given mixin.</li>
|
||||||
<li><b>Postconditions</b>: <code>f</code> targets a copy of <code>g</code> if <code>g</code> is nonempty, or <code>f.<a href="#empty">empty</a>()</code> if <code>g</code> is empty.</li>
|
<li><b>Postconditions</b>: <code>f</code> targets a copy of <code>g</code> if <code>g</code> is nonempty, or <code>f.<a href="#empty">empty</a>()</code> if <code>g</code> is empty.</li>
|
||||||
<li><b>Rationale</b>: <code>g</code> is a reference-to-<code><b>const</b></code> because it is a portable, efficient, and concise way to accept any function object or function pointer. In the case of a function pointer, the type of <code>g</code> is reference-to-<code><b>const</b></code> pointer-to-function.</li>
|
<li><b>Throws</b>: will not throw when <code>g</code> is a <a href="#stateless">stateless</a> function object unless construction of the <code>Mixin</code> subobject throws.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p> <a name="functionN_target_ref"><code><b>template</b><<b>typename</b> F> function<i>N</i>(<a href="../../bind/ref.html">reference_wrapper</a><F> g);</code></a>
|
||||||
|
<ul>
|
||||||
|
<li><b>Requires</b>: <code>g.get()</code> is a <a href="#compatible">compatible</a> function object.</li>
|
||||||
|
<li><b>Effects</b>: Constructs the <code>Mixin</code> subobject from the given mixin.</li>
|
||||||
|
<li><b>Postconditions</b>: <code>this</code> object targets <code>g</code> (<em>not</em> a copy of <code>g.get()</code>) if <code>g.get()</code> is nonempty, or <code>this->empty()</code> if <code>g.get()</code> is empty.</li>
|
||||||
|
<li><b>Throws</b>: will not throw unless the construction of the <code>Mixin</code> subobject throws.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p> <a name="functionN_copy_assn"><code>function<i>N</i><b>&</b> <b>operator</b>=(<b>const</b> function<i>N</i><b>&</b> g);</code></a>
|
<p> <a name="functionN_copy_assn"><code>function<i>N</i><b>&</b> <b>operator</b>=(<b>const</b> function<i>N</i><b>&</b> g);</code></a>
|
||||||
<ul>
|
<ul>
|
||||||
<li><b>Postconditions</b>: <code>f</code> targets a copy of <code>g</code>'s target, if it has one, or is empty if <code>g.<a href="#empty">empty</a>()</code>. The mixin for <code>f</code> is assigned the value of the mixin for <code>g</code>.</li>
|
<li><b>Postconditions</b>: <code>f</code> targets a copy of <code>g</code>'s target, if it has one, or is empty if <code>g.<a href="#empty">empty</a>()</code>. The mixin for <code>f</code> is assigned the value of the mixin for <code>g</code>.</li>
|
||||||
<li><b>Returns</b>: <code>*this</code>.</li>
|
<li><b>Returns</b>: <code>*this</code>.</li>
|
||||||
|
<li><b>Throws</b>: will not throw when the target of <code>g</code> is a <a href="#stateless">stateless</a> function object or a reference to the function object, unless the copy of the <code>Mixin</code> subobject throws.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p> <a name="functionN_target_assn"><code><b>template</b><<b>typename</b> F> function<i>N</i><b>&</b> <b>operator</b>=(<b>const</b> F<b>&</b> g);</code></a>
|
<p> <a name="functionN_target_assn"><code><b>template</b><<b>typename</b> F> function<i>N</i><b>&</b> <b>operator</b>=(F g);</code></a>
|
||||||
<ul>
|
<ul>
|
||||||
<li><b>Requires</b>: <code>g</code> is a <a href="#compatible">compatible</a> function object.</li>
|
<li><b>Requires</b>: <code>g</code> is a <a href="#compatible">compatible</a> function object.</li>
|
||||||
<li><b>Postconditions</b>: <code>f</code> targets a copy of <code>g</code> if <code>g</code> is nonempty, or <code>f.<a href="#empty">empty</a>()</code> if <code>g</code> is empty.</li>
|
<li><b>Postconditions</b>: <code>f</code> targets a copy of <code>g</code> if <code>g</code> is nonempty, or <code>f.<a href="#empty">empty</a>()</code> if <code>g</code> is empty.</li>
|
||||||
<li><b>Returns</b>: <code>*this</code>.</li>
|
<li><b>Returns</b>: <code>*this</code>.</li>
|
||||||
<li><b>Rationale</b>: <code>g</code> is a reference-to-<code><b>const</b></code> because it is a portable, efficient, and concise way to accept any function object or function pointer. In the case of a function pointer, the type of <code>g</code> is reference-to-<code><b>const</b></code> pointer-to-function.</li>
|
<li><b>Throws</b>: will not throw when <code>g</code> is a <a href="#stateless">stateless</a> function object.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p> <a name="functionN_target_ref_assn"><code><b>template</b><<b>typename</b> F> function<i>N</i><b>&</b> <b>operator</b>=(<a href="../../bind/ref.html">reference_wrapper</a><F> g);</code></a>
|
||||||
|
<ul>
|
||||||
|
<li><b>Requires</b>: <code>g.get()</code> is a <a href="#compatible">compatible</a> function object.</li>
|
||||||
|
<li><b>Postconditions</b>: <code>f</code> targets <code>g.get()</code> (not a copy of <code>g.get()</code>) if <code>g.get()</code> is nonempty, or <code>f.<a href="#empty">empty</a>()</code> if <code>g.get()</code> is empty.</li>
|
||||||
|
<li><b>Returns</b>: <code>*this</code>.</li>
|
||||||
|
<li><b>Throws</b>: will throw only if the destruction or deallocation of the target of <code>this</code> throws.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p> <a name="functionN_copy_set"><code><b>void</b> set(<b>const</b> function<i>N</i><b>&</b> g);</code></a>
|
<p> <a name="functionN_copy_set"><code><b>void</b> set(<b>const</b> function<i>N</i><b>&</b> g);</code></a>
|
||||||
@@ -209,7 +220,7 @@
|
|||||||
<li><b>Effects</b>: <code><a href="#functionN_copy_assn">*this = g</a></code>.</li>
|
<li><b>Effects</b>: <code><a href="#functionN_copy_assn">*this = g</a></code>.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p> <a name="functionN_target_set"><code><b>template</b><<b>typename</b> F> <b>void</b> set(<b>const</b> F<b>&</b> g);</code></a>
|
<p> <a name="functionN_target_set"><code><b>template</b><<b>typename</b> F> <b>void</b> set(F g);</code></a>
|
||||||
<ul>
|
<ul>
|
||||||
<li><b>Effects</b>: <code><a href="#functionN_target_assn">*this = g</a></code>.</li>
|
<li><b>Effects</b>: <code><a href="#functionN_target_assn">*this = g</a></code>.</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -255,8 +266,8 @@
|
|||||||
<b>typename</b> Policy,
|
<b>typename</b> Policy,
|
||||||
<b>typename</b> Mixin,
|
<b>typename</b> Mixin,
|
||||||
<b>typename</b> Allocator>
|
<b>typename</b> Allocator>
|
||||||
<b>void</b> <a name="swap_functionN">swap</a>(<b>const</b> function<i>N</i><Arg1, Arg2, <i>...</i>, Arg<i>N</i>, Policy, Mixin, Allocator><b>&</b> f,
|
<b>void</b> <a name="swap_functionN">swap</a>(function<i>N</i><ResultType, Arg1, Arg2, <i>...</i>, Arg<i>N</i>, Policy, Mixin, Allocator><b>&</b> f,
|
||||||
<b>const</b> function<i>N</i><Arg1, Arg2, <i>...</i>, Arg<i>N</i>, Policy, Mixin, Allocator><b>&</b> g);
|
function<i>N</i><ResultType, Arg1, Arg2, <i>...</i>, Arg<i>N</i>, Policy, Mixin, Allocator><b>&</b> g);
|
||||||
</pre>
|
</pre>
|
||||||
<ul>
|
<ul>
|
||||||
<li><b>Effects</b>: <code>f.<a href="#functionN_swap">swap</a>(g);</code></li>
|
<li><b>Effects</b>: <code>f.<a href="#functionN_swap">swap</a>(g);</code></li>
|
||||||
@@ -269,18 +280,20 @@
|
|||||||
<b>typename</b> Arg2,
|
<b>typename</b> Arg2,
|
||||||
<i>...</i>
|
<i>...</i>
|
||||||
<b>typename</b> Arg<i>MAX_ARGS</i>>
|
<b>typename</b> Arg<i>MAX_ARGS</i>>
|
||||||
<b>void</b> <a name="swap_function">swap</a>(<b>const</b> function<Arg1, Arg2, <i>...</i>, Arg<i>MAX_ARGS</i>><b>&</b> f,
|
<b>void</b> <a name="swap_function">swap</a>(function<ResultType, Arg1, Arg2, <i>...</i>, Arg<i>MAX_ARGS</i>><b>&</b> f,
|
||||||
<b>const</b> function<Arg1, Arg2, <i>...</i>, Arg<i>MAX_ARGS</i>><b>&</b> g);
|
function<ResultType, Arg1, Arg2, <i>...</i>, Arg<i>MAX_ARGS</i>><b>&</b> g);
|
||||||
</pre>
|
</pre>
|
||||||
<ul>
|
<ul>
|
||||||
<li><b>Effects</b>: <code>f.<a href="#functionN_swap">swap</a>(g);</code></li>
|
<li><b>Effects</b>: <code>f.<a href="#functionN_swap">swap</a>(g);</code></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
<p><a name="novoid">[1]</a> On compilers not supporting void returns, when the <code>ReturnType</code> is <b>void</b>, the <code>result_type</code> of a Boost.Function object is implementation-defined.
|
||||||
|
<hr>
|
||||||
<address><a href="mailto:gregod@cs.rpi.edu">Douglas Gregor</a></address>
|
<address><a href="mailto:gregod@cs.rpi.edu">Douglas Gregor</a></address>
|
||||||
<!-- Created: Fri Jul 13 10:57:20 EDT 2001 -->
|
<!-- Created: Fri Jul 13 10:57:20 EDT 2001 -->
|
||||||
<!-- hhmts start -->
|
<!-- hhmts start -->
|
||||||
Last modified: Sun Oct 28 00:40:55 EDT 2001
|
Last modified: Thu Jan 31 21:55:35 EST 2002
|
||||||
<!-- hhmts end -->
|
<!-- hhmts end -->
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -60,9 +60,11 @@ else
|
|||||||
<p> Free function pointers can be considered singleton function objects with const function call operators, and can therefore be directly used with the function object wrappers:
|
<p> Free function pointers can be considered singleton function objects with const function call operators, and can therefore be directly used with the function object wrappers:
|
||||||
<pre>
|
<pre>
|
||||||
float mul_ints(int x, int y) { return ((float)x) * y; }
|
float mul_ints(int x, int y) { return ((float)x) * y; }
|
||||||
f = &mul_ints;
|
f = &mul_ints;
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
|
<p> Note that the <code>&</code> isn't really necessary unless you happen to be using Microsoft Visual C++ version 6.
|
||||||
|
|
||||||
<h3>Member functions</h3>
|
<h3>Member functions</h3>
|
||||||
<a name="member_func">
|
<a name="member_func">
|
||||||
<p> In many systems, callbacks often call to member functions of a particular
|
<p> In many systems, callbacks often call to member functions of a particular
|
||||||
@@ -73,10 +75,10 @@ object. This is often referred to as "argument binding", and is beyond the scope
|
|||||||
};
|
};
|
||||||
|
|
||||||
boost::function<int, X*, int> f;
|
boost::function<int, X*, int> f;
|
||||||
f = &X::foo;
|
f = &X::foo;
|
||||||
|
|
||||||
X x;
|
X x;
|
||||||
f(&x, 5);
|
f(&x, 5);
|
||||||
</pre>
|
</pre>
|
||||||
<p> Several libraries exist that support argument binding. Three such libraries are summarized below:
|
<p> Several libraries exist that support argument binding. Three such libraries are summarized below:
|
||||||
<ul>
|
<ul>
|
||||||
@@ -97,6 +99,30 @@ object. This is often referred to as "argument binding", and is beyond the scope
|
|||||||
<li><a href="http://lambda.cs.utu.fi/">The Lambda library</a>. This library provides a powerful composition mechanism to construct function objects that uses very natural C++ syntax. Lambda requires a compiler that is reasonably conformant to the C++ standard. Note that it is not a Boost library.</li>
|
<li><a href="http://lambda.cs.utu.fi/">The Lambda library</a>. This library provides a powerful composition mechanism to construct function objects that uses very natural C++ syntax. Lambda requires a compiler that is reasonably conformant to the C++ standard. Note that it is not a Boost library.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<h3>References to Functions</h3>
|
||||||
|
<p> In some cases it is expensive (or semantically incorrect) to have
|
||||||
|
Boost.Function clone a function object. In such cases, it is possible
|
||||||
|
to request that Boost.Function keep only a reference to the actual
|
||||||
|
function object. This is done using the <a
|
||||||
|
href="../../bind/ref.html"><code>ref</code></a> and <a
|
||||||
|
href="../../bind/ref.html"><code>cref</code></a> functions to wrap a
|
||||||
|
reference to a function object:
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
stateful_type a_function_object;
|
||||||
|
boost::function<int, int> f;
|
||||||
|
f = ref(a_function_object);
|
||||||
|
|
||||||
|
boost::function<int, int> f2(f);
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
Here, <code>f</code> will not make a copy of
|
||||||
|
<code>a_function_object</code>, nor will <code>f2</code> when it is
|
||||||
|
targeted to <code>f</code>'s reference to
|
||||||
|
<code>a_function_object</code>. Additionally, when using references to
|
||||||
|
function objects, Boost.Function will not throw exceptions during
|
||||||
|
assignment or construction.
|
||||||
|
|
||||||
<h2><a name="family">The <code>function</code> family</a></h2>
|
<h2><a name="family">The <code>function</code> family</a></h2>
|
||||||
<p> The header <<a href="../../../boost/function.hpp">boost/function.hpp</a>> defines the primary entry point to the function object wrappers, the class template <code>boost::function</code>. This class template is essentially a thin wrapper around a set of similar numbered function object wrappers, <code>boost::function0</code>, <code>boost::function1</code>, etc., where the number indicates the number of arguments passed to the function object target. The declaration of <code>f</code> above could also be written as:
|
<p> The header <<a href="../../../boost/function.hpp">boost/function.hpp</a>> defines the primary entry point to the function object wrappers, the class template <code>boost::function</code>. This class template is essentially a thin wrapper around a set of similar numbered function object wrappers, <code>boost::function0</code>, <code>boost::function1</code>, etc., where the number indicates the number of arguments passed to the function object target. The declaration of <code>f</code> above could also be written as:
|
||||||
<pre>
|
<pre>
|
||||||
@@ -173,7 +199,7 @@ boost::function2<float, int, int, SynchronizedPolicy, SynchronizedMixin> f
|
|||||||
<address><a href="mailto:gregod@cs.rpi.edu">Douglas Gregor</a></address>
|
<address><a href="mailto:gregod@cs.rpi.edu">Douglas Gregor</a></address>
|
||||||
<!-- Created: Fri Jul 13 12:47:11 EDT 2001 -->
|
<!-- Created: Fri Jul 13 12:47:11 EDT 2001 -->
|
||||||
<!-- hhmts start -->
|
<!-- hhmts start -->
|
||||||
Last modified: Sun Oct 28 00:49:02 EDT 2001
|
Last modified: Fri Dec 14 19:58:14 EST 2001
|
||||||
<!-- hhmts end -->
|
<!-- hhmts end -->
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -27,7 +27,9 @@ void do_sum_avg(int values[], int n, int& sum, float& avg)
|
|||||||
int
|
int
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
boost::function<void, int[], int, int&, float&> sum_avg;
|
// The second parameter should be int[], but some compilers (e.g., GCC)
|
||||||
|
// complain about this
|
||||||
|
boost::function<void, int*, int, int&, float&> sum_avg;
|
||||||
|
|
||||||
sum_avg = &do_sum_avg;
|
sum_avg = &do_sum_avg;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// Boost.Function library
|
// Boost.Function library
|
||||||
|
|
||||||
// Copyright (C) 2001 Doug Gregor (gregod@cs.rpi.edu)
|
// Copyright (C) 2001-2002 Doug Gregor (gregod@cs.rpi.edu)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, sell and distribute this software is granted
|
// Permission to copy, use, sell and distribute this software is granted
|
||||||
// provided this copyright notice appears in all copies.
|
// provided this copyright notice appears in all copies.
|
||||||
@@ -53,13 +53,12 @@ namespace boost {
|
|||||||
typename T8,
|
typename T8,
|
||||||
typename T9,
|
typename T9,
|
||||||
typename T10,
|
typename T10,
|
||||||
typename Policy = empty_function_policy,
|
typename ThreadingPolicy,
|
||||||
typename Mixin = empty_function_mixin,
|
typename Allocator
|
||||||
typename Allocator = std::allocator<function_base>
|
|
||||||
>
|
>
|
||||||
struct params
|
struct params
|
||||||
{
|
{
|
||||||
typedef function0<R, Policy, Mixin, Allocator> type;
|
typedef function0<R, ThreadingPolicy, Allocator> type;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -78,13 +77,12 @@ namespace boost {
|
|||||||
typename T8,
|
typename T8,
|
||||||
typename T9,
|
typename T9,
|
||||||
typename T10,
|
typename T10,
|
||||||
typename Policy = empty_function_policy,
|
typename ThreadingPolicy,
|
||||||
typename Mixin = empty_function_mixin,
|
typename Allocator
|
||||||
typename Allocator = std::allocator<function_base>
|
|
||||||
>
|
>
|
||||||
struct params
|
struct params
|
||||||
{
|
{
|
||||||
typedef function1<R, T1, Policy, Mixin, Allocator> type;
|
typedef function1<R, T1, ThreadingPolicy, Allocator> type;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -103,13 +101,12 @@ namespace boost {
|
|||||||
typename T8,
|
typename T8,
|
||||||
typename T9,
|
typename T9,
|
||||||
typename T10,
|
typename T10,
|
||||||
typename Policy = empty_function_policy,
|
typename ThreadingPolicy,
|
||||||
typename Mixin = empty_function_mixin,
|
typename Allocator
|
||||||
typename Allocator = std::allocator<function_base>
|
|
||||||
>
|
>
|
||||||
struct params
|
struct params
|
||||||
{
|
{
|
||||||
typedef function2<R, T1, T2, Policy, Mixin, Allocator> type;
|
typedef function2<R, T1, T2, ThreadingPolicy, Allocator> type;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -128,13 +125,12 @@ namespace boost {
|
|||||||
typename T8,
|
typename T8,
|
||||||
typename T9,
|
typename T9,
|
||||||
typename T10,
|
typename T10,
|
||||||
typename Policy = empty_function_policy,
|
typename ThreadingPolicy,
|
||||||
typename Mixin = empty_function_mixin,
|
typename Allocator
|
||||||
typename Allocator = std::allocator<function_base>
|
|
||||||
>
|
>
|
||||||
struct params
|
struct params
|
||||||
{
|
{
|
||||||
typedef function3<R, T1, T2, T3, Policy, Mixin, Allocator> type;
|
typedef function3<R, T1, T2, T3, ThreadingPolicy, Allocator> type;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -153,13 +149,12 @@ namespace boost {
|
|||||||
typename T8,
|
typename T8,
|
||||||
typename T9,
|
typename T9,
|
||||||
typename T10,
|
typename T10,
|
||||||
typename Policy = empty_function_policy,
|
typename ThreadingPolicy,
|
||||||
typename Mixin = empty_function_mixin,
|
typename Allocator
|
||||||
typename Allocator = std::allocator<function_base>
|
|
||||||
>
|
>
|
||||||
struct params
|
struct params
|
||||||
{
|
{
|
||||||
typedef function4<R, T1, T2, T3, T4, Policy, Mixin, Allocator> type;
|
typedef function4<R, T1, T2, T3, T4, ThreadingPolicy, Allocator> type;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -178,13 +173,12 @@ namespace boost {
|
|||||||
typename T8,
|
typename T8,
|
||||||
typename T9,
|
typename T9,
|
||||||
typename T10,
|
typename T10,
|
||||||
typename Policy = empty_function_policy,
|
typename ThreadingPolicy,
|
||||||
typename Mixin = empty_function_mixin,
|
typename Allocator
|
||||||
typename Allocator = std::allocator<function_base>
|
|
||||||
>
|
>
|
||||||
struct params
|
struct params
|
||||||
{
|
{
|
||||||
typedef function5<R, T1, T2, T3, T4, T5, Policy, Mixin, Allocator>
|
typedef function5<R, T1, T2, T3, T4, T5, ThreadingPolicy, Allocator>
|
||||||
type;
|
type;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -204,13 +198,12 @@ namespace boost {
|
|||||||
typename T8,
|
typename T8,
|
||||||
typename T9,
|
typename T9,
|
||||||
typename T10,
|
typename T10,
|
||||||
typename Policy = empty_function_policy,
|
typename ThreadingPolicy,
|
||||||
typename Mixin = empty_function_mixin,
|
typename Allocator
|
||||||
typename Allocator = std::allocator<function_base>
|
|
||||||
>
|
>
|
||||||
struct params
|
struct params
|
||||||
{
|
{
|
||||||
typedef function6<R, T1, T2, T3, T4, T5, T6, Policy, Mixin, Allocator>
|
typedef function6<R, T1, T2, T3, T4, T5, T6, ThreadingPolicy, Allocator>
|
||||||
type;
|
type;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -230,13 +223,12 @@ namespace boost {
|
|||||||
typename T8,
|
typename T8,
|
||||||
typename T9,
|
typename T9,
|
||||||
typename T10,
|
typename T10,
|
||||||
typename Policy = empty_function_policy,
|
typename ThreadingPolicy,
|
||||||
typename Mixin = empty_function_mixin,
|
typename Allocator
|
||||||
typename Allocator = std::allocator<function_base>
|
|
||||||
>
|
>
|
||||||
struct params
|
struct params
|
||||||
{
|
{
|
||||||
typedef function7<R, T1, T2, T3, T4, T5, T6, T7, Policy, Mixin,
|
typedef function7<R, T1, T2, T3, T4, T5, T6, T7, ThreadingPolicy,
|
||||||
Allocator> type;
|
Allocator> type;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -256,13 +248,12 @@ namespace boost {
|
|||||||
typename T8,
|
typename T8,
|
||||||
typename T9,
|
typename T9,
|
||||||
typename T10,
|
typename T10,
|
||||||
typename Policy = empty_function_policy,
|
typename ThreadingPolicy,
|
||||||
typename Mixin = empty_function_mixin,
|
typename Allocator
|
||||||
typename Allocator = std::allocator<function_base>
|
|
||||||
>
|
>
|
||||||
struct params
|
struct params
|
||||||
{
|
{
|
||||||
typedef function8<R, T1, T2, T3, T4, T5, T6, T7, T8, Policy, Mixin,
|
typedef function8<R, T1, T2, T3, T4, T5, T6, T7, T8, ThreadingPolicy,
|
||||||
Allocator> type;
|
Allocator> type;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -282,14 +273,13 @@ namespace boost {
|
|||||||
typename T8,
|
typename T8,
|
||||||
typename T9,
|
typename T9,
|
||||||
typename T10,
|
typename T10,
|
||||||
typename Policy = empty_function_policy,
|
typename ThreadingPolicy,
|
||||||
typename Mixin = empty_function_mixin,
|
typename Allocator
|
||||||
typename Allocator = std::allocator<function_base>
|
|
||||||
>
|
>
|
||||||
struct params
|
struct params
|
||||||
{
|
{
|
||||||
typedef function9<R, T1, T2, T3, T4, T5, T6, T7, T8, T9, Policy,
|
typedef function9<R, T1, T2, T3, T4, T5, T6, T7, T8, T9,
|
||||||
Mixin, Allocator> type;
|
ThreadingPolicy, Allocator> type;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -308,14 +298,13 @@ namespace boost {
|
|||||||
typename T8,
|
typename T8,
|
||||||
typename T9,
|
typename T9,
|
||||||
typename T10,
|
typename T10,
|
||||||
typename Policy = empty_function_policy,
|
typename ThreadingPolicy,
|
||||||
typename Mixin = empty_function_mixin,
|
typename Allocator
|
||||||
typename Allocator = std::allocator<function_base>
|
|
||||||
>
|
>
|
||||||
struct params
|
struct params
|
||||||
{
|
{
|
||||||
typedef function10<R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
|
typedef function10<R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
|
||||||
Policy, Mixin, Allocator> type;
|
ThreadingPolicy, Allocator> type;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -331,16 +320,15 @@ namespace boost {
|
|||||||
typename T8,
|
typename T8,
|
||||||
typename T9,
|
typename T9,
|
||||||
typename T10,
|
typename T10,
|
||||||
typename Policy = empty_function_policy,
|
typename ThreadingPolicy = BOOST_FUNCTION_DEFAULT_THREADING_POLICY,
|
||||||
typename Mixin = empty_function_mixin,
|
typename Allocator = BOOST_FUNCTION_DEFAULT_ALLOCATOR
|
||||||
typename Allocator = std::allocator<function_base>
|
|
||||||
>
|
>
|
||||||
struct get_function_impl
|
struct get_function_impl
|
||||||
{
|
{
|
||||||
typedef typename real_get_function_impl<
|
typedef typename real_get_function_impl<
|
||||||
(count_used_args<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>::value)
|
(count_used_args<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>::value)
|
||||||
>::template params<R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
|
>::template params<R, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10,
|
||||||
Policy, Mixin, Allocator>::type
|
ThreadingPolicy, Allocator>::type
|
||||||
type;
|
type;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -356,55 +344,37 @@ namespace boost {
|
|||||||
typename T8,
|
typename T8,
|
||||||
typename T9,
|
typename T9,
|
||||||
typename T10,
|
typename T10,
|
||||||
typename MyPolicy = empty_function_policy,
|
typename MyThreadingPolicy = BOOST_FUNCTION_DEFAULT_THREADING_POLICY,
|
||||||
typename MyMixin = empty_function_mixin,
|
typename MyAllocator = BOOST_FUNCTION_DEFAULT_ALLOCATOR
|
||||||
typename MyAllocator = std::allocator<function_base>
|
|
||||||
>
|
>
|
||||||
struct function_traits_builder
|
struct function_traits_builder
|
||||||
{
|
{
|
||||||
typedef typename get_function_impl<R, T1, T2, T3, T4, T5, T6, T7,
|
typedef typename get_function_impl<R, T1, T2, T3, T4, T5, T6, T7,
|
||||||
T8, T9, T10, MyPolicy, MyMixin,
|
T8, T9, T10, MyThreadingPolicy,
|
||||||
MyAllocator>::type
|
MyAllocator>::type
|
||||||
type;
|
type;
|
||||||
|
|
||||||
typedef MyPolicy policy_type;
|
typedef MyThreadingPolicy threading_policy_type;
|
||||||
typedef MyMixin mixin_type;
|
|
||||||
typedef MyAllocator allocator_type;
|
typedef MyAllocator allocator_type;
|
||||||
|
|
||||||
#ifndef BOOST_NO_DEPENDENT_NESTED_DERIVATIONS
|
#ifndef BOOST_NO_DEPENDENT_NESTED_DERIVATIONS
|
||||||
template<typename Policy>
|
template<typename ThreadingPolicy>
|
||||||
struct policy :
|
struct threading_policy :
|
||||||
public function_traits_builder<R, T1, T2, T3, T4, T5, T6, T7, T8, T9,
|
public function_traits_builder<R, T1, T2, T3, T4, T5, T6, T7, T8, T9,
|
||||||
T10, Policy, mixin_type,
|
T10, ThreadingPolicy,
|
||||||
allocator_type> {};
|
|
||||||
|
|
||||||
template<typename Mixin>
|
|
||||||
struct mixin :
|
|
||||||
public function_traits_builder<R, T1, T2, T3, T4, T5, T6, T7, T8, T9,
|
|
||||||
T10, policy_type, Mixin,
|
|
||||||
allocator_type> {};
|
allocator_type> {};
|
||||||
|
|
||||||
template<typename Allocator>
|
template<typename Allocator>
|
||||||
struct allocator :
|
struct allocator :
|
||||||
public function_traits_builder<R, T1, T2, T3, T4, T5, T6, T7, T8, T9,
|
public function_traits_builder<R, T1, T2, T3, T4, T5, T6, T7, T8, T9,
|
||||||
T10, policy_type, mixin_type,
|
T10, threading_policy_type,
|
||||||
Allocator> {};
|
Allocator> {};
|
||||||
#else
|
#else
|
||||||
template<typename Policy>
|
template<typename ThreadingPolicy>
|
||||||
struct policy
|
struct threading_policy
|
||||||
{
|
{
|
||||||
typedef typename function_traits_builder<R, T1, T2, T3, T4, T5, T6, T7,
|
typedef typename function_traits_builder<R, T1, T2, T3, T4, T5, T6, T7,
|
||||||
T8, T9, T10, Policy,
|
T8, T9, T10, ThreadingPolicy,
|
||||||
mixin_type,
|
|
||||||
allocator_type>::type
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Mixin>
|
|
||||||
struct mixin
|
|
||||||
{
|
|
||||||
typedef typename function_traits_builder<R, T1, T2, T3, T4, T5, T6, T7,
|
|
||||||
T8, T9, T10, policy_type, Mixin,
|
|
||||||
allocator_type>::type
|
allocator_type>::type
|
||||||
type;
|
type;
|
||||||
};
|
};
|
||||||
@@ -413,8 +383,9 @@ namespace boost {
|
|||||||
struct allocator
|
struct allocator
|
||||||
{
|
{
|
||||||
typedef typename function_traits_builder<R, T1, T2, T3, T4, T5, T6, T7,
|
typedef typename function_traits_builder<R, T1, T2, T3, T4, T5, T6, T7,
|
||||||
T8, T9, T10, policy_type,
|
T8, T9, T10,
|
||||||
mixin_type, Allocator>::type
|
threading_policy_type,
|
||||||
|
Allocator>::type
|
||||||
type;
|
type;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
@@ -448,73 +419,35 @@ namespace boost {
|
|||||||
base_type;
|
base_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef typename base_type::policy_type policy_type;
|
typedef typename base_type::threading_policy_type policy_type;
|
||||||
typedef typename base_type::mixin_type mixin_type;
|
|
||||||
typedef typename base_type::allocator_type allocator_type;
|
typedef typename base_type::allocator_type allocator_type;
|
||||||
typedef function self_type;
|
typedef function self_type;
|
||||||
|
|
||||||
function() : base_type() {}
|
function() : base_type() {}
|
||||||
|
|
||||||
template<typename Functor>
|
template<typename Functor>
|
||||||
function(const Functor& f) : base_type(f) {}
|
function(Functor BOOST_FUNCTION_TARGET_FIX(const &) f) : base_type(f) {}
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
|
||||||
template<typename Functor> function(Functor* f) : base_type(f) {}
|
|
||||||
#endif // __BORLANDC__
|
|
||||||
|
|
||||||
function(const self_type& f) : base_type(static_cast<const base_type&>(f)){}
|
function(const self_type& f) : base_type(static_cast<const base_type&>(f)){}
|
||||||
|
|
||||||
template<typename Functor>
|
template<typename Functor>
|
||||||
function& operator=(const Functor& f)
|
self_type& operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
|
||||||
{
|
{
|
||||||
self_type(f).swap(*this);
|
base_type::operator=(f);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
|
||||||
template<typename Functor>
|
|
||||||
self_type& operator=(Functor* f)
|
|
||||||
{
|
|
||||||
self_type(f).swap(*this);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
#endif // __BORLANDC__
|
|
||||||
|
|
||||||
self_type& operator=(const base_type& f)
|
self_type& operator=(const base_type& f)
|
||||||
{
|
{
|
||||||
self_type(f).swap(*this);
|
base_type::operator=(f);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
self_type& operator=(const self_type& f)
|
self_type& operator=(const self_type& f)
|
||||||
{
|
{
|
||||||
self_type(f).swap(*this);
|
base_type::operator=(static_cast<const base_type&>(f));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Functor>
|
|
||||||
void set(const Functor& f)
|
|
||||||
{
|
|
||||||
self_type(f).swap(*this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
|
||||||
template<typename Functor>
|
|
||||||
void set(Functor* f)
|
|
||||||
{
|
|
||||||
self_type(f).swap(*this);
|
|
||||||
}
|
|
||||||
#endif // __BORLANDC__
|
|
||||||
|
|
||||||
void set(const base_type& f)
|
|
||||||
{
|
|
||||||
self_type(f).swap(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void set(const self_type& f)
|
|
||||||
{
|
|
||||||
self_type(f).swap(*this);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename R,
|
template<typename R,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// Boost.Function library
|
// Boost.Function library
|
||||||
|
|
||||||
// Copyright (C) 2001 Doug Gregor (gregod@cs.rpi.edu)
|
// Copyright (C) 2001-2002 Doug Gregor (gregod@cs.rpi.edu)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, sell and distribute this software is granted
|
// Permission to copy, use, sell and distribute this software is granted
|
||||||
// provided this copyright notice appears in all copies.
|
// provided this copyright notice appears in all copies.
|
||||||
@@ -23,52 +23,31 @@
|
|||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <boost/type_traits.hpp>
|
#include <boost/type_traits.hpp>
|
||||||
|
#include <boost/ref.hpp>
|
||||||
|
#include <boost/function/threading/single.hpp>
|
||||||
|
#include <boost/pending/ct_if.hpp>
|
||||||
|
|
||||||
|
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 || defined(__ICL) && __ICL <= 600 || defined(__MWERKS__) && __MWERKS__ < 0x2406
|
||||||
|
# define BOOST_FUNCTION_TARGET_FIX(x) x
|
||||||
|
#else
|
||||||
|
# define BOOST_FUNCTION_TARGET_FIX(x)
|
||||||
|
#endif // not MSVC
|
||||||
|
|
||||||
|
#ifndef BOOST_FUNCTION_DEFAULT_THREADING_POLICY
|
||||||
|
# define BOOST_FUNCTION_DEFAULT_THREADING_POLICY single_threaded
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Type of the default allocator
|
||||||
|
#ifndef BOOST_NO_STD_ALLOCATOR
|
||||||
|
# define BOOST_FUNCTION_DEFAULT_ALLOCATOR std::allocator<function_base>
|
||||||
|
#else
|
||||||
|
# define BOOST_FUNCTION_DEFAULT_ALLOCATOR int
|
||||||
|
#endif // BOOST_NO_STD_ALLOCATOR
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
namespace function {
|
namespace function {
|
||||||
/*
|
template<bool> struct truth {};
|
||||||
* The IF implementation is temporary code. When a Boost metaprogramming
|
|
||||||
* library is introduced, Boost.Function will use it instead.
|
|
||||||
*/
|
|
||||||
namespace intimate {
|
|
||||||
struct SelectThen
|
|
||||||
{
|
|
||||||
template<typename Then, typename Else>
|
|
||||||
struct Result
|
|
||||||
{
|
|
||||||
typedef Then type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SelectElse
|
|
||||||
{
|
|
||||||
template<typename Then, typename Else>
|
|
||||||
struct Result
|
|
||||||
{
|
|
||||||
typedef Else type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
template<bool Condition>
|
|
||||||
struct Selector
|
|
||||||
{
|
|
||||||
typedef SelectThen type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct Selector<false>
|
|
||||||
{
|
|
||||||
typedef SelectElse type;
|
|
||||||
};
|
|
||||||
} // end namespace intimate
|
|
||||||
|
|
||||||
template<bool Condition, typename Then, typename Else>
|
|
||||||
struct IF
|
|
||||||
{
|
|
||||||
typedef typename intimate::Selector<Condition>::type select;
|
|
||||||
typedef typename select::template Result<Then,Else>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A union of a function pointer and a void pointer. This is necessary
|
* A union of a function pointer and a void pointer. This is necessary
|
||||||
@@ -122,20 +101,41 @@ namespace boost {
|
|||||||
struct function_ptr_tag {};
|
struct function_ptr_tag {};
|
||||||
struct function_obj_tag {};
|
struct function_obj_tag {};
|
||||||
struct member_ptr_tag {};
|
struct member_ptr_tag {};
|
||||||
|
struct function_obj_ref_tag {};
|
||||||
|
struct stateless_function_obj_tag {};
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
class get_function_tag
|
class get_function_tag
|
||||||
{
|
{
|
||||||
typedef typename IF<(is_pointer<F>::value),
|
typedef typename ct_if<(is_pointer<F>::value),
|
||||||
function_ptr_tag,
|
function_ptr_tag,
|
||||||
function_obj_tag>::type ptr_or_obj_tag;
|
function_obj_tag>::type ptr_or_obj_tag;
|
||||||
|
|
||||||
|
typedef typename ct_if<(is_member_pointer<F>::value),
|
||||||
|
member_ptr_tag,
|
||||||
|
ptr_or_obj_tag>::type ptr_or_obj_or_mem_tag;
|
||||||
|
|
||||||
|
typedef typename ct_if<(is_reference_wrapper<F>::value),
|
||||||
|
function_obj_ref_tag,
|
||||||
|
ptr_or_obj_or_mem_tag>::type or_ref_tag;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef typename IF<(is_member_pointer<F>::value),
|
typedef typename ct_if<(is_stateless<F>::value),
|
||||||
member_ptr_tag,
|
stateless_function_obj_tag,
|
||||||
ptr_or_obj_tag>::type type;
|
or_ref_tag>::type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// The trivial manager does nothing but return the same pointer (if we
|
||||||
|
// are cloning) or return the null pointer (if we are deleting).
|
||||||
|
inline any_pointer trivial_manager(any_pointer f,
|
||||||
|
functor_manager_operation_type op)
|
||||||
|
{
|
||||||
|
if (op == clone_functor_tag)
|
||||||
|
return f;
|
||||||
|
else
|
||||||
|
return any_pointer(reinterpret_cast<void*>(0));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The functor_manager class contains a static function "manage" which
|
* The functor_manager class contains a static function "manage" which
|
||||||
* can clone or destroy the given function/function object pointer.
|
* can clone or destroy the given function/function object pointer.
|
||||||
@@ -148,7 +148,8 @@ namespace boost {
|
|||||||
|
|
||||||
// For function pointers, the manager is trivial
|
// For function pointers, the manager is trivial
|
||||||
static inline any_pointer
|
static inline any_pointer
|
||||||
manager(any_pointer function_ptr, functor_manager_operation_type op,
|
manager(any_pointer function_ptr,
|
||||||
|
functor_manager_operation_type op,
|
||||||
function_ptr_tag)
|
function_ptr_tag)
|
||||||
{
|
{
|
||||||
if (op == clone_functor_tag)
|
if (op == clone_functor_tag)
|
||||||
@@ -273,12 +274,16 @@ namespace boost {
|
|||||||
// Is this function empty?
|
// Is this function empty?
|
||||||
bool empty() const { return !manager; }
|
bool empty() const { return !manager; }
|
||||||
|
|
||||||
protected:
|
public: // should be protected, but GCC 2.95.3 will fail to allow access
|
||||||
detail::function::any_pointer (*manager)(
|
detail::function::any_pointer (*manager)(
|
||||||
detail::function::any_pointer,
|
detail::function::any_pointer,
|
||||||
detail::function::functor_manager_operation_type);
|
detail::function::functor_manager_operation_type);
|
||||||
detail::function::any_pointer functor;
|
detail::function::any_pointer functor;
|
||||||
|
|
||||||
|
#if (defined __SUNPRO_CC) && (__SUNPRO_CC <= 0x530) && !(defined BOOST_NO_COMPILER_CONFIG)
|
||||||
|
// Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it
|
||||||
|
operator bool () const { return !this->empty(); }
|
||||||
|
#else
|
||||||
private:
|
private:
|
||||||
struct dummy {
|
struct dummy {
|
||||||
void nonnull() {};
|
void nonnull() {};
|
||||||
@@ -289,6 +294,7 @@ namespace boost {
|
|||||||
public:
|
public:
|
||||||
operator safe_bool () const
|
operator safe_bool () const
|
||||||
{ return (this->empty())? 0 : &dummy::nonnull; }
|
{ return (this->empty())? 0 : &dummy::nonnull; }
|
||||||
|
#endif
|
||||||
|
|
||||||
safe_bool operator!() const
|
safe_bool operator!() const
|
||||||
{ return (this->empty())? &dummy::nonnull : 0; }
|
{ return (this->empty())? &dummy::nonnull : 0; }
|
||||||
@@ -305,112 +311,35 @@ namespace boost {
|
|||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
namespace function {
|
namespace function {
|
||||||
/**
|
// The result is not a Boost.Function object, so we assume that this
|
||||||
* Determine if the given target is empty.
|
// target is not empty
|
||||||
*/
|
template<typename FunctionObj>
|
||||||
|
inline bool has_empty_target(const FunctionObj&, truth<false>)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Fallback - assume target is not empty
|
// The result is a Boost.Function object, so query whether it is empty
|
||||||
inline bool has_empty_target(...)
|
// or not
|
||||||
|
template<typename FunctionObj>
|
||||||
|
inline bool has_empty_target(const FunctionObj& f, truth<true>)
|
||||||
{
|
{
|
||||||
return false;
|
return f.empty();
|
||||||
}
|
|
||||||
|
|
||||||
// If the target is a 'function', query the empty() method
|
|
||||||
inline bool has_empty_target(const function_base* af)
|
|
||||||
{
|
|
||||||
return af->empty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the target is a 'function', query the empty() method
|
template<typename Lock, typename Mixin>
|
||||||
inline bool has_empty_target(const function_base& af)
|
struct scoped_double_lock
|
||||||
{
|
|
||||||
return af.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
// A function pointer is empty if it is null
|
|
||||||
template<typename R>
|
|
||||||
inline bool has_empty_target(R (*f)())
|
|
||||||
{
|
{
|
||||||
return f == 0;
|
scoped_double_lock(const Mixin& m1, const Mixin& m2) :
|
||||||
}
|
lock1(&m1 < &m2? m1 : m2), lock2(!(&m1 < &m2)? m1 : m2)
|
||||||
|
{
|
||||||
template<typename R, typename T1>
|
}
|
||||||
inline bool has_empty_target(R (*f)(T1))
|
|
||||||
{
|
Lock lock1;
|
||||||
return f == 0;
|
Lock lock2;
|
||||||
}
|
};
|
||||||
|
|
||||||
template<typename R, typename T1, typename T2>
|
|
||||||
inline bool has_empty_target(R (*f)(T1, T2))
|
|
||||||
{
|
|
||||||
return f == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename R, typename T1, typename T2, typename T3>
|
|
||||||
inline bool has_empty_target(R (*f)(T1, T2, T3))
|
|
||||||
{
|
|
||||||
return f == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename R, typename T1, typename T2, typename T3, typename T4>
|
|
||||||
inline bool has_empty_target(R (*f)(T1, T2, T3, T4))
|
|
||||||
{
|
|
||||||
return f == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename R, typename T1, typename T2, typename T3, typename T4,
|
|
||||||
typename T5>
|
|
||||||
inline bool has_empty_target(R (*f)(T1, T2, T3, T4, T5))
|
|
||||||
{
|
|
||||||
return f == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename R, typename T1, typename T2, typename T3, typename T4,
|
|
||||||
typename T5, typename T6>
|
|
||||||
inline bool has_empty_target(R (*f)(T1, T2, T3, T4, T5, T6))
|
|
||||||
{
|
|
||||||
return f == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename R, typename T1, typename T2, typename T3, typename T4,
|
|
||||||
typename T5, typename T6, typename T7>
|
|
||||||
inline bool has_empty_target(R (*f)(T1, T2, T3, T4, T5, T6, T7))
|
|
||||||
{
|
|
||||||
return f == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename R, typename T1, typename T2, typename T3, typename T4,
|
|
||||||
typename T5, typename T6, typename T7, typename T8>
|
|
||||||
inline bool has_empty_target(R (*f)(T1, T2, T3, T4, T5, T6, T7, T8))
|
|
||||||
{
|
|
||||||
return f == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename R, typename T1, typename T2, typename T3, typename T4,
|
|
||||||
typename T5, typename T6, typename T7, typename T8, typename T9>
|
|
||||||
inline bool has_empty_target(R (*f)(T1, T2, T3, T4, T5, T6, T7, T8, T9))
|
|
||||||
{
|
|
||||||
return f == 0;
|
|
||||||
}
|
|
||||||
} // end namespace function
|
} // end namespace function
|
||||||
} // end namespace detail
|
} // end namespace detail
|
||||||
|
|
||||||
// The default function policy is to do nothing before and after the call.
|
|
||||||
struct empty_function_policy
|
|
||||||
{
|
|
||||||
inline void precall(const function_base*) {}
|
|
||||||
inline void postcall(const function_base*) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
// The default function mixin does nothing. The assignment and copy-construction operators
|
|
||||||
// are all defined because MSVC defines broken versions.
|
|
||||||
struct empty_function_mixin {
|
|
||||||
empty_function_mixin() {};
|
|
||||||
empty_function_mixin(const empty_function_mixin&) {};
|
|
||||||
|
|
||||||
empty_function_mixin& operator=(const empty_function_mixin&)
|
|
||||||
{return *this; }
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // BOOST_FUNCTION_BASE_HEADER
|
#endif // BOOST_FUNCTION_BASE_HEADER
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// Boost.Function library
|
// Boost.Function library
|
||||||
|
|
||||||
// Copyright (C) 2001 Doug Gregor (gregod@cs.rpi.edu)
|
// Copyright (C) 2001-2002 Doug Gregor (gregod@cs.rpi.edu)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, sell and distribute this software is granted
|
// Permission to copy, use, sell and distribute this software is granted
|
||||||
// provided this copyright notice appears in all copies.
|
// provided this copyright notice appears in all copies.
|
||||||
@@ -25,13 +25,6 @@
|
|||||||
# include <boost/mem_fn.hpp>
|
# include <boost/mem_fn.hpp>
|
||||||
#endif // BOOST_FUNCTION_FUNCTION_TEMPLATE_HPP
|
#endif // BOOST_FUNCTION_FUNCTION_TEMPLATE_HPP
|
||||||
|
|
||||||
// Type of the default allocator
|
|
||||||
#ifndef BOOST_NO_STD_ALLOCATOR
|
|
||||||
# define BOOST_FUNCTION_DEFAULT_ALLOCATOR std::allocator<function_base>
|
|
||||||
#else
|
|
||||||
# define BOOST_FUNCTION_DEFAULT_ALLOCATOR int
|
|
||||||
#endif // BOOST_NO_STD_ALLOCATOR
|
|
||||||
|
|
||||||
// Comma if nonzero number of arguments
|
// Comma if nonzero number of arguments
|
||||||
#if BOOST_FUNCTION_NUM_ARGS == 0
|
#if BOOST_FUNCTION_NUM_ARGS == 0
|
||||||
# define BOOST_FUNCTION_COMMA
|
# define BOOST_FUNCTION_COMMA
|
||||||
@@ -41,7 +34,6 @@
|
|||||||
|
|
||||||
// Class names used in this version of the code
|
// Class names used in this version of the code
|
||||||
#define BOOST_FUNCTION_FUNCTION BOOST_JOIN(function,BOOST_FUNCTION_NUM_ARGS)
|
#define BOOST_FUNCTION_FUNCTION BOOST_JOIN(function,BOOST_FUNCTION_NUM_ARGS)
|
||||||
#define BOOST_FUNCTION_BASE BOOST_JOIN(function_base,BOOST_FUNCTION_NUM_ARGS)
|
|
||||||
#define BOOST_FUNCTION_FUNCTION_INVOKER \
|
#define BOOST_FUNCTION_FUNCTION_INVOKER \
|
||||||
BOOST_JOIN(function_invoker,BOOST_FUNCTION_NUM_ARGS)
|
BOOST_JOIN(function_invoker,BOOST_FUNCTION_NUM_ARGS)
|
||||||
#define BOOST_FUNCTION_VOID_FUNCTION_INVOKER \
|
#define BOOST_FUNCTION_VOID_FUNCTION_INVOKER \
|
||||||
@@ -50,10 +42,16 @@
|
|||||||
BOOST_JOIN(function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
|
BOOST_JOIN(function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
|
||||||
#define BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER \
|
#define BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER \
|
||||||
BOOST_JOIN(void_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
|
BOOST_JOIN(void_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
|
||||||
|
#define BOOST_FUNCTION_STATELESS_FUNCTION_OBJ_INVOKER \
|
||||||
|
BOOST_JOIN(stateless_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
|
||||||
|
#define BOOST_FUNCTION_STATELESS_VOID_FUNCTION_OBJ_INVOKER \
|
||||||
|
BOOST_JOIN(stateless_void_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
|
||||||
#define BOOST_FUNCTION_GET_FUNCTION_INVOKER \
|
#define BOOST_FUNCTION_GET_FUNCTION_INVOKER \
|
||||||
BOOST_JOIN(get_function_invoker,BOOST_FUNCTION_NUM_ARGS)
|
BOOST_JOIN(get_function_invoker,BOOST_FUNCTION_NUM_ARGS)
|
||||||
#define BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER \
|
#define BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER \
|
||||||
BOOST_JOIN(get_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
|
BOOST_JOIN(get_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
|
||||||
|
#define BOOST_FUNCTION_GET_STATELESS_FUNCTION_OBJ_INVOKER \
|
||||||
|
BOOST_JOIN(get_stateless_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS)
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
@@ -101,7 +99,7 @@ namespace boost {
|
|||||||
BOOST_FUNCTION_PARMS)
|
BOOST_FUNCTION_PARMS)
|
||||||
|
|
||||||
{
|
{
|
||||||
FunctionObj* f = static_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
|
FunctionObj* f = (FunctionObj*)(function_obj_ptr.obj_ptr);
|
||||||
return (*f)(BOOST_FUNCTION_ARGS);
|
return (*f)(BOOST_FUNCTION_ARGS);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -118,12 +116,43 @@ namespace boost {
|
|||||||
BOOST_FUNCTION_PARMS)
|
BOOST_FUNCTION_PARMS)
|
||||||
|
|
||||||
{
|
{
|
||||||
FunctionObj* f = static_cast<FunctionObj*>(function_obj_ptr.obj_ptr);
|
FunctionObj* f = (FunctionObj*)(function_obj_ptr.obj_ptr);
|
||||||
(*f)(BOOST_FUNCTION_ARGS);
|
(*f)(BOOST_FUNCTION_ARGS);
|
||||||
return unusable();
|
return unusable();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
typename FunctionObj,
|
||||||
|
typename R BOOST_FUNCTION_COMMA
|
||||||
|
BOOST_FUNCTION_TEMPLATE_PARMS
|
||||||
|
>
|
||||||
|
struct BOOST_FUNCTION_STATELESS_FUNCTION_OBJ_INVOKER
|
||||||
|
{
|
||||||
|
static R invoke(any_pointer BOOST_FUNCTION_COMMA BOOST_FUNCTION_PARMS)
|
||||||
|
{
|
||||||
|
FunctionObj f = FunctionObj();
|
||||||
|
return f(BOOST_FUNCTION_ARGS);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
typename FunctionObj,
|
||||||
|
typename R BOOST_FUNCTION_COMMA
|
||||||
|
BOOST_FUNCTION_TEMPLATE_PARMS
|
||||||
|
>
|
||||||
|
struct BOOST_FUNCTION_STATELESS_VOID_FUNCTION_OBJ_INVOKER
|
||||||
|
{
|
||||||
|
static unusable invoke(any_pointer BOOST_FUNCTION_COMMA
|
||||||
|
BOOST_FUNCTION_PARMS)
|
||||||
|
|
||||||
|
{
|
||||||
|
FunctionObj f = FunctionObj();
|
||||||
|
f(BOOST_FUNCTION_ARGS);
|
||||||
|
return unusable();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<
|
template<
|
||||||
typename FunctionPtr,
|
typename FunctionPtr,
|
||||||
typename R BOOST_FUNCTION_COMMA
|
typename R BOOST_FUNCTION_COMMA
|
||||||
@@ -131,7 +160,7 @@ namespace boost {
|
|||||||
>
|
>
|
||||||
struct BOOST_FUNCTION_GET_FUNCTION_INVOKER
|
struct BOOST_FUNCTION_GET_FUNCTION_INVOKER
|
||||||
{
|
{
|
||||||
typedef typename IF<(is_void<R>::value),
|
typedef typename ct_if<(is_void<R>::value),
|
||||||
BOOST_FUNCTION_VOID_FUNCTION_INVOKER<
|
BOOST_FUNCTION_VOID_FUNCTION_INVOKER<
|
||||||
FunctionPtr,
|
FunctionPtr,
|
||||||
R BOOST_FUNCTION_COMMA
|
R BOOST_FUNCTION_COMMA
|
||||||
@@ -152,7 +181,7 @@ namespace boost {
|
|||||||
>
|
>
|
||||||
struct BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
|
struct BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
|
||||||
{
|
{
|
||||||
typedef typename IF<(is_void<R>::value),
|
typedef typename ct_if<(is_void<R>::value),
|
||||||
BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER<
|
BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER<
|
||||||
FunctionObj,
|
FunctionObj,
|
||||||
R BOOST_FUNCTION_COMMA
|
R BOOST_FUNCTION_COMMA
|
||||||
@@ -165,18 +194,46 @@ namespace boost {
|
|||||||
>
|
>
|
||||||
>::type type;
|
>::type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
typename FunctionObj,
|
||||||
|
typename R BOOST_FUNCTION_COMMA
|
||||||
|
BOOST_FUNCTION_TEMPLATE_PARMS
|
||||||
|
>
|
||||||
|
struct BOOST_FUNCTION_GET_STATELESS_FUNCTION_OBJ_INVOKER
|
||||||
|
{
|
||||||
|
typedef typename ct_if<(is_void<R>::value),
|
||||||
|
BOOST_FUNCTION_STATELESS_VOID_FUNCTION_OBJ_INVOKER<
|
||||||
|
FunctionObj,
|
||||||
|
R BOOST_FUNCTION_COMMA
|
||||||
|
BOOST_FUNCTION_TEMPLATE_ARGS
|
||||||
|
>,
|
||||||
|
BOOST_FUNCTION_STATELESS_FUNCTION_OBJ_INVOKER<
|
||||||
|
FunctionObj,
|
||||||
|
R BOOST_FUNCTION_COMMA
|
||||||
|
BOOST_FUNCTION_TEMPLATE_ARGS
|
||||||
|
>
|
||||||
|
>::type type;
|
||||||
|
};
|
||||||
|
|
||||||
} // end namespace function
|
} // end namespace function
|
||||||
} // end namespace detail
|
} // end namespace detail
|
||||||
|
|
||||||
template<
|
template<
|
||||||
typename R BOOST_FUNCTION_COMMA
|
typename R BOOST_FUNCTION_COMMA
|
||||||
BOOST_FUNCTION_TEMPLATE_PARMS,
|
BOOST_FUNCTION_TEMPLATE_PARMS,
|
||||||
typename Policy = empty_function_policy,
|
typename ThreadingPolicy = BOOST_FUNCTION_DEFAULT_THREADING_POLICY,
|
||||||
typename Mixin = empty_function_mixin,
|
|
||||||
typename Allocator = BOOST_FUNCTION_DEFAULT_ALLOCATOR
|
typename Allocator = BOOST_FUNCTION_DEFAULT_ALLOCATOR
|
||||||
>
|
>
|
||||||
class BOOST_FUNCTION_FUNCTION : public function_base, public Mixin
|
class BOOST_FUNCTION_FUNCTION : public function_base,
|
||||||
|
public ThreadingPolicy::mixin
|
||||||
{
|
{
|
||||||
|
typedef typename detail::function::function_return_type<R>::type
|
||||||
|
internal_result_type;
|
||||||
|
|
||||||
|
typedef typename ThreadingPolicy::mixin threading_mixin;
|
||||||
|
typedef typename ThreadingPolicy::lock lock;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BOOST_STATIC_CONSTANT(int, args = BOOST_FUNCTION_NUM_ARGS);
|
BOOST_STATIC_CONSTANT(int, args = BOOST_FUNCTION_NUM_ARGS);
|
||||||
|
|
||||||
@@ -186,65 +243,59 @@ namespace boost {
|
|||||||
typedef T0 first_argument_type;
|
typedef T0 first_argument_type;
|
||||||
typedef T1 second_argument_type;
|
typedef T1 second_argument_type;
|
||||||
#endif
|
#endif
|
||||||
typedef typename detail::function::function_return_type<R>::type
|
|
||||||
result_type;
|
#ifndef BOOST_NO_VOID_RETURNS
|
||||||
typedef Policy policy_type;
|
typedef R result_type;
|
||||||
typedef Mixin mixin_type;
|
#else
|
||||||
|
typedef internal_result_type result_type;
|
||||||
|
#endif // BOOST_NO_VOID_RETURNS
|
||||||
typedef Allocator allocator_type;
|
typedef Allocator allocator_type;
|
||||||
typedef BOOST_FUNCTION_FUNCTION self_type;
|
typedef BOOST_FUNCTION_FUNCTION self_type;
|
||||||
|
typedef ThreadingPolicy threading_policy_type;
|
||||||
|
|
||||||
BOOST_FUNCTION_FUNCTION() : function_base(), Mixin(), invoker(0) {}
|
BOOST_FUNCTION_FUNCTION() : function_base(), invoker(0) {}
|
||||||
|
|
||||||
explicit BOOST_FUNCTION_FUNCTION(const Mixin& m) :
|
|
||||||
function_base(), Mixin(m), invoker(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// MSVC chokes if the following two constructors are collapsed into
|
// MSVC chokes if the following two constructors are collapsed into
|
||||||
// one with a default parameter.
|
// one with a default parameter.
|
||||||
template<typename Functor>
|
template<typename Functor>
|
||||||
BOOST_FUNCTION_FUNCTION(const Functor& f) :
|
BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f) :
|
||||||
function_base(), Mixin(), invoker(0)
|
function_base(), invoker(0)
|
||||||
{
|
|
||||||
this->assign_to(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
|
||||||
template<typename Functor>
|
|
||||||
BOOST_FUNCTION_FUNCTION(Functor* f) :
|
|
||||||
function_base(), Mixin(), invoker(0)
|
|
||||||
{
|
|
||||||
this->assign_to(f);
|
|
||||||
}
|
|
||||||
#endif // __BORLANDC__
|
|
||||||
|
|
||||||
template<typename Functor>
|
|
||||||
BOOST_FUNCTION_FUNCTION(const Functor& f, const Mixin& m) :
|
|
||||||
function_base(), Mixin(m), invoker(0)
|
|
||||||
{
|
{
|
||||||
this->assign_to(f);
|
this->assign_to(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) :
|
BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) :
|
||||||
function_base(), Mixin(static_cast<const Mixin&>(f)), invoker(0)
|
function_base(), invoker(0)
|
||||||
{
|
{
|
||||||
|
// Lock the other function object so it can't change during assignment
|
||||||
|
lock l(static_cast<const self_type&>(f));
|
||||||
|
(void)l;
|
||||||
this->assign_to_own(f);
|
this->assign_to_own(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
~BOOST_FUNCTION_FUNCTION() { clear(); }
|
~BOOST_FUNCTION_FUNCTION()
|
||||||
|
{
|
||||||
|
lock l(static_cast<const threading_mixin&>(*this));
|
||||||
|
(void)l;
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
result_type operator()(BOOST_FUNCTION_PARMS) const
|
result_type operator()(BOOST_FUNCTION_PARMS) const
|
||||||
{
|
{
|
||||||
|
// Make sure this function can't change while it is being invoked
|
||||||
|
lock l(static_cast<const threading_mixin&>(*this));
|
||||||
|
(void)l;
|
||||||
assert(!this->empty());
|
assert(!this->empty());
|
||||||
|
|
||||||
policy_type policy;
|
internal_result_type result = invoker(function_base::functor
|
||||||
policy.precall(this);
|
BOOST_FUNCTION_COMMA
|
||||||
|
BOOST_FUNCTION_ARGS);
|
||||||
|
|
||||||
result_type result = invoker(functor BOOST_FUNCTION_COMMA
|
#ifndef BOOST_NO_VOID_RETURNS
|
||||||
BOOST_FUNCTION_ARGS);
|
return static_cast<result_type>(result);
|
||||||
|
#else
|
||||||
policy.postcall(this);
|
|
||||||
return result;
|
return result;
|
||||||
|
#endif // BOOST_NO_VOID_RETURNS
|
||||||
}
|
}
|
||||||
|
|
||||||
// The distinction between when to use BOOST_FUNCTION_FUNCTION and
|
// The distinction between when to use BOOST_FUNCTION_FUNCTION and
|
||||||
@@ -253,72 +304,55 @@ namespace boost {
|
|||||||
// handle BOOST_FUNCTION_FUNCTION as the type of the temporary to
|
// handle BOOST_FUNCTION_FUNCTION as the type of the temporary to
|
||||||
// construct.
|
// construct.
|
||||||
template<typename Functor>
|
template<typename Functor>
|
||||||
BOOST_FUNCTION_FUNCTION& operator=(const Functor& f)
|
BOOST_FUNCTION_FUNCTION&
|
||||||
|
operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f)
|
||||||
{
|
{
|
||||||
self_type(f, static_cast<const Mixin&>(*this)).swap(*this);
|
self_type other(f);
|
||||||
|
lock l(static_cast<const threading_mixin&>(*this));
|
||||||
|
(void)l;
|
||||||
|
other.unlocked_swap(*this);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
|
||||||
template<typename Functor>
|
|
||||||
BOOST_FUNCTION_FUNCTION& operator=(Functor* f)
|
|
||||||
{
|
|
||||||
self_type(f, static_cast<const Mixin&>(*this)).swap(*this);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
#endif // __BORLANDC__
|
|
||||||
|
|
||||||
template<typename Functor>
|
|
||||||
void set(const Functor& f)
|
|
||||||
{
|
|
||||||
self_type(f, static_cast<const Mixin&>(*this)).swap(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
|
||||||
template<typename Functor>
|
|
||||||
void set(Functor* f)
|
|
||||||
{
|
|
||||||
self_type(f, static_cast<const Mixin&>(*this)).swap(*this);
|
|
||||||
}
|
|
||||||
#endif // __BORLANDC__
|
|
||||||
|
|
||||||
// Assignment from another BOOST_FUNCTION_FUNCTION
|
// Assignment from another BOOST_FUNCTION_FUNCTION
|
||||||
BOOST_FUNCTION_FUNCTION& operator=(const BOOST_FUNCTION_FUNCTION& f)
|
BOOST_FUNCTION_FUNCTION& operator=(const BOOST_FUNCTION_FUNCTION& f)
|
||||||
{
|
{
|
||||||
if (&f == this)
|
if (&f == this)
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
self_type(f).swap(*this);
|
self_type other(f);
|
||||||
|
lock l(static_cast<const threading_mixin&>(*this));
|
||||||
|
(void)l;
|
||||||
|
other.unlocked_swap(*this);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assignment from another BOOST_FUNCTION_FUNCTION
|
|
||||||
void set(const BOOST_FUNCTION_FUNCTION& f)
|
|
||||||
{
|
|
||||||
if (&f == this)
|
|
||||||
return;
|
|
||||||
|
|
||||||
self_type(f).swap(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void swap(BOOST_FUNCTION_FUNCTION& other)
|
void swap(BOOST_FUNCTION_FUNCTION& other)
|
||||||
{
|
{
|
||||||
if (&other == this)
|
if (&other == this)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::swap(manager, other.manager);
|
detail::function::scoped_double_lock<lock, threading_mixin> l(*this,
|
||||||
std::swap(functor, other.functor);
|
other);
|
||||||
std::swap(invoker, other.invoker);
|
(void)l;
|
||||||
std::swap(static_cast<Mixin&>(*this), static_cast<Mixin&>(other));
|
|
||||||
|
unlocked_swap(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear out a target, if there is one
|
// Clear out a target, if there is one
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
if (manager)
|
lock l(static_cast<const threading_mixin&>(*this));
|
||||||
functor = manager(functor, detail::function::destroy_functor_tag);
|
(void)l;
|
||||||
|
|
||||||
manager = 0;
|
if (function_base::manager) {
|
||||||
|
function_base::functor =
|
||||||
|
function_base::manager(function_base::functor,
|
||||||
|
detail::function::destroy_functor_tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
function_base::manager = 0;
|
||||||
invoker = 0;
|
invoker = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,13 +361,14 @@ namespace boost {
|
|||||||
{
|
{
|
||||||
if (!f.empty()) {
|
if (!f.empty()) {
|
||||||
invoker = f.invoker;
|
invoker = f.invoker;
|
||||||
manager = f.manager;
|
function_base::manager = f.manager;
|
||||||
functor = f.manager(f.functor, detail::function::clone_functor_tag);
|
function_base::functor =
|
||||||
}
|
f.manager(f.functor, detail::function::clone_functor_tag);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Functor>
|
template<typename Functor>
|
||||||
void assign_to(const Functor& f)
|
void assign_to(Functor f)
|
||||||
{
|
{
|
||||||
typedef typename detail::function::get_function_tag<Functor>::type tag;
|
typedef typename detail::function::get_function_tag<Functor>::type tag;
|
||||||
this->assign_to(f, tag());
|
this->assign_to(f, tag());
|
||||||
@@ -353,10 +388,13 @@ namespace boost {
|
|||||||
invoker_type;
|
invoker_type;
|
||||||
|
|
||||||
invoker = &invoker_type::invoke;
|
invoker = &invoker_type::invoke;
|
||||||
manager = &detail::function::functor_manager<FunctionPtr,
|
function_base::manager =
|
||||||
Allocator>::manage;
|
&detail::function::functor_manager<FunctionPtr, Allocator>::manage;
|
||||||
functor = manager(detail::function::any_pointer(
|
function_base::functor =
|
||||||
reinterpret_cast<void (*)()>(f)
|
function_base::manager(detail::function::any_pointer(
|
||||||
|
// should be a reinterpret cast, but some compilers
|
||||||
|
// insist on giving cv-qualifiers to free functions
|
||||||
|
(void (*)())(f)
|
||||||
),
|
),
|
||||||
detail::function::clone_functor_tag);
|
detail::function::clone_functor_tag);
|
||||||
}
|
}
|
||||||
@@ -371,9 +409,13 @@ namespace boost {
|
|||||||
#endif // BOOST_FUNCTION_NUM_ARGS > 0
|
#endif // BOOST_FUNCTION_NUM_ARGS > 0
|
||||||
|
|
||||||
template<typename FunctionObj>
|
template<typename FunctionObj>
|
||||||
void assign_to(const FunctionObj& f, detail::function::function_obj_tag)
|
void assign_to(FunctionObj f, detail::function::function_obj_tag)
|
||||||
{
|
{
|
||||||
if (!detail::function::has_empty_target(&f)) {
|
typedef detail::function::truth<
|
||||||
|
boost::is_base_and_derived<function_base, FunctionObj>::value>
|
||||||
|
is_boost_function;
|
||||||
|
|
||||||
|
if (!detail::function::has_empty_target(f, is_boost_function())) {
|
||||||
typedef
|
typedef
|
||||||
typename detail::function::BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
|
typename detail::function::BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
|
||||||
FunctionObj,
|
FunctionObj,
|
||||||
@@ -383,35 +425,95 @@ namespace boost {
|
|||||||
invoker_type;
|
invoker_type;
|
||||||
|
|
||||||
invoker = &invoker_type::invoke;
|
invoker = &invoker_type::invoke;
|
||||||
manager = &detail::function::functor_manager<FunctionObj,
|
function_base::manager = &detail::function::functor_manager<
|
||||||
Allocator>::manage;
|
FunctionObj, Allocator>::manage;
|
||||||
functor =
|
#ifndef BOOST_NO_STD_ALLOCATOR
|
||||||
manager(detail::function::any_pointer(const_cast<FunctionObj*>(&f)),
|
typedef typename Allocator::template rebind<FunctionObj>::other
|
||||||
detail::function::clone_functor_tag);
|
allocator_type;
|
||||||
|
typedef typename allocator_type::pointer pointer_type;
|
||||||
|
allocator_type allocator;
|
||||||
|
pointer_type copy = allocator.allocate(1);
|
||||||
|
allocator.construct(copy, f);
|
||||||
|
|
||||||
|
// Get back to the original pointer type
|
||||||
|
FunctionObj* new_f = static_cast<FunctionObj*>(copy);
|
||||||
|
#else
|
||||||
|
FunctionObj* new_f = new FunctionObj(f);
|
||||||
|
#endif // BOOST_NO_STD_ALLOCATOR
|
||||||
|
function_base::functor =
|
||||||
|
detail::function::any_pointer(static_cast<void*>(new_f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef result_type (*invoker_type)(detail::function::any_pointer
|
template<typename FunctionObj>
|
||||||
BOOST_FUNCTION_COMMA
|
void assign_to(const reference_wrapper<FunctionObj>& f,
|
||||||
BOOST_FUNCTION_TEMPLATE_ARGS);
|
detail::function::function_obj_ref_tag)
|
||||||
|
{
|
||||||
|
typedef detail::function::truth<
|
||||||
|
boost::is_base_and_derived<function_base, FunctionObj>::value>
|
||||||
|
is_boost_function;
|
||||||
|
|
||||||
|
if (!detail::function::has_empty_target(f.get(), is_boost_function())) {
|
||||||
|
typedef
|
||||||
|
typename detail::function::BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
|
||||||
|
FunctionObj,
|
||||||
|
R BOOST_FUNCTION_COMMA
|
||||||
|
BOOST_FUNCTION_TEMPLATE_ARGS
|
||||||
|
>::type
|
||||||
|
invoker_type;
|
||||||
|
|
||||||
|
invoker = &invoker_type::invoke;
|
||||||
|
function_base::manager = &detail::function::trivial_manager;
|
||||||
|
function_base::functor =
|
||||||
|
function_base::manager(
|
||||||
|
detail::function::any_pointer(
|
||||||
|
const_cast<FunctionObj*>(f.get_pointer())),
|
||||||
|
detail::function::clone_functor_tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename FunctionObj>
|
||||||
|
void assign_to(FunctionObj, detail::function::stateless_function_obj_tag)
|
||||||
|
{
|
||||||
|
typedef
|
||||||
|
typename detail::function::
|
||||||
|
BOOST_FUNCTION_GET_STATELESS_FUNCTION_OBJ_INVOKER<
|
||||||
|
FunctionObj,
|
||||||
|
R BOOST_FUNCTION_COMMA
|
||||||
|
BOOST_FUNCTION_TEMPLATE_ARGS
|
||||||
|
>::type
|
||||||
|
invoker_type;
|
||||||
|
invoker = &invoker_type::invoke;
|
||||||
|
function_base::manager = &detail::function::trivial_manager;
|
||||||
|
function_base::functor = detail::function::any_pointer(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void unlocked_swap(BOOST_FUNCTION_FUNCTION& other)
|
||||||
|
{
|
||||||
|
std::swap(function_base::manager, other.manager);
|
||||||
|
std::swap(function_base::functor, other.functor);
|
||||||
|
std::swap(invoker, other.invoker);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef internal_result_type (*invoker_type)(detail::function::any_pointer
|
||||||
|
BOOST_FUNCTION_COMMA
|
||||||
|
BOOST_FUNCTION_TEMPLATE_ARGS);
|
||||||
|
|
||||||
invoker_type invoker;
|
invoker_type invoker;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
|
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
|
||||||
typename Policy, typename Mixin, typename Allocator>
|
typename ThreadingPolicy, typename Allocator>
|
||||||
inline void swap(BOOST_FUNCTION_FUNCTION<
|
inline void swap(BOOST_FUNCTION_FUNCTION<
|
||||||
R BOOST_FUNCTION_COMMA
|
R BOOST_FUNCTION_COMMA
|
||||||
BOOST_FUNCTION_TEMPLATE_ARGS ,
|
BOOST_FUNCTION_TEMPLATE_ARGS ,
|
||||||
Policy,
|
ThreadingPolicy,
|
||||||
Mixin,
|
|
||||||
Allocator
|
Allocator
|
||||||
>& f1,
|
>& f1,
|
||||||
BOOST_FUNCTION_FUNCTION<
|
BOOST_FUNCTION_FUNCTION<
|
||||||
R BOOST_FUNCTION_COMMA
|
R BOOST_FUNCTION_COMMA
|
||||||
BOOST_FUNCTION_TEMPLATE_ARGS,
|
BOOST_FUNCTION_TEMPLATE_ARGS,
|
||||||
Policy,
|
ThreadingPolicy,
|
||||||
Mixin,
|
|
||||||
Allocator
|
Allocator
|
||||||
>& f2)
|
>& f2)
|
||||||
{
|
{
|
||||||
@@ -420,16 +522,15 @@ namespace boost {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Cleanup after ourselves...
|
// Cleanup after ourselves...
|
||||||
#undef BOOST_FUNCTION_DEFAULT_ALLOCATOR
|
|
||||||
#undef BOOST_FUNCTION_COMMA
|
#undef BOOST_FUNCTION_COMMA
|
||||||
#undef BOOST_FUNCTION_FUNCTION
|
#undef BOOST_FUNCTION_FUNCTION
|
||||||
#undef BOOST_FUNCTION_BASE
|
|
||||||
#undef BOOST_FUNCTION_INVOKER_BASE
|
|
||||||
#undef BOOST_FUNCTION_FUNCTION_INVOKER
|
#undef BOOST_FUNCTION_FUNCTION_INVOKER
|
||||||
#undef BOOST_FUNCTION_VOID_FUNCTION_INVOKER
|
#undef BOOST_FUNCTION_VOID_FUNCTION_INVOKER
|
||||||
#undef BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
|
#undef BOOST_FUNCTION_FUNCTION_OBJ_INVOKER
|
||||||
#undef BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
|
#undef BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER
|
||||||
|
#undef BOOST_FUNCTION_STATELESS_FUNCTION_OBJ_INVOKER
|
||||||
|
#undef BOOST_FUNCTION_STATELESS_VOID_FUNCTION_OBJ_INVOKER
|
||||||
#undef BOOST_FUNCTION_GET_FUNCTION_INVOKER
|
#undef BOOST_FUNCTION_GET_FUNCTION_INVOKER
|
||||||
#undef BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
|
#undef BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER
|
||||||
|
#undef BOOST_FUNCTION_GET_STATELESS_FUNCTION_OBJ_INVOKER
|
||||||
#undef BOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER
|
#undef BOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER
|
||||||
|
|
||||||
|
|||||||
48
include/boost/function/threading/detail/mutex_mixin.hpp
Normal file
48
include/boost/function/threading/detail/mutex_mixin.hpp
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
// Copyright (C) 2002
|
||||||
|
// Doug Gregor (gregod@cs.rpi.edu)
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, distribute and sell this software
|
||||||
|
// and its documentation for any purpose is hereby granted without fee,
|
||||||
|
// provided that the above copyright notice appear in all copies and
|
||||||
|
// that both that copyright notice and this permission notice appear
|
||||||
|
// in supporting documentation. William E. Kempf makes no representations
|
||||||
|
// about the suitability of this software for any purpose.
|
||||||
|
// It is provided "as is" without express or implied warranty.
|
||||||
|
#ifndef BOOST_THREAD_MODEL_DETAIL_MUTEX_MIXIN_HPP
|
||||||
|
#define BOOST_THREAD_MODEL_DETAIL_MUTEX_MIXIN_HPP
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<typename Mutex>
|
||||||
|
class mutex_mixin
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
mutex_mixin(const mutex_mixin&) {}
|
||||||
|
mutex_mixin& operator=(const mutex_mixin&) { return *this; }
|
||||||
|
|
||||||
|
operator const Mutex&() const { return mutex; }
|
||||||
|
operator Mutex&() { return mutex; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Mutex mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Mutex>
|
||||||
|
class static_mutex_mixin
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static_mutex_mixin(const mutex_mixin&) {}
|
||||||
|
static_mutex_mixin& operator=(const mutex_mixin&) { return *this; }
|
||||||
|
|
||||||
|
operator const Mutex&() const { return mutex; }
|
||||||
|
operator Mutex&() { return mutex; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
static Mutex mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace detail
|
||||||
|
} // end namespace boost
|
||||||
|
|
||||||
|
#endif // BOOST_THREAD_MODEL_DETAIL_MUTEX_MIXIN_HPP
|
||||||
28
include/boost/function/threading/per_class.hpp
Normal file
28
include/boost/function/threading/per_class.hpp
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
// Copyright (C) 2002
|
||||||
|
// Doug Gregor (gregod@cs.rpi.edu)
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, distribute and sell this software
|
||||||
|
// and its documentation for any purpose is hereby granted without fee,
|
||||||
|
// provided that the above copyright notice appear in all copies and
|
||||||
|
// that both that copyright notice and this permission notice appear
|
||||||
|
// in supporting documentation. William E. Kempf makes no representations
|
||||||
|
// about the suitability of this software for any purpose.
|
||||||
|
// It is provided "as is" without express or implied warranty.
|
||||||
|
#ifndef BOOST_THREAD_MODEL_PER_CLASS_HPP
|
||||||
|
#define BOOST_THREAD_MODEL_PER_CLASS_HPP
|
||||||
|
|
||||||
|
#include <boost/thread/mutex.hpp>
|
||||||
|
#include <boost/thread/model/detail/mutex_mixin.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
template<typename Mutex = boost::mutex>
|
||||||
|
struct per_class_locking
|
||||||
|
{
|
||||||
|
typedef detail::static_mutex_mixin<Mutex> mixin;
|
||||||
|
typedef typename Mutex::scoped_lock lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace boost
|
||||||
|
|
||||||
|
#endif // BOOST_THREAD_MODEL_PER_CLASS_HPP
|
||||||
28
include/boost/function/threading/per_object.hpp
Normal file
28
include/boost/function/threading/per_object.hpp
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
// Copyright (C) 2002
|
||||||
|
// Doug Gregor (gregod@cs.rpi.edu)
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, distribute and sell this software
|
||||||
|
// and its documentation for any purpose is hereby granted without fee,
|
||||||
|
// provided that the above copyright notice appear in all copies and
|
||||||
|
// that both that copyright notice and this permission notice appear
|
||||||
|
// in supporting documentation. William E. Kempf makes no representations
|
||||||
|
// about the suitability of this software for any purpose.
|
||||||
|
// It is provided "as is" without express or implied warranty.
|
||||||
|
#ifndef BOOST_THREAD_MODEL_PER_OBJECT_HPP
|
||||||
|
#define BOOST_THREAD_MODEL_PER_OBJECT_HPP
|
||||||
|
|
||||||
|
#include <boost/thread/mutex.hpp>
|
||||||
|
#include <boost/thread/model/detail/mutex_mixin.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
template<typename Mutex = boost::mutex>
|
||||||
|
struct per_object_locking
|
||||||
|
{
|
||||||
|
typedef detail::mutex_mixin<Mutex> mixin;
|
||||||
|
typedef typename Mutex::scoped_lock lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace boost
|
||||||
|
|
||||||
|
#endif // BOOST_THREAD_MODEL_PER_OBJECT_HPP
|
||||||
27
include/boost/function/threading/single.hpp
Normal file
27
include/boost/function/threading/single.hpp
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
// Copyright (C) 2002
|
||||||
|
// Doug Gregor (gregod@cs.rpi.edu)
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, distribute and sell this software
|
||||||
|
// and its documentation for any purpose is hereby granted without fee,
|
||||||
|
// provided that the above copyright notice appear in all copies and
|
||||||
|
// that both that copyright notice and this permission notice appear
|
||||||
|
// in supporting documentation. William E. Kempf makes no representations
|
||||||
|
// about the suitability of this software for any purpose.
|
||||||
|
// It is provided "as is" without express or implied warranty.
|
||||||
|
#ifndef BOOST_THREAD_MODEL_SINGLE_HPP
|
||||||
|
#define BOOST_THREAD_MODEL_SINGLE_HPP
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
|
||||||
|
struct single_threaded {
|
||||||
|
struct mixin {};
|
||||||
|
|
||||||
|
struct lock
|
||||||
|
{
|
||||||
|
lock(const mixin&) {}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace boost
|
||||||
|
|
||||||
|
#endif // BOOST_THREAD_MODEL_SINGLE_HPP
|
||||||
@@ -50,7 +50,7 @@ And, of course, function pointers have several advantages over Boost.Function:
|
|||||||
<p> Function object wrappers will be the size of two function pointers plus one function pointer or data pointer (whichever is larger). On common 32-bit platforms, this amounts to 12 bytes per wrapper. Additionally, the function object target will be allocated on the heap.
|
<p> Function object wrappers will be the size of two function pointers plus one function pointer or data pointer (whichever is larger). On common 32-bit platforms, this amounts to 12 bytes per wrapper. Additionally, the function object target will be allocated on the heap.
|
||||||
|
|
||||||
<h3>Copying efficiency</h3>
|
<h3>Copying efficiency</h3>
|
||||||
<p> Copying function object wrappers requires allocating member for a copy of the function object target. The default allocator may be replaced with a faster custom allocator if the cost of this cloning becomes prohibitive.
|
<p> Copying function object wrappers may require allocating memory for a copy of the function object target. The default allocator may be replaced with a faster custom allocator or one may choose to allow the function object wrappers to only store function object targets by reference (using <a href="../bind/ref.html"><code>ref</code></a>) if the cost of this cloning becomes prohibitive.
|
||||||
|
|
||||||
<h3>Invocation efficiency</h3>
|
<h3>Invocation efficiency</h3>
|
||||||
<p> With a properly inlining compiler, an invocation of a function object requires one call through a function pointer. If the call is to a free function pointer, an additional call must be made to that function pointer (unless the compiler has very powerful interprocedural analysis).
|
<p> With a properly inlining compiler, an invocation of a function object requires one call through a function pointer. If the call is to a free function pointer, an additional call must be made to that function pointer (unless the compiler has very powerful interprocedural analysis).
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// Boost.Function library
|
// Boost.Function library
|
||||||
|
|
||||||
// Copyright (C) 2001 Doug Gregor (gregod@cs.rpi.edu)
|
// Copyright (C) 2001-2002 Doug Gregor (gregod@cs.rpi.edu)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, sell and distribute this software is granted
|
// Permission to copy, use, sell and distribute this software is granted
|
||||||
// provided this copyright notice appears in all copies.
|
// provided this copyright notice appears in all copies.
|
||||||
@@ -93,7 +93,7 @@ test_zero_args()
|
|||||||
|
|
||||||
// Invocation and self-assignment
|
// Invocation and self-assignment
|
||||||
global_int = 0;
|
global_int = 0;
|
||||||
v1.set(v1);
|
v1 = (v1);
|
||||||
v1();
|
v1();
|
||||||
BOOST_TEST(global_int == 5);
|
BOOST_TEST(global_int == 5);
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ test_zero_args()
|
|||||||
BOOST_TEST(v1.empty());
|
BOOST_TEST(v1.empty());
|
||||||
|
|
||||||
// Assignment to an empty function from a free function
|
// Assignment to an empty function from a free function
|
||||||
v1 = &write_five;
|
v1 = write_five;
|
||||||
BOOST_TEST(!v1.empty());
|
BOOST_TEST(!v1.empty());
|
||||||
|
|
||||||
// Invocation
|
// Invocation
|
||||||
@@ -129,7 +129,7 @@ test_zero_args()
|
|||||||
BOOST_TEST(global_int == 5);
|
BOOST_TEST(global_int == 5);
|
||||||
|
|
||||||
// Assignment to a non-empty function from a free function
|
// Assignment to a non-empty function from a free function
|
||||||
v1 = &write_three;
|
v1 = write_three;
|
||||||
BOOST_TEST(!v1.empty());
|
BOOST_TEST(!v1.empty());
|
||||||
|
|
||||||
// Invocation
|
// Invocation
|
||||||
@@ -152,7 +152,7 @@ test_zero_args()
|
|||||||
BOOST_TEST(global_int == 3);
|
BOOST_TEST(global_int == 3);
|
||||||
|
|
||||||
// Assignment to a non-empty function
|
// Assignment to a non-empty function
|
||||||
v2.set(five);
|
v2 = (five);
|
||||||
|
|
||||||
// Invocation
|
// Invocation
|
||||||
global_int = 0;
|
global_int = 0;
|
||||||
@@ -163,7 +163,7 @@ test_zero_args()
|
|||||||
BOOST_TEST(v2.empty());
|
BOOST_TEST(v2.empty());
|
||||||
|
|
||||||
// Assignment to an empty function from a free function
|
// Assignment to an empty function from a free function
|
||||||
v2.set(&write_five);
|
v2 = (&write_five);
|
||||||
BOOST_TEST(v2);
|
BOOST_TEST(v2);
|
||||||
|
|
||||||
// Invocation
|
// Invocation
|
||||||
@@ -604,6 +604,35 @@ test_member_functions()
|
|||||||
BOOST_TEST(f2(five, 4) == 9);
|
BOOST_TEST(f2(five, 4) == 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct add_with_throw_on_copy {
|
||||||
|
int operator()(int x, int y) const { return x+y; }
|
||||||
|
|
||||||
|
add_with_throw_on_copy() {}
|
||||||
|
|
||||||
|
add_with_throw_on_copy(const add_with_throw_on_copy&)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("But this CAN'T throw");
|
||||||
|
}
|
||||||
|
|
||||||
|
add_with_throw_on_copy& operator=(const add_with_throw_on_copy&)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("But this CAN'T throw");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_ref()
|
||||||
|
{
|
||||||
|
add_with_throw_on_copy atc;
|
||||||
|
try {
|
||||||
|
boost::function2<int, int, int> f(ref(atc));
|
||||||
|
BOOST_TEST(f(1, 3) == 4);
|
||||||
|
}
|
||||||
|
catch(std::runtime_error e) {
|
||||||
|
BOOST_ERROR("Nonthrowing constructor threw an exception");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int test_main(int, char* [])
|
int test_main(int, char* [])
|
||||||
{
|
{
|
||||||
test_zero_args();
|
test_zero_args();
|
||||||
@@ -611,5 +640,6 @@ int test_main(int, char* [])
|
|||||||
test_two_args();
|
test_two_args();
|
||||||
test_emptiness();
|
test_emptiness();
|
||||||
test_member_functions();
|
test_member_functions();
|
||||||
|
test_ref();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// Boost.Function library
|
// Boost.Function library
|
||||||
|
|
||||||
// Copyright (C) 2001 Doug Gregor (gregod@cs.rpi.edu)
|
// Copyright (C) 2001-2002 Doug Gregor (gregod@cs.rpi.edu)
|
||||||
//
|
//
|
||||||
// Permission to copy, use, sell and distribute this software is granted
|
// Permission to copy, use, sell and distribute this software is granted
|
||||||
// provided this copyright notice appears in all copies.
|
// provided this copyright notice appears in all copies.
|
||||||
@@ -93,7 +93,7 @@ test_zero_args()
|
|||||||
|
|
||||||
// Invocation and self-assignment
|
// Invocation and self-assignment
|
||||||
global_int = 0;
|
global_int = 0;
|
||||||
v1.set(v1);
|
v1 = (v1);
|
||||||
v1();
|
v1();
|
||||||
BOOST_TEST(global_int == 5);
|
BOOST_TEST(global_int == 5);
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ test_zero_args()
|
|||||||
BOOST_TEST(v1.empty());
|
BOOST_TEST(v1.empty());
|
||||||
|
|
||||||
// Assignment to an empty function from a free function
|
// Assignment to an empty function from a free function
|
||||||
v1 = &write_five;
|
v1 = BOOST_FUNCTION_TARGET_FIX(&) write_five;
|
||||||
BOOST_TEST(!v1.empty());
|
BOOST_TEST(!v1.empty());
|
||||||
|
|
||||||
// Invocation
|
// Invocation
|
||||||
@@ -111,7 +111,7 @@ test_zero_args()
|
|||||||
BOOST_TEST(global_int == 5);
|
BOOST_TEST(global_int == 5);
|
||||||
|
|
||||||
// Assignment to a non-empty function from a free function
|
// Assignment to a non-empty function from a free function
|
||||||
v1 = &write_three;
|
v1 = BOOST_FUNCTION_TARGET_FIX(&) write_three;
|
||||||
BOOST_TEST(!v1.empty());
|
BOOST_TEST(!v1.empty());
|
||||||
|
|
||||||
// Invocation
|
// Invocation
|
||||||
@@ -152,7 +152,7 @@ test_zero_args()
|
|||||||
BOOST_TEST(global_int == 3);
|
BOOST_TEST(global_int == 3);
|
||||||
|
|
||||||
// Assignment to a non-empty function
|
// Assignment to a non-empty function
|
||||||
v2.set(five);
|
v2 = (five);
|
||||||
|
|
||||||
// Invocation
|
// Invocation
|
||||||
global_int = 0;
|
global_int = 0;
|
||||||
@@ -163,7 +163,7 @@ test_zero_args()
|
|||||||
BOOST_TEST(v2.empty());
|
BOOST_TEST(v2.empty());
|
||||||
|
|
||||||
// Assignment to an empty function from a free function
|
// Assignment to an empty function from a free function
|
||||||
v2.set(&write_five);
|
v2 = (BOOST_FUNCTION_TARGET_FIX(&) write_five);
|
||||||
BOOST_TEST(v2);
|
BOOST_TEST(v2);
|
||||||
|
|
||||||
// Invocation
|
// Invocation
|
||||||
@@ -172,7 +172,7 @@ test_zero_args()
|
|||||||
BOOST_TEST(global_int == 5);
|
BOOST_TEST(global_int == 5);
|
||||||
|
|
||||||
// Assignment to a non-empty function from a free function
|
// Assignment to a non-empty function from a free function
|
||||||
v2 = &write_three;
|
v2 = BOOST_FUNCTION_TARGET_FIX(&) write_three;
|
||||||
BOOST_TEST(!v2.empty());
|
BOOST_TEST(!v2.empty());
|
||||||
|
|
||||||
// Invocation
|
// Invocation
|
||||||
@@ -227,7 +227,7 @@ test_zero_args()
|
|||||||
BOOST_TEST(global_int == 3);
|
BOOST_TEST(global_int == 3);
|
||||||
|
|
||||||
// Assign to a function from a function with a function
|
// Assign to a function from a function with a function
|
||||||
v2 = &write_five;
|
v2 = BOOST_FUNCTION_TARGET_FIX(&) write_five;
|
||||||
v1 = v2;
|
v1 = v2;
|
||||||
BOOST_TEST(!v1.empty());
|
BOOST_TEST(!v1.empty());
|
||||||
BOOST_TEST(!v2.empty());
|
BOOST_TEST(!v2.empty());
|
||||||
@@ -603,6 +603,35 @@ test_member_functions()
|
|||||||
BOOST_TEST(f2(five, 4) == 9);
|
BOOST_TEST(f2(five, 4) == 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct add_with_throw_on_copy {
|
||||||
|
int operator()(int x, int y) const { return x+y; }
|
||||||
|
|
||||||
|
add_with_throw_on_copy() {}
|
||||||
|
|
||||||
|
add_with_throw_on_copy(const add_with_throw_on_copy&)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("But this CAN'T throw");
|
||||||
|
}
|
||||||
|
|
||||||
|
add_with_throw_on_copy& operator=(const add_with_throw_on_copy&)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("But this CAN'T throw");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_ref()
|
||||||
|
{
|
||||||
|
add_with_throw_on_copy atc;
|
||||||
|
try {
|
||||||
|
boost::function<int, int, int> f(ref(atc));
|
||||||
|
BOOST_TEST(f(1, 3) == 4);
|
||||||
|
}
|
||||||
|
catch(std::runtime_error e) {
|
||||||
|
BOOST_ERROR("Nonthrowing constructor threw an exception");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int test_main(int, char* [])
|
int test_main(int, char* [])
|
||||||
{
|
{
|
||||||
test_zero_args();
|
test_zero_args();
|
||||||
@@ -610,5 +639,7 @@ int test_main(int, char* [])
|
|||||||
test_two_args();
|
test_two_args();
|
||||||
test_emptiness();
|
test_emptiness();
|
||||||
test_member_functions();
|
test_member_functions();
|
||||||
|
test_ref();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
// Boost.Function library
|
|
||||||
|
|
||||||
// Copyright (C) 2001 Doug Gregor (gregod@cs.rpi.edu)
|
|
||||||
//
|
|
||||||
// Permission to copy, use, sell and distribute this software is granted
|
|
||||||
// provided this copyright notice appears in all copies.
|
|
||||||
// Permission to modify the code and to distribute modified code is granted
|
|
||||||
// provided this copyright notice appears in all copies, and a notice
|
|
||||||
// that the code was modified is included with the copyright notice.
|
|
||||||
//
|
|
||||||
// This software is provided "as is" without express or implied warranty,
|
|
||||||
// and with no claim as to its suitability for any purpose.
|
|
||||||
|
|
||||||
// For more information, see http://www.boost.org
|
|
||||||
|
|
||||||
#define BOOST_INCLUDE_MAIN
|
|
||||||
#include <boost/test/test_tools.hpp>
|
|
||||||
#include <cassert>
|
|
||||||
#include <functional>
|
|
||||||
#include <boost/function.hpp>
|
|
||||||
|
|
||||||
struct id_mixin
|
|
||||||
{
|
|
||||||
id_mixin(const id_mixin& rhs) : id(rhs.id) {}
|
|
||||||
id_mixin& operator=(const id_mixin& rhs){id = rhs.id; return *this;}
|
|
||||||
id_mixin(int i = 0){ id = i;}
|
|
||||||
int id;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int do_plus(int x, int y) { return x+y; }
|
|
||||||
|
|
||||||
typedef boost::function<int,int,int>::mixin<id_mixin>::type func;
|
|
||||||
|
|
||||||
int test_main(int, char*[])
|
|
||||||
{
|
|
||||||
func f(id_mixin(3));
|
|
||||||
f = std::plus<int>();
|
|
||||||
BOOST_TEST(f.id == 3);
|
|
||||||
|
|
||||||
f = &do_plus;
|
|
||||||
BOOST_TEST(f.id == 3);
|
|
||||||
|
|
||||||
f.clear();
|
|
||||||
f.id = 7;
|
|
||||||
BOOST_TEST(f.id == 7);
|
|
||||||
|
|
||||||
func g(f);
|
|
||||||
BOOST_TEST(g.id == 7);
|
|
||||||
|
|
||||||
f.id = 21;
|
|
||||||
BOOST_TEST(f.id == 21);
|
|
||||||
|
|
||||||
boost::swap(f,g);
|
|
||||||
BOOST_TEST(f.id == 7);
|
|
||||||
BOOST_TEST(g.id == 21);
|
|
||||||
|
|
||||||
g = f;
|
|
||||||
BOOST_TEST(g.id == 7);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -11,4 +11,4 @@ compile-fail libs/function/test/function_test_fail1.cpp
|
|||||||
compile-fail libs/function/test/function_test_fail2.cpp
|
compile-fail libs/function/test/function_test_fail2.cpp
|
||||||
run libs/function/test/mixin_test.cpp
|
run libs/function/test/mixin_test.cpp
|
||||||
run libs/function/test/policy_test.cpp
|
run libs/function/test/policy_test.cpp
|
||||||
|
run libs/function/test/stateless_test.cpp
|
||||||
|
|||||||
@@ -15,33 +15,33 @@
|
|||||||
|
|
||||||
#define BOOST_INCLUDE_MAIN
|
#define BOOST_INCLUDE_MAIN
|
||||||
#include <boost/test/test_tools.hpp>
|
#include <boost/test/test_tools.hpp>
|
||||||
#include <cassert>
|
|
||||||
#include <iostream>
|
|
||||||
#include <functional>
|
|
||||||
#include <boost/function.hpp>
|
#include <boost/function.hpp>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
using namespace std;
|
struct stateless_integer_add {
|
||||||
using namespace boost;
|
int operator()(int x, int y) const { return x+y; }
|
||||||
|
|
||||||
struct counting_policy
|
void* operator new(std::size_t, stateless_integer_add*)
|
||||||
{
|
{
|
||||||
static int count;
|
throw std::runtime_error("Cannot allocate a stateless_integer_add");
|
||||||
|
}
|
||||||
|
|
||||||
void precall(const function_base*) { count++; }
|
void operator delete(void*, stateless_integer_add*)
|
||||||
void postcall(const function_base*) { count+=2; }
|
{
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
int counting_policy::count = 0;
|
namespace boost {
|
||||||
|
template<>
|
||||||
|
struct is_stateless<stateless_integer_add> {
|
||||||
|
BOOST_STATIC_CONSTANT(bool, value = true);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int test_main(int, char*[])
|
||||||
test_main(int, char*[])
|
|
||||||
{
|
{
|
||||||
function<int, int, int>::policy<counting_policy>::type f;
|
boost::function<int, int, int> f;
|
||||||
|
f = stateless_integer_add();
|
||||||
f = plus<int>();
|
|
||||||
|
|
||||||
BOOST_TEST(5 == f(2,3));
|
|
||||||
BOOST_TEST(counting_policy::count==3);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user