Compare commits

..

1 Commits

Author SHA1 Message Date
687dff0782 Created a branch from trunk
[SVN r38959]
2007-08-26 05:34:35 +00:00
12 changed files with 203 additions and 524 deletions

View File

@ -1,8 +1,3 @@
# Copyright (c) 2002 Douglas Gregor <doug.gregor -at- gmail.com>
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
project boost/doc ; project boost/doc ;
import boostbook : boostbook ; import boostbook : boostbook ;

View File

@ -1,11 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2002 Douglas Gregor <doug.gregor -at- gmail.com>
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
-->
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd"> "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
<section id="function.faq" last-revision="$Date$"> <section id="function.faq" last-revision="$Date$">

View File

@ -1,11 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2002 Douglas Gregor <doug.gregor -at- gmail.com>
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
-->
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd"> "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
<section id="function.history" last-revision="$Date$"> <section id="function.history" last-revision="$Date$">
@ -13,22 +6,6 @@
<itemizedlist spacing="compact"> <itemizedlist spacing="compact">
<listitem><para><bold>Version 1.36.0</bold>: </para>
<itemizedlist spacing="compact">
<listitem><para>Boost.Function now implements allocator support
in the same way that is is provided in C++0x, based on C++
committee
proposal <ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2308.html">N2308</ulink>. This
change removes the <computeroutput>Allocator</computeroutput>
template parameter of <classname>boost::function</classname> in
favor of a constructor that takes an argument. While this is a
backward-incompatible change, it is likely to affect only a few
users. This change to Function was contributed by Emil
Dotchevski, which also authored the corresponding C++ committee
proposal.</para></listitem>
</itemizedlist>
</listitem>
<listitem><para><bold>Version 1.34.0</bold>: </para> <listitem><para><bold>Version 1.34.0</bold>: </para>
<itemizedlist spacing="compact"> <itemizedlist spacing="compact">
<listitem><para>Boost.Function now implements a small buffer optimization, which can drastically improve the performance when copying or construction Boost.Function objects storing small function objects. For instance, <code>bind(&amp;X:foo, &amp;x, _1, _2)</code> requires no heap allocation when placed into a Boost.Function object. Note that some exception-safety guarantees have changed: assignment provides the basic exception guarantee and <code>swap()</code> may throw.</para></listitem> <listitem><para>Boost.Function now implements a small buffer optimization, which can drastically improve the performance when copying or construction Boost.Function objects storing small function objects. For instance, <code>bind(&amp;X:foo, &amp;x, _1, _2)</code> requires no heap allocation when placed into a Boost.Function object. Note that some exception-safety guarantees have changed: assignment provides the basic exception guarantee and <code>swap()</code> may throw.</para></listitem>

View File

@ -1,11 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2002 Douglas Gregor <doug.gregor -at- gmail.com>
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
-->
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd"> "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
<section id="function.misc" last-revision="$Date$"> <section id="function.misc" last-revision="$Date$">
@ -24,7 +17,7 @@
<para> And, of course, function pointers have several advantages over Boost.Function: <para> And, of course, function pointers have several advantages over Boost.Function:
<itemizedlist spacing="compact"> <itemizedlist spacing="compact">
<listitem><para> Function pointers are smaller (the size of one pointer instead of four or more) </para></listitem> <listitem><para> Function pointers are smaller (the size of one pointer instead of three) </para></listitem>
<listitem><para> Function pointers are faster (Boost.Function may require two calls through function pointers) </para></listitem> <listitem><para> Function pointers are faster (Boost.Function may require two calls through function pointers) </para></listitem>
<listitem><para> Function pointers are backward-compatible with C libraries.</para></listitem> <listitem><para> Function pointers are backward-compatible with C libraries.</para></listitem>
<listitem><para> More readable error messages. </para></listitem> <listitem><para> More readable error messages. </para></listitem>
@ -37,12 +30,12 @@
<section> <section>
<title>Function object wrapper size</title> <title>Function object wrapper size</title>
<para> Function object wrappers will be the size of a struct containing a member function pointer and two data pointers. The actual size can vary significantly depending on the underlying platform; on 32-bit Mac OS X with GCC, this amounts to 16 bytes, while it is 32 bytes Windows with Visual C++. Additionally, the function object target may be allocated on the heap, if it cannot be placed into the small-object buffer in the <code>boost::function</code> object.</para> <para> 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.</para>
</section> </section>
<section> <section>
<title>Copying efficiency</title> <title>Copying efficiency</title>
<para> 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 <computeroutput>ref</computeroutput>) if the cost of this cloning becomes prohibitive. Small function objects can be stored within the <code>boost::function</code> object itself, improving copying efficiency.</para> <para> 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 <computeroutput>ref</computeroutput>) if the cost of this cloning becomes prohibitive.</para>
</section> </section>
<section> <section>

View File

@ -1,11 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2002 Douglas Gregor <doug.gregor -at- gmail.com>
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
-->
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd"> "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
@ -141,6 +134,9 @@
<template-type-parameter name="T2"/> <template-type-parameter name="T2"/>
<template-varargs/> <template-varargs/>
<template-type-parameter name="TN"/> <template-type-parameter name="TN"/>
<template-type-parameter name="Allocator">
<default><classname>std::allocator</classname>&lt;void&gt;</default>
</template-type-parameter>
</template> </template>
<inherit access="public"><classname>function_base</classname></inherit> <inherit access="public"><classname>function_base</classname></inherit>
@ -157,6 +153,7 @@
</description> </description>
<typedef name="result_type"><type>R</type></typedef> <typedef name="result_type"><type>R</type></typedef>
<typedef name="allocator_type"><type>Allocator</type></typedef>
<typedef name="argument_type"> <typedef name="argument_type">
<type>T1</type><purpose>If N == 1</purpose> <type>T1</type><purpose>If N == 1</purpose>
</typedef> </typedef>
@ -212,19 +209,6 @@
<postconditions><simpara><code>*this</code> targets a copy of <code>f</code> if <code>f</code> is nonempty, or <code>this-&gt;<methodname>empty</methodname>()</code> if <code>f</code> is empty.</simpara></postconditions> <postconditions><simpara><code>*this</code> targets a copy of <code>f</code> if <code>f</code> is nonempty, or <code>this-&gt;<methodname>empty</methodname>()</code> if <code>f</code> is empty.</simpara></postconditions>
</constructor> </constructor>
<constructor>
<template>
<template-type-parameter name="F"/>
<template-type-parameter name="Allocator"/>
</template>
<parameter name="f"><paramtype>F</paramtype></parameter>
<parameter name="alloc"><paramtype>Allocator</paramtype></parameter>
<requires><simpara>F is a function object Callable from <code>this</code>, Allocator is an allocator. The copy constructor and destructor of Allocator shall not throw.</simpara></requires>
<postconditions><simpara><code>*this</code> targets a copy of <code>f</code> if <code>f</code> is nonempty, or <code>this-&gt;<methodname>empty</methodname>()</code> if <code>f</code> is empty.</simpara></postconditions>
<effects><simpara>If memory allocation is required, the given allocator (or a copy of it) will be used to allocate that memory.</simpara></effects>
</constructor>
<destructor> <destructor>
<effects><simpara>If <code>!this-&gt;<methodname>empty</methodname>()</code>, destroys the target of this.</simpara></effects> <effects><simpara>If <code>!this-&gt;<methodname>empty</methodname>()</code>, destroys the target of this.</simpara></effects>
@ -333,10 +317,11 @@
<template-type-parameter name="T2"/> <template-type-parameter name="T2"/>
<template-varargs/> <template-varargs/>
<template-type-parameter name="TN"/> <template-type-parameter name="TN"/>
<template-type-parameter name="Allocator"/>
</template> </template>
<type>void</type> <type>void</type>
<parameter name="f1"><paramtype><classname>functionN</classname>&lt;T1, T2, ..., TN&gt;&amp;</paramtype></parameter> <parameter name="f1"><paramtype><classname>functionN</classname>&lt;T1, T2, ..., TN, Allocator&gt;&amp;</paramtype></parameter>
<parameter name="f2"><paramtype><classname>functionN</classname>&lt;T1, T2, ..., TN&gt;&amp;</paramtype></parameter> <parameter name="f2"><paramtype><classname>functionN</classname>&lt;T1, T2, ..., TN, Allocator&gt;&amp;</paramtype></parameter>
<effects><simpara><code>f1.<methodname>swap</methodname>(f2)</code></simpara></effects> <effects><simpara><code>f1.<methodname>swap</methodname>(f2)</code></simpara></effects>
</function> </function>
</free-function-group> </free-function-group>
@ -349,10 +334,11 @@
<template-type-parameter name="T2"/> <template-type-parameter name="T2"/>
<template-varargs/> <template-varargs/>
<template-type-parameter name="TN"/> <template-type-parameter name="TN"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/> <template-type-parameter name="Functor"/>
</template> </template>
<type>bool</type> <type>bool</type>
<parameter name="f"><paramtype>const <classname>functionN</classname>&lt;T1, T2, ..., TN&gt;&amp;</paramtype></parameter> <parameter name="f"><paramtype>const <classname>functionN</classname>&lt;T1, T2, ..., TN, Allocator&gt;&amp;</paramtype></parameter>
<parameter name="g"><paramtype>Functor</paramtype></parameter> <parameter name="g"><paramtype>Functor</paramtype></parameter>
</signature> </signature>
<signature> <signature>
@ -361,11 +347,12 @@
<template-type-parameter name="T2"/> <template-type-parameter name="T2"/>
<template-varargs/> <template-varargs/>
<template-type-parameter name="TN"/> <template-type-parameter name="TN"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/> <template-type-parameter name="Functor"/>
</template> </template>
<type>bool</type> <type>bool</type>
<parameter name="g"><paramtype>Functor</paramtype></parameter> <parameter name="g"><paramtype>Functor</paramtype></parameter>
<parameter name="f"><paramtype>const <classname>functionN</classname>&lt;T1, T2, ..., TN&gt;&amp;</paramtype></parameter> <parameter name="f"><paramtype>const <classname>functionN</classname>&lt;T1, T2, ..., TN, Allocator&gt;&amp;</paramtype></parameter>
</signature> </signature>
<signature> <signature>
<template> <template>
@ -373,10 +360,11 @@
<template-type-parameter name="T2"/> <template-type-parameter name="T2"/>
<template-varargs/> <template-varargs/>
<template-type-parameter name="TN"/> <template-type-parameter name="TN"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/> <template-type-parameter name="Functor"/>
</template> </template>
<type>bool</type> <type>bool</type>
<parameter name="f"><paramtype>const <classname>functionN</classname>&lt;T1, T2, ..., TN&gt;&amp;</paramtype></parameter> <parameter name="f"><paramtype>const <classname>functionN</classname>&lt;T1, T2, ..., TN, Allocator&gt;&amp;</paramtype></parameter>
<parameter name="g"><paramtype><classname>reference_wrapper</classname>&lt;Functor&gt;</paramtype></parameter> <parameter name="g"><paramtype><classname>reference_wrapper</classname>&lt;Functor&gt;</paramtype></parameter>
</signature> </signature>
<signature> <signature>
@ -385,11 +373,12 @@
<template-type-parameter name="T2"/> <template-type-parameter name="T2"/>
<template-varargs/> <template-varargs/>
<template-type-parameter name="TN"/> <template-type-parameter name="TN"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/> <template-type-parameter name="Functor"/>
</template> </template>
<type>bool</type> <type>bool</type>
<parameter name="g"><paramtype><classname>reference_wrapper</classname>&lt;Functor&gt;</paramtype></parameter> <parameter name="g"><paramtype><classname>reference_wrapper</classname>&lt;Functor&gt;</paramtype></parameter>
<parameter name="f"><paramtype>const <classname>functionN</classname>&lt;T1, T2, ..., TN&gt;&amp;</paramtype></parameter> <parameter name="f"><paramtype>const <classname>functionN</classname>&lt;T1, T2, ..., TN, Allocator&gt;&amp;</paramtype></parameter>
</signature> </signature>
<signature> <signature>
<template> <template>
@ -397,14 +386,16 @@
<template-type-parameter name="T2"/> <template-type-parameter name="T2"/>
<template-varargs/> <template-varargs/>
<template-type-parameter name="TN"/> <template-type-parameter name="TN"/>
<template-type-parameter name="Allocator1"/>
<template-type-parameter name="U1"/> <template-type-parameter name="U1"/>
<template-type-parameter name="U2"/> <template-type-parameter name="U2"/>
<template-varargs/> <template-varargs/>
<template-type-parameter name="UN"/> <template-type-parameter name="UN"/>
<template-type-parameter name="Allocator2"/>
</template> </template>
<type>void</type> <type>void</type>
<parameter name="f1"><paramtype>const <classname>functionN</classname>&lt;T1, T2, ..., TN&gt;&amp;</paramtype></parameter> <parameter name="f1"><paramtype>const <classname>functionN</classname>&lt;T1, T2, ..., TN, Allocator1&gt;&amp;</paramtype></parameter>
<parameter name="f2"><paramtype>const <classname>functionN</classname>&lt;U1, U2, ..., UN&gt;&amp;</paramtype></parameter> <parameter name="f2"><paramtype>const <classname>functionN</classname>&lt;U1, U2, ..., UN, Allocator2&gt;&amp;</paramtype></parameter>
</signature> </signature>
<returns><simpara>True when <code>f</code> stores an object of <returns><simpara>True when <code>f</code> stores an object of
@ -444,10 +435,11 @@
<template-type-parameter name="T2"/> <template-type-parameter name="T2"/>
<template-varargs/> <template-varargs/>
<template-type-parameter name="TN"/> <template-type-parameter name="TN"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/> <template-type-parameter name="Functor"/>
</template> </template>
<type>bool</type> <type>bool</type>
<parameter name="f"><paramtype>const <classname>functionN</classname>&lt;T1, T2, ..., TN&gt;&amp;</paramtype></parameter> <parameter name="f"><paramtype>const <classname>functionN</classname>&lt;T1, T2, ..., TN, Allocator&gt;&amp;</paramtype></parameter>
<parameter name="g"><paramtype>Functor</paramtype></parameter> <parameter name="g"><paramtype>Functor</paramtype></parameter>
</signature> </signature>
<signature> <signature>
@ -456,11 +448,12 @@
<template-type-parameter name="T2"/> <template-type-parameter name="T2"/>
<template-varargs/> <template-varargs/>
<template-type-parameter name="TN"/> <template-type-parameter name="TN"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/> <template-type-parameter name="Functor"/>
</template> </template>
<type>bool</type> <type>bool</type>
<parameter name="g"><paramtype>Functor</paramtype></parameter> <parameter name="g"><paramtype>Functor</paramtype></parameter>
<parameter name="f"><paramtype>const <classname>functionN</classname>&lt;T1, T2, ..., TN&gt;&amp;</paramtype></parameter> <parameter name="f"><paramtype>const <classname>functionN</classname>&lt;T1, T2, ..., TN, Allocator&gt;&amp;</paramtype></parameter>
</signature> </signature>
<signature> <signature>
<template> <template>
@ -468,10 +461,11 @@
<template-type-parameter name="T2"/> <template-type-parameter name="T2"/>
<template-varargs/> <template-varargs/>
<template-type-parameter name="TN"/> <template-type-parameter name="TN"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/> <template-type-parameter name="Functor"/>
</template> </template>
<type>bool</type> <type>bool</type>
<parameter name="f"><paramtype>const <classname>functionN</classname>&lt;T1, T2, ..., TN&gt;&amp;</paramtype></parameter> <parameter name="f"><paramtype>const <classname>functionN</classname>&lt;T1, T2, ..., TN, Allocator&gt;&amp;</paramtype></parameter>
<parameter name="g"><paramtype><classname>reference_wrapper</classname>&lt;Functor&gt;</paramtype></parameter> <parameter name="g"><paramtype><classname>reference_wrapper</classname>&lt;Functor&gt;</paramtype></parameter>
</signature> </signature>
<signature> <signature>
@ -480,11 +474,12 @@
<template-type-parameter name="T2"/> <template-type-parameter name="T2"/>
<template-varargs/> <template-varargs/>
<template-type-parameter name="TN"/> <template-type-parameter name="TN"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/> <template-type-parameter name="Functor"/>
</template> </template>
<type>bool</type> <type>bool</type>
<parameter name="g"><paramtype><classname>reference_wrapper</classname>&lt;Functor&gt;</paramtype></parameter> <parameter name="g"><paramtype><classname>reference_wrapper</classname>&lt;Functor&gt;</paramtype></parameter>
<parameter name="f"><paramtype>const <classname>functionN</classname>&lt;T1, T2, ..., TN&gt;&amp;</paramtype></parameter> <parameter name="f"><paramtype>const <classname>functionN</classname>&lt;T1, T2, ..., TN, Allocator&gt;&amp;</paramtype></parameter>
</signature> </signature>
<signature> <signature>
<template> <template>
@ -492,14 +487,16 @@
<template-type-parameter name="T2"/> <template-type-parameter name="T2"/>
<template-varargs/> <template-varargs/>
<template-type-parameter name="TN"/> <template-type-parameter name="TN"/>
<template-type-parameter name="Allocator1"/>
<template-type-parameter name="U1"/> <template-type-parameter name="U1"/>
<template-type-parameter name="U2"/> <template-type-parameter name="U2"/>
<template-varargs/> <template-varargs/>
<template-type-parameter name="UN"/> <template-type-parameter name="UN"/>
<template-type-parameter name="Allocator2"/>
</template> </template>
<type>void</type> <type>void</type>
<parameter name="f1"><paramtype>const <classname>functionN</classname>&lt;T1, T2, ..., TN&gt;&amp;</paramtype></parameter> <parameter name="f1"><paramtype>const <classname>functionN</classname>&lt;T1, T2, ..., TN, Allocator1&gt;&amp;</paramtype></parameter>
<parameter name="f2"><paramtype>const <classname>functionN</classname>&lt;U1, U2, ..., UN&gt;&amp;</paramtype></parameter> <parameter name="f2"><paramtype>const <classname>functionN</classname>&lt;U1, U2, ..., UN, Allocator2&gt;&amp;</paramtype></parameter>
</signature> </signature>
<returns><simpara>True when <code>f</code> does not store an <returns><simpara>True when <code>f</code> does not store an
@ -539,8 +536,11 @@
<template-type-parameter name="Signature"> <template-type-parameter name="Signature">
<purpose>Function type R (T1, T2, ..., TN)</purpose> <purpose>Function type R (T1, T2, ..., TN)</purpose>
</template-type-parameter> </template-type-parameter>
<template-type-parameter name="Allocator">
<default><classname>std::allocator</classname>&lt;void&gt;</default>
</template-type-parameter>
</template> </template>
<inherit access="public"><classname>functionN</classname>&lt;R, T1, T2, ..., TN&gt;</inherit> <inherit access="public"><classname>functionN</classname>&lt;R, T1, T2, ..., TN, Allocator&gt;</inherit>
<purpose>A generalized function pointer that can be used for <purpose>A generalized function pointer that can be used for
callbacks or wrapping function objects.</purpose> callbacks or wrapping function objects.</purpose>
@ -562,6 +562,7 @@
</description> </description>
<typedef name="result_type"><type>R</type></typedef> <typedef name="result_type"><type>R</type></typedef>
<typedef name="allocator_type"><type>Allocator</type></typedef>
<typedef name="argument_type"> <typedef name="argument_type">
<type>T1</type><purpose>If N == 1</purpose> <type>T1</type><purpose>If N == 1</purpose>
</typedef> </typedef>
@ -625,19 +626,6 @@
<postconditions><simpara><code>*this</code> targets a copy of <code>f</code> if <code>f</code> is nonempty, or <code>this-&gt;<methodname>empty</methodname>()</code> if <code>f</code> is empty.</simpara></postconditions> <postconditions><simpara><code>*this</code> targets a copy of <code>f</code> if <code>f</code> is nonempty, or <code>this-&gt;<methodname>empty</methodname>()</code> if <code>f</code> is empty.</simpara></postconditions>
</constructor> </constructor>
<constructor>
<template>
<template-type-parameter name="F"/>
<template-type-parameter name="Allocator"/>
</template>
<parameter name="f"><paramtype>F</paramtype></parameter>
<parameter name="alloc"><paramtype>Allocator</paramtype></parameter>
<requires><simpara>F is a function object Callable from <code>this</code>, Allocator is an allocator. The copy constructor and destructor of Allocator shall not throw.</simpara></requires>
<postconditions><simpara><code>*this</code> targets a copy of <code>f</code> if <code>f</code> is nonempty, or <code>this-&gt;<methodname>empty</methodname>()</code> if <code>f</code> is empty.</simpara></postconditions>
<effects><simpara>If memory allocation is required, the given allocator (or a copy of it) will be used to allocate that memory.</simpara></effects>
</constructor>
<destructor> <destructor>
<effects><simpara>If <code>!this-&gt;<methodname>empty</methodname>()</code>, destroys the target of <code>this</code>.</simpara></effects> <effects><simpara>If <code>!this-&gt;<methodname>empty</methodname>()</code>, destroys the target of <code>this</code>.</simpara></effects>
@ -750,10 +738,11 @@
<function name="swap"> <function name="swap">
<template> <template>
<template-type-parameter name="Signature"/> <template-type-parameter name="Signature"/>
<template-type-parameter name="Allocator"/>
</template> </template>
<type>void</type> <type>void</type>
<parameter name="f1"><paramtype><classname>function</classname>&lt;Signature&gt;&amp;</paramtype></parameter> <parameter name="f1"><paramtype><classname>function</classname>&lt;Signature, Allocator&gt;&amp;</paramtype></parameter>
<parameter name="f2"><paramtype><classname>function</classname>&lt;Signature&gt;&amp;</paramtype></parameter> <parameter name="f2"><paramtype><classname>function</classname>&lt;Signature, Allocator&gt;&amp;</paramtype></parameter>
<effects><simpara><code>f1.<methodname>swap</methodname>(f2)</code></simpara></effects> <effects><simpara><code>f1.<methodname>swap</methodname>(f2)</code></simpara></effects>
</function> </function>
</free-function-group> </free-function-group>
@ -763,47 +752,53 @@
<signature> <signature>
<template> <template>
<template-type-parameter name="Signature"/> <template-type-parameter name="Signature"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/> <template-type-parameter name="Functor"/>
</template> </template>
<type>bool</type> <type>bool</type>
<parameter name="f"><paramtype>const <classname>function</classname>&lt;Signature&gt;&amp;</paramtype></parameter> <parameter name="f"><paramtype>const <classname>function</classname>&lt;Signature, Allocator&gt;&amp;</paramtype></parameter>
<parameter name="g"><paramtype>Functor</paramtype></parameter> <parameter name="g"><paramtype>Functor</paramtype></parameter>
</signature> </signature>
<signature> <signature>
<template> <template>
<template-type-parameter name="Signature"/> <template-type-parameter name="Signature"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/> <template-type-parameter name="Functor"/>
</template> </template>
<type>bool</type> <type>bool</type>
<parameter name="g"><paramtype>Functor</paramtype></parameter> <parameter name="g"><paramtype>Functor</paramtype></parameter>
<parameter name="f"><paramtype>const <classname>function</classname>&lt;Signature&gt;&amp;</paramtype></parameter> <parameter name="f"><paramtype>const <classname>function</classname>&lt;Signature, Allocator&gt;&amp;</paramtype></parameter>
</signature> </signature>
<signature> <signature>
<template> <template>
<template-type-parameter name="Signature"/> <template-type-parameter name="Signature"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/> <template-type-parameter name="Functor"/>
</template> </template>
<type>bool</type> <type>bool</type>
<parameter name="f"><paramtype>const <classname>function</classname>&lt;Signature&gt;&amp;</paramtype></parameter> <parameter name="f"><paramtype>const <classname>function</classname>&lt;Signature, Allocator&gt;&amp;</paramtype></parameter>
<parameter name="g"><paramtype><classname>reference_wrapper</classname>&lt;Functor&gt;</paramtype></parameter> <parameter name="g"><paramtype><classname>reference_wrapper</classname>&lt;Functor&gt;</paramtype></parameter>
</signature> </signature>
<signature> <signature>
<template> <template>
<template-type-parameter name="Signature"/> <template-type-parameter name="Signature"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/> <template-type-parameter name="Functor"/>
</template> </template>
<type>bool</type> <type>bool</type>
<parameter name="g"><paramtype><classname>reference_wrapper</classname>&lt;Functor&gt;</paramtype></parameter> <parameter name="g"><paramtype><classname>reference_wrapper</classname>&lt;Functor&gt;</paramtype></parameter>
<parameter name="f"><paramtype>const <classname>function</classname>&lt;Signature&gt;&amp;</paramtype></parameter> <parameter name="f"><paramtype>const <classname>function</classname>&lt;Signature, Allocator&gt;&amp;</paramtype></parameter>
</signature> </signature>
<signature> <signature>
<template> <template>
<template-type-parameter name="Signature1"/> <template-type-parameter name="Signature1"/>
<template-type-parameter name="Allocator1"/>
<template-type-parameter name="Signature2"/> <template-type-parameter name="Signature2"/>
<template-type-parameter name="Allocator2"/>
</template> </template>
<type>void</type> <type>void</type>
<parameter name="f1"><paramtype>const <classname>function</classname>&lt;Signature1&gt;&amp;</paramtype></parameter> <parameter name="f1"><paramtype>const <classname>function</classname>&lt;Signature1, Allocator1&gt;&amp;</paramtype></parameter>
<parameter name="f2"><paramtype>const <classname>function</classname>&lt;Signature2&gt;&amp;</paramtype></parameter> <parameter name="f2"><paramtype>const <classname>function</classname>&lt;Signature2, Allocator2&gt;&amp;</paramtype></parameter>
</signature> </signature>
<returns><simpara>True when <code>f</code> stores an object of <returns><simpara>True when <code>f</code> stores an object of
@ -838,47 +833,53 @@
<signature> <signature>
<template> <template>
<template-type-parameter name="Signature"/> <template-type-parameter name="Signature"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/> <template-type-parameter name="Functor"/>
</template> </template>
<type>bool</type> <type>bool</type>
<parameter name="f"><paramtype>const <classname>function</classname>&lt;Signature&gt;&amp;</paramtype></parameter> <parameter name="f"><paramtype>const <classname>function</classname>&lt;Signature, Allocator&gt;&amp;</paramtype></parameter>
<parameter name="g"><paramtype>Functor</paramtype></parameter> <parameter name="g"><paramtype>Functor</paramtype></parameter>
</signature> </signature>
<signature> <signature>
<template> <template>
<template-type-parameter name="Signature"/> <template-type-parameter name="Signature"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/> <template-type-parameter name="Functor"/>
</template> </template>
<type>bool</type> <type>bool</type>
<parameter name="g"><paramtype>Functor</paramtype></parameter> <parameter name="g"><paramtype>Functor</paramtype></parameter>
<parameter name="f"><paramtype>const <classname>function</classname>&lt;Signature&gt;&amp;</paramtype></parameter> <parameter name="f"><paramtype>const <classname>function</classname>&lt;Signature, Allocator&gt;&amp;</paramtype></parameter>
</signature> </signature>
<signature> <signature>
<template> <template>
<template-type-parameter name="Signature"/> <template-type-parameter name="Signature"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/> <template-type-parameter name="Functor"/>
</template> </template>
<type>bool</type> <type>bool</type>
<parameter name="f"><paramtype>const <classname>function</classname>&lt;Signature&gt;&amp;</paramtype></parameter> <parameter name="f"><paramtype>const <classname>function</classname>&lt;Signature, Allocator&gt;&amp;</paramtype></parameter>
<parameter name="g"><paramtype><classname>reference_wrapper</classname>&lt;Functor&gt;</paramtype></parameter> <parameter name="g"><paramtype><classname>reference_wrapper</classname>&lt;Functor&gt;</paramtype></parameter>
</signature> </signature>
<signature> <signature>
<template> <template>
<template-type-parameter name="Signature"/> <template-type-parameter name="Signature"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/> <template-type-parameter name="Functor"/>
</template> </template>
<type>bool</type> <type>bool</type>
<parameter name="g"><paramtype><classname>reference_wrapper</classname>&lt;Functor&gt;</paramtype></parameter> <parameter name="g"><paramtype><classname>reference_wrapper</classname>&lt;Functor&gt;</paramtype></parameter>
<parameter name="f"><paramtype>const <classname>function</classname>&lt;Signature&gt;&amp;</paramtype></parameter> <parameter name="f"><paramtype>const <classname>function</classname>&lt;Signature, Allocator&gt;&amp;</paramtype></parameter>
</signature> </signature>
<signature> <signature>
<template> <template>
<template-type-parameter name="Signature1"/> <template-type-parameter name="Signature1"/>
<template-type-parameter name="Allocator1"/>
<template-type-parameter name="Signature2"/> <template-type-parameter name="Signature2"/>
<template-type-parameter name="Allocator2"/>
</template> </template>
<type>void</type> <type>void</type>
<parameter name="f1"><paramtype>const <classname>function</classname>&lt;Signature1&gt;&amp;</paramtype></parameter> <parameter name="f1"><paramtype>const <classname>function</classname>&lt;Signature1, Allocator1&gt;&amp;</paramtype></parameter>
<parameter name="f2"><paramtype>const <classname>function</classname>&lt;Signature2&gt;&amp;</paramtype></parameter> <parameter name="f2"><paramtype>const <classname>function</classname>&lt;Signature2, Allocator2&gt;&amp;</paramtype></parameter>
</signature> </signature>
<returns><simpara>True when <code>f</code> does not store an <returns><simpara>True when <code>f</code> does not store an

View File

@ -1,11 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2002 Douglas Gregor <doug.gregor -at- gmail.com>
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
-->
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd"> "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
<testsuite id="function.testsuite" last-revision="$Date$"> <testsuite id="function.testsuite" last-revision="$Date$">

View File

@ -1,11 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) 2002 Douglas Gregor <doug.gregor -at- gmail.com>
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
-->
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd"> "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
<section xmlns:xi="http://www.w3.org/2001/XInclude" id="function.tutorial" <section xmlns:xi="http://www.w3.org/2001/XInclude" id="function.tutorial"

View File

@ -11,7 +11,7 @@
#define BOOST_FUNCTION_PROLOGUE_HPP #define BOOST_FUNCTION_PROLOGUE_HPP
# include <cassert> # include <cassert>
# include <algorithm> # include <algorithm>
# include <boost/config/no_tr1/functional.hpp> // unary_function, binary_function # include <functional> // unary_function, binary_function
# include <boost/throw_exception.hpp> # include <boost/throw_exception.hpp>
# include <boost/config.hpp> # include <boost/config.hpp>
# include <boost/function/function_base.hpp> # include <boost/function/function_base.hpp>
@ -22,5 +22,4 @@
# include <boost/preprocessor/cat.hpp> # include <boost/preprocessor/cat.hpp>
# include <boost/preprocessor/repeat.hpp> # include <boost/preprocessor/repeat.hpp>
# include <boost/preprocessor/inc.hpp> # include <boost/preprocessor/inc.hpp>
# include <boost/type_traits/is_void.hpp>
#endif // BOOST_FUNCTION_PROLOGUE_HPP #endif // BOOST_FUNCTION_PROLOGUE_HPP

View File

@ -1,9 +1,8 @@
// Boost.Function library // Boost.Function library
// Copyright Douglas Gregor 2001-2006 // Copyright Douglas Gregor 2001-2006. Use, modification and
// Copyright Emil Dotchevski 2007 // distribution is subject to the Boost Software License, Version
// Use, modification and distribution is subject to the Boost Software License, Version 1.0. // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
// For more information, see http://www.boost.org // For more information, see http://www.boost.org
@ -31,12 +30,6 @@
#endif #endif
#include <boost/function_equal.hpp> #include <boost/function_equal.hpp>
#if defined(BOOST_MSVC)
# pragma warning( push )
# pragma warning( disable : 4793 ) // complaint about native code generation
# pragma warning( disable : 4127 ) // "conditional expression is constant"
#endif
// Define BOOST_FUNCTION_STD_NS to the namespace that contains type_info. // Define BOOST_FUNCTION_STD_NS to the namespace that contains type_info.
#ifdef BOOST_NO_EXCEPTION_STD_NAMESPACE #ifdef BOOST_NO_EXCEPTION_STD_NAMESPACE
// Embedded VC++ does not have type_info in namespace std // Embedded VC++ does not have type_info in namespace std
@ -74,7 +67,7 @@ namespace boost { namespace python { namespace objects {
#if defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ #if defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|| defined(BOOST_BCB_PARTIAL_SPECIALIZATION_BUG) \ || defined(BOOST_BCB_PARTIAL_SPECIALIZATION_BUG) \
|| !(BOOST_STRICT_CONFIG || !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x540) || !(defined(BOOST_STRICT_CONFIG) || !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x540)
# define BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX # define BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX
#endif #endif
@ -95,12 +88,21 @@ namespace boost { namespace python { namespace objects {
#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX) #if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
namespace boost { namespace boost {
template<typename Signature> #if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730 && !defined(BOOST_STRICT_CONFIG)
class function; // The library shipping with MIPSpro 7.3.1.3m has a broken allocator<void>
class function_base;
template<typename Signature> template<typename Signature,
inline void swap(function<Signature>& f1, typename Allocator = std::allocator<function_base> >
function<Signature>& f2) class function;
#else
template<typename Signature, typename Allocator = std::allocator<void> >
class function;
#endif
template<typename Signature, typename Allocator>
inline void swap(function<Signature, Allocator>& f1,
function<Signature, Allocator>& f2)
{ {
f1.swap(f2); f1.swap(f2);
} }
@ -251,29 +253,20 @@ namespace boost {
% alignment_of<F>::value == 0)))); % alignment_of<F>::value == 0))));
}; };
template <typename F,typename A>
struct functor_wrapper: public F, public A
{
functor_wrapper( F f, A a ):
F(f),
A(a)
{
}
};
/** /**
* 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.
*/ */
template<typename Functor> template<typename Functor, typename Allocator>
struct functor_manager_common struct functor_manager
{ {
private:
typedef Functor functor_type; typedef Functor functor_type;
// Function pointers // For function pointers, the manager is trivial
static inline void static inline void
manage_ptr(const function_buffer& in_buffer, function_buffer& out_buffer, manager(const function_buffer& in_buffer, function_buffer& out_buffer,
functor_manager_operation_type op) functor_manager_operation_type op, function_ptr_tag)
{ {
if (op == clone_functor_tag) if (op == clone_functor_tag)
out_buffer.func_ptr = in_buffer.func_ptr; out_buffer.func_ptr = in_buffer.func_ptr;
@ -291,8 +284,8 @@ namespace boost {
// Function objects that fit in the small-object buffer. // Function objects that fit in the small-object buffer.
static inline void static inline void
manage_small(const function_buffer& in_buffer, function_buffer& out_buffer, manager(const function_buffer& in_buffer, function_buffer& out_buffer,
functor_manager_operation_type op) functor_manager_operation_type op, mpl::true_)
{ {
if (op == clone_functor_tag) { if (op == clone_functor_tag) {
const functor_type* in_functor = const functor_type* in_functor =
@ -310,142 +303,57 @@ namespace boost {
out_buffer.obj_ptr = 0; out_buffer.obj_ptr = 0;
} }
} }
};
template<typename Functor>
struct functor_manager
{
private:
typedef Functor functor_type;
// Function pointers
static inline void
manager(const function_buffer& in_buffer, function_buffer& out_buffer,
functor_manager_operation_type op, function_ptr_tag)
{
functor_manager_common<Functor>::manage_ptr(in_buffer,out_buffer,op);
}
// Function objects that fit in the small-object buffer.
static inline void
manager(const function_buffer& in_buffer, function_buffer& out_buffer,
functor_manager_operation_type op, mpl::true_)
{
functor_manager_common<Functor>::manage_small(in_buffer,out_buffer,op);
}
// Function objects that require heap allocation // Function objects that require heap allocation
static inline void static inline void
manager(const function_buffer& in_buffer, function_buffer& out_buffer, manager(const function_buffer& in_buffer, function_buffer& out_buffer,
functor_manager_operation_type op, mpl::false_) functor_manager_operation_type op, mpl::false_)
{ {
#ifndef BOOST_NO_STD_ALLOCATOR
typedef typename Allocator::template rebind<functor_type>::other
allocator_type;
typedef typename allocator_type::pointer pointer_type;
#else
typedef functor_type* pointer_type;
#endif // BOOST_NO_STD_ALLOCATOR
# ifndef BOOST_NO_STD_ALLOCATOR
allocator_type allocator;
# endif // BOOST_NO_STD_ALLOCATOR
if (op == clone_functor_tag) { if (op == clone_functor_tag) {
// Clone the functor
// GCC 2.95.3 gets the CV qualifiers wrong here, so we // GCC 2.95.3 gets the CV qualifiers wrong here, so we
// can't do the static_cast that we should do. // can't do the static_cast that we should do.
const functor_type* f = const functor_type* f =
(const functor_type*)(in_buffer.obj_ptr); (const functor_type*)(in_buffer.obj_ptr);
// Clone the functor
# ifndef BOOST_NO_STD_ALLOCATOR
pointer_type copy = allocator.allocate(1);
allocator.construct(copy, *f);
// Get back to the original pointer type
functor_type* new_f = static_cast<functor_type*>(copy);
# else
functor_type* new_f = new functor_type(*f); functor_type* new_f = new functor_type(*f);
# endif // BOOST_NO_STD_ALLOCATOR
out_buffer.obj_ptr = new_f; out_buffer.obj_ptr = new_f;
} else if (op == destroy_functor_tag) { } else if (op == destroy_functor_tag) {
/* Cast from the void pointer to the functor pointer type */ /* Cast from the void pointer to the functor pointer type */
functor_type* f = functor_type* f =
static_cast<functor_type*>(out_buffer.obj_ptr); static_cast<functor_type*>(out_buffer.obj_ptr);
# ifndef BOOST_NO_STD_ALLOCATOR
/* Cast from the functor pointer type to the allocator's pointer
type */
pointer_type victim = static_cast<pointer_type>(f);
// Destroy and deallocate the functor
allocator.destroy(victim);
allocator.deallocate(victim, 1);
# else
delete f; delete f;
out_buffer.obj_ptr = 0; # endif // BOOST_NO_STD_ALLOCATOR
} else /* op == check_functor_type_tag */ {
const BOOST_FUNCTION_STD_NS::type_info& check_type =
*static_cast<const BOOST_FUNCTION_STD_NS::type_info*>(out_buffer.const_obj_ptr);
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor)))
out_buffer.obj_ptr = in_buffer.obj_ptr;
else
out_buffer.obj_ptr = 0;
}
}
// For function objects, we determine whether the function
// object can use the small-object optimization buffer or
// whether we need to allocate it on the heap.
static inline void
manager(const function_buffer& in_buffer, function_buffer& out_buffer,
functor_manager_operation_type op, function_obj_tag)
{
manager(in_buffer, out_buffer, op,
mpl::bool_<(function_allows_small_object_optimization<functor_type>::value)>());
}
public:
/* Dispatch to an appropriate manager based on whether we have a
function pointer or a function object pointer. */
static inline void
manage(const function_buffer& in_buffer, function_buffer& out_buffer,
functor_manager_operation_type op)
{
typedef typename get_function_tag<functor_type>::type tag_type;
switch (op) {
case get_functor_type_tag:
out_buffer.const_obj_ptr = &typeid(functor_type);
return;
default:
manager(in_buffer, out_buffer, op, tag_type());
return;
}
}
};
template<typename Functor, typename Allocator>
struct functor_manager_a
{
private:
typedef Functor functor_type;
// Function pointers
static inline void
manager(const function_buffer& in_buffer, function_buffer& out_buffer,
functor_manager_operation_type op, function_ptr_tag)
{
functor_manager_common<Functor>::manage_ptr(in_buffer,out_buffer,op);
}
// Function objects that fit in the small-object buffer.
static inline void
manager(const function_buffer& in_buffer, function_buffer& out_buffer,
functor_manager_operation_type op, mpl::true_)
{
functor_manager_common<Functor>::manage_small(in_buffer,out_buffer,op);
}
// Function objects that require heap allocation
static inline void
manager(const function_buffer& in_buffer, function_buffer& out_buffer,
functor_manager_operation_type op, mpl::false_)
{
typedef functor_wrapper<Functor,Allocator> functor_wrapper_type;
typedef typename Allocator::template rebind<functor_wrapper_type>::other
wrapper_allocator_type;
typedef typename wrapper_allocator_type::pointer wrapper_allocator_pointer_type;
if (op == clone_functor_tag) {
// Clone the functor
// GCC 2.95.3 gets the CV qualifiers wrong here, so we
// can't do the static_cast that we should do.
const functor_wrapper_type* f =
(const functor_wrapper_type*)(in_buffer.obj_ptr);
wrapper_allocator_type wrapper_allocator(static_cast<Allocator const &>(*f));
wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1);
wrapper_allocator.construct(copy, *f);
// Get back to the original pointer type
functor_wrapper_type* new_f = static_cast<functor_wrapper_type*>(copy);
out_buffer.obj_ptr = new_f;
} else if (op == destroy_functor_tag) {
/* Cast from the void pointer to the functor_wrapper_type */
functor_wrapper_type* victim =
static_cast<functor_wrapper_type*>(in_buffer.obj_ptr);
wrapper_allocator_type wrapper_allocator(static_cast<Allocator const &>(*victim));
wrapper_allocator.destroy(victim);
wrapper_allocator.deallocate(victim,1);
out_buffer.obj_ptr = 0; out_buffer.obj_ptr = 0;
} else /* op == check_functor_type_tag */ { } else /* op == check_functor_type_tag */ {
const BOOST_FUNCTION_STD_NS::type_info& check_type = const BOOST_FUNCTION_STD_NS::type_info& check_type =

View File

@ -1,9 +1,8 @@
// Boost.Function library // Boost.Function library
// Copyright Douglas Gregor 2001-2006 // Copyright Douglas Gregor 2001-2006. Use, modification and
// Copyright Emil Dotchevski 2007 // distribution is subject to the Boost Software License, Version
// Use, modification and distribution is subject to the Boost Software License, Version 1.0. // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
// For more information, see http://www.boost.org // For more information, see http://www.boost.org
@ -12,11 +11,6 @@
// protection. // protection.
#include <boost/function/detail/prologue.hpp> #include <boost/function/detail/prologue.hpp>
#if defined(BOOST_MSVC)
# pragma warning( push )
# pragma warning( disable : 4127 ) // "conditional expression is constant"
#endif
#define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T) #define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T)
#define BOOST_FUNCTION_TEMPLATE_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, T) #define BOOST_FUNCTION_TEMPLATE_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, T)
@ -32,6 +26,13 @@
#define BOOST_FUNCTION_ARG_TYPES BOOST_PP_REPEAT(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG_TYPE,BOOST_PP_EMPTY) #define BOOST_FUNCTION_ARG_TYPES BOOST_PP_REPEAT(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG_TYPE,BOOST_PP_EMPTY)
// 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
@ -246,7 +247,8 @@ namespace boost {
/** /**
* vtable for a specific boost::function instance. * vtable for a specific boost::function instance.
*/ */
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS> template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
typename Allocator>
struct BOOST_FUNCTION_VTABLE : vtable_base struct BOOST_FUNCTION_VTABLE : vtable_base
{ {
#ifndef BOOST_NO_VOID_RETURNS #ifndef BOOST_NO_VOID_RETURNS
@ -264,11 +266,6 @@ namespace boost {
{ {
init(f); init(f);
} }
template<typename F,typename Allocator>
BOOST_FUNCTION_VTABLE(F f, Allocator) : vtable_base(), invoker(0)
{
init_a<Allocator>(f);
}
template<typename F> template<typename F>
bool assign_to(F f, function_buffer& functor) bool assign_to(F f, function_buffer& functor)
@ -276,12 +273,6 @@ namespace boost {
typedef typename get_function_tag<F>::type tag; typedef typename get_function_tag<F>::type tag;
return assign_to(f, functor, tag()); return assign_to(f, functor, tag());
} }
template<typename F,typename Allocator>
bool assign_to_a(F f, function_buffer& functor, Allocator a)
{
typedef typename get_function_tag<F>::type tag;
return assign_to_a(f, functor, a, tag());
}
void clear(function_buffer& functor) void clear(function_buffer& functor)
{ {
@ -296,12 +287,6 @@ namespace boost {
typedef typename get_function_tag<F>::type tag; typedef typename get_function_tag<F>::type tag;
init(f, tag()); init(f, tag());
} }
template<typename Allocator,typename F>
void init_a(F f)
{
typedef typename get_function_tag<F>::type tag;
init_a<Allocator>(f, tag());
}
// Function pointers // Function pointers
template<typename FunctionPtr> template<typename FunctionPtr>
@ -315,20 +300,7 @@ namespace boost {
actual_invoker_type; actual_invoker_type;
invoker = &actual_invoker_type::invoke; invoker = &actual_invoker_type::invoke;
manager = &functor_manager<FunctionPtr>::manage; manager = &functor_manager<FunctionPtr, Allocator>::manage;
}
template<typename Allocator,typename FunctionPtr>
void init_a(FunctionPtr f, function_ptr_tag)
{
typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER<
FunctionPtr,
R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS
>::type
actual_invoker_type;
invoker = &actual_invoker_type::invoke;
manager = &functor_manager_a<FunctionPtr, Allocator>::manage;
} }
template<typename FunctionPtr> template<typename FunctionPtr>
@ -345,12 +317,6 @@ namespace boost {
return false; return false;
} }
} }
template<typename FunctionPtr,typename Allocator>
bool
assign_to_a(FunctionPtr f, function_buffer& functor, Allocator, function_ptr_tag)
{
return assign_to(f,functor,function_ptr_tag());
}
// Member pointers // Member pointers
#if BOOST_FUNCTION_NUM_ARGS > 0 #if BOOST_FUNCTION_NUM_ARGS > 0
@ -362,14 +328,6 @@ namespace boost {
// right target_type() values. // right target_type() values.
this->init(mem_fn(f)); this->init(mem_fn(f));
} }
template<typename Allocator,typename MemberPtr>
void init_a(MemberPtr f, member_ptr_tag)
{
// DPG TBD: Add explicit support for member function
// objects, so we invoke through mem_fn() but we retain the
// right target_type() values.
this->init_a<Allocator>(mem_fn(f));
}
template<typename MemberPtr> template<typename MemberPtr>
bool assign_to(MemberPtr f, function_buffer& functor, member_ptr_tag) bool assign_to(MemberPtr f, function_buffer& functor, member_ptr_tag)
@ -384,19 +342,6 @@ namespace boost {
return false; return false;
} }
} }
template<typename MemberPtr,typename Allocator>
bool assign_to_a(MemberPtr f, function_buffer& functor, Allocator a, member_ptr_tag)
{
// DPG TBD: Add explicit support for member function
// objects, so we invoke through mem_fn() but we retain the
// right target_type() values.
if (f) {
this->assign_to_a(mem_fn(f), functor, a);
return true;
} else {
return false;
}
}
#endif // BOOST_FUNCTION_NUM_ARGS > 0 #endif // BOOST_FUNCTION_NUM_ARGS > 0
// Function objects // Function objects
@ -411,20 +356,7 @@ namespace boost {
actual_invoker_type; actual_invoker_type;
invoker = &actual_invoker_type::invoke; invoker = &actual_invoker_type::invoke;
manager = &functor_manager<FunctionObj>::manage; manager = &functor_manager<FunctionObj, Allocator>::manage;
}
template<typename Allocator,typename FunctionObj>
void init_a(FunctionObj /*f*/, function_obj_tag)
{
typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER<
FunctionObj,
R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS
>::type
actual_invoker_type;
invoker = &actual_invoker_type::invoke;
manager = &functor_manager_a<FunctionObj, Allocator>::manage;
} }
// Assign to a function object using the small object optimization // Assign to a function object using the small object optimization
@ -434,33 +366,26 @@ namespace boost {
{ {
new ((void*)&functor.data) FunctionObj(f); new ((void*)&functor.data) FunctionObj(f);
} }
template<typename FunctionObj,typename Allocator>
void
assign_functor_a(FunctionObj f, function_buffer& functor, Allocator, mpl::true_)
{
assign_functor(f,functor,mpl::true_());
}
// Assign to a function object allocated on the heap. // Assign to a function object allocated on the heap.
template<typename FunctionObj> template<typename FunctionObj>
void void
assign_functor(FunctionObj f, function_buffer& functor, mpl::false_) assign_functor(FunctionObj f, function_buffer& functor, mpl::false_)
{ {
#ifndef BOOST_NO_STD_ALLOCATOR
typedef typename Allocator::template rebind<FunctionObj>::other
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
functor.obj_ptr = static_cast<FunctionObj*>(copy);
# else
functor.obj_ptr = new FunctionObj(f); functor.obj_ptr = new FunctionObj(f);
} # endif // BOOST_NO_STD_ALLOCATOR
template<typename FunctionObj,typename Allocator>
void
assign_functor_a(FunctionObj f, function_buffer& functor, Allocator a, mpl::false_)
{
typedef functor_wrapper<FunctionObj,Allocator> functor_wrapper_type;
typedef typename Allocator::template rebind<functor_wrapper_type>::other
wrapper_allocator_type;
typedef typename wrapper_allocator_type::pointer wrapper_allocator_pointer_type;
wrapper_allocator_type wrapper_allocator(a);
wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1);
wrapper_allocator.construct(copy, functor_wrapper_type(f,a));
functor_wrapper_type* new_f = static_cast<functor_wrapper_type*>(copy);
functor.obj_ptr = new_f;
} }
template<typename FunctionObj> template<typename FunctionObj>
@ -475,18 +400,6 @@ namespace boost {
return false; return false;
} }
} }
template<typename FunctionObj,typename Allocator>
bool
assign_to_a(FunctionObj f, function_buffer& functor, Allocator a, function_obj_tag)
{
if (!boost::detail::function::has_empty_target(boost::addressof(f))) {
assign_functor_a(f, functor, a,
mpl::bool_<(function_allows_small_object_optimization<FunctionObj>::value)>());
return true;
} else {
return false;
}
}
// Reference to a function object // Reference to a function object
template<typename FunctionObj> template<typename FunctionObj>
@ -503,12 +416,6 @@ namespace boost {
invoker = &actual_invoker_type::invoke; invoker = &actual_invoker_type::invoke;
manager = &reference_manager<FunctionObj>::get; manager = &reference_manager<FunctionObj>::get;
} }
template<typename Allocator,typename FunctionObj>
void
init_a(const reference_wrapper<FunctionObj>& f, function_obj_ref_tag)
{
init(f,function_obj_ref_tag());
}
template<typename FunctionObj> template<typename FunctionObj>
bool bool
@ -526,13 +433,6 @@ namespace boost {
return false; return false;
} }
} }
template<typename FunctionObj,typename Allocator>
bool
assign_to_a(const reference_wrapper<FunctionObj>& f,
function_buffer& functor, Allocator, function_obj_ref_tag)
{
return assign_to(f,functor,function_obj_ref_tag());
}
public: public:
invoker_type invoker; invoker_type invoker;
@ -542,7 +442,8 @@ namespace boost {
template< template<
typename R BOOST_FUNCTION_COMMA typename R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_PARMS BOOST_FUNCTION_TEMPLATE_PARMS,
typename Allocator = BOOST_FUNCTION_DEFAULT_ALLOCATOR
> >
class BOOST_FUNCTION_FUNCTION : public function_base class BOOST_FUNCTION_FUNCTION : public function_base
@ -567,7 +468,7 @@ namespace boost {
private: private:
typedef boost::detail::function::BOOST_FUNCTION_VTABLE< typedef boost::detail::function::BOOST_FUNCTION_VTABLE<
R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS, Allocator>
vtable_type; vtable_type;
struct clear_type {}; struct clear_type {};
@ -592,6 +493,7 @@ namespace boost {
BOOST_STATIC_CONSTANT(int, arity = BOOST_FUNCTION_NUM_ARGS); BOOST_STATIC_CONSTANT(int, arity = BOOST_FUNCTION_NUM_ARGS);
BOOST_FUNCTION_ARG_TYPES BOOST_FUNCTION_ARG_TYPES
typedef Allocator allocator_type;
typedef BOOST_FUNCTION_FUNCTION self_type; typedef BOOST_FUNCTION_FUNCTION self_type;
BOOST_FUNCTION_FUNCTION() : function_base() { } BOOST_FUNCTION_FUNCTION() : function_base() { }
@ -611,19 +513,6 @@ namespace boost {
{ {
this->assign_to(f); this->assign_to(f);
} }
template<typename Functor,typename Allocator>
BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a
#ifndef BOOST_NO_SFINAE
,typename enable_if_c<
(boost::type_traits::ice_not<
(is_integral<Functor>::value)>::value),
int>::type = 0
#endif // BOOST_NO_SFINAE
) :
function_base()
{
this->assign_to_a(f,a);
}
#ifndef BOOST_NO_SFINAE #ifndef BOOST_NO_SFINAE
BOOST_FUNCTION_FUNCTION(clear_type*) : function_base() { } BOOST_FUNCTION_FUNCTION(clear_type*) : function_base() { }
@ -681,17 +570,6 @@ namespace boost {
} }
return *this; return *this;
} }
template<typename Functor,typename Allocator>
void assign(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a)
{
this->clear();
try {
this->assign_to_a(f,a);
} catch (...) {
vtable = 0;
throw;
}
}
#ifndef BOOST_NO_SFINAE #ifndef BOOST_NO_SFINAE
BOOST_FUNCTION_FUNCTION& operator=(clear_type*) BOOST_FUNCTION_FUNCTION& operator=(clear_type*)
@ -779,33 +657,33 @@ namespace boost {
if (stored_vtable.assign_to(f, functor)) vtable = &stored_vtable; if (stored_vtable.assign_to(f, functor)) vtable = &stored_vtable;
else vtable = 0; else vtable = 0;
} }
template<typename Functor,typename Allocator>
void assign_to_a(Functor f,Allocator a)
{
static vtable_type stored_vtable(f,a);
if (stored_vtable.assign_to_a(f, functor, a)) vtable = &stored_vtable;
else vtable = 0;
}
}; };
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS> template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
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 ,
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,
Allocator
>& f2) >& f2)
{ {
f1.swap(f2); f1.swap(f2);
} }
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS> template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS,
typename Allocator>
typename BOOST_FUNCTION_FUNCTION< typename BOOST_FUNCTION_FUNCTION<
R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>::result_type R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS,
BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> Allocator>::result_type
BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS,
Allocator>
::operator()(BOOST_FUNCTION_PARMS) const ::operator()(BOOST_FUNCTION_PARMS) const
{ {
if (this->empty()) if (this->empty())
@ -817,20 +695,26 @@ namespace boost {
#endif #endif
// Poison comparisons between boost::function objects of the same type. // Poison comparisons between boost::function objects of the same type.
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS> template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
typename Allocator>
void operator==(const BOOST_FUNCTION_FUNCTION< void operator==(const BOOST_FUNCTION_FUNCTION<
R BOOST_FUNCTION_COMMA R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS>&, BOOST_FUNCTION_TEMPLATE_ARGS ,
Allocator>&,
const BOOST_FUNCTION_FUNCTION< const BOOST_FUNCTION_FUNCTION<
R BOOST_FUNCTION_COMMA R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS>&); BOOST_FUNCTION_TEMPLATE_ARGS ,
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS> Allocator>&);
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
typename Allocator>
void operator!=(const BOOST_FUNCTION_FUNCTION< void operator!=(const BOOST_FUNCTION_FUNCTION<
R BOOST_FUNCTION_COMMA R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS>&, BOOST_FUNCTION_TEMPLATE_ARGS ,
Allocator>&,
const BOOST_FUNCTION_FUNCTION< const BOOST_FUNCTION_FUNCTION<
R BOOST_FUNCTION_COMMA R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS>& ); BOOST_FUNCTION_TEMPLATE_ARGS ,
Allocator>&);
#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX) #if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
@ -841,16 +725,20 @@ template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
#endif #endif
template<typename R BOOST_FUNCTION_COMMA template<typename R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_PARMS> BOOST_FUNCTION_TEMPLATE_PARMS,
class function<BOOST_FUNCTION_PARTIAL_SPEC> typename Allocator>
: public BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> class function<BOOST_FUNCTION_PARTIAL_SPEC, Allocator>
: public BOOST_FUNCTION_FUNCTION<R, BOOST_FUNCTION_TEMPLATE_ARGS
BOOST_FUNCTION_COMMA Allocator>
{ {
typedef BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> base_type; typedef BOOST_FUNCTION_FUNCTION<R, BOOST_FUNCTION_TEMPLATE_ARGS
BOOST_FUNCTION_COMMA Allocator> base_type;
typedef function self_type; typedef function self_type;
struct clear_type {}; struct clear_type {};
public: public:
typedef typename base_type::allocator_type allocator_type;
function() : base_type() {} function() : base_type() {}
@ -866,18 +754,6 @@ public:
base_type(f) base_type(f)
{ {
} }
template<typename Functor,typename Allocator>
function(Functor f, Allocator a
#ifndef BOOST_NO_SFINAE
,typename enable_if_c<
(boost::type_traits::ice_not<
(is_integral<Functor>::value)>::value),
int>::type = 0
#endif
) :
base_type(f,a)
{
}
#ifndef BOOST_NO_SFINAE #ifndef BOOST_NO_SFINAE
function(clear_type*) : base_type() {} function(clear_type*) : base_type() {}
@ -930,6 +806,7 @@ public:
// Cleanup after ourselves... // Cleanup after ourselves...
#undef BOOST_FUNCTION_VTABLE #undef BOOST_FUNCTION_VTABLE
#undef BOOST_FUNCTION_DEFAULT_ALLOCATOR
#undef BOOST_FUNCTION_COMMA #undef BOOST_FUNCTION_COMMA
#undef BOOST_FUNCTION_FUNCTION #undef BOOST_FUNCTION_FUNCTION
#undef BOOST_FUNCTION_FUNCTION_INVOKER #undef BOOST_FUNCTION_FUNCTION_INVOKER
@ -951,7 +828,3 @@ public:
#undef BOOST_FUNCTION_ARG_TYPES #undef BOOST_FUNCTION_ARG_TYPES
#undef BOOST_FUNCTION_VOID_RETURN_TYPE #undef BOOST_FUNCTION_VOID_RETURN_TYPE
#undef BOOST_FUNCTION_RETURN #undef BOOST_FUNCTION_RETURN
#if defined(BOOST_MSVC)
# pragma warning( pop )
#endif

View File

@ -1,11 +1,4 @@
<html> <html>
<!--
Copyright (c) 2002 Douglas Gregor <doug.gregor -at- gmail.com>
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
-->
<head> <head>
<meta http-equiv="refresh" content="0; URL=../../doc/html/function.html"> <meta http-equiv="refresh" content="0; URL=../../doc/html/function.html">
</head> </head>

View File

@ -27,14 +27,6 @@ struct counting_allocator : public std::allocator<T>
typedef counting_allocator<U> other; typedef counting_allocator<U> other;
}; };
counting_allocator()
{
}
template<typename U>
counting_allocator( counting_allocator<U> )
{
}
T* allocate(std::size_t n) T* allocate(std::size_t n)
{ {
@ -49,27 +41,20 @@ struct counting_allocator : public std::allocator<T>
} }
}; };
struct enable_small_object_optimization struct plus_int
{
};
struct disable_small_object_optimization
{
int unused_state_data[32];
};
template <typename base>
struct plus_int: base
{ {
int operator()(int x, int y) const { return x + y; } int operator()(int x, int y) const { return x + y; }
int unused_state_data[32];
}; };
static int do_minus(int x, int y) { return x-y; } static int do_minus(int x, int y) { return x-y; }
template <typename base> struct DoNothing
struct DoNothing: base
{ {
void operator()() const {} void operator()() const {}
int unused_state_data[32];
}; };
static void do_nothing() {} static void do_nothing() {}
@ -77,57 +62,33 @@ static void do_nothing() {}
int int
test_main(int, char*[]) test_main(int, char*[])
{ {
function2<int, int, int> f; function2<int, int, int, counting_allocator<int> > f;
f.assign( plus_int<disable_small_object_optimization>(), counting_allocator<int>() ); f = plus_int();
f.clear(); f.clear();
BOOST_CHECK(alloc_count == 1); BOOST_CHECK(alloc_count == 1);
BOOST_CHECK(dealloc_count == 1); BOOST_CHECK(dealloc_count == 1);
alloc_count = 0;
dealloc_count = 0;
f.assign( plus_int<enable_small_object_optimization>(), counting_allocator<int>() );
f.clear();
BOOST_CHECK(alloc_count == 0);
BOOST_CHECK(dealloc_count == 0);
f.assign( plus_int<disable_small_object_optimization>(), std::allocator<int>() );
f.clear();
f.assign( plus_int<enable_small_object_optimization>(), std::allocator<int>() );
f.clear();
alloc_count = 0; alloc_count = 0;
dealloc_count = 0; dealloc_count = 0;
f.assign( &do_minus, counting_allocator<int>() ); f = &do_minus;
f.clear(); f.clear();
BOOST_CHECK(alloc_count == 0); BOOST_CHECK(alloc_count == 0);
BOOST_CHECK(dealloc_count == 0); BOOST_CHECK(dealloc_count == 0);
f.assign( &do_minus, std::allocator<int>() );
f.clear();
function0<void> fv; function0<void, counting_allocator<int> > fv;
alloc_count = 0; alloc_count = 0;
dealloc_count = 0; dealloc_count = 0;
fv.assign( DoNothing<disable_small_object_optimization>(), counting_allocator<int>() ); fv = DoNothing();
fv.clear(); fv.clear();
BOOST_CHECK(alloc_count == 1); BOOST_CHECK(alloc_count == 1);
BOOST_CHECK(dealloc_count == 1); BOOST_CHECK(dealloc_count == 1);
alloc_count = 0;
dealloc_count = 0;
fv.assign( DoNothing<enable_small_object_optimization>(), counting_allocator<int>() );
fv.clear();
BOOST_CHECK(alloc_count == 0);
BOOST_CHECK(dealloc_count == 0);
fv.assign( DoNothing<disable_small_object_optimization>(), std::allocator<int>() );
fv.clear();
fv.assign( DoNothing<enable_small_object_optimization>(), std::allocator<int>() );
fv.clear();
alloc_count = 0; alloc_count = 0;
dealloc_count = 0; dealloc_count = 0;
fv.assign( &do_nothing, counting_allocator<int>() ); fv = &do_nothing;
fv.clear(); fv.clear();
BOOST_CHECK(alloc_count == 0); BOOST_CHECK(alloc_count == 0);
BOOST_CHECK(dealloc_count == 0); BOOST_CHECK(dealloc_count == 0);
fv.assign( &do_nothing, std::allocator<int>() );
fv.clear();
return 0; return 0;
} }