docu updated

This commit is contained in:
Oliver Kowalke 2016-02-10 21:01:25 +01:00
parent 1a72352c9c
commit 6c8c8e6ff8
5 changed files with 342 additions and 29 deletions

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
<library id="context" name="Context" dirname="context" last-revision="$Date: 2016/02/09 16:25:31 $"
<library id="context" name="Context" dirname="context" last-revision="$Date: 2016/02/10 20:01:07 $"
xmlns:xi="http://www.w3.org/2001/XInclude">
<libraryinfo>
<authorgroup>
@ -233,6 +233,10 @@
represented by <code><phrase role="identifier">source</phrase></code>. Calculated
Fibonacci numbers are transferred between the two context' via expression
<emphasis>sink(a)</emphasis> (and returned by <emphasis>source()</emphasis>).
Note that this example represents a <emphasis>generator</emphasis> thus the
value transferred into the lambda via <emphasis>source()</emphasis> is not
used. Using <emphasis>boost::optional&lt;&gt;</emphasis> as transferred type,
might be appropriate to express this fact.
</para>
<para>
The locale variables <code><phrase role="identifier">a</phrase></code>, <code><phrase
@ -379,6 +383,33 @@
<phrase id="context.ecv2.parameter_passing"/><link linkend="context.ecv2.parameter_passing">parameter
passing</link>
</bridgehead>
<para>
With <code><phrase role="identifier">execution_context</phrase><phrase role="special">&lt;</phrase><phrase
role="keyword">void</phrase><phrase role="special">&gt;</phrase></code> no
data will be transferred, only the context switch is executed.
</para>
<programlisting><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">void</phrase><phrase role="special">&gt;</phrase> <phrase role="identifier">ctx1</phrase><phrase role="special">([](</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">void</phrase><phrase role="special">&gt;</phrase> <phrase role="identifier">ctx2</phrase><phrase role="special">){</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">&quot;inside ctx1\n&quot;</phrase><phrase role="special">);</phrase>
<phrase role="identifier">ctx2</phrase><phrase role="special">();</phrase>
<phrase role="keyword">return</phrase> <phrase role="identifier">ctx2</phrase><phrase role="special">;</phrase>
<phrase role="special">});</phrase>
<phrase role="identifier">ctx1</phrase><phrase role="special">();</phrase>
<phrase role="identifier">output</phrase><phrase role="special">:</phrase>
<phrase role="identifier">inside</phrase> <phrase role="identifier">ctx1</phrase>
</programlisting>
<para>
<code><phrase role="identifier">ctx1</phrase><phrase role="special">()</phrase></code>
resumes <code><phrase role="identifier">ctx1</phrase></code>, e.g. the lambda
passed at the constructor of <code><phrase role="identifier">ctx1</phrase></code>
is entered. Argument <code><phrase role="identifier">ctx2</phrase></code> represents
the context that has been suspended with the invocation of <code><phrase role="identifier">ctx1</phrase><phrase
role="special">()</phrase></code>. When the lambda returns <code><phrase role="identifier">ctx2</phrase></code>,
context <code><phrase role="identifier">ctx1</phrase></code> will be terminated
while the context represented by <code><phrase role="identifier">ctx2</phrase></code>
is resumed, hence the control of execution returns from <code><phrase role="identifier">ctx1</phrase><phrase
role="special">()</phrase></code>.
</para>
<para>
The arguments passed to <emphasis>execution_context::operator()</emphasis>,
in one context, is passed as the last arguments of the <emphasis>context-function</emphasis>
@ -387,6 +418,56 @@
to <emphasis>execution_context::operator()</emphasis>, in one context, is returned
by <emphasis>execution_context::operator()</emphasis> in the other context.
</para>
<programlisting><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">int</phrase><phrase role="special">&gt;</phrase> <phrase role="identifier">ctx1</phrase><phrase role="special">([](</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">int</phrase><phrase role="special">&gt;</phrase> <phrase role="identifier">ctx2</phrase><phrase role="special">,</phrase> <phrase role="keyword">int</phrase> <phrase role="identifier">j</phrase><phrase role="special">){</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">&quot;inside ctx1, j == %d\n&quot;</phrase><phrase role="special">,</phrase> <phrase role="identifier">j</phrase><phrase role="special">);</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tie</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx2</phrase><phrase role="special">,</phrase> <phrase role="identifier">j</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx2</phrase><phrase role="special">(</phrase><phrase role="identifier">j</phrase><phrase role="special">+</phrase><phrase role="number">1</phrase><phrase role="special">);</phrase>
<phrase role="keyword">return</phrase> <phrase role="identifier">ctx2</phrase><phrase role="special">;</phrase>
<phrase role="special">});</phrase>
<phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase> <phrase role="special">=</phrase> <phrase role="number">1</phrase><phrase role="special">;</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tie</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx1</phrase><phrase role="special">,</phrase> <phrase role="identifier">i</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx1</phrase><phrase role="special">(</phrase><phrase role="identifier">i</phrase><phrase role="special">);</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">&quot;i == %d\n&quot;</phrase><phrase role="special">,</phrase> <phrase role="identifier">i</phrase><phrase role="special">);</phrase>
<phrase role="identifier">output</phrase><phrase role="special">:</phrase>
<phrase role="identifier">inside</phrase> <phrase role="identifier">ctx1</phrase><phrase role="special">,</phrase> <phrase role="identifier">j</phrase> <phrase role="special">==</phrase> <phrase role="number">1</phrase>
<phrase role="identifier">i</phrase> <phrase role="special">==</phrase> <phrase role="number">2</phrase>
</programlisting>
<para>
<code><phrase role="identifier">ctx1</phrase><phrase role="special">(</phrase><phrase
role="identifier">i</phrase><phrase role="special">)</phrase></code> enters
the lambda in context <code><phrase role="identifier">ctx1</phrase></code>
with argument <code><phrase role="identifier">j</phrase><phrase role="special">=</phrase><phrase
role="number">1</phrase></code>. The expression <code><phrase role="identifier">ctx2</phrase><phrase
role="special">(</phrase><phrase role="identifier">j</phrase><phrase role="special">+</phrase><phrase
role="number">1</phrase><phrase role="special">)</phrase></code> resumes the
context represented by <code><phrase role="identifier">ctx2</phrase></code>
and transfers back an integer of <code><phrase role="identifier">j</phrase><phrase
role="special">+</phrase><phrase role="number">1</phrase></code>. On return
of <code><phrase role="identifier">ctx1</phrase><phrase role="special">(</phrase><phrase
role="identifier">i</phrase><phrase role="special">)</phrase></code>, the variable
<code><phrase role="identifier">i</phrase></code> contains the value of <code><phrase
role="identifier">j</phrase><phrase role="special">+</phrase><phrase role="number">1</phrase></code>.
</para>
<para>
If more than one argument has to be transferred, the signature of the context-function
is simply extended.
</para>
<programlisting><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">int</phrase><phrase role="special">,</phrase><phrase role="keyword">int</phrase><phrase role="special">&gt;</phrase> <phrase role="identifier">ctx1</phrase><phrase role="special">([](</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">int</phrase><phrase role="special">,</phrase><phrase role="keyword">int</phrase><phrase role="special">&gt;</phrase> <phrase role="identifier">ctx2</phrase><phrase role="special">,</phrase> <phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase><phrase role="special">,</phrase> <phrase role="keyword">int</phrase> <phrase role="identifier">j</phrase><phrase role="special">){</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">&quot;inside ctx1, i == %d j == %d\n&quot;</phrase><phrase role="special">,</phrase> <phrase role="identifier">i</phrase><phrase role="special">,</phrase> <phrase role="identifier">j</phrase><phrase role="special">);</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tie</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx2</phrase><phrase role="special">,</phrase> <phrase role="identifier">i</phrase><phrase role="special">,</phrase> <phrase role="identifier">j</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx2</phrase><phrase role="special">(</phrase><phrase role="identifier">i</phrase><phrase role="special">+</phrase><phrase role="identifier">j</phrase><phrase role="special">,</phrase><phrase role="identifier">i</phrase><phrase role="special">-</phrase><phrase role="identifier">j</phrase><phrase role="special">);</phrase>
<phrase role="keyword">return</phrase> <phrase role="identifier">ctx2</phrase><phrase role="special">;</phrase>
<phrase role="special">});</phrase>
<phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase> <phrase role="special">=</phrase> <phrase role="number">2</phrase><phrase role="special">,</phrase> <phrase role="identifier">j</phrase> <phrase role="special">=</phrase> <phrase role="number">1</phrase><phrase role="special">;</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tie</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx1</phrase><phrase role="special">,</phrase> <phrase role="identifier">i</phrase><phrase role="special">,</phrase> <phrase role="identifier">j</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx1</phrase><phrase role="special">(</phrase><phrase role="identifier">i</phrase><phrase role="special">,</phrase><phrase role="identifier">j</phrase><phrase role="special">);</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">&quot;i == %d j == %d\n&quot;</phrase><phrase role="special">,</phrase> <phrase role="identifier">i</phrase><phrase role="special">,</phrase> <phrase role="identifier">j</phrase><phrase role="special">);</phrase>
<phrase role="identifier">output</phrase><phrase role="special">:</phrase>
<phrase role="identifier">inside</phrase> <phrase role="identifier">ctx1</phrase><phrase role="special">,</phrase> <phrase role="identifier">i</phrase> <phrase role="special">==</phrase> <phrase role="number">2</phrase> <phrase role="identifier">j</phrase> <phrase role="special">==</phrase> <phrase role="number">1</phrase>
<phrase role="identifier">i</phrase> <phrase role="special">==</phrase> <phrase role="number">3</phrase> <phrase role="identifier">j</phrase> <phrase role="special">==</phrase> <phrase role="number">1</phrase>
</programlisting>
<para>
For use-cases, that require to transfer data of different type in each direction,
<emphasis>boost::variant&lt;&gt;</emphasis> could be used.
</para>
<programlisting><phrase role="keyword">class</phrase> <phrase role="identifier">X</phrase><phrase role="special">{</phrase>
<phrase role="keyword">private</phrase><phrase role="special">:</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">exception_ptr</phrase> <phrase role="identifier">excptr_</phrase><phrase role="special">;</phrase>
@ -432,12 +513,61 @@
<phrase role="identifier">output</phrase><phrase role="special">:</phrase>
<phrase role="number">7</phrase>
</programlisting>
<para>
In the case of unidirectional transfer of data, <emphasis>boost::optional&lt;&gt;</emphasis>
or a pointer are appropriate.
</para>
<anchor id="ecv2_ontop"/>
<bridgehead renderas="sect3" id="context.ecv2.h5">
<phrase id="context.ecv2.executing_function_on_top_of_a_context"/><link linkend="context.ecv2.executing_function_on_top_of_a_context">Executing
function on top of a context</link>
</bridgehead>
<para>
Sometimes it is useful to execute a new function on top of a resumed context.
For this purpose <emphasis>execution_context::operator()</emphasis> with first
argument <code><phrase role="identifier">exec_ontop_arg</phrase></code> has
to be used. The function passed as argument must return a tuple of execution_context
and arguments.
</para>
<programlisting><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">int</phrase><phrase role="special">&gt;</phrase> <phrase role="identifier">f1</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">int</phrase><phrase role="special">&gt;</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">,</phrase><phrase role="keyword">int</phrase> <phrase role="identifier">data</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="string">&quot;f1: entered first time: &quot;</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">data</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tie</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx</phrase><phrase role="special">,</phrase><phrase role="identifier">data</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">(</phrase><phrase role="identifier">data</phrase><phrase role="special">+</phrase><phrase role="number">1</phrase><phrase role="special">);</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="string">&quot;f1: entered second time: &quot;</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">data</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tie</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx</phrase><phrase role="special">,</phrase><phrase role="identifier">data</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">(</phrase><phrase role="identifier">data</phrase><phrase role="special">+</phrase><phrase role="number">1</phrase><phrase role="special">);</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="string">&quot;f1: entered third time: &quot;</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">data</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
<phrase role="keyword">return</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">;</phrase>
<phrase role="special">}</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tuple</phrase><phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">int</phrase><phrase role="special">&gt;,</phrase><phrase role="keyword">int</phrase><phrase role="special">&gt;</phrase> <phrase role="identifier">f2</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">int</phrase><phrase role="special">&gt;</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">,</phrase><phrase role="keyword">int</phrase> <phrase role="identifier">data</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="string">&quot;f2: entered: &quot;</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">data</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
<phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">make_tuple</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx</phrase><phrase role="special">),-</phrase><phrase role="number">1</phrase><phrase role="special">);</phrase>
<phrase role="special">}</phrase>
<phrase role="keyword">int</phrase> <phrase role="identifier">data</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">;</phrase>
<phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">int</phrase> <phrase role="special">&gt;</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">(</phrase><phrase role="identifier">f1</phrase><phrase role="special">);</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tie</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx</phrase><phrase role="special">,</phrase><phrase role="identifier">data</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">(</phrase><phrase role="identifier">data</phrase><phrase role="special">+</phrase><phrase role="number">1</phrase><phrase role="special">);</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="string">&quot;f1: returned first time: &quot;</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">data</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tie</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx</phrase><phrase role="special">,</phrase><phrase role="identifier">data</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">(</phrase><phrase role="identifier">data</phrase><phrase role="special">+</phrase><phrase role="number">1</phrase><phrase role="special">);</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="string">&quot;f1: returned second time: &quot;</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">data</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tie</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx</phrase><phrase role="special">,</phrase><phrase role="identifier">data</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">exec_ontop_arg</phrase><phrase role="special">,</phrase><phrase role="identifier">f2</phrase><phrase role="special">,</phrase><phrase role="identifier">data</phrase><phrase role="special">+</phrase><phrase role="number">1</phrase><phrase role="special">);</phrase>
<phrase role="identifier">output</phrase><phrase role="special">:</phrase>
<phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">entered</phrase> <phrase role="identifier">first</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase>
<phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">returned</phrase> <phrase role="identifier">first</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="number">2</phrase>
<phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">entered</phrase> <phrase role="identifier">second</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="number">3</phrase>
<phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">returned</phrase> <phrase role="identifier">second</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="number">4</phrase>
<phrase role="identifier">f2</phrase><phrase role="special">:</phrase> <phrase role="identifier">entered</phrase><phrase role="special">:</phrase> <phrase role="number">5</phrase>
<phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">entered</phrase> <phrase role="identifier">third</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="special">-</phrase><phrase role="number">1</phrase>
</programlisting>
<bridgehead renderas="sect3" id="context.ecv2.h6">
<phrase id="context.ecv2.class__code__phrase_role__identifier__execution_context__phrase___code_"/><link
linkend="context.ecv2.class__code__phrase_role__identifier__execution_context__phrase___code_">Class
<code><phrase role="identifier">execution_context</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&gt;</phrase>
<programlisting><phrase role="keyword">struct</phrase> <phrase role="identifier">exec_ontop_arg_t</phrase> <phrase role="special">{};</phrase>
<phrase role="keyword">const</phrase> <phrase role="identifier">exec_ontop_arg_t</phrase> <phrase role="identifier">exec_ontop_arg</phrase><phrase role="special">{};</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Params</phrase> <phrase role="special">&gt;</phrase>
@ -449,7 +579,6 @@
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAlloc</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Params</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">preallocated</phrase> <phrase role="identifier">palloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">StackAlloc</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Params</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="special">...</phrase> <phrase role="identifier">params</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Params</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">segemented_stack</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Params</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="special">...</phrase> <phrase role="identifier">params</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
@ -677,6 +806,16 @@
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
Function <code><phrase role="identifier">fn</phrase></code> needs to
return a tuple of execution_context and arguments (<link linkend="ecv2_ontop">see
description</link>).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
@ -689,6 +828,16 @@
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
The context calling this function must not be destroyed before the arguments,
that will be returned from <code><phrase role="identifier">fn</phrase></code>,
are preserved at least in the stack frame of the resumed context.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="ecv2_operator_call_ontop_bridgehead">
@ -733,11 +882,12 @@
<term>Note:</term>
<listitem>
<para>
The returned execution_context indicates if the suspended context has
terminated (return from context-function) via <code><phrase role="keyword">bool</phrase>
<phrase role="keyword">operator</phrase><phrase role="special">()</phrase></code>.
If the returned execution_context has terminated no data are transferred
in the returned tuple.
The tuple of execution_context and returned arguments from <code><phrase
role="identifier">fn</phrase></code> are passed as arguments to the context-function
of resumed context (if the context is entered the first time) or those
arguments are returned from <code><phrase role="identifier">execution_context</phrase><phrase
role="special">::</phrase><phrase role="keyword">operator</phrase><phrase
role="special">()</phrase></code> within the resumed context.
</para>
</listitem>
</varlistentry>
@ -960,7 +1110,7 @@
(version 1)</link></title>
<note>
<para>
This class is enabled if property <emphasis>segmented-stacks=on</emphasis>
This class is only enabled if property <emphasis>segmented-stacks=on</emphasis>
(enables segmented stacks) or compiler flag <emphasis>BOOST_EXECUTION_CONTEXT=1</emphasis>
is specified at b2-commandline.
</para>

View File

@ -51,7 +51,6 @@ __ec_op__ on `*this`) and `args` are the data passed to __ec_op__. The return
value is the execution_context that has to be resumed, while this context
terminates.
Benefits of __ecv2__ over __ecv1__ are: faster context switch, type-safety of
passed/returned arguments.
@ -161,7 +160,6 @@ the stack is exchanged by each context switch.
Parsed: +
Parsed: 1
In this example a recursive descent parser uses a callback to emit a newly
passed symbol. Using __econtext__ the control flow can be inverted, e.g. the
user-code pulls parsed symbols from the parser - instead to get pushed from the
@ -177,6 +175,7 @@ Sometimes it is necessary to unwind the stack of an unfinished context to
destroy local stack variables so they can release allocated resources (RAII
pattern). The user is responsible for this task.
[#ecv2_prealloc]
[heading allocating control structures on top of stack]
Allocating control structures on top of the stack requires to allocated the
@ -210,17 +209,20 @@ of the stack.]
...
};
[heading exception handling]
If the function executed inside a __econtext__ emits ans exception, the
application is terminated by calling ['std::terminate()]. ['std::exception_ptr]
can be used to transfer exceptions between different execution contexts.
[heading parameter passing]
With `execution_context<void>` no data will be transferred, only the context
switch is executed.
boost::context::execution_context<void> ctx1([](boost::context::execution_context<void> ctx2){
std::printf("inside ctx1\n");
ctx2();
return ctx2;
});
ctx1();
@ -230,16 +232,16 @@ switch is executed.
`ctx1()` resumes `ctx1`, e.g. the lambda passed at the constructor of `ctx1` is
entered. Argument `ctx2` represents the context that has been suspended with the
invocation of `ctx1()`. The lambda returns `ctx2` that let terminate context
`ctx1`, while the context represented by `ctx2` is resumed, hence the control of
execution returns from `ctx1()`.
invocation of `ctx1()`. When the lambda returns `ctx2`, context `ctx1` will be
terminated while the context represented by `ctx2` is resumed, hence the control
of execution returns from `ctx1()`.
The arguments passed to __ec_op__, in one context, is passed as the last
arguments of the __context_fn__ if the context is started for the first time.
In all following invocations of __ec_op__ the arguments passed to __ec_op__, in
one context, is returned by __ec_op__ in the other context.
std::tuple<boost::context::execution_context<int>,int> ctx1([](boost::context::execution_context<int> ctx2, int j){
boost::context::execution_context<int> ctx1([](boost::context::execution_context<int> ctx2, int j){
std::printf("inside ctx1, j == %d\n", j);
std::tie(ctx2, j) = ctx2(j+1);
return ctx2;
@ -260,7 +262,7 @@ value of `j+1`.
If more than one argument has to be transferred, the signature of the
context-function is simply extended.
std::tuple<boost::context::execution_context<int,int>,int,int> ctx1([](boost::context::execution_context<int,int> ctx2, int i, int j){
boost::context::execution_context<int,int> ctx1([](boost::context::execution_context<int,int> ctx2, int i, int j){
std::printf("inside ctx1, i == %d j == %d\n", i, j);
std::tie(ctx2, i, j) = ctx2(i+j,i-j);
return ctx2;
@ -327,6 +329,40 @@ pointer are appropriate.
[#ecv2_ontop]
[heading Executing function on top of a context]
Sometimes it is useful to execute a new function on top of a resumed context.
For this purpose __ec_op__ with first argument `exec_ontop_arg` has to be used.
The function passed as argument must return a tuple of execution_context and
arguments.
boost::context::execution_context<int> f1(boost::context::execution_context<int> ctx,int data) {
std::cout << "f1: entered first time: " << data << std::endl;
std::tie(ctx,data) = ctx(data+1);
std::cout << "f1: entered second time: " << data << std::endl;
std::tie(ctx,data) = ctx(data+1);
std::cout << "f1: entered third time: " << data << std::endl;
return ctx;
}
std::tuple<boost::context::execution_context<int>,int> f2(boost::context::execution_context<int> ctx,int data) {
std::cout << "f2: entered: " << data << std::endl;
return std::make_tuple(std::move(ctx),-1);
}
int data = 0;
ctx::execution_context< int > ctx(f1);
std::tie(ctx,data) = ctx(data+1);
std::cout << "f1: returned first time: " << data << std::endl;
std::tie(ctx,data) = ctx(data+1);
std::cout << "f1: returned second time: " << data << std::endl;
std::tie(ctx,data) = ctx(ctx::exec_ontop_arg,f2,data+1);
output:
f1: entered first time: 1
f1: returned first time: 2
f1: entered second time: 3
f1: returned second time: 4
f2: entered: 5
f1: entered third time: -1
[heading Class `execution_context`]
@ -456,9 +492,7 @@ by the most recent call to `execution_context::operator()` in the same thread.]]
most recent call to `execution_context::operator()`, if any and a
execution_context representing the context that has been suspended.]]
[[Note:] [Function `fn` needs to return a tuple of execution_context and
arguments ([link ev2_ontop see description]).]]
terminated (return from context-function) via `bool operator()`. If the returned
execution_context has terminated no data are transferred in the returned tuple.]]
arguments ([link ecv2_ontop see description]).]]
[[Note:] [The returned execution_context indicates if the suspended context has
terminated (return from context-function) via `bool operator()`. If the returned
execution_context has terminated no data are transferred in the returned tuple.]]

View File

@ -33,7 +33,7 @@
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
This class is enabled if property <span class="emphasis"><em>segmented-stacks=on</em></span>
This class is only enabled if property <span class="emphasis"><em>segmented-stacks=on</em></span>
(enables segmented stacks) or compiler flag <span class="emphasis"><em>BOOST_EXECUTION_CONTEXT=1</em></span>
is specified at b2-commandline.
</p></td></tr>

View File

@ -148,6 +148,10 @@
represented by <code class="computeroutput"><span class="identifier">source</span></code>. Calculated
Fibonacci numbers are transferred between the two context' via expression
<span class="emphasis"><em>sink(a)</em></span> (and returned by <span class="emphasis"><em>source()</em></span>).
Note that this example represents a <span class="emphasis"><em>generator</em></span> thus the
value transferred into the lambda via <span class="emphasis"><em>source()</em></span> is not
used. Using <span class="emphasis"><em>boost::optional&lt;&gt;</em></span> as transferred type,
might be appropriate to express this fact.
</p>
<p>
The locale variables <code class="computeroutput"><span class="identifier">a</span></code>, <code class="computeroutput"><span class="identifier">b</span></code> and <code class="computeroutput"> <span class="identifier">next</span></code>
@ -299,6 +303,30 @@
<span><a name="context.ecv2.parameter_passing"></a></span><a class="link" href="ecv2.html#context.ecv2.parameter_passing">parameter
passing</a>
</h4>
<p>
With <code class="computeroutput"><span class="identifier">execution_context</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span></code> no
data will be transferred, only the context switch is executed.
</p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">execution_context</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span> <span class="identifier">ctx1</span><span class="special">([](</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">execution_context</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span> <span class="identifier">ctx2</span><span class="special">){</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">printf</span><span class="special">(</span><span class="string">"inside ctx1\n"</span><span class="special">);</span>
<span class="identifier">ctx2</span><span class="special">();</span>
<span class="keyword">return</span> <span class="identifier">ctx2</span><span class="special">;</span>
<span class="special">});</span>
<span class="identifier">ctx1</span><span class="special">();</span>
<span class="identifier">output</span><span class="special">:</span>
<span class="identifier">inside</span> <span class="identifier">ctx1</span>
</pre>
<p>
<code class="computeroutput"><span class="identifier">ctx1</span><span class="special">()</span></code>
resumes <code class="computeroutput"><span class="identifier">ctx1</span></code>, e.g. the lambda
passed at the constructor of <code class="computeroutput"><span class="identifier">ctx1</span></code>
is entered. Argument <code class="computeroutput"><span class="identifier">ctx2</span></code> represents
the context that has been suspended with the invocation of <code class="computeroutput"><span class="identifier">ctx1</span><span class="special">()</span></code>. When the lambda returns <code class="computeroutput"><span class="identifier">ctx2</span></code>,
context <code class="computeroutput"><span class="identifier">ctx1</span></code> will be terminated
while the context represented by <code class="computeroutput"><span class="identifier">ctx2</span></code>
is resumed, hence the control of execution returns from <code class="computeroutput"><span class="identifier">ctx1</span><span class="special">()</span></code>.
</p>
<p>
The arguments passed to <span class="emphasis"><em>execution_context::operator()</em></span>,
in one context, is passed as the last arguments of the <span class="emphasis"><em>context-function</em></span>
@ -307,6 +335,49 @@
to <span class="emphasis"><em>execution_context::operator()</em></span>, in one context, is returned
by <span class="emphasis"><em>execution_context::operator()</em></span> in the other context.
</p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">execution_context</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">ctx1</span><span class="special">([](</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">execution_context</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">ctx2</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">j</span><span class="special">){</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">printf</span><span class="special">(</span><span class="string">"inside ctx1, j == %d\n"</span><span class="special">,</span> <span class="identifier">j</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tie</span><span class="special">(</span><span class="identifier">ctx2</span><span class="special">,</span> <span class="identifier">j</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">ctx2</span><span class="special">(</span><span class="identifier">j</span><span class="special">+</span><span class="number">1</span><span class="special">);</span>
<span class="keyword">return</span> <span class="identifier">ctx2</span><span class="special">;</span>
<span class="special">});</span>
<span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tie</span><span class="special">(</span><span class="identifier">ctx1</span><span class="special">,</span> <span class="identifier">i</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">ctx1</span><span class="special">(</span><span class="identifier">i</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">printf</span><span class="special">(</span><span class="string">"i == %d\n"</span><span class="special">,</span> <span class="identifier">i</span><span class="special">);</span>
<span class="identifier">output</span><span class="special">:</span>
<span class="identifier">inside</span> <span class="identifier">ctx1</span><span class="special">,</span> <span class="identifier">j</span> <span class="special">==</span> <span class="number">1</span>
<span class="identifier">i</span> <span class="special">==</span> <span class="number">2</span>
</pre>
<p>
<code class="computeroutput"><span class="identifier">ctx1</span><span class="special">(</span><span class="identifier">i</span><span class="special">)</span></code> enters
the lambda in context <code class="computeroutput"><span class="identifier">ctx1</span></code>
with argument <code class="computeroutput"><span class="identifier">j</span><span class="special">=</span><span class="number">1</span></code>. The expression <code class="computeroutput"><span class="identifier">ctx2</span><span class="special">(</span><span class="identifier">j</span><span class="special">+</span><span class="number">1</span><span class="special">)</span></code> resumes the
context represented by <code class="computeroutput"><span class="identifier">ctx2</span></code>
and transfers back an integer of <code class="computeroutput"><span class="identifier">j</span><span class="special">+</span><span class="number">1</span></code>. On return
of <code class="computeroutput"><span class="identifier">ctx1</span><span class="special">(</span><span class="identifier">i</span><span class="special">)</span></code>, the variable
<code class="computeroutput"><span class="identifier">i</span></code> contains the value of <code class="computeroutput"><span class="identifier">j</span><span class="special">+</span><span class="number">1</span></code>.
</p>
<p>
If more than one argument has to be transferred, the signature of the context-function
is simply extended.
</p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">execution_context</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">ctx1</span><span class="special">([](</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">execution_context</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">,</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">ctx2</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">i</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">j</span><span class="special">){</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">printf</span><span class="special">(</span><span class="string">"inside ctx1, i == %d j == %d\n"</span><span class="special">,</span> <span class="identifier">i</span><span class="special">,</span> <span class="identifier">j</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tie</span><span class="special">(</span><span class="identifier">ctx2</span><span class="special">,</span> <span class="identifier">i</span><span class="special">,</span> <span class="identifier">j</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">ctx2</span><span class="special">(</span><span class="identifier">i</span><span class="special">+</span><span class="identifier">j</span><span class="special">,</span><span class="identifier">i</span><span class="special">-</span><span class="identifier">j</span><span class="special">);</span>
<span class="keyword">return</span> <span class="identifier">ctx2</span><span class="special">;</span>
<span class="special">});</span>
<span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">2</span><span class="special">,</span> <span class="identifier">j</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tie</span><span class="special">(</span><span class="identifier">ctx1</span><span class="special">,</span> <span class="identifier">i</span><span class="special">,</span> <span class="identifier">j</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">ctx1</span><span class="special">(</span><span class="identifier">i</span><span class="special">,</span><span class="identifier">j</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">printf</span><span class="special">(</span><span class="string">"i == %d j == %d\n"</span><span class="special">,</span> <span class="identifier">i</span><span class="special">,</span> <span class="identifier">j</span><span class="special">);</span>
<span class="identifier">output</span><span class="special">:</span>
<span class="identifier">inside</span> <span class="identifier">ctx1</span><span class="special">,</span> <span class="identifier">i</span> <span class="special">==</span> <span class="number">2</span> <span class="identifier">j</span> <span class="special">==</span> <span class="number">1</span>
<span class="identifier">i</span> <span class="special">==</span> <span class="number">3</span> <span class="identifier">j</span> <span class="special">==</span> <span class="number">1</span>
</pre>
<p>
For use-cases, that require to transfer data of different type in each direction,
<span class="emphasis"><em>boost::variant&lt;&gt;</em></span> could be used.
</p>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">X</span><span class="special">{</span>
<span class="keyword">private</span><span class="special">:</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span> <span class="identifier">excptr_</span><span class="special">;</span>
@ -352,12 +423,61 @@
<span class="identifier">output</span><span class="special">:</span>
<span class="number">7</span>
</pre>
<h4>
<p>
In the case of unidirectional transfer of data, <span class="emphasis"><em>boost::optional&lt;&gt;</em></span>
or a pointer are appropriate.
</p>
<a name="ecv2_ontop"></a><h4>
<a name="context.ecv2.h5"></a>
<span><a name="context.ecv2.executing_function_on_top_of_a_context"></a></span><a class="link" href="ecv2.html#context.ecv2.executing_function_on_top_of_a_context">Executing
function on top of a context</a>
</h4>
<p>
Sometimes it is useful to execute a new function on top of a resumed context.
For this purpose <span class="emphasis"><em>execution_context::operator()</em></span> with first
argument <code class="computeroutput"><span class="identifier">exec_ontop_arg</span></code> has
to be used. The function passed as argument must return a tuple of execution_context
and arguments.
</p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">execution_context</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">f1</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">execution_context</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">ctx</span><span class="special">,</span><span class="keyword">int</span> <span class="identifier">data</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: entered first time: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tie</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">,</span><span class="identifier">data</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">ctx</span><span class="special">(</span><span class="identifier">data</span><span class="special">+</span><span class="number">1</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: entered second time: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tie</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">,</span><span class="identifier">data</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">ctx</span><span class="special">(</span><span class="identifier">data</span><span class="special">+</span><span class="number">1</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: entered third time: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="keyword">return</span> <span class="identifier">ctx</span><span class="special">;</span>
<span class="special">}</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tuple</span><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">execution_context</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;,</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">f2</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">execution_context</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">ctx</span><span class="special">,</span><span class="keyword">int</span> <span class="identifier">data</span><span class="special">)</span> <span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f2: entered: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_tuple</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">),-</span><span class="number">1</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">int</span> <span class="identifier">data</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="identifier">ctx</span><span class="special">::</span><span class="identifier">execution_context</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;</span> <span class="identifier">ctx</span><span class="special">(</span><span class="identifier">f1</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tie</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">,</span><span class="identifier">data</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">ctx</span><span class="special">(</span><span class="identifier">data</span><span class="special">+</span><span class="number">1</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: returned first time: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tie</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">,</span><span class="identifier">data</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">ctx</span><span class="special">(</span><span class="identifier">data</span><span class="special">+</span><span class="number">1</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"f1: returned second time: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">tie</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">,</span><span class="identifier">data</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">ctx</span><span class="special">(</span><span class="identifier">ctx</span><span class="special">::</span><span class="identifier">exec_ontop_arg</span><span class="special">,</span><span class="identifier">f2</span><span class="special">,</span><span class="identifier">data</span><span class="special">+</span><span class="number">1</span><span class="special">);</span>
<span class="identifier">output</span><span class="special">:</span>
<span class="identifier">f1</span><span class="special">:</span> <span class="identifier">entered</span> <span class="identifier">first</span> <span class="identifier">time</span><span class="special">:</span> <span class="number">1</span>
<span class="identifier">f1</span><span class="special">:</span> <span class="identifier">returned</span> <span class="identifier">first</span> <span class="identifier">time</span><span class="special">:</span> <span class="number">2</span>
<span class="identifier">f1</span><span class="special">:</span> <span class="identifier">entered</span> <span class="identifier">second</span> <span class="identifier">time</span><span class="special">:</span> <span class="number">3</span>
<span class="identifier">f1</span><span class="special">:</span> <span class="identifier">returned</span> <span class="identifier">second</span> <span class="identifier">time</span><span class="special">:</span> <span class="number">4</span>
<span class="identifier">f2</span><span class="special">:</span> <span class="identifier">entered</span><span class="special">:</span> <span class="number">5</span>
<span class="identifier">f1</span><span class="special">:</span> <span class="identifier">entered</span> <span class="identifier">third</span> <span class="identifier">time</span><span class="special">:</span> <span class="special">-</span><span class="number">1</span>
</pre>
<h4>
<a name="context.ecv2.h6"></a>
<span><a name="context.ecv2.class__code__phrase_role__identifier__execution_context__phrase___code_"></a></span><a class="link" href="ecv2.html#context.ecv2.class__code__phrase_role__identifier__execution_context__phrase___code_">Class
<code class="computeroutput"><span class="identifier">execution_context</span></code></a>
</h4>
<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Args</span> <span class="special">&gt;</span>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">exec_ontop_arg_t</span> <span class="special">{};</span>
<span class="keyword">const</span> <span class="identifier">exec_ontop_arg_t</span> <span class="identifier">exec_ontop_arg</span><span class="special">{};</span>
<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Args</span> <span class="special">&gt;</span>
<span class="keyword">class</span> <span class="identifier">execution_context</span> <span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">,</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Params</span> <span class="special">&gt;</span>
@ -369,7 +489,6 @@
<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">StackAlloc</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">,</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Params</span> <span class="special">&gt;</span>
<span class="identifier">execution_context</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator_arg_t</span><span class="special">,</span> <span class="identifier">preallocated</span> <span class="identifier">palloc</span><span class="special">,</span> <span class="identifier">StackAlloc</span> <span class="identifier">salloc</span><span class="special">,</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">,</span> <span class="identifier">Params</span> <span class="special">&amp;&amp;</span> <span class="special">...</span> <span class="identifier">params</span><span class="special">);</span>
<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">,</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Params</span> <span class="special">&gt;</span>
<span class="identifier">execution_context</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator_arg_t</span><span class="special">,</span> <span class="identifier">segemented_stack</span><span class="special">,</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">,</span> <span class="identifier">Params</span> <span class="special">&amp;&amp;</span> <span class="special">...</span> <span class="identifier">params</span><span class="special">)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
@ -573,6 +692,12 @@
the context that has been suspended.
</p></dd>
<dt><span class="term">Note:</span></dt>
<dd><p>
Function <code class="computeroutput"><span class="identifier">fn</span></code> needs to
return a tuple of execution_context and arguments (<a class="link" href="ecv2.html#ecv2_ontop">see
description</a>).
</p></dd>
<dt><span class="term">Note:</span></dt>
<dd><p>
The returned execution_context indicates if the suspended context has
terminated (return from context-function) via <code class="computeroutput"><span class="keyword">bool</span>
@ -580,6 +705,12 @@
If the returned execution_context has terminated no data are transferred
in the returned tuple.
</p></dd>
<dt><span class="term">Note:</span></dt>
<dd><p>
The context calling this function must not be destroyed before the arguments,
that will be returned from <code class="computeroutput"><span class="identifier">fn</span></code>,
are preserved at least in the stack frame of the resumed context.
</p></dd>
</dl>
</div>
<p>
@ -616,11 +747,9 @@
</p></dd>
<dt><span class="term">Note:</span></dt>
<dd><p>
The returned execution_context indicates if the suspended context has
terminated (return from context-function) via <code class="computeroutput"><span class="keyword">bool</span>
<span class="keyword">operator</span><span class="special">()</span></code>.
If the returned execution_context has terminated no data are transferred
in the returned tuple.
The tuple of execution_context and returned arguments from <code class="computeroutput"><span class="identifier">fn</span></code> are passed as arguments to the context-function
of resumed context (if the context is entered the first time) or those
arguments are returned from <code class="computeroutput"><span class="identifier">execution_context</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()</span></code> within the resumed context.
</p></dd>
</dl>
</div>

View File

@ -67,7 +67,7 @@
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"><p><small>Last revised: February 09, 2016 at 16:25:35 GMT</small></p></td>
<td align="left"><p><small>Last revised: February 10, 2016 at 20:01:10 GMT</small></p></td>
<td align="right"><div class="copyright-footer"></div></td>
</tr></table>
<hr>