<html>
	<head>
		<title>Proposed Text for Parallel Task Execution</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 bgColor="#ffffff">
		<ADDRESS>Document number: N2185=07-0045</ADDRESS>
		<ADDRESS>Programming Language C++, Evolution/Library</ADDRESS>
		<ADDRESS>&nbsp;</ADDRESS>
		<ADDRESS>Peter Dimov, &lt;<A href="mailto:pdimov@pdimov.com">pdimov@pdimov.com</A>&gt;</ADDRESS>
		<ADDRESS>&nbsp;</ADDRESS>
		<ADDRESS>
            2007-03-06</ADDRESS>
		<h1>Proposed Text for Parallel Task Execution</h1>
		<h2>I. Overview</h2>
		<p>
            This document proposes an addition to Chapter 30 [threads] that allows easy and
            straightforward parallel execution of tasks. The mechanism of transporting the result
            to the caller is based on N2096, <em>Transporting Values and Exceptions between Threads</em>.
            The execution syntax is inspired by N1875, <em>C++ Threads</em>, by Lawrence Crowl.
            The exception propagation depends on the language support proposed in N2179, but
            the prototype implementation uses a library approximation. The cancelation support
            depends on the thread handle class proposed in N2178, but should be implementable
            under competing proposals as well.</p>
		<h2>
            II. Example Use</h2>
		<p>
            Given the sequential example:</p>
<pre>double f( double a, int n )
{
    double r = 0.0;

    for( int i = 1; i &lt;= n; ++i )
    {
        double x = 1.0 / i;
        r += std::pow( x, a );
    }

    return r;
}

int main()
{
    double m1 = f( 1.0, 1000000 );
    double m2 = f( 1.0, 5000000 );
    double m3 = f( 2.2, 1000000 );
    double m4 = f( 2.2, 5000000 );

    std::cout &lt;&lt; m2 - m1 + m3 - m4 &lt;&lt; std::endl;
}
</pre>
        <p>
            this proposal allows a programmer to switch to parallel execution as follows:</p>
<pre>int main()
{
    std::future&lt;double&gt; fm1 = std::fork( f, 1.0, 1000000 );
    std::future&lt;double&gt; fm2 = std::fork( f, 1.0, 5000000 );
    std::future&lt;double&gt; fm3 = std::fork( f, 2.2, 1000000 );
    std::future&lt;double&gt; fm4 = std::fork( f, 2.2, 5000000 );

    std::cout &lt;&lt; fm2 - fm1 + fm3 - fm4 &lt;&lt; std::endl;
}
</pre>
        <p>
            The notation can be shortened by using the auto keyword:</p>
<pre>    auto fm1 = std::fork( f, 1.0, 1000000 );
</pre>
        <p>
            A function might return a type that is expensive to copy:</p>
<pre>std::vector&lt; std::string &gt; tokenize( std::string const &amp; input );
</pre>
        <p>
            In this case, the programmer can use an explicit notation that expresses intent
            to destructively move the result value from the <code>future</code>:</p>
<pre>    auto fs1 = std::fork( tokenize, std::ref( input ) );
    auto s1 = fs1.move();

    std::future&lt; std::vector&lt; std::string &gt; &amp;&amp; &gt; fs2 = std::fork( tokenize, std::ref( input ) );
    std::string s2 = fs2;
</pre>
        <p>
            Of course, the result can only be moved once.</p>
        <p>
            If the function that is passed to <code>fork</code> throws an exception, it is stored into the
            <code>future</code> and thrown when its result is obtained:</p>
<pre>int f()
{
    throw std::runtime_error( &quot;Hello future world!&quot; );
}

int main()
{
    std::future&lt; int &gt; fi = std::fork( f );

    try
    {
        std::cout &lt;&lt; fi &lt;&lt; std::endl;
    }
    catch( std::exception const &amp; x )
    {
        std::cout &lt;&lt; x.what() &lt;&lt; std::endl;
    }
}
</pre>
        <p>
            The above program prints &quot;Hello future world!&quot;.</p>
		<h2>
            III. Proposed Text</h2>
		<p>
            Add to the synopsis of <em>&lt;thread&gt;</em> the following:</p>
<pre>namespace std {

    class future_result_moved: public exception;
    class fork_canceled: public exception;

    template&lt; class R &gt; class future;
    template&lt; class R &gt; class future&lt; R&amp; &gt;;
    template&lt; class R &gt; class future&lt; R&amp;&amp; &gt;;
    template&lt;&gt; class future&lt; void &gt;;

    template&lt; class Fn &gt; future&lt; typename result_of&lt;Fn()&gt;::type &gt; fork( Fn fn );
    template&lt; class Fn, class A1, ..., class An &gt; future&lt; typename result_of&lt;Fn(A1, ..., An)&gt;::type &gt; fork( Fn fn, A1 a1, ..., An an );

}
</pre>
        <p>
            Add the following at the appropriate place of chapter 30 after the synopsis:</p>
<pre>class future_result_moved: public exception
{
public:

    char const * what() const throw();
};
</pre>
        <p>
            The exception <code>future_result_moved</code> is thrown by <code>future&lt;R&amp;&amp;&gt;</code> if an attempt is made to obtain its result more than once.</p>
        <pre>char const * what() const throw();</pre>
        <p>
            <em>Returns:</em> <code>&quot;std::future_result_moved&quot;</code>.</p>

<pre>class fork_canceled: public exception
{
public:

    char const * what() const throw();
};
</pre>
        <p>
            The exception <code>fork_canceled</code> is placed by <code>fork( f )</code> or <code>fork( f, a1, ..., aN )</code>
            into the future result if the thread executing <code>f()</code> or <code>f( a1, ..., aN )</code> is canceled.</p>
        <pre>char const * what() const throw();</pre>
        <p>
            <em>Returns:</em> <code>&quot;std::fork_canceled&quot;</code>.</p>

<pre>template&lt; class R &gt; class future
{
public:

    future();
    
    future( future const &amp; rhs );
    future &amp; operator=( future const &amp; rhs );
    
    ~future();

    bool has_value() const;
    bool has_exception() const;

    void join();
    bool try_join();
    bool timed_join( timespec const &amp; abstime );
    
    void cancel();

    operator R() const;
    R get() const;
    R move();

    void set_value( R const &amp; r );
    void set_value( R &amp;&amp; r );
    void set_exception( exception_ptr p );

    void set_cancel_handle( thread::handle const &amp; th );
};
</pre>
        <p>
            The class template <code>future&lt;R&gt;</code> represents a future result value of type <em>R</em>.
            A <em>producer</em> thread can put a value or an exception into a <code>future&lt;R&gt;</code>
            via its member functions <code>set_value</code> and <code>set_exception</code>. A <em>consumer</em> thread can
            wait for the result to become available via the join member functions, or obtain
            the result via the member function <em>get</em> or the conversion operator.</p>
        <p>
            <code>future&lt;R&gt;</code> has reference semantics and all of its copies refer to the same
            underlying shared state. Its operations except the destructor and the assignment
            operator can be invoked concurrently from multiple threads. It can be likened to
            a <em>shared_ptr</em> to a thread-safe container of a single element of type <em>R</em>.</p>
		<pre>future();</pre>
		<p>
            <em>Effects:</em> constructs a <em>future</em> whose associated state holds no value,
            no exception and a null thread handle.</p>
		<p>
            <em>Postconditions:</em> <code>!has_value() &amp;&amp; !has_exception()</code>.</p>
<pre>future( future const &amp; rhs );
future &amp; operator=( future const &amp; rhs );</pre>
		<p>
            <em>Postconditions:</em> <em>*this</em> refers to the same state as <em>rhs</em>.</p>
        <p>
            <em>Throws:</em> nothing.</p>
		<pre>~future();</pre>
		<p>
            <em>Effects:</em> destroys <em>*this</em> and its associated state if no other instance refers to it.</p>
        <p>
            <em>Throws:</em> nothing.</p>
        <pre>bool has_value() const;</pre>
        <p>
            <em>Returns:</em> <em>true</em> if the state associated with <em>*this</em> contains
            a value, otherwise <em>false</em>.</p>
        <pre>bool has_exception() const;</pre>
        <p>
            <em>Returns:</em> <em>true</em> if the state associated with <em>*this</em> contains
            an exception, otherwise <em>false</em>.</p>
        <pre>void join();</pre>
        <p>
            <em>Effects:</em> blocks until the state associated with <em>*this</em> contains
            a value or an exception. Cancelation point.</p>
        <p>
            <em>Throws:</em> <code>thread_cancel</code>.</p>
        <pre>bool try_join();</pre>
        <p>
            <em>Returns:</em> <em>true</em> if the state associated with <em>*this</em> contains
            a value or an exception, <em>false</em> otherwise.</p>
        <p>
            <em>Throws:</em> nothing.</p>
        <pre>void timed_join( timespec const &amp; abstime );</pre>
        <p>
            <em>Effects:</em> blocks until the state associated with <em>*this</em> contains
            a value or an exception or until <em>abstime</em> is reached. Cancelation point.</p>
        <p>
            <em>Returns:</em> <em>true</em> if the state associated with <em>*this</em> contains
            a value or an exception, <em>false</em> otherwise.</p>
        <p>
            <em>Throws:</em> <code>thread_error</code>, <code>thread_cancel</code>.</p>

        <pre>void cancel();</pre>
        <p>
            <em>Effects:</em> calls <code>thread::cancel</code> on the thread handle of <em>*this</em>'s
            associated state.</p>
        <p>
            [<em>Note:</em> if the thread handle is null, <code>thread::cancel</code> is a no-op.]</p>

<pre>operator R() const;
R get() const;</pre>
        <p>
            <em>Effects:</em> blocks until the state associated with <em>*this</em> contains
            a value or an exception. Cancelation point unless the state already contains a value
            or an exception.</p>
        <p>
            <em>Returns:</em> the stored value.</p>
        <p>
            <em>Throws:</em> the stored exception, <code>thread_cancel</code>, or any exception
            thrown by the copy constructor of <em>R</em>.</p>

        <pre>R move();</pre>
        <p>
            <em>Effects:</em> blocks until the state associated with <em>*this</em> contains
            a value or an exception. Cancelation point unless the state already contains a value
            or an exception.</p>
        <p>
            <em>Returns:</em> the stored value <em>r_</em> by moving from it as if via <code>return std::move(
            r_ )</code>. Stores an exception of type <em>future_result_moved</em> into <em>*this</em>'s
            associated state.</p>
        <p>
            <em>Throws:</em> the stored exception, <code>thread_cancel</code>, or any exception
            thrown by the move constructor of <em>R</em>.</p>

<pre>void set_value( R const &amp; r );
void set_value( R &amp;&amp; r );</pre>
        <p>
            <em>Effects:</em> if <em>*this</em>'s associated state contains no value and no
            exception, stores the value <em>r</em> into the state. If the attempt to copy <em>r</em>
            into the state throws, stores the thrown exception instead as if by using <code>set_exception(
            current_exception() )</code>. Sets the thread handle of the associated state to null.</p>
        <p>
            <em>Throws:</em> nothing.</p>
        <pre>void set_exception( exception_ptr p );</pre>
        <p>
            <em>Effects:</em> if <em>*this</em>'s associated state contains no value and no
            exception, stores the exception <em>p</em> refers to into the state. Sets the thread
            handle of the associated state to null.</p>

        <pre>void set_cancel_handle( thread::handle const &amp; th );</pre>
        <p>
            <em>Effects:</em> sets the thread handle of <em>*this</em>'s associated state to
            <em>th</em>.</p>

<pre>template&lt; class R &gt; class future&lt; R &amp; &gt;
{
public:

    future();
    
    future( future const &amp; rhs );
    future &amp; operator=( future const &amp; rhs );
    
    ~future();

    bool has_value() const;
    bool has_exception() const;

    void join();
    bool try_join();
    bool timed_join( timespec const &amp; abstime );
    
    void cancel();

    operator R &amp;() const;
    R &amp; get() const;

    void set_value( R &amp; r );
    void set_exception( exception_ptr p );

    void set_cancel_handle( thread::handle const &amp; th );
};
</pre>
        <p>The specialization <code>future&lt;R&amp;&gt;</code> stores a reference to <em>R</em>
            instead of a value of type <em>R </em>and has a different signature of <em>set_value</em>.
            It is otherwise identical in behavior to the primary template.</p>

<pre>template&lt; class R &gt; class future&lt; R &amp;&amp; &gt;
{
public:

    future();
    
    future( future const &amp; rhs );
    future( future&lt; R &gt; const &amp; rhs );
    future &amp; operator=( future const &amp; rhs );

    ~future();

    bool has_value() const;
    bool has_exception() const;

    void join();
    bool try_join();
    bool timed_join( timespec const &amp; abstime );

    void cancel();

    operator R ();
    R get();
    R move();

    void set_value( R const &amp; r );
    void set_value( R &amp;&amp; r );
    void set_exception( exception_ptr p );

    void set_cancel_handle( thread::handle const &amp; th );
};
</pre>
        <p>The specialization <code>future&lt;R&amp;&amp;&gt;</code> is identical in behavior
            to <code>future&lt;R&gt;</code>, except as stated below:</p>

        <pre>future( future&lt; R &gt; const &amp; rhs );</pre>
		<p>
            <em>Postconditions:</em> <em>*this</em> refers to the same state as <em>rhs</em>.</p>

<pre>operator R();
R get();</pre>
        <p>
            <em>Returns:</em> <code>move()</code>.</p>

<pre>template&lt;&gt; class future&lt; void &gt;
{
public:

    future();
    
    future( future const &amp; rhs );
    future &amp; operator=( future const &amp; rhs );
    
    ~future();

    bool has_value() const;
    bool has_exception() const;

    void join();
    bool try_join();
    bool timed_join( timespec const &amp; abstime );

    void cancel();

    void get() const;

    void set_value();
    void set_exception( exception_ptr p );

    void set_cancel_handle( thread::handle const &amp; th );
};
</pre>
        <p>The specialization <code>future&lt;void&gt;</code> is identical in behavior
            to the primary template, except as stated below:</p>

        <pre>void get() const;</pre>
        <p>
            <em>Effects:</em> blocks until the state associated with <em>*this</em> contains
            a value or an exception. Cancelation point unless the state already contains a value
            or an exception.</p>
        <p>
            <em>Throws:</em> the stored exception, or <code>thread_cancel</code>.</p>
        <p>
            [<em>Note:</em> this allows generic code to use <code>f.get()</code> in a return statement, even
            when <code>f</code> is <code>future&lt;void&gt;</code>.]</p>
        <p>
            [<em>Example:</em></p>
<pre>template&lt;class R&gt; R generic_function( future&lt;R&gt; ft )
{
    return ft.get();
}
</pre>
        <p>
            <em>--end example.</em> ]</p>

        <pre>void set_value();</pre>
        <p>
            <em>Effects:</em> if <em>*this</em>'s associated state contains no value and no
            exception, stores the value <em>0</em> into the state. Sets the thread handle of the associated state to null.</p>
        <p>
            <em>Throws:</em> nothing.</p>

        <pre>template&lt; class Fn &gt; future&lt; typename result_of&lt;Fn()&gt;::type &gt; fork( Fn fn );</pre>

        <p><em>Requires:</em> The expression <code>fn()</code> must be valid and have a type
            convertible to <em>R</em>, where <em>R</em> is <code>typename result_of&lt;Fn()&gt;::type</code>.</p>

        <p><em>Effects:</em> Evaluates the expression <code>fn()</code> asynchronously with
            respect to the calling thread and places its result in an object <code>ft</code>
            of type <code>future&lt;R&gt;</code> as if by using <code>ft.set_value( fn() )</code>.
            If the expression <code>fn()</code> throws an exception <code>e</code>, places <code>e</code>
            into <code>ft</code> as if by using <code>ft.set_exception( current_exception() )</code>. If
            <code>e</code> is of type <code>thread_cancel</code>, translates it to an exception of type
            <code>fork_canceled</code> before placing it into <code>ft</code>.</p>

        <p><em>Returns:</em> <code>ft</code>.</p>

        <pre>template&lt; class Fn, class A1, ..., class An &gt; future&lt; typename result_of&lt;Fn(A1, ..., An)&gt;::type &gt; fork( Fn fn, A1 a1, ..., An an );</pre>
        <p>
            <em>Returns:</em> <code>fork( bind( fn, a1, ..., an ) )</code>.</p>

		<h2>
            IV. Implementability</h2>
        <p>
            A prototype implementation is available at:</p>
        <ul>
            <li><a href="http://www.pdimov.com/cpp/N2185/future.hpp">http://www.pdimov.com/cpp/N2185/future.hpp</a></li>
            <li><a href="http://www.pdimov.com/cpp/N2185/fork.hpp">http://www.pdimov.com/cpp/N2185/fork.hpp</a></li>
            <li><a href="http://www.pdimov.com/cpp/N2185/fork.cpp">http://www.pdimov.com/cpp/N2185/fork.cpp</a></li>
            <li><a href="http://www.pdimov.com/cpp/N2179/exception_ptr.hpp">http://www.pdimov.com/cpp/N2179/exception_ptr.hpp</a></li>
            <li><a href="http://www.pdimov.com/cpp/N2179/exception_ptr.cpp">http://www.pdimov.com/cpp/N2179/exception_ptr.cpp</a></li>
            <li><a href="http://www.pdimov.com/cpp/N2178/event.hpp">http://www.pdimov.com/cpp/N2178/event.hpp</a></li>
            <li><a href="http://www.pdimov.com/cpp/N2178/event.cpp">http://www.pdimov.com/cpp/N2178/event.cpp</a></li>
        </ul>

        <hr />

		<p><em>--end</em></p>
	</body>
</html>
