docu updated
This commit is contained in:
parent
1a72352c9c
commit
6c8c8e6ff8
168
doc/context.xml
168
doc/context.xml
@ -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<></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"><</phrase><phrase
|
||||
role="keyword">void</phrase><phrase role="special">></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"><</phrase><phrase role="keyword">void</phrase><phrase role="special">></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"><</phrase><phrase role="keyword">void</phrase><phrase role="special">></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">"inside ctx1\n"</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"><</phrase><phrase role="keyword">int</phrase><phrase role="special">></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"><</phrase><phrase role="keyword">int</phrase><phrase role="special">></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">"inside ctx1, j == %d\n"</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">"i == %d\n"</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"><</phrase><phrase role="keyword">int</phrase><phrase role="special">,</phrase><phrase role="keyword">int</phrase><phrase role="special">></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"><</phrase><phrase role="keyword">int</phrase><phrase role="special">,</phrase><phrase role="keyword">int</phrase><phrase role="special">></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">"inside ctx1, i == %d j == %d\n"</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">"i == %d j == %d\n"</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<></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<></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"><</phrase><phrase role="keyword">int</phrase><phrase role="special">></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"><</phrase><phrase role="keyword">int</phrase><phrase role="special">></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"><<</phrase> <phrase role="string">"f1: entered first time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</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"><<</phrase> <phrase role="string">"f1: entered second time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</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"><<</phrase> <phrase role="string">"f1: entered third time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</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"><</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"><</phrase><phrase role="keyword">int</phrase><phrase role="special">>,</phrase><phrase role="keyword">int</phrase><phrase role="special">></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"><</phrase><phrase role="keyword">int</phrase><phrase role="special">></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"><<</phrase> <phrase role="string">"f2: entered: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</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"><</phrase> <phrase role="keyword">int</phrase> <phrase role="special">></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"><<</phrase> <phrase role="string">"f1: returned first time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</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"><<</phrase> <phrase role="string">"f1: returned second time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</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"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></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"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></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"><</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">></phrase>
|
||||
@ -449,7 +579,6 @@
|
||||
<phrase role="keyword">template</phrase><phrase role="special"><</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">></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">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Params</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">params</phrase><phrase role="special">);</phrase>
|
||||
|
||||
|
||||
<phrase role="keyword">template</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">></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">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Params</phrase> <phrase role="special">&&</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>
|
||||
|
@ -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.]]
|
||||
|
@ -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>
|
||||
|
@ -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<></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"><</span><span class="keyword">void</span><span class="special">></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"><</span><span class="keyword">void</span><span class="special">></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"><</span><span class="keyword">void</span><span class="special">></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"><</span><span class="keyword">int</span><span class="special">></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"><</span><span class="keyword">int</span><span class="special">></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"><</span><span class="keyword">int</span><span class="special">,</span><span class="keyword">int</span><span class="special">></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"><</span><span class="keyword">int</span><span class="special">,</span><span class="keyword">int</span><span class="special">></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<></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<></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"><</span><span class="keyword">int</span><span class="special">></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"><</span><span class="keyword">int</span><span class="special">></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"><<</span> <span class="string">"f1: entered first time: "</span> <span class="special"><<</span> <span class="identifier">data</span> <span class="special"><<</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"><<</span> <span class="string">"f1: entered second time: "</span> <span class="special"><<</span> <span class="identifier">data</span> <span class="special"><<</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"><<</span> <span class="string">"f1: entered third time: "</span> <span class="special"><<</span> <span class="identifier">data</span> <span class="special"><<</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"><</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"><</span><span class="keyword">int</span><span class="special">>,</span><span class="keyword">int</span><span class="special">></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"><</span><span class="keyword">int</span><span class="special">></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"><<</span> <span class="string">"f2: entered: "</span> <span class="special"><<</span> <span class="identifier">data</span> <span class="special"><<</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"><</span> <span class="keyword">int</span> <span class="special">></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"><<</span> <span class="string">"f1: returned first time: "</span> <span class="special"><<</span> <span class="identifier">data</span> <span class="special"><<</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"><<</span> <span class="string">"f1: returned second time: "</span> <span class="special"><<</span> <span class="identifier">data</span> <span class="special"><<</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"><</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Args</span> <span class="special">></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"><</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Args</span> <span class="special">></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"><</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">></span>
|
||||
@ -369,7 +489,6 @@
|
||||
<span class="keyword">template</span><span class="special"><</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">></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">&&</span> <span class="identifier">fn</span><span class="special">,</span> <span class="identifier">Params</span> <span class="special">&&</span> <span class="special">...</span> <span class="identifier">params</span><span class="special">);</span>
|
||||
|
||||
|
||||
<span class="keyword">template</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">></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">&&</span> <span class="identifier">fn</span><span class="special">,</span> <span class="identifier">Params</span> <span class="special">&&</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>
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user