Compare commits

..

1 Commits

Author SHA1 Message Date
80f27498ac + creating a branch for a xpressive extension that allows nesting
of regular expressions


[SVN r38759]
2007-08-19 15:07:44 +00:00
19 changed files with 278 additions and 936 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 ;
import boostbook : boostbook ;

View File

@ -1,11 +1,4 @@
<?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"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
<section id="function.faq" last-revision="$Date$">

View File

@ -1,11 +1,4 @@
<?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"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
<section id="function.history" last-revision="$Date$">
@ -13,42 +6,6 @@
<itemizedlist spacing="compact">
<listitem><para><bold>Version 1.37.0</bold>: </para>
<itemizedlist spacing="compact">
<listitem><para>Improved the performance of Boost.Function's
swap() operation for large function objects. Original patch
contributed by Niels Dekker.</para></listitem>
<listitem><para>Added a new header &lt;boost/function/function_typeof.hpp&gt; that provides support for using the Boost.Typeof library on Boost.Function objects.</para></listitem>
<listitem><para>Added a new header &lt;boost/function/function_fwd.hpp&gt; that provides support for using the Boost.Typeof library on Boost.Function objects.</para></listitem>
<listitem><para>The <methodname alt="boost::function::target">target</methodname>()
function now respects the cv-qualifiers of function objects
stored by reference
(using <classname>boost::reference_wrapper</classname>), such
that a reference to a <code>const</code> function object cannot
be accessed as a reference to a non-<code>const</code> function
object.</para></listitem>
</itemizedlist>
</listitem>
<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>
<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>

View File

@ -1,11 +1,4 @@
<?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"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
<section id="function.misc" last-revision="$Date$">
@ -24,7 +17,7 @@
<para> And, of course, function pointers have several advantages over Boost.Function:
<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 backward-compatible with C libraries.</para></listitem>
<listitem><para> More readable error messages. </para></listitem>
@ -37,12 +30,12 @@
<section>
<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>
<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>

View File

@ -1,11 +1,4 @@
<?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"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
@ -141,6 +134,9 @@
<template-type-parameter name="T2"/>
<template-varargs/>
<template-type-parameter name="TN"/>
<template-type-parameter name="Allocator">
<default><classname>std::allocator</classname>&lt;void&gt;</default>
</template-type-parameter>
</template>
<inherit access="public"><classname>function_base</classname></inherit>
@ -157,6 +153,7 @@
</description>
<typedef name="result_type"><type>R</type></typedef>
<typedef name="allocator_type"><type>Allocator</type></typedef>
<typedef name="argument_type">
<type>T1</type><purpose>If N == 1</purpose>
</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>
</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>
<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-varargs/>
<template-type-parameter name="TN"/>
<template-type-parameter name="Allocator"/>
</template>
<type>void</type>
<parameter name="f1"><paramtype><classname>functionN</classname>&lt;T1, T2, ..., TN&gt;&amp;</paramtype></parameter>
<parameter name="f2"><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, Allocator&gt;&amp;</paramtype></parameter>
<effects><simpara><code>f1.<methodname>swap</methodname>(f2)</code></simpara></effects>
</function>
</free-function-group>
@ -349,10 +334,11 @@
<template-type-parameter name="T2"/>
<template-varargs/>
<template-type-parameter name="TN"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/>
</template>
<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>
</signature>
<signature>
@ -361,11 +347,12 @@
<template-type-parameter name="T2"/>
<template-varargs/>
<template-type-parameter name="TN"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/>
</template>
<type>bool</type>
<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>
<template>
@ -373,10 +360,11 @@
<template-type-parameter name="T2"/>
<template-varargs/>
<template-type-parameter name="TN"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/>
</template>
<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>
</signature>
<signature>
@ -385,11 +373,12 @@
<template-type-parameter name="T2"/>
<template-varargs/>
<template-type-parameter name="TN"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/>
</template>
<type>bool</type>
<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>
<template>
@ -397,14 +386,16 @@
<template-type-parameter name="T2"/>
<template-varargs/>
<template-type-parameter name="TN"/>
<template-type-parameter name="Allocator1"/>
<template-type-parameter name="U1"/>
<template-type-parameter name="U2"/>
<template-varargs/>
<template-type-parameter name="UN"/>
<template-type-parameter name="Allocator2"/>
</template>
<type>void</type>
<parameter name="f1"><paramtype>const <classname>functionN</classname>&lt;T1, T2, ..., TN&gt;&amp;</paramtype></parameter>
<parameter name="f2"><paramtype>const <classname>functionN</classname>&lt;U1, U2, ..., UN&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, Allocator2&gt;&amp;</paramtype></parameter>
</signature>
<returns><simpara>True when <code>f</code> stores an object of
@ -444,10 +435,11 @@
<template-type-parameter name="T2"/>
<template-varargs/>
<template-type-parameter name="TN"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/>
</template>
<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>
</signature>
<signature>
@ -456,11 +448,12 @@
<template-type-parameter name="T2"/>
<template-varargs/>
<template-type-parameter name="TN"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/>
</template>
<type>bool</type>
<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>
<template>
@ -468,10 +461,11 @@
<template-type-parameter name="T2"/>
<template-varargs/>
<template-type-parameter name="TN"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/>
</template>
<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>
</signature>
<signature>
@ -480,11 +474,12 @@
<template-type-parameter name="T2"/>
<template-varargs/>
<template-type-parameter name="TN"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/>
</template>
<type>bool</type>
<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>
<template>
@ -492,14 +487,16 @@
<template-type-parameter name="T2"/>
<template-varargs/>
<template-type-parameter name="TN"/>
<template-type-parameter name="Allocator1"/>
<template-type-parameter name="U1"/>
<template-type-parameter name="U2"/>
<template-varargs/>
<template-type-parameter name="UN"/>
<template-type-parameter name="Allocator2"/>
</template>
<type>void</type>
<parameter name="f1"><paramtype>const <classname>functionN</classname>&lt;T1, T2, ..., TN&gt;&amp;</paramtype></parameter>
<parameter name="f2"><paramtype>const <classname>functionN</classname>&lt;U1, U2, ..., UN&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, Allocator2&gt;&amp;</paramtype></parameter>
</signature>
<returns><simpara>True when <code>f</code> does not store an
@ -539,8 +536,11 @@
<template-type-parameter name="Signature">
<purpose>Function type R (T1, T2, ..., TN)</purpose>
</template-type-parameter>
<template-type-parameter name="Allocator">
<default><classname>std::allocator</classname>&lt;void&gt;</default>
</template-type-parameter>
</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
callbacks or wrapping function objects.</purpose>
@ -562,6 +562,7 @@
</description>
<typedef name="result_type"><type>R</type></typedef>
<typedef name="allocator_type"><type>Allocator</type></typedef>
<typedef name="argument_type">
<type>T1</type><purpose>If N == 1</purpose>
</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>
</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>
<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">
<template>
<template-type-parameter name="Signature"/>
<template-type-parameter name="Allocator"/>
</template>
<type>void</type>
<parameter name="f1"><paramtype><classname>function</classname>&lt;Signature&gt;&amp;</paramtype></parameter>
<parameter name="f2"><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, Allocator&gt;&amp;</paramtype></parameter>
<effects><simpara><code>f1.<methodname>swap</methodname>(f2)</code></simpara></effects>
</function>
</free-function-group>
@ -763,47 +752,53 @@
<signature>
<template>
<template-type-parameter name="Signature"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/>
</template>
<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>
</signature>
<signature>
<template>
<template-type-parameter name="Signature"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/>
</template>
<type>bool</type>
<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>
<template>
<template-type-parameter name="Signature"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/>
</template>
<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>
</signature>
<signature>
<template>
<template-type-parameter name="Signature"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/>
</template>
<type>bool</type>
<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>
<template>
<template-type-parameter name="Signature1"/>
<template-type-parameter name="Allocator1"/>
<template-type-parameter name="Signature2"/>
<template-type-parameter name="Allocator2"/>
</template>
<type>void</type>
<parameter name="f1"><paramtype>const <classname>function</classname>&lt;Signature1&gt;&amp;</paramtype></parameter>
<parameter name="f2"><paramtype>const <classname>function</classname>&lt;Signature2&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, Allocator2&gt;&amp;</paramtype></parameter>
</signature>
<returns><simpara>True when <code>f</code> stores an object of
@ -838,47 +833,53 @@
<signature>
<template>
<template-type-parameter name="Signature"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/>
</template>
<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>
</signature>
<signature>
<template>
<template-type-parameter name="Signature"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/>
</template>
<type>bool</type>
<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>
<template>
<template-type-parameter name="Signature"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/>
</template>
<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>
</signature>
<signature>
<template>
<template-type-parameter name="Signature"/>
<template-type-parameter name="Allocator"/>
<template-type-parameter name="Functor"/>
</template>
<type>bool</type>
<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>
<template>
<template-type-parameter name="Signature1"/>
<template-type-parameter name="Allocator1"/>
<template-type-parameter name="Signature2"/>
<template-type-parameter name="Allocator2"/>
</template>
<type>void</type>
<parameter name="f1"><paramtype>const <classname>function</classname>&lt;Signature1&gt;&amp;</paramtype></parameter>
<parameter name="f2"><paramtype>const <classname>function</classname>&lt;Signature2&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, Allocator2&gt;&amp;</paramtype></parameter>
</signature>
<returns><simpara>True when <code>f</code> does not store an

View File

@ -1,11 +1,4 @@
<?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"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
<testsuite id="function.testsuite" last-revision="$Date$">

View File

@ -1,11 +1,4 @@
<?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"
"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
<section xmlns:xi="http://www.w3.org/2001/XInclude" id="function.tutorial"

View File

@ -11,7 +11,7 @@
#define BOOST_FUNCTION_PROLOGUE_HPP
# include <cassert>
# 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/config.hpp>
# include <boost/function/function_base.hpp>
@ -22,5 +22,4 @@
# include <boost/preprocessor/cat.hpp>
# include <boost/preprocessor/repeat.hpp>
# include <boost/preprocessor/inc.hpp>
# include <boost/type_traits/is_void.hpp>
#endif // BOOST_FUNCTION_PROLOGUE_HPP

View File

@ -1,9 +1,8 @@
// Boost.Function library
// Copyright Douglas Gregor 2001-2006
// Copyright Emil Dotchevski 2007
// Use, modification and distribution is subject to the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// Copyright Douglas Gregor 2001-2006. Use, modification and
// distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// For more information, see http://www.boost.org
@ -18,11 +17,8 @@
#include <typeinfo>
#include <boost/config.hpp>
#include <boost/assert.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_integral.hpp>
#include <boost/type_traits/is_volatile.hpp>
#include <boost/type_traits/composite_traits.hpp>
#include <boost/type_traits/ice.hpp>
#include <boost/ref.hpp>
#include <boost/mpl/if.hpp>
#include <boost/detail/workaround.hpp>
@ -33,13 +29,6 @@
# include "boost/mpl/bool.hpp"
#endif
#include <boost/function_equal.hpp>
#include <boost/function/function_fwd.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.
#ifdef BOOST_NO_EXCEPTION_STD_NAMESPACE
@ -67,7 +56,22 @@
# define BOOST_FUNCTION_TARGET_FIX(x)
#endif // not MSVC
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x5A0)
#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730 && !defined(BOOST_STRICT_CONFIG)
// Work around a compiler bug.
// boost::python::objects::function has to be seen by the compiler before the
// boost::function class template.
namespace boost { namespace python { namespace objects {
class function;
}}}
#endif
#if defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|| defined(BOOST_BCB_PARTIAL_SPECIALIZATION_BUG) \
|| !(BOOST_STRICT_CONFIG || !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x540)
# define BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX
#endif
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x600)
# define BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor,Type) \
typename ::boost::enable_if_c<(::boost::type_traits::ice_not< \
(::boost::is_integral<Functor>::value)>::value), \
@ -81,6 +85,31 @@
Type>::type
#endif
#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
namespace boost {
#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730 && !defined(BOOST_STRICT_CONFIG)
// The library shipping with MIPSpro 7.3.1.3m has a broken allocator<void>
class function_base;
template<typename Signature,
typename Allocator = std::allocator<function_base> >
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);
}
} // end namespace boost
#endif // have partial specialization
namespace boost {
namespace detail {
namespace function {
@ -95,18 +124,11 @@ namespace boost {
union function_buffer
{
// For pointers to function objects
mutable void* obj_ptr;
void* obj_ptr;
// For pointers to std::type_info objects
struct type_t {
// (get_functor_type_tag, check_functor_type_tag).
const BOOST_FUNCTION_STD_NS::type_info* type;
// Whether the type is const-qualified.
bool const_qualified;
// Whether the type is volatile-qualified.
bool volatile_qualified;
} type;
// (get_functor_type_tag, check_functor_type_tag).
const void* const_obj_ptr;
// For function pointers of all kinds
mutable void (*func_ptr)();
@ -117,14 +139,6 @@ namespace boost {
void* obj_ptr;
} bound_memfunc_ptr;
// For references to function objects. We explicitly keep
// track of the cv-qualifiers on the object referenced.
struct obj_ref_t {
mutable void* obj_ptr;
bool is_const_qualified;
bool is_volatile_qualified;
} obj_ref;
// To relax aliasing constraints
mutable char data;
};
@ -156,7 +170,6 @@ namespace boost {
// The operation type to perform on the given functor/function pointer
enum functor_manager_operation_type {
clone_functor_tag,
move_functor_tag,
destroy_functor_tag,
check_functor_type_tag,
get_functor_type_tag
@ -198,40 +211,29 @@ namespace boost {
{
switch (op) {
case clone_functor_tag:
out_buffer.obj_ref.obj_ptr = in_buffer.obj_ref.obj_ptr;
return;
case move_functor_tag:
out_buffer.obj_ref.obj_ptr = in_buffer.obj_ref.obj_ptr;
in_buffer.obj_ref.obj_ptr = 0;
out_buffer.obj_ptr = in_buffer.obj_ptr;
return;
case destroy_functor_tag:
out_buffer.obj_ref.obj_ptr = 0;
out_buffer.obj_ptr = 0;
return;
case check_functor_type_tag:
{
const BOOST_FUNCTION_STD_NS::type_info& check_type
= *out_buffer.type.type;
// Check whether we have the same type. We can add
// cv-qualifiers, but we can't take them away.
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(F))
&& (!in_buffer.obj_ref.is_const_qualified
|| out_buffer.type.const_qualified)
&& (!in_buffer.obj_ref.is_volatile_qualified
|| out_buffer.type.volatile_qualified))
out_buffer.obj_ptr = in_buffer.obj_ref.obj_ptr;
// DPG TBD: Since we're only storing a pointer, it's
// possible that the user could ask for a base class or
// derived class. Is that okay?
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(F)))
out_buffer.obj_ptr = in_buffer.obj_ptr;
else
out_buffer.obj_ptr = 0;
}
return;
case get_functor_type_tag:
out_buffer.type.type = &typeid(F);
out_buffer.type.const_qualified = in_buffer.obj_ref.is_const_qualified;
out_buffer.type.volatile_qualified = in_buffer.obj_ref.is_volatile_qualified;
out_buffer.const_obj_ptr = &typeid(F);
return;
}
}
@ -251,94 +253,33 @@ namespace boost {
% 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
* can clone or destroy the given function/function object pointer.
*/
template<typename Functor>
struct functor_manager_common
{
typedef Functor functor_type;
// Function pointers
static inline void
manage_ptr(const function_buffer& in_buffer, function_buffer& out_buffer,
functor_manager_operation_type op)
{
if (op == clone_functor_tag)
out_buffer.func_ptr = in_buffer.func_ptr;
else if (op == move_functor_tag) {
out_buffer.func_ptr = in_buffer.func_ptr;
in_buffer.func_ptr = 0;
} else if (op == destroy_functor_tag)
out_buffer.func_ptr = 0;
else if (op == check_functor_type_tag) {
const BOOST_FUNCTION_STD_NS::type_info& check_type
= *out_buffer.type.type;
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor)))
out_buffer.obj_ptr = &in_buffer.func_ptr;
else
out_buffer.obj_ptr = 0;
} else /* op == get_functor_type_tag */ {
out_buffer.type.type = &typeid(Functor);
out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false;
}
}
// Function objects that fit in the small-object buffer.
static inline void
manage_small(const function_buffer& in_buffer, function_buffer& out_buffer,
functor_manager_operation_type op)
{
if (op == clone_functor_tag || op == move_functor_tag) {
const functor_type* in_functor =
reinterpret_cast<const functor_type*>(&in_buffer.data);
new ((void*)&out_buffer.data) functor_type(*in_functor);
if (op == move_functor_tag) {
reinterpret_cast<functor_type*>(&in_buffer.data)->~Functor();
}
} else if (op == destroy_functor_tag) {
// Some compilers (Borland, vc6, ...) are unhappy with ~functor_type.
reinterpret_cast<functor_type*>(&out_buffer.data)->~Functor();
} else if (op == check_functor_type_tag) {
const BOOST_FUNCTION_STD_NS::type_info& check_type
= *out_buffer.type.type;
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor)))
out_buffer.obj_ptr = &in_buffer.data;
else
out_buffer.obj_ptr = 0;
} else /* op == get_functor_type_tag */ {
out_buffer.type.type = &typeid(Functor);
out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false;
}
}
};
template<typename Functor>
template<typename Functor, typename Allocator>
struct functor_manager
{
private:
typedef Functor functor_type;
// Function pointers
// For function pointers, the manager is trivial
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);
if (op == clone_functor_tag)
out_buffer.func_ptr = in_buffer.func_ptr;
else if (op == destroy_functor_tag)
out_buffer.func_ptr = 0;
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.func_ptr;
else
out_buffer.obj_ptr = 0;
}
}
// Function objects that fit in the small-object buffer.
@ -346,7 +287,21 @@ namespace boost {
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);
if (op == clone_functor_tag) {
const functor_type* in_functor =
reinterpret_cast<const functor_type*>(&in_buffer.data);
new ((void*)&out_buffer.data) functor_type(*in_functor);
} else if (op == destroy_functor_tag) {
// Some compilers (Borland, vc6, ...) are unhappy with ~functor_type.
reinterpret_cast<functor_type*>(&out_buffer.data)->~Functor();
} 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.data;
else
out_buffer.obj_ptr = 0;
}
}
// Function objects that require heap allocation
@ -354,34 +309,59 @@ namespace boost {
manager(const function_buffer& in_buffer, function_buffer& out_buffer,
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) {
// 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_type* f =
(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);
# endif // BOOST_NO_STD_ALLOCATOR
out_buffer.obj_ptr = new_f;
} else if (op == move_functor_tag) {
out_buffer.obj_ptr = in_buffer.obj_ptr;
in_buffer.obj_ptr = 0;
} else if (op == destroy_functor_tag) {
/* Cast from the void pointer to the functor pointer type */
functor_type* f =
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;
# endif // BOOST_NO_STD_ALLOCATOR
out_buffer.obj_ptr = 0;
} else if (op == check_functor_type_tag) {
const BOOST_FUNCTION_STD_NS::type_info& check_type
= *out_buffer.type.type;
} 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;
} else /* op == get_functor_type_tag */ {
out_buffer.type.type = &typeid(Functor);
out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false;
}
}
@ -406,112 +386,7 @@ namespace boost {
typedef typename get_function_tag<functor_type>::type tag_type;
switch (op) {
case get_functor_type_tag:
out_buffer.type.type = &typeid(functor_type);
out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false;
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 == move_functor_tag) {
out_buffer.obj_ptr = in_buffer.obj_ptr;
in_buffer.obj_ptr = 0;
} 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;
} else if (op == check_functor_type_tag) {
const BOOST_FUNCTION_STD_NS::type_info& check_type
= *out_buffer.type.type;
if (BOOST_FUNCTION_COMPARE_TYPE_ID(check_type, typeid(Functor)))
out_buffer.obj_ptr = in_buffer.obj_ptr;
else
out_buffer.obj_ptr = 0;
} else /* op == get_functor_type_tag */ {
out_buffer.type.type = &typeid(Functor);
out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false;
}
}
// 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.type.type = &typeid(functor_type);
out_buffer.type.const_qualified = false;
out_buffer.type.volatile_qualified = false;
out_buffer.const_obj_ptr = &typeid(functor_type);
return;
default:
@ -619,7 +494,7 @@ public:
detail::function::function_buffer type;
vtable->manager(functor, type, detail::function::get_functor_type_tag);
return *type.type.type;
return *static_cast<const BOOST_FUNCTION_STD_NS::type_info*>(type.const_obj_ptr);
}
template<typename Functor>
@ -628,9 +503,7 @@ public:
if (!vtable) return 0;
detail::function::function_buffer type_result;
type_result.type.type = &typeid(Functor);
type_result.type.const_qualified = is_const<Functor>::value;
type_result.type.volatile_qualified = is_volatile<Functor>::value;
type_result.const_obj_ptr = &typeid(Functor);
vtable->manager(functor, type_result,
detail::function::check_functor_type_tag);
return static_cast<Functor*>(type_result.obj_ptr);
@ -646,9 +519,7 @@ public:
if (!vtable) return 0;
detail::function::function_buffer type_result;
type_result.type.type = &typeid(Functor);
type_result.type.const_qualified = true;
type_result.type.volatile_qualified = is_volatile<Functor>::value;
type_result.const_obj_ptr = &typeid(Functor);
vtable->manager(functor, type_result,
detail::function::check_functor_type_tag);
// GCC 2.95.3 gets the CV qualifiers wrong here, so we

View File

@ -1,70 +0,0 @@
// Boost.Function library
// Copyright (C) Douglas Gregor 2008
//
// Use, modification and distribution is subject to the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org
#ifndef BOOST_FUNCTION_FWD_HPP
#define BOOST_FUNCTION_FWD_HPP
#include <boost/config.hpp>
#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730 && !defined(BOOST_STRICT_CONFIG)
// Work around a compiler bug.
// boost::python::objects::function has to be seen by the compiler before the
// boost::function class template.
namespace boost { namespace python { namespace objects {
class function;
}}}
#endif
#if defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|| defined(BOOST_BCB_PARTIAL_SPECIALIZATION_BUG) \
|| !(BOOST_STRICT_CONFIG || !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x540)
# define BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX
#endif
namespace boost {
class bad_function_call;
#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
// Preferred syntax
template<typename Signature> class function;
template<typename Signature>
inline void swap(function<Signature>& f1, function<Signature>& f2)
{
f1.swap(f2);
}
#endif // have partial specialization
// Portable syntax
template<typename R> class function0;
template<typename R, typename T1> class function1;
template<typename R, typename T1, typename T2> class function2;
template<typename R, typename T1, typename T2, typename T3> class function3;
template<typename R, typename T1, typename T2, typename T3, typename T4>
class function4;
template<typename R, typename T1, typename T2, typename T3, typename T4,
typename T5>
class function5;
template<typename R, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6>
class function6;
template<typename R, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7>
class function7;
template<typename R, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8>
class function8;
template<typename R, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9>
class function9;
template<typename R, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10>
class function10;
}
#endif

View File

@ -1,9 +1,8 @@
// Boost.Function library
// Copyright Douglas Gregor 2001-2006
// Copyright Emil Dotchevski 2007
// Use, modification and distribution is subject to the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// Copyright Douglas Gregor 2001-2006. Use, modification and
// distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// For more information, see http://www.boost.org
@ -12,11 +11,6 @@
// protection.
#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_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)
// 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
#if BOOST_FUNCTION_NUM_ARGS == 0
# define BOOST_FUNCTION_COMMA
@ -246,7 +247,8 @@ namespace boost {
/**
* 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
{
#ifndef BOOST_NO_VOID_RETURNS
@ -264,11 +266,6 @@ namespace boost {
{
init(f);
}
template<typename F,typename Allocator>
BOOST_FUNCTION_VTABLE(F f, Allocator) : vtable_base(), invoker(0)
{
init_a<Allocator>(f);
}
template<typename F>
bool assign_to(F f, function_buffer& functor)
@ -276,12 +273,6 @@ namespace boost {
typedef typename get_function_tag<F>::type 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)
{
@ -296,12 +287,6 @@ namespace boost {
typedef typename get_function_tag<F>::type 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
template<typename FunctionPtr>
@ -315,20 +300,7 @@ namespace boost {
actual_invoker_type;
invoker = &actual_invoker_type::invoke;
manager = &functor_manager<FunctionPtr>::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;
manager = &functor_manager<FunctionPtr, Allocator>::manage;
}
template<typename FunctionPtr>
@ -345,12 +317,6 @@ namespace boost {
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
#if BOOST_FUNCTION_NUM_ARGS > 0
@ -362,14 +328,6 @@ namespace boost {
// right target_type() values.
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>
bool assign_to(MemberPtr f, function_buffer& functor, member_ptr_tag)
@ -384,19 +342,6 @@ namespace boost {
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
// Function objects
@ -411,20 +356,7 @@ namespace boost {
actual_invoker_type;
invoker = &actual_invoker_type::invoke;
manager = &functor_manager<FunctionObj>::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;
manager = &functor_manager<FunctionObj, Allocator>::manage;
}
// Assign to a function object using the small object optimization
@ -434,33 +366,26 @@ namespace boost {
{
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.
template<typename FunctionObj>
void
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);
}
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;
# endif // BOOST_NO_STD_ALLOCATOR
}
template<typename FunctionObj>
@ -475,18 +400,6 @@ namespace boost {
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
template<typename FunctionObj>
@ -503,12 +416,6 @@ namespace boost {
invoker = &actual_invoker_type::invoke;
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>
bool
@ -516,21 +423,16 @@ namespace boost {
function_buffer& functor, function_obj_ref_tag)
{
if (!boost::detail::function::has_empty_target(f.get_pointer())) {
functor.obj_ref.obj_ptr = (void *)f.get_pointer();
functor.obj_ref.is_const_qualified = is_const<FunctionObj>::value;
functor.obj_ref.is_volatile_qualified = is_volatile<FunctionObj>::value;
// DPG TBD: We might need to detect constness of
// FunctionObj to assign into obj_ptr or const_obj_ptr to
// be truly legit, but no platform in existence makes
// const void* different from void*.
functor.const_obj_ptr = f.get_pointer();
return true;
} else {
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:
invoker_type invoker;
@ -540,7 +442,8 @@ namespace boost {
template<
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
@ -565,7 +468,7 @@ namespace boost {
private:
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;
struct clear_type {};
@ -590,6 +493,7 @@ namespace boost {
BOOST_STATIC_CONSTANT(int, arity = BOOST_FUNCTION_NUM_ARGS);
BOOST_FUNCTION_ARG_TYPES
typedef Allocator allocator_type;
typedef BOOST_FUNCTION_FUNCTION self_type;
BOOST_FUNCTION_FUNCTION() : function_base() { }
@ -609,19 +513,6 @@ namespace boost {
{
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
BOOST_FUNCTION_FUNCTION(clear_type*) : function_base() { }
@ -679,17 +570,6 @@ namespace boost {
}
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
BOOST_FUNCTION_FUNCTION& operator=(clear_type*)
@ -727,10 +607,9 @@ namespace boost {
if (&other == this)
return;
BOOST_FUNCTION_FUNCTION tmp;
tmp.move_assign(*this);
this->move_assign(other);
other.move_assign(tmp);
BOOST_FUNCTION_FUNCTION tmp = *this;
*this = other;
other = tmp;
}
// Clear out a target, if there is one
@ -778,60 +657,33 @@ namespace boost {
if (stored_vtable.assign_to(f, functor)) vtable = &stored_vtable;
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;
}
// Moves the value from the specified argument to *this. If the argument
// has its function object allocated on the heap, move_assign will pass
// its buffer to *this, and set the argument's buffer pointer to NULL.
void move_assign(BOOST_FUNCTION_FUNCTION& f)
{
if (&f == this)
return;
#if !defined(BOOST_NO_EXCEPTIONS)
try {
#endif
if (!f.empty()) {
this->vtable = f.vtable;
f.vtable->manager(f.functor, this->functor,
boost::detail::function::move_functor_tag);
f.vtable = 0;
#if !defined(BOOST_NO_EXCEPTIONS)
} else {
clear();
}
} catch (...) {
vtable = 0;
throw;
}
#endif
}
};
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<
R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS
BOOST_FUNCTION_TEMPLATE_ARGS ,
Allocator
>& f1,
BOOST_FUNCTION_FUNCTION<
R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS
BOOST_FUNCTION_TEMPLATE_ARGS,
Allocator
>& f2)
{
f1.swap(f2);
}
#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<
R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>::result_type
BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
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
{
if (this->empty())
@ -843,20 +695,26 @@ namespace boost {
#endif
// 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<
R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS>&,
BOOST_FUNCTION_TEMPLATE_ARGS ,
Allocator>&,
const BOOST_FUNCTION_FUNCTION<
R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS>&);
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
BOOST_FUNCTION_TEMPLATE_ARGS ,
Allocator>&);
template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS ,
typename Allocator>
void operator!=(const BOOST_FUNCTION_FUNCTION<
R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS>&,
BOOST_FUNCTION_TEMPLATE_ARGS ,
Allocator>&,
const BOOST_FUNCTION_FUNCTION<
R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_ARGS>& );
BOOST_FUNCTION_TEMPLATE_ARGS ,
Allocator>&);
#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
@ -867,16 +725,20 @@ template<typename R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_PARMS>
#endif
template<typename R BOOST_FUNCTION_COMMA
BOOST_FUNCTION_TEMPLATE_PARMS>
class function<BOOST_FUNCTION_PARTIAL_SPEC>
: public BOOST_FUNCTION_FUNCTION<R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS>
BOOST_FUNCTION_TEMPLATE_PARMS,
typename Allocator>
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;
struct clear_type {};
public:
typedef typename base_type::allocator_type allocator_type;
function() : base_type() {}
@ -892,18 +754,6 @@ public:
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
function(clear_type*) : base_type() {}
@ -956,6 +806,7 @@ public:
// Cleanup after ourselves...
#undef BOOST_FUNCTION_VTABLE
#undef BOOST_FUNCTION_DEFAULT_ALLOCATOR
#undef BOOST_FUNCTION_COMMA
#undef BOOST_FUNCTION_FUNCTION
#undef BOOST_FUNCTION_FUNCTION_INVOKER
@ -977,7 +828,3 @@ public:
#undef BOOST_FUNCTION_ARG_TYPES
#undef BOOST_FUNCTION_VOID_RETURN_TYPE
#undef BOOST_FUNCTION_RETURN
#if defined(BOOST_MSVC)
# pragma warning( pop )
#endif

View File

@ -1,45 +0,0 @@
// Boost.Function library - Typeof support
// Copyright (C) Douglas Gregor 2008
//
// Use, modification and distribution is subject to the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org
#ifndef BOOST_FUNCTION_TYPEOF_HPP
#define BOOST_FUNCTION_TYPEOF_HPP
#include <boost/function/function_fwd.hpp>
#include <boost/typeof/typeof.hpp>
#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
BOOST_TYPEOF_REGISTER_TYPE(boost::bad_function_call)
#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX)
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::function, (typename))
#endif
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::function0, (typename))
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::function1, (typename)(typename))
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::function2, (typename)(typename)(typename))
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::function3,
(typename)(typename)(typename)(typename))
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::function4,
(typename)(typename)(typename)(typename)(typename))
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::function5,
(typename)(typename)(typename)(typename)(typename)(typename))
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::function6,
(typename)(typename)(typename)(typename)(typename)(typename)(typename))
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::function7,
(typename)(typename)(typename)(typename)(typename)(typename)(typename)
(typename))
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::function8,
(typename)(typename)(typename)(typename)(typename)(typename)(typename)
(typename)(typename))
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::function9,
(typename)(typename)(typename)(typename)(typename)(typename)(typename)
(typename)(typename)(typename))
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::function10,
(typename)(typename)(typename)(typename)(typename)(typename)(typename)
(typename)(typename)(typename)(typename))
#endif

View File

@ -1,11 +1,4 @@
<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>
<meta http-equiv="refresh" content="0; URL=../../doc/html/function.html">
</head>

View File

@ -58,9 +58,6 @@ import testing ;
[ run libs/function/test/contains2_test.cpp : : : : ]
[ run libs/function/test/nothrow_swap.cpp : : : : ]
[ compile libs/function/test/function_typeof_test.cpp ]
;
}

View File

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

View File

@ -88,15 +88,6 @@ static void target_test()
BOOST_CHECK(!f.target<int (*)()>());
BOOST_CHECK(f.target<Seventeen>());
BOOST_CHECK(f.target<Seventeen>() == &this_seventeen);
const Seventeen const_seventeen = this_seventeen;
f = boost::ref(const_seventeen);
BOOST_CHECK(!f.target<int (*)()>());
BOOST_CHECK(f.target<const Seventeen>());
BOOST_CHECK(f.target<const Seventeen>() == &const_seventeen);
BOOST_CHECK(f.target<const volatile Seventeen>());
BOOST_CHECK(!f.target<Seventeen>());
BOOST_CHECK(!f.target<volatile Seventeen>());
}
static void equal_test()

View File

@ -636,54 +636,6 @@ test_ref()
}
}
static unsigned construction_count = 0;
static unsigned destruction_count = 0;
struct MySmallFunctor {
MySmallFunctor() { ++construction_count; }
MySmallFunctor(const MySmallFunctor &) { ++construction_count; }
~MySmallFunctor() { ++destruction_count; }
int operator()() { return 0; }
};
struct MyLargeFunctor {
MyLargeFunctor() { ++construction_count; }
MyLargeFunctor(const MyLargeFunctor &) { ++construction_count; }
~MyLargeFunctor() { ++destruction_count; }
int operator()() { return 0; }
float data[128];
};
void test_construct_destroy_count()
{
{
boost::function0<int> f;
boost::function0<int> g;
f = MySmallFunctor();
g = MySmallFunctor();
f.swap(g);
}
// MySmallFunctor objects should be constructed as many times as
// they are destroyed.
BOOST_CHECK(construction_count == destruction_count);
construction_count = 0;
destruction_count = 0;
{
boost::function0<int> f;
boost::function0<int> g;
f = MyLargeFunctor();
g = MyLargeFunctor();
f.swap(g);
}
// MyLargeFunctor objects should be constructed as many times as
// they are destroyed.
BOOST_CHECK(construction_count == destruction_count);
}
int test_main(int, char* [])
{
test_zero_args();
@ -692,6 +644,5 @@ int test_main(int, char* [])
test_emptiness();
test_member_functions();
test_ref();
test_construct_destroy_count();
return 0;
}

View File

@ -1,18 +0,0 @@
// Boost.Function library
// Copyright Douglas Gregor 2008. Use, modification and
// distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// For more information, see http://www.boost.org
#include <boost/function/function_typeof.hpp>
#include <boost/function.hpp>
#include <boost/typeof/typeof.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/static_assert.hpp>
void f(boost::function0<void> f, boost::function0<void> g)
{
BOOST_STATIC_ASSERT((boost::is_same<boost::function0<void>, BOOST_TYPEOF(f = g)>::value));
}

View File

@ -1,60 +0,0 @@
// Boost.Function library
// Copyright Douglas Gregor 2008. Use, modification and
// distribution is subject to the Boost Software License, Version
// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// For more information, see http://www.boost.org
#include <boost/test/minimal.hpp>
#include <boost/function.hpp>
struct tried_to_copy { };
struct MaybeThrowOnCopy {
MaybeThrowOnCopy(int value = 0) : value(value) { }
MaybeThrowOnCopy(const MaybeThrowOnCopy& other) : value(other.value) {
if (throwOnCopy)
throw tried_to_copy();
}
MaybeThrowOnCopy& operator=(const MaybeThrowOnCopy& other) {
if (throwOnCopy)
throw tried_to_copy();
value = other.value;
return *this;
}
int operator()() { return value; }
int value;
// Make sure that this function object doesn't trigger the
// small-object optimization in Function.
float padding[100];
static bool throwOnCopy;
};
bool MaybeThrowOnCopy::throwOnCopy = false;
int test_main(int, char* [])
{
boost::function0<int> f;
boost::function0<int> g;
MaybeThrowOnCopy::throwOnCopy = false;
f = MaybeThrowOnCopy(1);
g = MaybeThrowOnCopy(2);
BOOST_CHECK(f() == 1);
BOOST_CHECK(g() == 2);
MaybeThrowOnCopy::throwOnCopy = true;
f.swap(g);
BOOST_CHECK(f() == 2);
BOOST_CHECK(g() == 1);
return 0;
}