<?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: 2018/02/15 16:18:27 $"
+<library id="context" name="Context" dirname="context" last-revision="$Date: 2019/10/02 06:15:27 $"
xmlns:xi="http://www.w3.org/2001/XInclude">
<libraryinfo>
<authorgroup>
is done within a single thread.
</para>
<para>
- In order to use the classes and functions described here, you can either include
- the specific headers specified by the descriptions of each class or function,
- or include the master library header:
- </para>
-<programlisting><phrase role="preprocessor">#include</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">all</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">></phrase>
-</programlisting>
- <para>
- which includes all the other headers in turn.
- </para>
- <para>
All functions and classes are contained in the namespace <emphasis>boost::context</emphasis>.
</para>
<note>
</note>
<important>
<para>
- Windows: turn off global program optimization (/GL) and change /EHsc (compiler
- assumes that functions declared as extern "C" never throw a C++
- exception) to /EHs (tells compiler assumes that functions declared as extern
- "C" may throw an exception).
+ Windows using fcontext_t: turn off global program optimization (/GL) and
+ change /EHsc (compiler assumes that functions declared as extern "C"
+ never throw a C++ exception) to /EHs (tells compiler assumes that functions
+ declared as extern "C" may throw an exception).
</para>
</important>
</section>
</important>
<important>
<para>
- Windows: for safe SEH the property 'asmflags=\safeseh' must be specified
- at bjam command line.
+ Windows using fcontext_t: for safe SEH the property 'asmflags=\safeseh' must
+ be specified at bjam command line.
</para>
</important>
<important>
<para>
- Windows: turn off global program optimization (/GL) and change /EHsc (compiler
- assumes that functions declared as extern "C" never throw a C++
- exception) to /EHs (tells compiler assumes that functions declared as extern
- "C" may throw an exception).
+ Windows using fcontext_t: turn off global program optimization (/GL) and
+ change /EHsc (compiler assumes that functions declared as extern "C"
+ never throw a C++ exception) to /EHs (tells compiler assumes that functions
+ declared as extern "C" may throw an exception).
</para>
</important>
+ <para>
+ Because this library uses C++11 extensively, it requires a compatible compiler.
+ Known minimum working versions are as follows: Microsoft Visual Studio 2015
+ (msvc-14.0), GCC 4.8 (with -std=c++11), Clang 3.4 (with -std=c++11). Other
+ compilers may work, if they support the following language features: auto declarations,
+ constexpr, defaulted functions, final, hdr thread, hdr tuple, lambdas, noexcept,
+ nullptr, rvalue references, template aliases. thread local, variadic templates.
+ </para>
</section>
<section id="context.ff">
<title><anchor id="ff"/><link linkend="context.ff">Context switching with fibers</link></title>
</bridgehead>
<para>
If the function executed inside a <emphasis>context-function</emphasis> emits
- ans exception, the application is terminated by calling <code><phrase role="identifier">std</phrase><phrase
+ an exception, the application is terminated by calling <code><phrase role="identifier">std</phrase><phrase
role="special">::</phrase><phrase role="identifier">terminate</phrase><phrase
role="special">()</phrase></code>. <code><phrase role="identifier">std</phrase><phrase
role="special">::</phrase><phrase role="identifier">exception_ptr</phrase></code>
</variablelist>
</section>
</section>
- <section id="context.ecv2">
- <title><anchor id="ecv2"/><link linkend="context.ecv2">Class execution_context
- (version 2)</link></title>
- <note>
+ <section id="context.stack">
+ <title><anchor id="stack"/><link linkend="context.stack">Stack allocation</link></title>
+ <para>
+ The memory used by the stack is allocated/deallocated via a <emphasis>StackAllocator</emphasis>
+ which is required to model a <emphasis>stack-allocator concept</emphasis>.
+ </para>
+ <bridgehead renderas="sect3" id="context.stack.h0">
+ <phrase id="context.stack._emphasis_stack_allocator_concept__emphasis_"/><link
+ linkend="context.stack._emphasis_stack_allocator_concept__emphasis_"><emphasis>stack-allocator
+ concept</emphasis></link>
+ </bridgehead>
+ <para>
+ A <emphasis>StackAllocator</emphasis> must satisfy the <emphasis>stack-allocator
+ concept</emphasis> requirements shown in the following table, in which <code><phrase
+ role="identifier">a</phrase></code> is an object of a <emphasis>StackAllocator</emphasis>
+ type, <code><phrase role="identifier">sctx</phrase></code> is a <code><phrase
+ role="identifier">stack_context</phrase></code>, and <code><phrase role="identifier">size</phrase></code>
+ is a <code><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
+ role="identifier">size_t</phrase></code>:
+ </para>
+ <informaltable frame="all">
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>
+ <para>
+ expression
+ </para>
+ </entry>
+ <entry>
+ <para>
+ return type
+ </para>
+ </entry>
+ <entry>
+ <para>
+ notes
+ </para>
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <para>
+ <code><phrase role="identifier">a</phrase><phrase role="special">(</phrase><phrase
+ role="identifier">size</phrase><phrase role="special">)</phrase></code>
+ </para>
+ </entry>
+ <entry>
+ </entry>
+ <entry>
+ <para>
+ creates a stack allocator
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para>
+ <code><phrase role="identifier">a</phrase><phrase role="special">.</phrase><phrase
+ role="identifier">allocate</phrase><phrase role="special">()</phrase></code>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ <code><phrase role="identifier">stack_context</phrase></code>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ creates a stack
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para>
+ <code><phrase role="identifier">a</phrase><phrase role="special">.</phrase><phrase
+ role="identifier">deallocate</phrase><phrase role="special">(</phrase>
+ <phrase role="identifier">sctx</phrase><phrase role="special">)</phrase></code>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ <code><phrase role="keyword">void</phrase></code>
+ </para>
+ </entry>
+ <entry>
+ <para>
+ deallocates the stack created by <code><phrase role="identifier">a</phrase><phrase
+ role="special">.</phrase><phrase role="identifier">allocate</phrase><phrase
+ role="special">()</phrase></code>
+ </para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ <important>
<para>
- <emphasis>execution_context</emphasis> (v2) is the reference implementation
- of C++ proposal <ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0099r1.pdf">P099R1:
- A low-level API for stackful context switching</ulink>.
+ The implementation of <code><phrase role="identifier">allocate</phrase><phrase
+ role="special">()</phrase></code> might include logic to protect against
+ exceeding the context's available stack size rather than leaving it as undefined
+ behaviour.
</para>
- </note>
- <note>
+ </important>
+ <important>
<para>
- <emphasis>execution_context</emphasis> (v2) resides in the inlined sub-namespace
- <code><phrase role="identifier">v2</phrase></code>.
+ Calling <code><phrase role="identifier">deallocate</phrase><phrase role="special">()</phrase></code>
+ with a <code><phrase role="identifier">stack_context</phrase></code> not
+ set by <code><phrase role="identifier">allocate</phrase><phrase role="special">()</phrase></code>
+ results in undefined behaviour.
</para>
- </note>
+ </important>
<note>
<para>
- Segmented stacks (<emphasis>segmented-stacks=on</emphasis>), e.g. on demand
- growing stacks, are not supported by <emphasis>execution_context</emphasis>
- (v2).
+ Depending on the architecture <code><phrase role="identifier">allocate</phrase><phrase
+ role="special">()</phrase></code> stores an address from the top of the stack
+ (growing downwards) or the bottom of the stack (growing upwards).
</para>
</note>
- <para>
- Class <emphasis>execution_context</emphasis> encapsulates context switching
- and manages the associated context' stack (allocation/deallocation).
- </para>
- <para>
- <emphasis>execution_context</emphasis> allocates the context stack (using its
- <link linkend="stack"><emphasis>StackAllocator</emphasis></link> argument)
- and creates a control structure on top of it. This structure is responsible
- for managing context' stack. The address of the control structure is stored
- in the first frame of context' stack (e.g. it can not directly accessed from
- within <emphasis>execution_context</emphasis>). In contrast to <link linkend="ecv1"><emphasis>execution_context</emphasis>
- (v1)</link> the ownership of the control structure is not shared (no member
- variable to control structure in <emphasis>execution_context</emphasis>).
- <emphasis>execution_context</emphasis> keeps internally a state that is moved
- by a call of <emphasis>execution_context::operator()</emphasis> (<code><phrase
- role="special">*</phrase><phrase role="keyword">this</phrase></code> will be
- invalidated), e.g. after a calling <emphasis>execution_context::operator()</emphasis>,
- <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
- can not be used for an additional context switch.
- </para>
- <para>
- <emphasis>execution_context</emphasis> is only move-constructible and move-assignable.
- </para>
- <para>
- The moved state is assigned to a new instance of <emphasis>execution_context</emphasis>.
- This object becomes the first argument of the context-function, if the context
- was resumed the first time, or the first element in a tuple returned by <emphasis>execution_context::operator()</emphasis>
- that has been called in the resumed context. In contrast to <link linkend="ecv1"><emphasis>execution_context</emphasis>
- (v1)</link>, the context switch is faster because no global pointer etc. is
- involved.
- </para>
- <important>
+ <section id="context.stack.protected_fixedsize">
+ <title><link linkend="context.stack.protected_fixedsize">Class <emphasis>protected_fixedsize</emphasis></link></title>
<para>
- Segmented stacks are not supported by <emphasis>execution_context</emphasis>
- (v2).
+ <emphasis role="bold">Boost.Context</emphasis> provides the class <emphasis>protected_fixedsize_stack</emphasis>
+ which models the <emphasis>stack-allocator concept</emphasis>. It appends
+ a guard page at the end of each stack to protect against exceeding the stack.
+ If the guard page is accessed (read or write operation) a segmentation fault/access
+ violation is generated by the operating system.
</para>
- </important>
- <para>
- On return the context-function of the current context has to specify an <emphasis>execution_context</emphasis>
- to which the execution control is transferred after termination of the current
- context.
- </para>
- <para>
- If an instance with valid state goes out of scope and the context-function
- has not yet returned, the stack is traversed in order to access the control
- structure (address stored at the first stack frame) and context' stack is deallocated
- via the <emphasis>StackAllocator</emphasis>. The stack walking makes the destruction
- of <emphasis>execution_context</emphasis> slow and should be prevented if possible.
- </para>
- <para>
- <emphasis>execution_context</emphasis> expects a <emphasis>context-function</emphasis>
- with signature <code><phrase role="identifier">execution_context</phrase><phrase
- role="special">(</phrase><phrase role="identifier">execution_context</phrase>
- <phrase role="identifier">ctx</phrase><phrase role="special">,</phrase> <phrase
- role="identifier">Args</phrase> <phrase role="special">...</phrase> <phrase
- role="identifier">args</phrase><phrase role="special">)</phrase></code>. The
- parameter <code><phrase role="identifier">ctx</phrase></code> represents the
- context from which this context was resumed (e.g. that has called <emphasis>execution_context::operator()</emphasis>
- on <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>)
- and <code><phrase role="identifier">args</phrase></code> are the data passed
- to <emphasis>execution_context::operator()</emphasis>. The return value represents
- the execution_context that has to be resumed, after termiantion of this context.
- </para>
- <para>
- Benefits of <link linkend="ecv2"><emphasis>execution_context</emphasis> (v2)</link>
- over <link linkend="ecv1"><emphasis>execution_context</emphasis> (v1)</link>
- are: faster context switch, type-safety of passed/returned arguments.
- </para>
- <bridgehead renderas="sect3" id="context.ecv2.h0">
- <phrase id="context.ecv2.usage_of__emphasis_execution_context__emphasis_"/><link
- linkend="context.ecv2.usage_of__emphasis_execution_context__emphasis_">usage
- of <emphasis>execution_context</emphasis></link>
- </bridgehead>
-<programlisting><phrase role="keyword">int</phrase> <phrase role="identifier">n</phrase><phrase role="special">=</phrase><phrase role="number">35</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">source</phrase><phrase role="special">(</phrase>
- <phrase role="special">[</phrase><phrase role="identifier">n</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="special">&&</phrase> <phrase role="identifier">sink</phrase><phrase role="special">,</phrase><phrase role="keyword">int</phrase><phrase role="special">)</phrase> <phrase role="keyword">mutable</phrase> <phrase role="special">{</phrase>
- <phrase role="keyword">int</phrase> <phrase role="identifier">a</phrase><phrase role="special">=</phrase><phrase role="number">0</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">int</phrase> <phrase role="identifier">b</phrase><phrase role="special">=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">while</phrase><phrase role="special">(</phrase><phrase role="identifier">n</phrase><phrase role="special">--></phrase><phrase role="number">0</phrase><phrase role="special">){</phrase>
- <phrase role="keyword">auto</phrase> <phrase role="identifier">result</phrase><phrase role="special">=</phrase><phrase role="identifier">sink</phrase><phrase role="special">(</phrase><phrase role="identifier">a</phrase><phrase role="special">);</phrase>
- <phrase role="identifier">sink</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">std</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special"><</phrase><phrase role="number">0</phrase><phrase role="special">>(</phrase><phrase role="identifier">result</phrase><phrase role="special">));</phrase>
- <phrase role="keyword">auto</phrase> <phrase role="identifier">next</phrase><phrase role="special">=</phrase><phrase role="identifier">a</phrase><phrase role="special">+</phrase><phrase role="identifier">b</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">a</phrase><phrase role="special">=</phrase><phrase role="identifier">b</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">b</phrase><phrase role="special">=</phrase><phrase role="identifier">next</phrase><phrase role="special">;</phrase>
- <phrase role="special">}</phrase>
- <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">sink</phrase><phrase role="special">);</phrase>
- <phrase role="special">});</phrase>
-<phrase role="keyword">for</phrase><phrase role="special">(</phrase><phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase><phrase role="special">=</phrase><phrase role="number">0</phrase><phrase role="special">;</phrase><phrase role="identifier">i</phrase><phrase role="special"><</phrase><phrase role="number">10</phrase><phrase role="special">;++</phrase><phrase role="identifier">i</phrase><phrase role="special">){</phrase>
- <phrase role="keyword">auto</phrase> <phrase role="identifier">result</phrase><phrase role="special">=</phrase><phrase role="identifier">source</phrase><phrase role="special">(</phrase><phrase role="identifier">i</phrase><phrase role="special">);</phrase>
- <phrase role="identifier">source</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">std</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special"><</phrase><phrase role="number">0</phrase><phrase role="special">>(</phrase><phrase role="identifier">result</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="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special"><</phrase><phrase role="number">1</phrase><phrase role="special">>(</phrase><phrase role="identifier">result</phrase><phrase role="special">)<<</phrase><phrase role="string">" "</phrase><phrase role="special">;</phrase>
-<phrase role="special">}</phrase>
-
-<phrase role="identifier">output</phrase><phrase role="special">:</phrase>
- <phrase role="number">0</phrase> <phrase role="number">1</phrase> <phrase role="number">1</phrase> <phrase role="number">2</phrase> <phrase role="number">3</phrase> <phrase role="number">5</phrase> <phrase role="number">8</phrase> <phrase role="number">13</phrase> <phrase role="number">21</phrase> <phrase role="number">34</phrase>
-</programlisting>
- <para>
- This simple example demonstrates the basic usage of <emphasis>execution_context</emphasis>
- as a generator. The context <code><phrase role="identifier">sink</phrase></code>
- represents the <emphasis>main</emphasis>-context (function <emphasis>main()</emphasis>
- running). <code><phrase role="identifier">sink</phrase></code> is generated
- by the framework (first element of lambda's parameter list). Because the state
- is invalidated (== changed) by each call of <emphasis>execution_context::operator()</emphasis>,
- the new state of the <emphasis>execution_context</emphasis>, returned by <emphasis>execution_context::operator()</emphasis>,
- needs to be assigned to <code><phrase role="identifier">sink</phrase></code>
- after each call.
- </para>
- <para>
- The lambda that calculates the Fibonacci numbers is executed inside the context
- 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 also appropriate to express this fact.
- </para>
- <para>
- The locale variables <code><phrase role="identifier">a</phrase></code>, <code><phrase
- role="identifier">b</phrase></code> and <code> <phrase role="identifier">next</phrase></code>
- remain their values during each context switch (<emphasis>yield(a)</emphasis>).
- This is possible due <code><phrase role="identifier">source</phrase></code>
- has its own stack and the stack is exchanged by each context switch.
- </para>
- <bridgehead renderas="sect3" id="context.ecv2.h1">
- <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="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="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>
- if the context is started for the first time. In all following invocations
- of <emphasis>execution_context::operator()</emphasis> the arguments passed
- 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="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="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">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</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="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="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="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">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</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="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="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">3</phrase><phrase role="special">,</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>
- <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="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">variant</phrase><phrase role="special"><</phrase><phrase role="keyword">int</phrase><phrase role="special">,</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">>></phrase> <phrase role="identifier">ctx_</phrase><phrase role="special">;</phrase>
-
-<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
- <phrase role="identifier">X</phrase><phrase role="special">():</phrase>
- <phrase role="identifier">excptr_</phrase><phrase role="special">(),</phrase>
- <phrase role="identifier">ctx_</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="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">variant</phrase><phrase role="special"><</phrase><phrase role="keyword">int</phrase><phrase role="special">,</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">>></phrase> <phrase role="special">&&</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">,</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">variant</phrase><phrase role="special"><</phrase><phrase role="keyword">int</phrase><phrase role="special">,</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">></phrase> <phrase role="identifier">data</phrase><phrase role="special">){</phrase>
- <phrase role="keyword">try</phrase> <phrase role="special">{</phrase>
- <phrase role="keyword">for</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="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special"><</phrase><phrase role="keyword">int</phrase><phrase role="special">>(</phrase><phrase role="identifier">data</phrase><phrase role="special">);</phrase>
- <phrase role="identifier">data</phrase><phrase role="special">=</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">lexical_cast</phrase><phrase role="special"><</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">>(</phrase><phrase role="identifier">i</phrase><phrase role="special">);</phrase>
- <phrase role="keyword">auto</phrase> <phrase role="identifier">result</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="identifier">ctx</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">std</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special"><</phrase><phrase role="number">0</phrase><phrase role="special">>(</phrase><phrase role="identifier">result</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">get</phrase><phrase role="special"><</phrase><phrase role="number">1</phrase><phrase role="special">>(</phrase><phrase role="identifier">result</phrase><phrase role="special">);</phrase>
- <phrase role="special">}</phrase> <phrase role="keyword">catch</phrase> <phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">bad_cast</phrase> <phrase role="keyword">const</phrase><phrase role="special">&)</phrase> <phrase role="special">{</phrase>
- <phrase role="identifier">excptr_</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">current_exception</phrase><phrase role="special">();</phrase>
- <phrase role="special">}</phrase>
- <phrase role="keyword">return</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="special">})</phrase>
- <phrase role="special">{}</phrase>
+ <important>
+ <para>
+ Using <emphasis>protected_fixedsize_stack</emphasis> is expensive. That
+ is, launching a new coroutine with a new stack is expensive; the allocated
+ stack is just as efficient to use as any other stack.
+ </para>
+ </important>
+ <note>
+ <para>
+ The appended <code><phrase role="identifier">guard</phrase> <phrase role="identifier">page</phrase></code>
+ is <emphasis role="bold">not</emphasis> mapped to physical memory, only
+ virtual addresses are used.
+ </para>
+ </note>
+<programlisting><phrase role="preprocessor">#include</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">protected_fixedsize</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">></phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase><phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase><phrase role="special">){</phrase>
- <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">variant</phrase><phrase role="special"><</phrase><phrase role="keyword">int</phrase><phrase role="special">,</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">></phrase> <phrase role="identifier">data</phrase><phrase role="special">=</phrase><phrase role="identifier">i</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">auto</phrase> <phrase role="identifier">result</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="identifier">ctx_</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">std</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special"><</phrase><phrase role="number">0</phrase><phrase role="special">>(</phrase><phrase role="identifier">result</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">get</phrase><phrase role="special"><</phrase><phrase role="number">1</phrase><phrase role="special">>(</phrase><phrase role="identifier">result</phrase><phrase role="special">);</phrase>
- <phrase role="keyword">if</phrase><phrase role="special">(</phrase><phrase role="identifier">excptr_</phrase><phrase role="special">){</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">rethrow_exception</phrase><phrase role="special">(</phrase><phrase role="identifier">excptr_</phrase><phrase role="special">);</phrase>
- <phrase role="special">}</phrase>
- <phrase role="keyword">return</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special"><</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">>(</phrase><phrase role="identifier">data</phrase><phrase role="special">);</phrase>
- <phrase role="special">}</phrase>
-<phrase role="special">};</phrase>
+<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase>
+<phrase role="keyword">struct</phrase> <phrase role="identifier">basic_protected_fixedsize</phrase> <phrase role="special">{</phrase>
+ <phrase role="keyword">typedef</phrase> <phrase role="identifier">traitT</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">;</phrase>
-<phrase role="identifier">X</phrase> <phrase role="identifier">x</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="identifier">x</phrase><phrase role="special">(</phrase><phrase role="number">7</phrase><phrase role="special">)</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">basic_protected_fixesize</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase> <phrase role="special">=</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase role="identifier">default_size</phrase><phrase role="special">());</phrase>
-<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>
- <bridgehead renderas="sect3" id="context.ecv2.h2">
- <phrase id="context.ecv2.exception_handling"/><link linkend="context.ecv2.exception_handling">exception
- handling</link>
- </bridgehead>
- <para>
- If the function executed inside a <emphasis>execution_context</emphasis> emits
- ans exception, the application is terminated by calling <emphasis>std::terminate()</emphasis>.
- <emphasis>std::exception_ptr</emphasis> can be used to transfer exceptions
- between different execution contexts.
- </para>
- <important>
- <para>
- Do not jump from inside a catch block and then re-throw the exception in
- another execution context.
- </para>
- </important>
- <anchor id="ecv2_ontop"/>
- <bridgehead renderas="sect3" id="context.ecv2.h3">
- <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="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="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="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">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="special">}</phrase>
+ <phrase role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">();</phrase>
-<phrase role="keyword">int</phrase> <phrase role="identifier">f2</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="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">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="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="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="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="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>
- <para>
- The expression <code><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></code> executes <code><phrase role="identifier">f2</phrase><phrase
- role="special">()</phrase></code> on top of context <code><phrase role="identifier">ctx</phrase></code>,
- e.g. an additional stack frame is allocated on top of the context stack (in
- front of <code><phrase role="identifier">f1</phrase><phrase role="special">()</phrase></code>).
- <code><phrase role="identifier">f2</phrase><phrase role="special">()</phrase></code>
- returns argument <code><phrase role="special">-</phrase><phrase role="number">1</phrase></code>
- that will returned by the second invocation of <code><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></code> in <code><phrase
- role="identifier">f1</phrase><phrase role="special">()</phrase></code>.
- </para>
- <para>
- <bridgehead renderas="sect4" id="ecv2_destructor destructor_bridgehead">
- <phrase id="ecv2_destructor destructor"/>
- <link linkend="ecv2_destructor
- destructor">Destructor</link>
-</bridgehead>
- </para>
-<programlisting><phrase role="special">~</phrase><phrase role="identifier">execution_context</phrase><phrase role="special">();</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Destructs the associated stack if <code><phrase role="special">*</phrase><phrase
- role="keyword">this</phrase></code> is a valid context, e.g. <emphasis>execution_context::operator
- bool()</emphasis> returns <code><phrase role="keyword">true</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv2_move constructor_bridgehead">
- <phrase id="ecv2_move constructor"/>
- <link linkend="ecv2_move constructor">Move
- constructor</link>
-</bridgehead>
- </para>
-<programlisting><phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Moves underlying capture record to <code><phrase role="special">*</phrase><phrase
- role="keyword">this</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv2_move assignment_bridgehead">
- <phrase id="ecv2_move assignment"/>
- <link linkend="ecv2_move assignment">Move
- assignment operator</link>
-</bridgehead>
- </para>
-<programlisting><phrase role="identifier">execution_context</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Moves the state of <code><phrase role="identifier">other</phrase></code>
- to <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
- using move semantics.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv2_operator_bool_bridgehead">
- <phrase id="ecv2_operator_bool"/>
- <link linkend="ecv2_operator_bool">Member function
- <code>operator bool</code>()</link>
-</bridgehead>
- </para>
-<programlisting><phrase role="keyword">explicit</phrase> <phrase role="keyword">operator</phrase> <phrase role="keyword">bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase
- role="keyword">this</phrase></code> points to a capture record.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv2_operator_not_bridgehead">
- <phrase id="ecv2_operator_not"/>
- <link linkend="ecv2_operator_not">Member function
- <code>operator!</code>()</link>
-</bridgehead>
- </para>
-<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase
- role="keyword">this</phrase></code> does not point to a capture record.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv2_operator_call_bridgehead">
- <phrase id="ecv2_operator_call"/>
- <link linkend="ecv2_operator_call">Member function
- <code>operator()</code>()</link>
-</bridgehead>
- </para>
-<programlisting><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tuple</phrase><phrase role="special"><</phrase> <phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">...</phrase> <phrase role="special">>,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">...</phrase> <phrase role="special">></phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase> <phrase role="comment">// member of generic execution_context template</phrase>
-
-<phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase> <phrase role="keyword">void</phrase> <phrase role="special">></phrase> <phrase role="keyword">operator</phrase><phrase role="special">()();</phrase> <phrase role="comment">// member of execution_context< void ></phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Stores internally the current context data (stack pointer, instruction
- pointer, and CPU registers) of the current active context and restores
- the context data from <code><phrase role="special">*</phrase><phrase
- role="keyword">this</phrase></code>, which implies jumping to <code><phrase
- role="special">*</phrase><phrase role="keyword">this</phrase></code>'s
- context. The arguments, <code><phrase role="special">...</phrase> <phrase
- role="identifier">args</phrase></code>, are passed to the current context
- to be returned by the most recent call to <code><phrase role="identifier">execution_context</phrase><phrase
- role="special">::</phrase><phrase role="keyword">operator</phrase><phrase
- role="special">()</phrase></code> in the same thread.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- The tuple of execution_context and returned arguments passed to the most
- recent call to <code><phrase role="identifier">execution_context</phrase><phrase
- role="special">::</phrase><phrase role="keyword">operator</phrase><phrase
- role="special">()</phrase></code>, if any and a execution_context representing
- the context that has been suspended.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <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.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv2_operator_call_ontop_bridgehead">
- <phrase id="ecv2_operator_call_ontop"/>
- <link linkend="ecv2_operator_call_ontop">Member
- function <code>operator()</code>()</link>
-</bridgehead>
- </para>
-<programlisting><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="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tuple</phrase><phrase role="special"><</phrase> <phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">...</phrase> <phrase role="special">>,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">...</phrase> <phrase role="special">></phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="identifier">exec_ontop_arg_t</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">Args</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase> <phrase role="comment">// member of generic execution_context</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="identifier">execution_context</phrase><phrase role="special"><</phrase> <phrase role="keyword">void</phrase> <phrase role="special">></phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="identifier">exec_ontop_arg_t</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="comment">// member of execution_context< void ></phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Same as <emphasis>execution_context::operator()</emphasis>. Additionally,
- function <code><phrase role="identifier">fn</phrase></code> is executed
- in the context of <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
- (e.g. the stack frame of <code><phrase role="identifier">fn</phrase></code>
- is allocated on stack of <code><phrase role="special">*</phrase><phrase
- role="keyword">this</phrase></code>).
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- The tuple of execution_context and returned arguments passed to the most
- recent call to <code><phrase role="identifier">execution_context</phrase><phrase
- role="special">::</phrase><phrase role="keyword">operator</phrase><phrase
- role="special">()</phrase></code>, if any and a execution_context representing
- the context that has been suspended .
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Note:</term>
- <listitem>
- <para>
- 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>
- <varlistentry>
- <term>Note:</term>
- <listitem>
- <para>
- Function <code><phrase role="identifier">fn</phrase></code> needs to
- return a tuple of arguments (<link linkend="ecv2_ontop">see description</link>).
- </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>
- <varlistentry>
- <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.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv2_operator_equal_bridgehead">
- <phrase id="ecv2_operator_equal"/>
- <link linkend="ecv2_operator_equal">Member
- function <code>operator==</code>()</link>
-</bridgehead>
- </para>
-<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">==(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase
- role="keyword">this</phrase></code> and <code><phrase role="identifier">other</phrase></code>
- represent the same execution context, <code><phrase role="keyword">false</phrase></code>
- otherwise.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv2_operator_notequal_bridgehead">
- <phrase id="ecv2_operator_notequal"/>
- <link linkend="ecv2_operator_notequal">Member
- function <code>operator!=</code>()</link>
-</bridgehead>
- </para>
-<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code>! (other == * this)</code>
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv2_operator_less_bridgehead">
- <phrase id="ecv2_operator_less"/>
- <link linkend="ecv2_operator_less">Member function
- <code>operator<</code>()</link>
-</bridgehead>
- </para>
-<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase
- role="keyword">this</phrase> <phrase role="special">!=</phrase> <phrase
- role="identifier">other</phrase></code> is true and the implementation-defined
- total order of <code><phrase role="identifier">execution_context</phrase></code>
- values places <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
- before <code><phrase role="identifier">other</phrase></code>, false otherwise.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv2_operator_greater_bridgehead">
- <phrase id="ecv2_operator_greater"/>
- <link linkend="ecv2_operator_greater">Member
- function <code>operator></code>()</link>
-</bridgehead>
- </para>
-<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="identifier">other</phrase> <phrase role="special"><</phrase>
- <phrase role="special">*</phrase> <phrase role="keyword">this</phrase></code>
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv2_operator_lesseq_bridgehead">
- <phrase id="ecv2_operator_lesseq"/>
- <link linkend="ecv2_operator_lesseq">Member
- function <code>operator<=</code>()</link>
-</bridgehead>
- </para>
-<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="special">!</phrase> <phrase role="special">(</phrase><phrase
- role="identifier">other</phrase> <phrase role="special"><</phrase>
- <phrase role="special">*</phrase> <phrase role="keyword">this</phrase><phrase
- role="special">)</phrase></code>
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv2_operator_greatereq_bridgehead">
- <phrase id="ecv2_operator_greatereq"/>
- <link linkend="ecv2_operator_greatereq">Member
- function <code>operator>=</code>()</link>
-</bridgehead>
- </para>
-<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="special">!</phrase> <phrase role="special">(*</phrase>
- <phrase role="keyword">this</phrase> <phrase role="special"><</phrase>
- <phrase role="identifier">other</phrase><phrase role="special">)</phrase></code>
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv2__bridgehead">
- <phrase id="ecv2_"/>
- <link linkend="ecv2_">Non-member function <code>operator<<()</code></link>
-</bridgehead>
- </para>
-<programlisting><phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase>
-<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase> <phrase role="special">&</phrase>
-<phrase role="keyword">operator</phrase><phrase role="special"><<(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase> <phrase role="special">&</phrase> <phrase role="identifier">os</phrase><phrase role="special">,</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">);</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Efects:</term>
- <listitem>
- <para>
- Writes the representation of <code><phrase role="identifier">other</phrase></code>
- to stream <code><phrase role="identifier">os</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="identifier">os</phrase></code>
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- </section>
- <section id="context.ecv1">
- <title><anchor id="ecv1"/><link linkend="context.ecv1">Class execution_context
- (version 1)</link></title>
- <warning>
- <para>
- <emphasis>execution_context</emphasis> (v1) is deprecated (does not prevent
- UB).
- </para>
- </warning>
- <note>
- <para>
- <emphasis>execution_context</emphasis> (v1) is the reference implementation
- of C++ proposal <ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0099r0.pdf">P099R0:
- A low-level API for stackful context switching</ulink>.
- </para>
- </note>
- <note>
- <para>
- <emphasis>execution_context</emphasis> (v1) resides in sub-namespace <code><phrase
- role="identifier">v1</phrase></code>.
- </para>
- </note>
- <note>
- <para>
- Segmented stacks (<emphasis>segmented-stacks=on</emphasis>), e.g. on demand
- growing stacks, can be used with <emphasis>execution_context</emphasis> (v1).
- </para>
- </note>
- <para>
- Class <emphasis>execution_context</emphasis> encapsulates context switching
- and manages the associated context' stack (allocation/deallocation).
- </para>
- <para>
- <emphasis>execution_context</emphasis> allocates the context stack (using its
- <link linkend="stack"><emphasis>StackAllocator</emphasis></link> argument)
- and creates a control structure on top of it. This structure is responsible
- for managing context' stack. Instances of <emphasis>execution_context</emphasis>,
- associated with a specific context, share the ownership of the control structure.
- If the last reference goes out of scope, the control structure is destroyed
- and the stack gets deallocated via the <emphasis>StackAllocator</emphasis>.
- </para>
- <para>
- <emphasis>execution_context</emphasis> is copy-constructible, move-constructible,
- copy-assignable and move-assignable.
- </para>
- <para>
- <emphasis>execution_context</emphasis> maintains a static (thread-local) pointer,
- accessed by <emphasis>execution_context::current()</emphasis>, pointing to
- the active context. On each context switch the pointer is updated. The usage
- of this global pointer makes the context switch a little bit slower (due access
- of thread local storage) but has some advantages. It allows to access the control
- structure of the current active context from arbitrary code paths required
- in order to support segmented stacks, which require to call certain maintenance
- functions (like __splitstack_getcontext() etc.) before each context switch
- (each context switch exchanges the stack).
- </para>
- <para>
- <emphasis>execution_context</emphasis> expects a function/functor with signature
- <code><phrase role="keyword">void</phrase><phrase role="special">(</phrase><phrase
- role="keyword">void</phrase><phrase role="special">*</phrase> <phrase role="identifier">vp</phrase><phrase
- role="special">)</phrase></code> (<code><phrase role="identifier">vp</phrase></code>
- is the data passed at the first invocation of <link linkend="ecv1_operator_call"> <code>ecv1::operator()()</code></link>).
- </para>
- <bridgehead renderas="sect3" id="context.ecv1.h0">
- <phrase id="context.ecv1.usage_of__emphasis_execution_context__emphasis_"/><link
- linkend="context.ecv1.usage_of__emphasis_execution_context__emphasis_">usage
- of <emphasis>execution_context</emphasis></link>
- </bridgehead>
-<programlisting><phrase role="keyword">int</phrase> <phrase role="identifier">n</phrase><phrase role="special">=</phrase><phrase role="number">35</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">v1</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase> <phrase role="identifier">sink</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">v1</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special">::</phrase><phrase role="identifier">current</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">v1</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase> <phrase role="identifier">source</phrase><phrase role="special">(</phrase>
- <phrase role="special">[</phrase><phrase role="identifier">n</phrase><phrase role="special">,&</phrase><phrase role="identifier">sink</phrase><phrase role="special">](</phrase><phrase role="keyword">void</phrase><phrase role="special">*)</phrase><phrase role="keyword">mutable</phrase><phrase role="special">{</phrase>
- <phrase role="keyword">int</phrase> <phrase role="identifier">a</phrase><phrase role="special">=</phrase><phrase role="number">0</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">int</phrase> <phrase role="identifier">b</phrase><phrase role="special">=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">while</phrase><phrase role="special">(</phrase><phrase role="identifier">n</phrase><phrase role="special">--></phrase><phrase role="number">0</phrase><phrase role="special">){</phrase>
- <phrase role="identifier">sink</phrase><phrase role="special">(&</phrase><phrase role="identifier">a</phrase><phrase role="special">);</phrase>
- <phrase role="keyword">auto</phrase> <phrase role="identifier">next</phrase><phrase role="special">=</phrase><phrase role="identifier">a</phrase><phrase role="special">+</phrase><phrase role="identifier">b</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">a</phrase><phrase role="special">=</phrase><phrase role="identifier">b</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">b</phrase><phrase role="special">=</phrase><phrase role="identifier">next</phrase><phrase role="special">;</phrase>
- <phrase role="special">}</phrase>
- <phrase role="special">});</phrase>
-<phrase role="keyword">for</phrase><phrase role="special">(</phrase><phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase><phrase role="special">=</phrase><phrase role="number">0</phrase><phrase role="special">;</phrase><phrase role="identifier">i</phrase><phrase role="special"><</phrase><phrase role="number">10</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">cout</phrase><phrase role="special"><<*(</phrase><phrase role="keyword">int</phrase><phrase role="special">*)</phrase><phrase role="identifier">source</phrase><phrase role="special">()<<</phrase><phrase role="string">" "</phrase><phrase role="special">;</phrase>
-<phrase role="special">}</phrase>
-
-<phrase role="identifier">output</phrase><phrase role="special">:</phrase>
- <phrase role="number">0</phrase> <phrase role="number">1</phrase> <phrase role="number">1</phrase> <phrase role="number">2</phrase> <phrase role="number">3</phrase> <phrase role="number">5</phrase> <phrase role="number">8</phrase> <phrase role="number">13</phrase> <phrase role="number">21</phrase> <phrase role="number">34</phrase>
-</programlisting>
- <para>
- This simple example demonstrates the basic usage of <emphasis>execution_context</emphasis>.
- The context <code><phrase role="identifier">sink</phrase></code>, returned
- by <emphasis>execution_context::current()</emphasis>, represents the <emphasis>main</emphasis>-context
- (function <emphasis>main()</emphasis> running) and is one of the captured parameters
- in the lambda expression. The lambda that calculates the Fibonacci numbers
- is executed inside the context 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>).
- </para>
- <para>
- The locale variables <code><phrase role="identifier">a</phrase></code>, <code><phrase
- role="identifier">b</phrase></code> and <code> <phrase role="identifier">next</phrase></code>
- remain their values during each context switch (<emphasis>yield(a)</emphasis>).
- This is possible because <code><phrase role="identifier">ctx</phrase></code>
- owns a stack (exchanged by context switch).
- </para>
- <bridgehead renderas="sect3" id="context.ecv1.h1">
- <phrase id="context.ecv1.inverting_the_control_flow"/><link linkend="context.ecv1.inverting_the_control_flow">inverting
- the control flow</link>
- </bridgehead>
-<programlisting><phrase role="comment">/*
- * grammar:
- * P ---> E '\0'
- * E ---> T {('+'|'-') T}
- * T ---> S {('*'|'/') S}
- * S ---> digit | '(' E ')'
- */</phrase>
-<phrase role="keyword">class</phrase> <phrase role="identifier">Parser</phrase><phrase role="special">{</phrase>
- <phrase role="comment">// implementation omitted; see examples directory</phrase>
-<phrase role="special">};</phrase>
-
-<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">istringstream</phrase> <phrase role="identifier">is</phrase><phrase role="special">(</phrase><phrase role="string">"1+1"</phrase><phrase role="special">);</phrase>
-<phrase role="keyword">bool</phrase> <phrase role="identifier">done</phrase><phrase role="special">=</phrase><phrase role="keyword">false</phrase><phrase role="special">;</phrase>
-<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">exception_ptr</phrase> <phrase role="identifier">except</phrase><phrase role="special">;</phrase>
-
-<phrase role="comment">// create handle to main execution context</phrase>
-<phrase role="keyword">auto</phrase> <phrase role="identifier">main_ctx</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">v1</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special">::</phrase><phrase role="identifier">current</phrase><phrase role="special">());</phrase>
-<phrase role="comment">// execute parser in new execution context</phrase>
-<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">v1</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase> <phrase role="identifier">source</phrase><phrase role="special">(</phrase>
- <phrase role="special">[&</phrase><phrase role="identifier">sink</phrase><phrase role="special">,&</phrase><phrase role="identifier">is</phrase><phrase role="special">,&</phrase><phrase role="identifier">done</phrase><phrase role="special">,&</phrase><phrase role="identifier">except</phrase><phrase role="special">](</phrase><phrase role="keyword">void</phrase><phrase role="special">*){</phrase>
- <phrase role="comment">// create parser with callback function</phrase>
- <phrase role="identifier">Parser</phrase> <phrase role="identifier">p</phrase><phrase role="special">(</phrase><phrase role="identifier">is</phrase><phrase role="special">,</phrase>
- <phrase role="special">[&</phrase><phrase role="identifier">sink</phrase><phrase role="special">](</phrase><phrase role="keyword">char</phrase> <phrase role="identifier">ch</phrase><phrase role="special">){</phrase>
- <phrase role="comment">// resume main execution context</phrase>
- <phrase role="identifier">sink</phrase><phrase role="special">(&</phrase><phrase role="identifier">ch</phrase><phrase role="special">);</phrase>
- <phrase role="special">});</phrase>
- <phrase role="keyword">try</phrase> <phrase role="special">{</phrase>
- <phrase role="comment">// start recursive parsing</phrase>
- <phrase role="identifier">p</phrase><phrase role="special">.</phrase><phrase role="identifier">run</phrase><phrase role="special">();</phrase>
- <phrase role="special">}</phrase> <phrase role="keyword">catch</phrase> <phrase role="special">(...)</phrase> <phrase role="special">{</phrase>
- <phrase role="comment">// store other exceptions in exception-pointer</phrase>
- <phrase role="identifier">except</phrase> <phrase role="special">=</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">current_exception</phrase><phrase role="special">();</phrase>
- <phrase role="special">}</phrase>
- <phrase role="comment">// set termination flag</phrase>
- <phrase role="identifier">done</phrase><phrase role="special">=</phrase><phrase role="keyword">true</phrase><phrase role="special">;</phrase>
- <phrase role="comment">// resume main execution context</phrase>
- <phrase role="identifier">sink</phrase><phrase role="special">();</phrase>
- <phrase role="special">});</phrase>
-
-<phrase role="comment">// user-code pulls parsed data from parser</phrase>
-<phrase role="comment">// invert control flow</phrase>
-<phrase role="keyword">void</phrase><phrase role="special">*</phrase> <phrase role="identifier">vp</phrase> <phrase role="special">=</phrase> <phrase role="identifier">source</phrase><phrase role="special">();</phrase>
-<phrase role="keyword">if</phrase> <phrase role="special">(</phrase><phrase role="identifier">except</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">rethrow_exception</phrase><phrase role="special">(</phrase><phrase role="identifier">except</phrase><phrase role="special">);</phrase>
-<phrase role="special">}</phrase>
-<phrase role="keyword">while</phrase><phrase role="special">(</phrase> <phrase role="special">!</phrase> <phrase role="identifier">done</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
- <phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">"Parsed: %c\n"</phrase><phrase role="special">,*</phrase> <phrase role="keyword">static_cast</phrase><phrase role="special"><</phrase><phrase role="keyword">char</phrase><phrase role="special">*>(</phrase><phrase role="identifier">vp</phrase><phrase role="special">));</phrase>
- <phrase role="identifier">vp</phrase> <phrase role="special">=</phrase> <phrase role="identifier">source</phrase><phrase role="special">();</phrase>
- <phrase role="keyword">if</phrase> <phrase role="special">(</phrase><phrase role="identifier">except</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">rethrow_exception</phrase><phrase role="special">(</phrase><phrase role="identifier">except</phrase><phrase role="special">);</phrase>
- <phrase role="special">}</phrase>
-<phrase role="special">}</phrase>
-
-<phrase role="identifier">output</phrase><phrase role="special">:</phrase>
- <phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase>
- <phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="special">+</phrase>
- <phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase>
-</programlisting>
- <para>
- In this example a recursive descent parser uses a callback to emit a newly
- passed symbol. Using <emphasis>execution_context</emphasis> the control flow
- can be inverted, e.g. the user-code pulls parsed symbols from the parser -
- instead to get pushed from the parser (via callback).
- </para>
- <para>
- The data (character) is transferred between the two <emphasis>execution_context</emphasis>.
- </para>
- <para>
- If the code executed by <emphasis>execution_context</emphasis> emits an exception,
- the application is terminated. <emphasis>std::exception_ptr</emphasis> can
- be used to transfer exceptions between different execution contexts.
- </para>
- <bridgehead renderas="sect3" id="context.ecv1.h2">
- <phrase id="context.ecv1.stack_unwinding"/><link linkend="context.ecv1.stack_unwinding">stack
- unwinding</link>
- </bridgehead>
- <para>
- 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.
- </para>
- <anchor id="ecv1_prealloc"/>
- <bridgehead renderas="sect3" id="context.ecv1.h3">
- <phrase id="context.ecv1.allocating_control_structures_on_top_of_stack"/><link
- linkend="context.ecv1.allocating_control_structures_on_top_of_stack">allocating
- control structures on top of stack</link>
- </bridgehead>
- <para>
- Allocating control structures on top of the stack requires to allocated the
- <emphasis>stack_context</emphasis> and create the control structure with placement
- new before <emphasis>execution_context</emphasis> is created.
- </para>
- <note>
- <para>
- The user is responsible for destructing the control structure at the top
- of the stack.
- </para>
- </note>
-<programlisting><phrase role="comment">// stack-allocator used for (de-)allocating stack</phrase>
-<phrase role="identifier">fixedsize_stack</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">(</phrase> <phrase role="number">4048</phrase><phrase role="special">);</phrase>
-<phrase role="comment">// allocate stack space</phrase>
-<phrase role="identifier">stack_context</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">(</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">.</phrase><phrase role="identifier">allocate</phrase><phrase role="special">()</phrase> <phrase role="special">);</phrase>
-<phrase role="comment">// reserve space for control structure on top of the stack</phrase>
-<phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase> <phrase role="special">=</phrase> <phrase role="keyword">static_cast</phrase><phrase role="special"><</phrase> <phrase role="keyword">char</phrase> <phrase role="special">*</phrase> <phrase role="special">>(</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase role="identifier">sp</phrase><phrase role="special">)</phrase> <phrase role="special">-</phrase> <phrase role="keyword">sizeof</phrase><phrase role="special">(</phrase> <phrase role="identifier">my_control_structure</phrase><phrase role="special">);</phrase>
-<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase> <phrase role="special">=</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase role="identifier">size</phrase> <phrase role="special">-</phrase> <phrase role="keyword">sizeof</phrase><phrase role="special">(</phrase> <phrase role="identifier">my_control_structure</phrase><phrase role="special">);</phrase>
-<phrase role="comment">// placement new creates control structure on reserved space</phrase>
-<phrase role="identifier">my_control_structure</phrase> <phrase role="special">*</phrase> <phrase role="identifier">cs</phrase> <phrase role="special">=</phrase> <phrase role="keyword">new</phrase> <phrase role="special">(</phrase> <phrase role="identifier">sp</phrase><phrase role="special">)</phrase> <phrase role="identifier">my_control_structure</phrase><phrase role="special">(</phrase> <phrase role="identifier">sp</phrase><phrase role="special">,</phrase> <phrase role="identifier">size</phrase><phrase role="special">,</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">,</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">);</phrase>
-<phrase role="special">...</phrase>
-<phrase role="comment">// destructing the control structure</phrase>
-<phrase role="identifier">cs</phrase><phrase role="special">->~</phrase><phrase role="identifier">my_control_structure</phrase><phrase role="special">();</phrase>
-<phrase role="special">...</phrase>
-<phrase role="keyword">struct</phrase> <phrase role="identifier">my_control_structure</phrase> <phrase role="special">{</phrase>
- <phrase role="comment">// execution context</phrase>
- <phrase role="identifier">execution_context</phrase> <phrase role="identifier">ectx</phrase><phrase role="special">;</phrase>
-
- <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase> <phrase role="special">></phrase>
- <phrase role="identifier">my_control_structure</phrase><phrase role="special">(</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">,</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">,</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">,</phrase> <phrase role="identifier">StackAllocator</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">)</phrase> <phrase role="special">:</phrase>
- <phrase role="comment">// create execution context</phrase>
- <phrase role="identifier">ectx</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg</phrase><phrase role="special">,</phrase> <phrase role="identifier">preallocated</phrase><phrase role="special">(</phrase> <phrase role="identifier">sp</phrase><phrase role="special">,</phrase> <phrase role="identifier">size</phrase><phrase role="special">,</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">),</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">entry_func</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
- <phrase role="special">}</phrase>
- <phrase role="special">...</phrase>
-<phrase role="special">};</phrase>
-</programlisting>
- <bridgehead renderas="sect3" id="context.ecv1.h4">
- <phrase id="context.ecv1.exception_handling"/><link linkend="context.ecv1.exception_handling">exception
- handling</link>
- </bridgehead>
- <para>
- If the function executed inside a <emphasis>execution_context</emphasis> emits
- ans exception, the application is terminated by calling <emphasis>std::terminate()</emphasis>.
- <emphasis>std::exception_ptr</emphasis> can be used to transfer exceptions
- between different execution contexts.
- </para>
- <important>
- <para>
- Do not jump from inside a catch block and then re-throw the exception in
- another execution context.
- </para>
- </important>
- <bridgehead renderas="sect3" id="context.ecv1.h5">
- <phrase id="context.ecv1.parameter_passing"/><link linkend="context.ecv1.parameter_passing">parameter
- passing</link>
- </bridgehead>
- <para>
- The void pointer argument passed to <emphasis>execution_context::operator()</emphasis>,
- in one context, is passed as the last argument of the <emphasis>context-function</emphasis>
- if the context is started for the first time. In all following invocations
- of <emphasis>execution_context::operator()</emphasis> the void pointer passed
- 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="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>
- <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">v1</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase> <phrase role="identifier">caller_</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">v1</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase> <phrase role="identifier">callee_</phrase><phrase role="special">;</phrase>
-
-<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
- <phrase role="identifier">X</phrase><phrase role="special">()</phrase> <phrase role="special">:</phrase>
- <phrase role="identifier">excptr_</phrase><phrase role="special">(),</phrase>
- <phrase role="identifier">caller_</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">v1</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special">::</phrase><phrase role="identifier">current</phrase><phrase role="special">()</phrase> <phrase role="special">),</phrase>
- <phrase role="identifier">callee_</phrase><phrase role="special">(</phrase> <phrase role="special">[=]</phrase> <phrase role="special">(</phrase><phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">vp</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
- <phrase role="keyword">try</phrase> <phrase role="special">{</phrase>
- <phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase> <phrase role="special">=</phrase> <phrase role="special">*</phrase> <phrase role="keyword">static_cast</phrase><phrase role="special"><</phrase> <phrase role="keyword">int</phrase> <phrase role="special">*</phrase> <phrase role="special">>(</phrase> <phrase role="identifier">vp</phrase><phrase role="special">);</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="identifier">str</phrase> <phrase role="special">=</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">lexical_cast</phrase><phrase role="special"><</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">>(</phrase><phrase role="identifier">i</phrase><phrase role="special">);</phrase>
- <phrase role="identifier">caller_</phrase><phrase role="special">(</phrase> <phrase role="special">&</phrase> <phrase role="identifier">str</phrase><phrase role="special">);</phrase>
- <phrase role="special">}</phrase> <phrase role="keyword">catch</phrase> <phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">bad_cast</phrase> <phrase role="keyword">const</phrase><phrase role="special">&)</phrase> <phrase role="special">{</phrase>
- <phrase role="identifier">excptr_</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">current_exception</phrase><phrase role="special">();</phrase>
- <phrase role="special">}</phrase>
- <phrase role="special">})</phrase>
- <phrase role="special">{}</phrase>
-
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
- <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">ret</phrase> <phrase role="special">=</phrase> <phrase role="identifier">callee_</phrase><phrase role="special">(</phrase> <phrase role="special">&</phrase> <phrase role="identifier">i</phrase><phrase role="special">);</phrase>
- <phrase role="keyword">if</phrase><phrase role="special">(</phrase><phrase role="identifier">excptr_</phrase><phrase role="special">){</phrase>
- <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">rethrow_exception</phrase><phrase role="special">(</phrase><phrase role="identifier">excptr_</phrase><phrase role="special">);</phrase>
- <phrase role="special">}</phrase>
- <phrase role="keyword">return</phrase> <phrase role="special">*</phrase> <phrase role="keyword">static_cast</phrase><phrase role="special"><</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="special">*</phrase> <phrase role="special">>(</phrase> <phrase role="identifier">ret</phrase><phrase role="special">);</phrase>
- <phrase role="special">}</phrase>
-<phrase role="special">};</phrase>
-
-<phrase role="identifier">X</phrase> <phrase role="identifier">x</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="identifier">x</phrase><phrase role="special">(</phrase> <phrase role="number">7</phrase><phrase role="special">)</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">output</phrase><phrase role="special">:</phrase>
- <phrase role="number">7</phrase>
-</programlisting>
- <bridgehead renderas="sect3" id="context.ecv1.h6">
- <phrase id="context.ecv1.class__code__phrase_role__identifier__execution_context__phrase___code_"/><link
- linkend="context.ecv1.class__code__phrase_role__identifier__execution_context__phrase___code_">Class
- <code><phrase role="identifier">execution_context</phrase></code></link>
- </bridgehead>
-<programlisting><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">static</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="identifier">current</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</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">Args</phrase> <phrase role="special">></phrase>
- <phrase role="identifier">execution_context</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">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase>
-
- <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">Args</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">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">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase>
-
- <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">Args</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">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase>
-
- <phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-
- <phrase role="identifier">execution_context</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="identifier">execution_context</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-
- <phrase role="keyword">explicit</phrase> <phrase role="keyword">operator</phrase> <phrase role="keyword">bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
- <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-
- <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">vp</phrase> <phrase role="special">=</phrase> <phrase role="keyword">nullptr</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">void</phrase> <phrase role="special">*</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="identifier">exec_ontop_arg_t</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="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">vp</phrase> <phrase role="special">=</phrase> <phrase role="keyword">nullptr</phrase><phrase role="special">);</phrase>
-
- <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">==(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-
- <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-
- <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-
- <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-
- <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-
- <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-
- <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase>
- <phrase role="keyword">friend</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase> <phrase role="special">&</phrase>
- <phrase role="keyword">operator</phrase><phrase role="special"><<(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase> <phrase role="special">&</phrase> <phrase role="identifier">os</phrase><phrase role="special">,</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">);</phrase>
-<phrase role="special">};</phrase>
-</programlisting>
- <para>
- <bridgehead renderas="sect4" id="ecv1_current_bridgehead">
- <phrase id="ecv1_current"/>
- <link linkend="ecv1_current">Static member function <code>current</code>()</link>
-</bridgehead>
- </para>
-<programlisting><phrase role="keyword">static</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="identifier">current</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- Returns an instance of excution_context pointing to the active execution
- context.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv1_constructor_bridgehead">
- <phrase id="ecv1_constructor"/>
- <link linkend="ecv1_constructor">Constructor</link>
-</bridgehead>
- </para>
-<programlisting><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">Args</phrase> <phrase role="special">></phrase>
-<phrase role="identifier">execution_context</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">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase>
-
-<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">Args</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">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">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase>
-
-<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">Args</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">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Creates a new execution context and prepares the context to execute
- <code><phrase role="identifier">fn</phrase></code>. <code><phrase role="identifier">fixedsize_stack</phrase></code>
- is used as default stack allocator (stack size == fixedsize_stack::traits::default_size()).
- The constructor with argument type <code><phrase role="identifier">preallocated</phrase></code>,
- is used to create a user defined data <link linkend="ecv1_prealloc">(for
- instance additional control structures)</link> on top of the stack.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv1_copy constructor_bridgehead">
- <phrase id="ecv1_copy constructor"/>
- <link linkend="ecv1_copy constructor">Copy
- constructor</link>
-</bridgehead>
- </para>
-<programlisting><phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Copies <code><phrase role="identifier">other</phrase></code>, e.g. underlying
- control structure is shared with <code><phrase role="special">*</phrase><phrase
- role="keyword">this</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv1_move constructor_bridgehead">
- <phrase id="ecv1_move constructor"/>
- <link linkend="ecv1_move constructor">Move
- constructor</link>
-</bridgehead>
- </para>
-<programlisting><phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Moves underlying control structure to <code><phrase role="special">*</phrase><phrase
- role="keyword">this</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv1_copy assignment_bridgehead">
- <phrase id="ecv1_copy assignment"/>
- <link linkend="ecv1_copy assignment">Copy
- assignment operator</link>
-</bridgehead>
- </para>
-<programlisting><phrase role="identifier">execution_context</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Copies the state of <code><phrase role="identifier">other</phrase></code>
- to <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>,
- control structure is shared.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv1_move assignment_bridgehead">
- <phrase id="ecv1_move assignment"/>
- <link linkend="ecv1_move assignment">Move
- assignment operator</link>
-</bridgehead>
- </para>
-<programlisting><phrase role="identifier">execution_context</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Moves the control structure of <code><phrase role="identifier">other</phrase></code>
- to <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
- using move semantics.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv1_operator_bool_bridgehead">
- <phrase id="ecv1_operator_bool"/>
- <link linkend="ecv1_operator_bool">Member function
- <code>operator bool</code>()</link>
-</bridgehead>
- </para>
-<programlisting><phrase role="keyword">explicit</phrase> <phrase role="keyword">operator</phrase> <phrase role="keyword">bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase
- role="keyword">this</phrase></code> points to a control structure.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv1_operator_not_bridgehead">
- <phrase id="ecv1_operator_not"/>
- <link linkend="ecv1_operator_not">Member function
- <code>operator!</code>()</link>
-</bridgehead>
- </para>
-<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase
- role="keyword">this</phrase></code> does not point to a control structure.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv1_operator_call_bridgehead">
- <phrase id="ecv1_operator_call"/>
- <link linkend="ecv1_operator_call">Member function
- <code>operator()</code>()</link>
-</bridgehead>
- </para>
-<programlisting><phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">vp</phrase> <phrase role="special">=</phrase> <phrase role="keyword">nullptr</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Stores internally the current context data (stack pointer, instruction
- pointer, and CPU registers) of the current active context and restores
- the context data from <code><phrase role="special">*</phrase><phrase
- role="keyword">this</phrase></code>, which implies jumping to <code><phrase
- role="special">*</phrase><phrase role="keyword">this</phrase></code>'s
- context. The void pointer argument, <code><phrase role="identifier">vp</phrase></code>,
- is passed to the current context to be returned by the most recent call
- to <code><phrase role="identifier">execution_context</phrase><phrase
- role="special">::</phrase><phrase role="keyword">operator</phrase><phrase
- role="special">()</phrase></code> in the same thread. <code><phrase role="identifier">fn</phrase></code>
- is executed with arguments <code><phrase role="identifier">args</phrase></code>
- on top of the stack of <code><phrase role="keyword">this</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Note:</term>
- <listitem>
- <para>
- The behaviour is undefined if <code><phrase role="keyword">operator</phrase><phrase
- role="special">()()</phrase></code> is called while <emphasis>execution_context::current()</emphasis>
- returns <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
- (e.g. resuming an already running context). If the top-level context
- function returns, <code><phrase role="identifier">std</phrase><phrase
- role="special">::</phrase><phrase role="identifier">exit</phrase><phrase
- role="special">()</phrase></code> is called.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- The void pointer argument passed to the most recent call to <emphasis>execution_context::operator()</emphasis>,
- if any.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv1_operator_call_ontop_bridgehead">
- <phrase id="ecv1_operator_call_ontop"/>
- <link linkend="ecv1_operator_call_ontop">Member
- function <code>operator(exec_ontop_arg_t)</code>()</link>
-</bridgehead>
- </para>
-<programlisting><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">void</phrase> <phrase role="special">*</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="identifier">exec_ontop_arg_t</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="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">vp</phrase> <phrase role="special">=</phrase> <phrase role="keyword">nullptr</phrase><phrase role="special">);</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Effects:</term>
- <listitem>
- <para>
- Same as <emphasis>execution_context::operator()</emphasis>. Additionally,
- function <code><phrase role="identifier">fn</phrase></code> is executed
- with arguments <code><phrase role="identifier">vp</phrase></code> in
- the context of <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
- (e.g. the stack frame of <code><phrase role="identifier">fn</phrase></code>
- is allocated on stack of <code><phrase role="special">*</phrase><phrase
- role="keyword">this</phrase></code>).
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- The void pointer argument passed to the most recent call to <emphasis>execution_context::operator()</emphasis>,
- if any.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv1_operator_equal_bridgehead">
- <phrase id="ecv1_operator_equal"/>
- <link linkend="ecv1_operator_equal">Member
- function <code>operator==</code>()</link>
-</bridgehead>
- </para>
-<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">==(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase
- role="keyword">this</phrase></code> and <code><phrase role="identifier">other</phrase></code>
- represent the same execution context, <code><phrase role="keyword">false</phrase></code>
- otherwise.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv1_operator_notequal_bridgehead">
- <phrase id="ecv1_operator_notequal"/>
- <link linkend="ecv1_operator_notequal">Member
- function <code>operator!=</code>()</link>
-</bridgehead>
- </para>
-<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code>! (other == * this)</code>
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv1_operator_less_bridgehead">
- <phrase id="ecv1_operator_less"/>
- <link linkend="ecv1_operator_less">Member function
- <code>operator<</code>()</link>
-</bridgehead>
- </para>
-<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase
- role="keyword">this</phrase> <phrase role="special">!=</phrase> <phrase
- role="identifier">other</phrase></code> is true and the implementation-defined
- total order of <code><phrase role="identifier">execution_context</phrase></code>
- values places <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
- before <code><phrase role="identifier">other</phrase></code>, false otherwise.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv1_operator_greater_bridgehead">
- <phrase id="ecv1_operator_greater"/>
- <link linkend="ecv1_operator_greater">Member
- function <code>operator></code>()</link>
-</bridgehead>
- </para>
-<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="identifier">other</phrase> <phrase role="special"><</phrase>
- <phrase role="special">*</phrase> <phrase role="keyword">this</phrase></code>
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv1_operator_lesseq_bridgehead">
- <phrase id="ecv1_operator_lesseq"/>
- <link linkend="ecv1_operator_lesseq">Member
- function <code>operator<=</code>()</link>
-</bridgehead>
- </para>
-<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="special">!</phrase> <phrase role="special">(</phrase><phrase
- role="identifier">other</phrase> <phrase role="special"><</phrase>
- <phrase role="special">*</phrase> <phrase role="keyword">this</phrase><phrase
- role="special">)</phrase></code>
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv1_operator_greatereq_bridgehead">
- <phrase id="ecv1_operator_greatereq"/>
- <link linkend="ecv1_operator_greatereq">Member
- function <code>operator>=</code>()</link>
-</bridgehead>
- </para>
-<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="special">!</phrase> <phrase role="special">(*</phrase>
- <phrase role="keyword">this</phrase> <phrase role="special"><</phrase>
- <phrase role="identifier">other</phrase><phrase role="special">)</phrase></code>
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Throws:</term>
- <listitem>
- <para>
- Nothing.
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- <para>
- <bridgehead renderas="sect4" id="ecv1__bridgehead">
- <phrase id="ecv1_"/>
- <link linkend="ecv1_">Non-member function <code>operator<<()</code></link>
-</bridgehead>
- </para>
-<programlisting><phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase>
-<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase> <phrase role="special">&</phrase>
-<phrase role="keyword">operator</phrase><phrase role="special"><<(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase> <phrase role="special">&</phrase> <phrase role="identifier">os</phrase><phrase role="special">,</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">);</phrase>
-</programlisting>
- <variablelist>
- <title></title>
- <varlistentry>
- <term>Efects:</term>
- <listitem>
- <para>
- Writes the representation of <code><phrase role="identifier">other</phrase></code>
- to stream <code><phrase role="identifier">os</phrase></code>.
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>Returns:</term>
- <listitem>
- <para>
- <code><phrase role="identifier">os</phrase></code>
- </para>
- </listitem>
- </varlistentry>
- </variablelist>
- </section>
- <section id="context.stack">
- <title><anchor id="stack"/><link linkend="context.stack">Stack allocation</link></title>
- <para>
- The memory used by the stack is allocated/deallocated via a <emphasis>StackAllocator</emphasis>
- which is required to model a <emphasis>stack-allocator concept</emphasis>.
- </para>
- <bridgehead renderas="sect3" id="context.stack.h0">
- <phrase id="context.stack._emphasis_stack_allocator_concept__emphasis_"/><link
- linkend="context.stack._emphasis_stack_allocator_concept__emphasis_"><emphasis>stack-allocator
- concept</emphasis></link>
- </bridgehead>
- <para>
- A <emphasis>StackAllocator</emphasis> must satisfy the <emphasis>stack-allocator
- concept</emphasis> requirements shown in the following table, in which <code><phrase
- role="identifier">a</phrase></code> is an object of a <emphasis>StackAllocator</emphasis>
- type, <code><phrase role="identifier">sctx</phrase></code> is a <code><phrase
- role="identifier">stack_context</phrase></code>, and <code><phrase role="identifier">size</phrase></code>
- is a <code><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
- role="identifier">size_t</phrase></code>:
- </para>
- <informaltable frame="all">
- <tgroup cols="3">
- <thead>
- <row>
- <entry>
- <para>
- expression
- </para>
- </entry>
- <entry>
- <para>
- return type
- </para>
- </entry>
- <entry>
- <para>
- notes
- </para>
- </entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>
- <para>
- <code><phrase role="identifier">a</phrase><phrase role="special">(</phrase><phrase
- role="identifier">size</phrase><phrase role="special">)</phrase></code>
- </para>
- </entry>
- <entry>
- </entry>
- <entry>
- <para>
- creates a stack allocator
- </para>
- </entry>
- </row>
- <row>
- <entry>
- <para>
- <code><phrase role="identifier">a</phrase><phrase role="special">.</phrase><phrase
- role="identifier">allocate</phrase><phrase role="special">()</phrase></code>
- </para>
- </entry>
- <entry>
- <para>
- <code><phrase role="identifier">stack_context</phrase></code>
- </para>
- </entry>
- <entry>
- <para>
- creates a stack
- </para>
- </entry>
- </row>
- <row>
- <entry>
- <para>
- <code><phrase role="identifier">a</phrase><phrase role="special">.</phrase><phrase
- role="identifier">deallocate</phrase><phrase role="special">(</phrase>
- <phrase role="identifier">sctx</phrase><phrase role="special">)</phrase></code>
- </para>
- </entry>
- <entry>
- <para>
- <code><phrase role="keyword">void</phrase></code>
- </para>
- </entry>
- <entry>
- <para>
- deallocates the stack created by <code><phrase role="identifier">a</phrase><phrase
- role="special">.</phrase><phrase role="identifier">allocate</phrase><phrase
- role="special">()</phrase></code>
- </para>
- </entry>
- </row>
- </tbody>
- </tgroup>
- </informaltable>
- <important>
- <para>
- The implementation of <code><phrase role="identifier">allocate</phrase><phrase
- role="special">()</phrase></code> might include logic to protect against
- exceeding the context's available stack size rather than leaving it as undefined
- behaviour.
- </para>
- </important>
- <important>
- <para>
- Calling <code><phrase role="identifier">deallocate</phrase><phrase role="special">()</phrase></code>
- with a <code><phrase role="identifier">stack_context</phrase></code> not
- set by <code><phrase role="identifier">allocate</phrase><phrase role="special">()</phrase></code>
- results in undefined behaviour.
- </para>
- </important>
- <note>
- <para>
- The stack is not required to be aligned; alignment takes place inside <emphasis>execution_context</emphasis>.
- </para>
- </note>
- <note>
- <para>
- Depending on the architecture <code><phrase role="identifier">allocate</phrase><phrase
- role="special">()</phrase></code> stores an address from the top of the stack
- (growing downwards) or the bottom of the stack (growing upwards).
- </para>
- </note>
- <section id="context.stack.protected_fixedsize">
- <title><link linkend="context.stack.protected_fixedsize">Class <emphasis>protected_fixedsize</emphasis></link></title>
- <para>
- <emphasis role="bold">Boost.Context</emphasis> provides the class <emphasis>protected_fixedsize_stack</emphasis>
- which models the <emphasis>stack-allocator concept</emphasis>. It appends
- a guard page at the end of each stack to protect against exceeding the stack.
- If the guard page is accessed (read or write operation) a segmentation fault/access
- violation is generated by the operating system.
- </para>
- <important>
- <para>
- Using <emphasis>protected_fixedsize_stack</emphasis> is expensive. That
- is, launching a new coroutine with a new stack is expensive; the allocated
- stack is just as efficient to use as any other stack.
- </para>
- </important>
- <note>
- <para>
- The appended <code><phrase role="identifier">guard</phrase> <phrase role="identifier">page</phrase></code>
- is <emphasis role="bold">not</emphasis> mapped to physical memory, only
- virtual addresses are used.
- </para>
- </note>
-<programlisting><phrase role="preprocessor">#include</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">protected_fixedsize</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">></phrase>
-
-<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase>
-<phrase role="keyword">struct</phrase> <phrase role="identifier">basic_protected_fixedsize</phrase> <phrase role="special">{</phrase>
- <phrase role="keyword">typedef</phrase> <phrase role="identifier">traitT</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">;</phrase>
-
- <phrase role="identifier">basic_protected_fixesize</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase> <phrase role="special">=</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase role="identifier">default_size</phrase><phrase role="special">());</phrase>
-
- <phrase role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">();</phrase>
-
- <phrase role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&);</phrase>
+ <phrase role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&);</phrase>
<phrase role="special">}</phrase>
<phrase role="keyword">typedef</phrase> <phrase role="identifier">basic_protected_fixedsize</phrase><phrase role="special"><</phrase> <phrase role="identifier">stack_traits</phrase> <phrase role="special">></phrase> <phrase role="identifier">protected_fixedsize</phrase>
<para>
Segmented stacks can only be used with <link linkend="cc"><emphasis>callcc()</emphasis></link>
(using <link linkend="implementation"><emphasis>ucontext_t</emphasis></link>)
- and <emphasis>execution_context</emphasis> (v1)
</para>
</note>
<para>
role="identifier">on</phrase></code>.
</para>
</section>
+ <section id="context.stack.sanitizers">
+ <title><link linkend="context.stack.sanitizers">Support for sanitizers</link></title>
+ <para>
+ Sanitizers (GCC/Clang) are confused by the stack switches. The library is
+ required to be compiled with property (b2 command-line) <code><phrase role="identifier">context</phrase><phrase
+ role="special">-</phrase><phrase role="identifier">impl</phrase><phrase role="special">=</phrase><phrase
+ role="identifier">ucontext</phrase></code> and compilers santizer options.
+ Users must define <code><phrase role="identifier">BOOST_USE_ASAN</phrase></code>
+ before including any Boost.Context headers when linking against Boost binaries.
+ </para>
+ </section>
</section>
<section id="context.struct__preallocated_">
<title><link linkend="context.struct__preallocated_">Struct <code><phrase role="identifier">preallocated</phrase></code></link></title>
<row>
<entry>
<para>
+ riscv64
+ </para>
+ </entry>
+ <entry>
+ <para>
+ SYSV|ELF
+ </para>
+ </entry>
+ <entry>
+ <para>
+ -
+ </para>
+ </entry>
+ <entry>
+ <para>
+ SYSV
+ </para>
+ </entry>
+ <entry>
+ <para>
+ -
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para>
+ s390x
+ </para>
+ </entry>
+ <entry>
+ <para>
+ SYSV|ELF
+ </para>
+ </entry>
+ <entry>
+ <para>
+ -
+ </para>
+ </entry>
+ <entry>
+ <para>
+ -
+ </para>
+ </entry>
+ <entry>
+ <para>
+ -
+ </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para>
sparc
</para>
</entry>