<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head><title>Allocator support to std::function for C++0x</title>


    
    <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
    <meta http-equiv="Content-Language" content="en-us">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body>
    <address>
        Document number: N2308=07-0168</address>
    <address>
        Programming Language C++, Library Subgroup</address>
    <address>
        &nbsp;</address>
    <address>
        Emil Dotchevski, &lt;<a href="mailto:emildotchevski@gmail.com">emil@revergestudios.com</a>&gt;</address>
    <address>
        &nbsp;</address>
    <address>
        2007-06-10</address>
    <h1>
        Adding allocator support to std::function for C++0x</h1>
    <ul>
        <li><a href="#overview">Overview</a></li>
        <li><a href="#motivation">Motivation</a></li>
        <li><a href="#impact">Impact</a></li>
        <li><a href="#text">Proposed text</a></li>
        <li><a href="#implementability">Implementability</a></li>
    </ul>
    <h2>
        <a name="overview">I. Overview</a></h2>
    <p>The <code>std::function</code> class template lacks the user-specified allocator support available in its predecessor
    	<code>boost::function</code>. The current definition of <code>boost::function</code> provides a second template parameter that
    	can be utilized to pass a custom allocator class to be used when memory allocations are needed. This second template
    	parameter is optional and defaults to <code>std::allocator</code>.</p>
    <p>The main drawback of the allocator support in <code>boost::function</code> is that using a different allocator type
    	leads to different instances of the <code>boost::function</code> class template, even for functions that have the
    	same signature.</p>
    <p>This document proposes an alternative approach for custom allocator support for <code>std::function</code> without
    	adding a second template parameter.</p>
    <h2>
        <a name="motivation">II. Motivation</a></h2>
    <p>The following are the types of function objects that can be used to initialize a <code>std::function</code> object:</p>
    <ol>
    	<li>Pointer to function</li>
    	<li>Pointer to member function</li>
    	<li>An object of user-defined type that defines suitable operator() member function.</li>
    </ol>
    <p>It is possible for <code>std::function</code> implementations to avoid dynamic allocations in the first two cases.
    In general, dynamic allocations can not be avoided in the third case. The current behavior of <code>std::function</code>
    in this case is to use <code>new</code>. This precludes its use in contexts where uncontrolled dynamic allocations
    are not allowed, such as embedded environments.</p>
	<p>Note that any use of <code>std::bind</code> with <code>std::function</code>, even when the targeted object is either
	pointer to function or pointer to member function, leads to the third case and the potential need for dynamic allocations.</p>
	<p>The proposed custom allocator support is consistent with the proposed allocator support in <code>shared_ptr</code> (N2232).
	Both <code>shared_ptr</code> and <code>std::function</code> instances retain source and binary compatibility
	independently of whether user-defined allocator was used or not.</p>
    <h2>
        <a name="impact">III. Impact</a></h2>
	<p>The allocator support does <em>not</em> add a second parameter to the <code>std::function</code> class template.
	It has no overhead when no allocator is used.</p>
	<p>Even when a custom allocator is supplied, the resulting <code>std::function</code> object is indistinguishable from
	any other instance of the <code>std::function</code> class template that use the same signature.</p>
    <p>The proposed feature affects the interface of <code>std::function</code>, allowing its broader use, and is therefore
    strongly recommended to be added to the C++0x standard.</p>
    <h2>
        <a name="text">IV. Proposed Text</a></h2>
    <p>Add to <code>std::function</code> the following constructor:</p>
    <blockquote>
    <pre>template &lt;class F,class A&gt;
function( F f, A a );</pre>
	</blockquote>
	<p><em>Requires:</em> <code>f</code> shall be callable for argument types <code>ArgTypes</code> and
	return type <code>R</code>. <code>A</code> shall be an allocator [allocator.requirements]. The copy constructor and destructor
	of <code>A</code> shall not throw.</p>
	<p><em>Postconditions:</em> <code>!*this</code> if any of the following hold:</p>
	<ul>
		<li><code>f</code> is a <code>NULL</code> function pointer.</li>
		<li><code>f</code> is a <code>NULL</code> member function pointer.</li>
		<li><code>F</code> is an instance of the function class template, and <code>!f</code></li>
	</ul>
	<p>Otherwise, <code>*this</code> targets a copy of <code>f</code> or <code>move(f)</code> if <code>f</code> is not a pointer
	to member function, and targets a copy of <code>mem_fn(f)</code> if <code>f</code> is a pointer to member function. A copy
	of <code>a</code> shall be used if dynamic storage must be allocated for the copy of <code>f</code>. [<em>Note:</em>
	Implementations are encouraged to avoid the use of dynamically allocated memory for small function objects, e.g., where
	<code>f</code>’s target is an object holding only a pointer or reference to an object and a member function pointer --
	<em>end note.</em>]</p>
	<p><em>Throws:</em> shall not throw exceptions when <code>f</code> is a function pointer or a <code>reference_wrapper&lt;T&gt;</code>
	for some <code>T</code>. Otherwise, may throw <code>bad_alloc</code> or any exception thrown by <code>F</code>’s copy or
	move constructor.</p>
    <p>Add to <code>std::function</code> the following member function template:</p>
    <blockquote>
    <pre>template &lt;class F,class A&gt;
void assign( F f, A a );</pre>
	</blockquote>
	<p><em>Effects:</em> <code>function(f,a).swap(*this);</code></p>
    <h2>
        <a name="implementability">V. Implementability</a></h2>
    <p>A proof of concept implementation is available at:</p>
    <p>
        <a href="http://www.revergestudios.com/boost-function">http://www.revergestudios.com/boost-function</a></p>
    <p>
        It is expected to be integrated with <code>boost::function</code> in time for the mailing.</p>
    <hr>
    <p>
        <em>Thanks to Peter Dimov and Doug Gregor for reviewing this document.</em></p>
    <p>
        <em>--end</em></p>
</body></html>