Files
coroutine/doc/coro.xml

3058 lines
268 KiB
XML

<?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="coroutine" name="Coroutine" dirname="coroutine" last-revision="$Date: 2014/01/27 18:42:43 $"
xmlns:xi="http://www.w3.org/2001/XInclude">
<libraryinfo>
<authorgroup>
<author>
<firstname>Oliver</firstname> <surname>Kowalke</surname>
</author>
</authorgroup>
<copyright>
<year>2009</year> <holder>Oliver Kowalke</holder>
</copyright>
<legalnotice id="coroutine.legal">
<para>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <ulink url="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</ulink>)
</para>
</legalnotice>
<librarypurpose>
C++ Library providing coroutine facility
</librarypurpose>
<librarycategory name="category:text"></librarycategory>
</libraryinfo>
<title>Coroutine</title>
<section id="coroutine.overview">
<title><link linkend="coroutine.overview">Overview</link></title>
<para>
<emphasis role="bold">Boost.Coroutine</emphasis> provides templates for generalized
subroutines which allow multiple entry points for suspending and resuming execution
at certain locations. It preserves the local state of execution and allows
re-entering subroutines more than once (useful if state must be kept across
function calls).
</para>
<para>
Coroutines can be viewed as a language-level construct providing a special
kind of control flow.
</para>
<para>
In contrast to threads, which are pre-emptive, <emphasis>coroutine</emphasis>
switches are cooperative (programmer controls when a switch will happen). The
kernel is not involved in the coroutine switches.
</para>
<para>
The implementation uses <emphasis role="bold">Boost.Context</emphasis> for
context switching.
</para>
<para>
This library is a follow-up on <ulink url="http://www.crystalclearsoftware.com/soc/coroutine/">Boost.Coroutine</ulink>
by Giovanni P. Deretta.
</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">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">/</phrase><phrase role="identifier">all</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
</programlisting>
<para>
which includes all the other headers in turn.
</para>
<para>
All functions and classes are contained in the namespace <emphasis>boost::coroutines</emphasis>.
</para>
</section>
<section id="coroutine.intro">
<title><link linkend="coroutine.intro">Introduction</link></title>
<bridgehead renderas="sect3" id="coroutine.intro.h0">
<phrase id="coroutine.intro.definition"/><link linkend="coroutine.intro.definition">Definition</link>
</bridgehead>
<para>
In computer science routines are defined as a sequence of operations. The execution
of routines forms a parent-child relationship and the child terminates always
before the parent. Coroutines (the term was introduced by Melvin Conway <footnote
id="coroutine.intro.f0">
<para>
Conway, Melvin E.. &quot;Design of a Separable Transition-Diagram Compiler&quot;.
Commun. ACM, Volume 6 Issue 7, July 1963, Articale No. 7
</para>
</footnote>), are a generalization of routines (Donald Knuth <footnote id="coroutine.intro.f1">
<para>
Knuth, Donald Ervin (1997). &quot;Fundamental Algorithms. The Art of Computer
Programming 1&quot;, (3rd ed.)
</para>
</footnote>. The principal difference between coroutines and routines is that
a coroutine enables explicit suspend and resume of its progress via additional
operations by preserving execution state and thus provides an <emphasis role="bold">enhanced
control flow</emphasis> (maintaining the execution context).
</para>
<bridgehead renderas="sect3" id="coroutine.intro.h1">
<phrase id="coroutine.intro.how_it_works"/><link linkend="coroutine.intro.how_it_works">How
it works</link>
</bridgehead>
<para>
Functions foo() and bar() are supposed to alternate their execution (leave
and enter function body).
</para>
<para>
<inlinemediaobject><imageobject><imagedata align="center" fileref="../../../../libs/coroutine/doc/images/foo_bar.png"></imagedata></imageobject>
<textobject>
<phrase>foo_bar</phrase>
</textobject>
</inlinemediaobject>
</para>
<para>
If coroutines would be called such as routines, the stack would grow with every
call and will never be degraded. A jump into the middle of a coroutine would
not be possible, because the return address would have been on top of stack
entries.
</para>
<para>
The solution is that each coroutine has its own stack and control-block (<emphasis>boost::contexts::fcontext_t</emphasis>
from <emphasis role="bold">Boost.Context</emphasis>). Before the coroutine
gets suspended, the non-volatile registers (including stack and instruction/program
pointer) of the currently active coroutine are stored in coroutine's control-block.
The registers of the newly activated coroutine must be restored from its associated
control-block before it can continue with their work.
</para>
<para>
The context switch requires no system privileges and provides cooperative multitasking
on the level of language. Coroutines provide quasi parallelism. When a program
is supposed to do several things at the same time, coroutines help to do this
much simpler and more elegant than with only a single flow of control. Advantages
can be seen particularly clearly with the use of a recursive function, such
as traversal of binary trees (see example 'same fringe').
</para>
<bridgehead renderas="sect3" id="coroutine.intro.h2">
<phrase id="coroutine.intro.characteristics"/><link linkend="coroutine.intro.characteristics">characteristics</link>
</bridgehead>
<para>
Characteristics <footnote id="coroutine.intro.f2">
<para>
Moura, Ana Lucia De and Ierusalimschy, Roberto. &quot;Revisiting coroutines&quot;.
ACM Trans. Program. Lang. Syst., Volume 31 Issue 2, February 2009, Article
No. 6
</para>
</footnote> of a coroutine are:
</para>
<itemizedlist>
<listitem>
<simpara>
values of local data persist between successive calls (context switches)
</simpara>
</listitem>
<listitem>
<simpara>
execution is suspended as control leaves coroutine and resumed at certain
time later
</simpara>
</listitem>
<listitem>
<simpara>
symmetric or asymmetric control-transfer mechanism
</simpara>
</listitem>
<listitem>
<simpara>
first-class object (can be passed as argument, returned by procedures,
stored in a data structure to be used later or freely manipulated by the
developer)
</simpara>
</listitem>
<listitem>
<simpara>
stackful or stackless
</simpara>
</listitem>
</itemizedlist>
<para>
Coroutines are useful in simulation, artificial intelligence, concurrent programming,
text processing and data manipulation, supporting the implementation of components
such as cooperative tasks (fibers), iterators, generators, infinite lists,
pipes etc.
</para>
<bridgehead renderas="sect3" id="coroutine.intro.h3">
<phrase id="coroutine.intro.execution_transfer_mechanism"/><link linkend="coroutine.intro.execution_transfer_mechanism">execution-transfer
mechanism</link>
</bridgehead>
<para>
Two categories of coroutines exist: symmetric and asymmetric coroutines. A
symmetric coroutine transfers the execution control only via one operation.
The target coroutine must be explicitly specified in the transfer operation.
Asymmetric coroutines provide two transfer operations: the <emphasis>suspend</emphasis>-operation
returns to the invoker by preserving the execution context and the <emphasis>resume</emphasis>-operation
restores the execution context, e.g. re-enters the coroutine at the same point
as it was suspended before.
</para>
<para>
<inlinemediaobject><imageobject><imagedata align="center" fileref="../../../../libs/coroutine/doc/images/foo_bar_seq.png"></imagedata></imageobject>
<textobject>
<phrase>foo_bar_seq</phrase>
</textobject>
</inlinemediaobject>
</para>
<para>
Both concepts are equivalent and a coroutine library can provide either symmetric
or asymmetric coroutines.
</para>
<bridgehead renderas="sect3" id="coroutine.intro.h4">
<phrase id="coroutine.intro.stackfulness"/><link linkend="coroutine.intro.stackfulness">stackfulness</link>
</bridgehead>
<para>
In contrast to a stackless coroutine a stackful coroutine allows to suspend
from nested stackframes. The execution resumes at exact the same point in the
code as it was suspended before. With a stackless coroutine, only the top-level
routine may be suspended. Any routine called by that top-level routine may
not itself suspend. This prohibits providing suspend/resume operations in routines
within a general-purpose library.
</para>
<bridgehead renderas="sect3" id="coroutine.intro.h5">
<phrase id="coroutine.intro.first_class_continuation"/><link linkend="coroutine.intro.first_class_continuation">first-class
continuation</link>
</bridgehead>
<para>
A first-class continuation can be passed as an argument, returned by a function
and stored in a data structure to be used later. In some implementations (for
instance C# <emphasis>yield</emphasis>) the continuation can not be directly
accessed or directly manipulated.
</para>
<para>
Without stackfulness and first-class semantics some useful execution control
flows cannot be supported (for instance cooperative multitasking or checkpointing).
</para>
</section>
<section id="coroutine.motivation">
<title><link linkend="coroutine.motivation">Motivation</link></title>
<para>
In order to support a broad range of execution control behaviour <emphasis>coroutine&lt;&gt;::push_type</emphasis>
and <emphasis>coroutine&lt;&gt;::pull_type</emphasis> can be used to <emphasis>escape-and-reenter</emphasis>
loops, to <emphasis>escape-and-reenter</emphasis> recursive computations and
for <emphasis>cooperative</emphasis> multitasking helping to solve problems
in a much simpler and more elegant way than with only a single flow of control.
</para>
<bridgehead renderas="sect3" id="coroutine.motivation.h0">
<phrase id="coroutine.motivation._same_fringe__problem"/><link linkend="coroutine.motivation._same_fringe__problem">'same
fringe' problem</link>
</bridgehead>
<para>
The advantages can be seen particularly clearly with the use of a recursive
function, such as traversal of trees. If traversing two different trees in
the same deterministic order produces the same list of leaf nodes, then both
trees have the same fringe.
</para>
<para>
<inlinemediaobject><imageobject><imagedata align="center" fileref="../../../../libs/coroutine/doc/images/fringe.png"></imagedata></imageobject>
<textobject>
<phrase>fringe</phrase>
</textobject>
</inlinemediaobject>
</para>
<para>
Both trees in the picture have the same fringe even though the structure of
the trees is different.
</para>
<para>
The same fringe problem could be solved using coroutines by iterating over
the leaf nodes and comparing this sequence via \cpp{std::equal()}. The range
of data values is generated by function <emphasis>traverse()</emphasis> which
recursively traverses the tree and passes each node's data value to its <emphasis>coroutine&lt;&gt;::push_type</emphasis>.
<emphasis>coroutine&lt;&gt;::push_type</emphasis> suspends the recursive computation
and transfers the data value to the main execution context. <emphasis>boost::coroutines::coroutine&lt;&gt;::pull_type::iterator</emphasis>,
created from <emphasis>coroutine&lt;&gt;::pull_type</emphasis>, steps over
those data values and delivers them to <emphasis>std::equal()</emphasis> for
comparison. Each increment of <emphasis>boost::coroutines::coroutine&lt;&gt;::pull_type::iterator</emphasis>
resumes <emphasis>traverse()</emphasis>. Upon return from <emphasis>iterator::operator++()</emphasis>,
either a new data value is available, or tree traversal is finished (iterator
is invalidated).
</para>
<programlisting><phrase role="keyword">struct</phrase> <phrase role="identifier">node</phrase><phrase role="special">{</phrase>
<phrase role="keyword">typedef</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">shared_ptr</phrase><phrase role="special">&lt;</phrase><phrase role="identifier">node</phrase><phrase role="special">&gt;</phrase> <phrase role="identifier">ptr_t</phrase><phrase role="special">;</phrase>
<phrase role="comment">// Each tree node has an optional left subtree,</phrase>
<phrase role="comment">// an optional right subtree and a value of its own.</phrase>
<phrase role="comment">// The value is considered to be between the left</phrase>
<phrase role="comment">// subtree and the right.</phrase>
<phrase role="identifier">ptr_t</phrase> <phrase role="identifier">left</phrase><phrase role="special">,</phrase><phrase role="identifier">right</phrase><phrase role="special">;</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="identifier">value</phrase><phrase role="special">;</phrase>
<phrase role="comment">// construct leaf</phrase>
<phrase role="identifier">node</phrase><phrase role="special">(</phrase><phrase role="keyword">const</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">v</phrase><phrase role="special">):</phrase>
<phrase role="identifier">left</phrase><phrase role="special">(),</phrase><phrase role="identifier">right</phrase><phrase role="special">(),</phrase><phrase role="identifier">value</phrase><phrase role="special">(</phrase><phrase role="identifier">v</phrase><phrase role="special">)</phrase>
<phrase role="special">{}</phrase>
<phrase role="comment">// construct nonleaf</phrase>
<phrase role="identifier">node</phrase><phrase role="special">(</phrase><phrase role="identifier">ptr_t</phrase> <phrase role="identifier">l</phrase><phrase role="special">,</phrase><phrase role="keyword">const</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">v</phrase><phrase role="special">,</phrase><phrase role="identifier">ptr_t</phrase> <phrase role="identifier">r</phrase><phrase role="special">):</phrase>
<phrase role="identifier">left</phrase><phrase role="special">(</phrase><phrase role="identifier">l</phrase><phrase role="special">),</phrase><phrase role="identifier">right</phrase><phrase role="special">(</phrase><phrase role="identifier">r</phrase><phrase role="special">),</phrase><phrase role="identifier">value</phrase><phrase role="special">(</phrase><phrase role="identifier">v</phrase><phrase role="special">)</phrase>
<phrase role="special">{}</phrase>
<phrase role="keyword">static</phrase> <phrase role="identifier">ptr_t</phrase> <phrase role="identifier">create</phrase><phrase role="special">(</phrase><phrase role="keyword">const</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">v</phrase><phrase role="special">){</phrase>
<phrase role="keyword">return</phrase> <phrase role="identifier">ptr_t</phrase><phrase role="special">(</phrase><phrase role="keyword">new</phrase> <phrase role="identifier">node</phrase><phrase role="special">(</phrase><phrase role="identifier">v</phrase><phrase role="special">));</phrase>
<phrase role="special">}</phrase>
<phrase role="keyword">static</phrase> <phrase role="identifier">ptr_t</phrase> <phrase role="identifier">create</phrase><phrase role="special">(</phrase><phrase role="identifier">ptr_t</phrase> <phrase role="identifier">l</phrase><phrase role="special">,</phrase><phrase role="keyword">const</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">v</phrase><phrase role="special">,</phrase><phrase role="identifier">ptr_t</phrase> <phrase role="identifier">r</phrase><phrase role="special">){</phrase>
<phrase role="keyword">return</phrase> <phrase role="identifier">ptr_t</phrase><phrase role="special">(</phrase><phrase role="keyword">new</phrase> <phrase role="identifier">node</phrase><phrase role="special">(</phrase><phrase role="identifier">l</phrase><phrase role="special">,</phrase><phrase role="identifier">v</phrase><phrase role="special">,</phrase><phrase role="identifier">r</phrase><phrase role="special">));</phrase>
<phrase role="special">}</phrase>
<phrase role="special">};</phrase>
<phrase role="identifier">node</phrase><phrase role="special">::</phrase><phrase role="identifier">ptr_t</phrase> <phrase role="identifier">create_left_tree_from</phrase><phrase role="special">(</phrase><phrase role="keyword">const</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">root</phrase><phrase role="special">){</phrase>
<phrase role="comment">/* --------
root
/ \
b e
/ \
a c
-------- */</phrase>
<phrase role="keyword">return</phrase> <phrase role="identifier">node</phrase><phrase role="special">::</phrase><phrase role="identifier">create</phrase><phrase role="special">(</phrase>
<phrase role="identifier">node</phrase><phrase role="special">::</phrase><phrase role="identifier">create</phrase><phrase role="special">(</phrase>
<phrase role="identifier">node</phrase><phrase role="special">::</phrase><phrase role="identifier">create</phrase><phrase role="special">(</phrase><phrase role="string">&quot;a&quot;</phrase><phrase role="special">),</phrase>
<phrase role="string">&quot;b&quot;</phrase><phrase role="special">,</phrase>
<phrase role="identifier">node</phrase><phrase role="special">::</phrase><phrase role="identifier">create</phrase><phrase role="special">(</phrase><phrase role="string">&quot;c&quot;</phrase><phrase role="special">)),</phrase>
<phrase role="identifier">root</phrase><phrase role="special">,</phrase>
<phrase role="identifier">node</phrase><phrase role="special">::</phrase><phrase role="identifier">create</phrase><phrase role="special">(</phrase><phrase role="string">&quot;e&quot;</phrase><phrase role="special">));</phrase>
<phrase role="special">}</phrase>
<phrase role="identifier">node</phrase><phrase role="special">::</phrase><phrase role="identifier">ptr_t</phrase> <phrase role="identifier">create_right_tree_from</phrase><phrase role="special">(</phrase><phrase role="keyword">const</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">root</phrase><phrase role="special">){</phrase>
<phrase role="comment">/* --------
root
/ \
a d
/ \
c e
-------- */</phrase>
<phrase role="keyword">return</phrase> <phrase role="identifier">node</phrase><phrase role="special">::</phrase><phrase role="identifier">create</phrase><phrase role="special">(</phrase>
<phrase role="identifier">node</phrase><phrase role="special">::</phrase><phrase role="identifier">create</phrase><phrase role="special">(</phrase><phrase role="string">&quot;a&quot;</phrase><phrase role="special">),</phrase>
<phrase role="identifier">root</phrase><phrase role="special">,</phrase>
<phrase role="identifier">node</phrase><phrase role="special">::</phrase><phrase role="identifier">create</phrase><phrase role="special">(</phrase>
<phrase role="identifier">node</phrase><phrase role="special">::</phrase><phrase role="identifier">create</phrase><phrase role="special">(</phrase><phrase role="string">&quot;c&quot;</phrase><phrase role="special">),</phrase>
<phrase role="string">&quot;d&quot;</phrase><phrase role="special">,</phrase>
<phrase role="identifier">node</phrase><phrase role="special">::</phrase><phrase role="identifier">create</phrase><phrase role="special">(</phrase><phrase role="string">&quot;e&quot;</phrase><phrase role="special">)));</phrase>
<phrase role="special">}</phrase>
<phrase role="comment">// recursively walk the tree, delivering values in order</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">traverse</phrase><phrase role="special">(</phrase><phrase role="identifier">node</phrase><phrase role="special">::</phrase><phrase role="identifier">ptr_t</phrase> <phrase role="identifier">n</phrase><phrase role="special">,</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutines</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">&gt;::</phrase><phrase role="identifier">push_type</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">out</phrase><phrase role="special">){</phrase>
<phrase role="keyword">if</phrase><phrase role="special">(</phrase><phrase role="identifier">n</phrase><phrase role="special">-&gt;</phrase><phrase role="identifier">left</phrase><phrase role="special">)</phrase> <phrase role="identifier">traverse</phrase><phrase role="special">(</phrase><phrase role="identifier">n</phrase><phrase role="special">-&gt;</phrase><phrase role="identifier">left</phrase><phrase role="special">,</phrase><phrase role="identifier">out</phrase><phrase role="special">);</phrase>
<phrase role="identifier">out</phrase><phrase role="special">(</phrase><phrase role="identifier">n</phrase><phrase role="special">-&gt;</phrase><phrase role="identifier">value</phrase><phrase role="special">);</phrase>
<phrase role="keyword">if</phrase><phrase role="special">(</phrase><phrase role="identifier">n</phrase><phrase role="special">-&gt;</phrase><phrase role="identifier">right</phrase><phrase role="special">)</phrase> <phrase role="identifier">traverse</phrase><phrase role="special">(</phrase><phrase role="identifier">n</phrase><phrase role="special">-&gt;</phrase><phrase role="identifier">right</phrase><phrase role="special">,</phrase><phrase role="identifier">out</phrase><phrase role="special">);</phrase>
<phrase role="special">}</phrase>
<phrase role="comment">// evaluation</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">node</phrase><phrase role="special">::</phrase><phrase role="identifier">ptr_t</phrase> <phrase role="identifier">left_d</phrase><phrase role="special">(</phrase><phrase role="identifier">create_left_tree_from</phrase><phrase role="special">(</phrase><phrase role="string">&quot;d&quot;</phrase><phrase role="special">));</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutines</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">&gt;::</phrase><phrase role="identifier">pull_type</phrase> <phrase role="identifier">left_d_reader</phrase><phrase role="special">(</phrase>
<phrase role="special">[&amp;](</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutines</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">&gt;::</phrase><phrase role="identifier">push_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">out</phrase><phrase role="special">){</phrase>
<phrase role="identifier">traverse</phrase><phrase role="special">(</phrase><phrase role="identifier">left_d</phrase><phrase role="special">,</phrase><phrase role="identifier">out</phrase><phrase role="special">);</phrase>
<phrase role="special">});</phrase>
<phrase role="identifier">node</phrase><phrase role="special">::</phrase><phrase role="identifier">ptr_t</phrase> <phrase role="identifier">right_b</phrase><phrase role="special">(</phrase><phrase role="identifier">create_right_tree_from</phrase><phrase role="special">(</phrase><phrase role="string">&quot;b&quot;</phrase><phrase role="special">));</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutines</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">&gt;::</phrase><phrase role="identifier">pull_type</phrase> <phrase role="identifier">right_b_reader</phrase><phrase role="special">(</phrase>
<phrase role="special">[&amp;](</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutines</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">&gt;::</phrase><phrase role="identifier">push_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">out</phrase><phrase role="special">){</phrase>
<phrase role="identifier">traverse</phrase><phrase role="special">(</phrase><phrase role="identifier">right_b</phrase><phrase role="special">,</phrase><phrase role="identifier">out</phrase><phrase role="special">);</phrase>
<phrase role="special">});</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="string">&quot;left tree from d == right tree from b? &quot;</phrase>
<phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">boolalpha</phrase>
<phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">equal</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">begin</phrase><phrase role="special">(</phrase><phrase role="identifier">left_d_reader</phrase><phrase role="special">),</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">end</phrase><phrase role="special">(</phrase><phrase role="identifier">left_d_reader</phrase><phrase role="special">),</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">begin</phrase><phrase role="special">(</phrase><phrase role="identifier">right_b_reader</phrase><phrase role="special">))</phrase>
<phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
<phrase role="special">}</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">node</phrase><phrase role="special">::</phrase><phrase role="identifier">ptr_t</phrase> <phrase role="identifier">left_d</phrase><phrase role="special">(</phrase><phrase role="identifier">create_left_tree_from</phrase><phrase role="special">(</phrase><phrase role="string">&quot;d&quot;</phrase><phrase role="special">));</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutines</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">&gt;::</phrase><phrase role="identifier">pull_type</phrase> <phrase role="identifier">left_d_reader</phrase><phrase role="special">(</phrase>
<phrase role="special">[&amp;](</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutines</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">&gt;::</phrase><phrase role="identifier">push_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">out</phrase><phrase role="special">){</phrase>
<phrase role="identifier">traverse</phrase><phrase role="special">(</phrase><phrase role="identifier">left_d</phrase><phrase role="special">,</phrase><phrase role="identifier">out</phrase><phrase role="special">);</phrase>
<phrase role="special">});</phrase>
<phrase role="identifier">node</phrase><phrase role="special">::</phrase><phrase role="identifier">ptr_t</phrase> <phrase role="identifier">right_x</phrase><phrase role="special">(</phrase><phrase role="identifier">create_right_tree_from</phrase><phrase role="special">(</phrase><phrase role="string">&quot;x&quot;</phrase><phrase role="special">));</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutines</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">&gt;::</phrase><phrase role="identifier">pull_type</phrase> <phrase role="identifier">right_x_reader</phrase><phrase role="special">(</phrase>
<phrase role="special">[&amp;](</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutines</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">&gt;::</phrase><phrase role="identifier">push_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">out</phrase><phrase role="special">){</phrase>
<phrase role="identifier">traverse</phrase><phrase role="special">(</phrase><phrase role="identifier">right_x</phrase><phrase role="special">,</phrase><phrase role="identifier">out</phrase><phrase role="special">);</phrase>
<phrase role="special">});</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="string">&quot;left tree from d == right tree from x? &quot;</phrase>
<phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">boolalpha</phrase>
<phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">equal</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">begin</phrase><phrase role="special">(</phrase><phrase role="identifier">left_d_reader</phrase><phrase role="special">),</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">end</phrase><phrase role="special">(</phrase><phrase role="identifier">left_d_reader</phrase><phrase role="special">),</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">begin</phrase><phrase role="special">(</phrase><phrase role="identifier">right_x_reader</phrase><phrase role="special">))</phrase>
<phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
<phrase role="special">}</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="string">&quot;Done&quot;</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
<phrase role="identifier">output</phrase><phrase role="special">:</phrase>
<phrase role="identifier">left</phrase> <phrase role="identifier">tree</phrase> <phrase role="identifier">from</phrase> <phrase role="identifier">d</phrase> <phrase role="special">==</phrase> <phrase role="identifier">right</phrase> <phrase role="identifier">tree</phrase> <phrase role="identifier">from</phrase> <phrase role="identifier">b</phrase><phrase role="special">?</phrase> <phrase role="keyword">true</phrase>
<phrase role="identifier">left</phrase> <phrase role="identifier">tree</phrase> <phrase role="identifier">from</phrase> <phrase role="identifier">d</phrase> <phrase role="special">==</phrase> <phrase role="identifier">right</phrase> <phrase role="identifier">tree</phrase> <phrase role="identifier">from</phrase> <phrase role="identifier">x</phrase><phrase role="special">?</phrase> <phrase role="keyword">false</phrase>
<phrase role="identifier">Done</phrase>
</programlisting>
<bridgehead renderas="sect3" id="coroutine.motivation.h1">
<phrase id="coroutine.motivation.chaining_coroutines"/><link linkend="coroutine.motivation.chaining_coroutines">chaining
coroutines</link>
</bridgehead>
<para>
The following example demonstrates how coroutines could be chained.
</para>
<programlisting><phrase role="keyword">typedef</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutines</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">&gt;</phrase> <phrase role="identifier">coro_t</phrase><phrase role="special">;</phrase>
<phrase role="comment">// deliver each line of input stream to sink as a separate string</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">readlines</phrase><phrase role="special">(</phrase><phrase role="identifier">coro_t</phrase><phrase role="special">::</phrase><phrase role="identifier">push_type</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">sink</phrase><phrase role="special">,</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">istream</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">in</phrase><phrase role="special">){</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="identifier">line</phrase><phrase role="special">;</phrase>
<phrase role="keyword">while</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">getline</phrase><phrase role="special">(</phrase><phrase role="identifier">in</phrase><phrase role="special">,</phrase><phrase role="identifier">line</phrase><phrase role="special">))</phrase>
<phrase role="identifier">sink</phrase><phrase role="special">(</phrase><phrase role="identifier">line</phrase><phrase role="special">);</phrase>
<phrase role="special">}</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">tokenize</phrase><phrase role="special">(</phrase><phrase role="identifier">coro_t</phrase><phrase role="special">::</phrase><phrase role="identifier">push_type</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">sink</phrase><phrase role="special">,</phrase> <phrase role="identifier">coro_t</phrase><phrase role="special">::</phrase><phrase role="identifier">pull_type</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">source</phrase><phrase role="special">){</phrase>
<phrase role="comment">// This tokenizer doesn't happen to be stateful: you could reasonably</phrase>
<phrase role="comment">// implement it with a single call to push each new token downstream. But</phrase>
<phrase role="comment">// I've worked with stateful tokenizers, in which the meaning of input</phrase>
<phrase role="comment">// characters depends in part on their position within the input line.</phrase>
<phrase role="identifier">BOOST_FOREACH</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="identifier">line</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">string</phrase><phrase role="special">::</phrase><phrase role="identifier">size_type</phrase> <phrase role="identifier">pos</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">;</phrase>
<phrase role="keyword">while</phrase><phrase role="special">(</phrase><phrase role="identifier">pos</phrase> <phrase role="special">&lt;</phrase> <phrase role="identifier">line</phrase><phrase role="special">.</phrase><phrase role="identifier">length</phrase><phrase role="special">()){</phrase>
<phrase role="keyword">if</phrase> <phrase role="special">(</phrase><phrase role="identifier">line</phrase><phrase role="special">[</phrase><phrase role="identifier">pos</phrase><phrase role="special">]</phrase> <phrase role="special">==</phrase> <phrase role="char">'&quot;'</phrase><phrase role="special">){</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="identifier">token</phrase><phrase role="special">;</phrase>
<phrase role="special">++</phrase><phrase role="identifier">pos</phrase><phrase role="special">;</phrase> <phrase role="comment">// skip open quote</phrase>
<phrase role="keyword">while</phrase> <phrase role="special">(</phrase><phrase role="identifier">pos</phrase> <phrase role="special">&lt;</phrase> <phrase role="identifier">line</phrase><phrase role="special">.</phrase><phrase role="identifier">length</phrase><phrase role="special">()</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">line</phrase><phrase role="special">[</phrase><phrase role="identifier">pos</phrase><phrase role="special">]</phrase> <phrase role="special">!=</phrase> <phrase role="char">'&quot;'</phrase><phrase role="special">)</phrase>
<phrase role="identifier">token</phrase> <phrase role="special">+=</phrase> <phrase role="identifier">line</phrase><phrase role="special">[</phrase><phrase role="identifier">pos</phrase><phrase role="special">++];</phrase>
<phrase role="special">++</phrase><phrase role="identifier">pos</phrase><phrase role="special">;</phrase> <phrase role="comment">// skip close quote</phrase>
<phrase role="identifier">sink</phrase><phrase role="special">(</phrase><phrase role="identifier">token</phrase><phrase role="special">);</phrase> <phrase role="comment">// pass token downstream</phrase>
<phrase role="special">}</phrase> <phrase role="keyword">else</phrase> <phrase role="keyword">if</phrase> <phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">isspace</phrase><phrase role="special">(</phrase><phrase role="identifier">line</phrase><phrase role="special">[</phrase><phrase role="identifier">pos</phrase><phrase role="special">])){</phrase>
<phrase role="special">++</phrase><phrase role="identifier">pos</phrase><phrase role="special">;</phrase> <phrase role="comment">// outside quotes, ignore whitespace</phrase>
<phrase role="special">}</phrase> <phrase role="keyword">else</phrase> <phrase role="keyword">if</phrase> <phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">isalpha</phrase><phrase role="special">(</phrase><phrase role="identifier">line</phrase><phrase role="special">[</phrase><phrase role="identifier">pos</phrase><phrase role="special">])){</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="identifier">token</phrase><phrase role="special">;</phrase>
<phrase role="keyword">while</phrase> <phrase role="special">(</phrase><phrase role="identifier">pos</phrase> <phrase role="special">&lt;</phrase> <phrase role="identifier">line</phrase><phrase role="special">.</phrase><phrase role="identifier">length</phrase><phrase role="special">()</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">isalpha</phrase><phrase role="special">(</phrase><phrase role="identifier">line</phrase><phrase role="special">[</phrase><phrase role="identifier">pos</phrase><phrase role="special">]))</phrase>
<phrase role="identifier">token</phrase> <phrase role="special">+=</phrase> <phrase role="identifier">line</phrase><phrase role="special">[</phrase><phrase role="identifier">pos</phrase><phrase role="special">++];</phrase>
<phrase role="identifier">sink</phrase><phrase role="special">(</phrase><phrase role="identifier">token</phrase><phrase role="special">);</phrase> <phrase role="comment">// pass token downstream</phrase>
<phrase role="special">}</phrase> <phrase role="keyword">else</phrase> <phrase role="special">{</phrase> <phrase role="comment">// punctuation</phrase>
<phrase role="identifier">sink</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="number">1</phrase><phrase role="special">,</phrase><phrase role="identifier">line</phrase><phrase role="special">[</phrase><phrase role="identifier">pos</phrase><phrase role="special">++]));</phrase>
<phrase role="special">}</phrase>
<phrase role="special">}</phrase>
<phrase role="special">}</phrase>
<phrase role="special">}</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">only_words</phrase><phrase role="special">(</phrase><phrase role="identifier">coro_t</phrase><phrase role="special">::</phrase><phrase role="identifier">push_type</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">sink</phrase><phrase role="special">,</phrase><phrase role="identifier">coro_t</phrase><phrase role="special">::</phrase><phrase role="identifier">pull_type</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">source</phrase><phrase role="special">){</phrase>
<phrase role="identifier">BOOST_FOREACH</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="identifier">token</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">token</phrase><phrase role="special">.</phrase><phrase role="identifier">empty</phrase><phrase role="special">()</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">isalpha</phrase><phrase role="special">(</phrase><phrase role="identifier">token</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">token</phrase><phrase role="special">);</phrase>
<phrase role="special">}</phrase>
<phrase role="special">}</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">trace</phrase><phrase role="special">(</phrase><phrase role="identifier">coro_t</phrase><phrase role="special">::</phrase><phrase role="identifier">push_type</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">sink</phrase><phrase role="special">,</phrase> <phrase role="identifier">coro_t</phrase><phrase role="special">::</phrase><phrase role="identifier">pull_type</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">source</phrase><phrase role="special">){</phrase>
<phrase role="identifier">BOOST_FOREACH</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="identifier">token</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">cout</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="string">&quot;trace: '&quot;</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">token</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="string">&quot;'\n&quot;</phrase><phrase role="special">;</phrase>
<phrase role="identifier">sink</phrase><phrase role="special">(</phrase><phrase role="identifier">token</phrase><phrase role="special">);</phrase>
<phrase role="special">}</phrase>
<phrase role="special">}</phrase>
<phrase role="keyword">struct</phrase> <phrase role="identifier">FinalEOL</phrase><phrase role="special">{</phrase>
<phrase role="special">~</phrase><phrase role="identifier">FinalEOL</phrase><phrase role="special">(){</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
<phrase role="special">}</phrase>
<phrase role="special">};</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">layout</phrase><phrase role="special">(</phrase><phrase role="identifier">coro_t</phrase><phrase role="special">::</phrase><phrase role="identifier">pull_type</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">source</phrase><phrase role="special">,</phrase><phrase role="keyword">int</phrase> <phrase role="identifier">num</phrase><phrase role="special">,</phrase><phrase role="keyword">int</phrase> <phrase role="identifier">width</phrase><phrase role="special">){</phrase>
<phrase role="comment">// Finish the last line when we leave by whatever means</phrase>
<phrase role="identifier">FinalEOL</phrase> <phrase role="identifier">eol</phrase><phrase role="special">;</phrase>
<phrase role="comment">// Pull values from upstream, lay them out 'num' to a line</phrase>
<phrase role="keyword">for</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">&lt;</phrase> <phrase role="identifier">num</phrase><phrase role="special">;</phrase> <phrase role="special">++</phrase><phrase role="identifier">i</phrase><phrase role="special">){</phrase>
<phrase role="comment">// when we exhaust the input, stop</phrase>
<phrase role="keyword">if</phrase> <phrase role="special">(!</phrase><phrase role="identifier">source</phrase><phrase role="special">)</phrase> <phrase role="keyword">return</phrase><phrase role="special">;</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">setw</phrase><phrase role="special">(</phrase><phrase role="identifier">width</phrase><phrase role="special">)</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">source</phrase><phrase role="special">.</phrase><phrase role="identifier">get</phrase><phrase role="special">();</phrase>
<phrase role="comment">// now that we've handled this item, advance to next</phrase>
<phrase role="identifier">source</phrase><phrase role="special">();</phrase>
<phrase role="special">}</phrase>
<phrase role="comment">// after 'num' items, line break</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
<phrase role="special">}</phrase>
<phrase role="special">}</phrase>
<phrase role="comment">// For example purposes, instead of having a separate text file in the</phrase>
<phrase role="comment">// local filesystem, construct an istringstream to read.</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="identifier">data</phrase><phrase role="special">(</phrase>
<phrase role="string">&quot;This is the first line.\n&quot;</phrase>
<phrase role="string">&quot;This, the second.\n&quot;</phrase>
<phrase role="string">&quot;The third has \&quot;a phrase\&quot;!\n&quot;</phrase>
<phrase role="special">);</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="string">&quot;\nfilter:\n&quot;</phrase><phrase role="special">;</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">istringstream</phrase> <phrase role="identifier">infile</phrase><phrase role="special">(</phrase><phrase role="identifier">data</phrase><phrase role="special">);</phrase>
<phrase role="identifier">coro_t</phrase><phrase role="special">::</phrase><phrase role="identifier">pull_type</phrase> <phrase role="identifier">reader</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">bind</phrase><phrase role="special">(</phrase><phrase role="identifier">readlines</phrase><phrase role="special">,</phrase> <phrase role="identifier">_1</phrase><phrase role="special">,</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">ref</phrase><phrase role="special">(</phrase><phrase role="identifier">infile</phrase><phrase role="special">)));</phrase>
<phrase role="identifier">coro_t</phrase><phrase role="special">::</phrase><phrase role="identifier">pull_type</phrase> <phrase role="identifier">tokenizer</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">bind</phrase><phrase role="special">(</phrase><phrase role="identifier">tokenize</phrase><phrase role="special">,</phrase> <phrase role="identifier">_1</phrase><phrase role="special">,</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">ref</phrase><phrase role="special">(</phrase><phrase role="identifier">reader</phrase><phrase role="special">)));</phrase>
<phrase role="identifier">coro_t</phrase><phrase role="special">::</phrase><phrase role="identifier">pull_type</phrase> <phrase role="identifier">filter</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">bind</phrase><phrase role="special">(</phrase><phrase role="identifier">only_words</phrase><phrase role="special">,</phrase> <phrase role="identifier">_1</phrase><phrase role="special">,</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">ref</phrase><phrase role="special">(</phrase><phrase role="identifier">tokenizer</phrase><phrase role="special">)));</phrase>
<phrase role="identifier">coro_t</phrase><phrase role="special">::</phrase><phrase role="identifier">pull_type</phrase> <phrase role="identifier">tracer</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">bind</phrase><phrase role="special">(</phrase><phrase role="identifier">trace</phrase><phrase role="special">,</phrase> <phrase role="identifier">_1</phrase><phrase role="special">,</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">ref</phrase><phrase role="special">(</phrase><phrase role="identifier">filter</phrase><phrase role="special">)));</phrase>
<phrase role="identifier">BOOST_FOREACH</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="identifier">token</phrase><phrase role="special">,</phrase><phrase role="identifier">tracer</phrase><phrase role="special">){</phrase>
<phrase role="comment">// just iterate, we're already pulling through tracer</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">cout</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="string">&quot;\nlayout() as coroutine::push_type:\n&quot;</phrase><phrase role="special">;</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">istringstream</phrase> <phrase role="identifier">infile</phrase><phrase role="special">(</phrase><phrase role="identifier">data</phrase><phrase role="special">);</phrase>
<phrase role="identifier">coro_t</phrase><phrase role="special">::</phrase><phrase role="identifier">pull_type</phrase> <phrase role="identifier">reader</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">bind</phrase><phrase role="special">(</phrase><phrase role="identifier">readlines</phrase><phrase role="special">,</phrase> <phrase role="identifier">_1</phrase><phrase role="special">,</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">ref</phrase><phrase role="special">(</phrase><phrase role="identifier">infile</phrase><phrase role="special">)));</phrase>
<phrase role="identifier">coro_t</phrase><phrase role="special">::</phrase><phrase role="identifier">pull_type</phrase> <phrase role="identifier">tokenizer</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">bind</phrase><phrase role="special">(</phrase><phrase role="identifier">tokenize</phrase><phrase role="special">,</phrase> <phrase role="identifier">_1</phrase><phrase role="special">,</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">ref</phrase><phrase role="special">(</phrase><phrase role="identifier">reader</phrase><phrase role="special">)));</phrase>
<phrase role="identifier">coro_t</phrase><phrase role="special">::</phrase><phrase role="identifier">pull_type</phrase> <phrase role="identifier">filter</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">bind</phrase><phrase role="special">(</phrase><phrase role="identifier">only_words</phrase><phrase role="special">,</phrase> <phrase role="identifier">_1</phrase><phrase role="special">,</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">ref</phrase><phrase role="special">(</phrase><phrase role="identifier">tokenizer</phrase><phrase role="special">)));</phrase>
<phrase role="identifier">coro_t</phrase><phrase role="special">::</phrase><phrase role="identifier">push_type</phrase> <phrase role="identifier">writer</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">bind</phrase><phrase role="special">(</phrase><phrase role="identifier">layout</phrase><phrase role="special">,</phrase> <phrase role="identifier">_1</phrase><phrase role="special">,</phrase> <phrase role="number">5</phrase><phrase role="special">,</phrase> <phrase role="number">15</phrase><phrase role="special">));</phrase>
<phrase role="identifier">BOOST_FOREACH</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="identifier">token</phrase><phrase role="special">,</phrase><phrase role="identifier">filter</phrase><phrase role="special">){</phrase>
<phrase role="identifier">writer</phrase><phrase role="special">(</phrase><phrase role="identifier">token</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">cout</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="string">&quot;\nfiltering output:\n&quot;</phrase><phrase role="special">;</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">istringstream</phrase> <phrase role="identifier">infile</phrase><phrase role="special">(</phrase><phrase role="identifier">data</phrase><phrase role="special">);</phrase>
<phrase role="identifier">coro_t</phrase><phrase role="special">::</phrase><phrase role="identifier">pull_type</phrase> <phrase role="identifier">reader</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">bind</phrase><phrase role="special">(</phrase><phrase role="identifier">readlines</phrase><phrase role="special">,</phrase><phrase role="identifier">_1</phrase><phrase role="special">,</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">ref</phrase><phrase role="special">(</phrase><phrase role="identifier">infile</phrase><phrase role="special">)));</phrase>
<phrase role="identifier">coro_t</phrase><phrase role="special">::</phrase><phrase role="identifier">pull_type</phrase> <phrase role="identifier">tokenizer</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">bind</phrase><phrase role="special">(</phrase><phrase role="identifier">tokenize</phrase><phrase role="special">,</phrase><phrase role="identifier">_1</phrase><phrase role="special">,</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">ref</phrase><phrase role="special">(</phrase><phrase role="identifier">reader</phrase><phrase role="special">)));</phrase>
<phrase role="identifier">coro_t</phrase><phrase role="special">::</phrase><phrase role="identifier">push_type</phrase> <phrase role="identifier">writer</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">bind</phrase><phrase role="special">(</phrase><phrase role="identifier">layout</phrase><phrase role="special">,</phrase><phrase role="identifier">_1</phrase><phrase role="special">,</phrase><phrase role="number">5</phrase><phrase role="special">,</phrase><phrase role="number">15</phrase><phrase role="special">));</phrase>
<phrase role="comment">// Because of the symmetry of the API, we can use any of these</phrase>
<phrase role="comment">// chaining functions in a push_type coroutine chain as well.</phrase>
<phrase role="identifier">coro_t</phrase><phrase role="special">::</phrase><phrase role="identifier">push_type</phrase> <phrase role="identifier">filter</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">bind</phrase><phrase role="special">(</phrase><phrase role="identifier">only_words</phrase><phrase role="special">,</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">ref</phrase><phrase role="special">(</phrase><phrase role="identifier">writer</phrase><phrase role="special">),</phrase><phrase role="identifier">_1</phrase><phrase role="special">));</phrase>
<phrase role="identifier">BOOST_FOREACH</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="identifier">token</phrase><phrase role="special">,</phrase><phrase role="identifier">tokenizer</phrase><phrase role="special">){</phrase>
<phrase role="identifier">filter</phrase><phrase role="special">(</phrase><phrase role="identifier">token</phrase><phrase role="special">);</phrase>
<phrase role="special">}</phrase>
<phrase role="special">}</phrase>
</programlisting>
<bridgehead renderas="sect3" id="coroutine.motivation.h2">
<phrase id="coroutine.motivation.asynchronous_operations_with_boost_asio"/><link
linkend="coroutine.motivation.asynchronous_operations_with_boost_asio">asynchronous
operations with boost.asio</link>
</bridgehead>
<para>
In the past the code using asio's <emphasis>asynchronous operations</emphasis>
was scattered by callbacks. <emphasis role="bold">Boost.Asio</emphasis> provides
with its new <emphasis>asynchronous result</emphasis> feature a new way to
simplify the code and make it easier to read. <emphasis>boost::asio::yield_context</emphasis>
uses internally <emphasis role="bold">Boost.Coroutine</emphasis>:
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">echo</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">asio</phrase><phrase role="special">::</phrase><phrase role="identifier">ip</phrase><phrase role="special">::</phrase><phrase role="identifier">tcp</phrase><phrase role="special">::</phrase><phrase role="identifier">socket</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">socket</phrase><phrase role="special">,</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">asio</phrase><phrase role="special">::</phrase><phrase role="identifier">yield_context</phrase> <phrase role="identifier">yield</phrase><phrase role="special">){</phrase>
<phrase role="keyword">char</phrase> <phrase role="identifier">data</phrase><phrase role="special">[</phrase><phrase role="number">128</phrase><phrase role="special">];</phrase>
<phrase role="comment">// read asynchronous data from socket</phrase>
<phrase role="comment">// execution context will be suspended until</phrase>
<phrase role="comment">// some bytes are read from socket</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">n</phrase><phrase role="special">=</phrase><phrase role="identifier">socket</phrase><phrase role="special">.</phrase><phrase role="identifier">async_read_some</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">asio</phrase><phrase role="special">::</phrase><phrase role="identifier">buffer</phrase><phrase role="special">(</phrase><phrase role="identifier">data</phrase><phrase role="special">),</phrase><phrase role="identifier">yield</phrase><phrase role="special">);</phrase>
<phrase role="comment">// write some bytes asynchronously</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">asio</phrase><phrase role="special">::</phrase><phrase role="identifier">async_write</phrase><phrase role="special">(</phrase><phrase role="identifier">socket</phrase><phrase role="special">,</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">asio</phrase><phrase role="special">::</phrase><phrase role="identifier">buffer</phrase><phrase role="special">(</phrase><phrase role="identifier">data</phrase><phrase role="special">,</phrase><phrase role="identifier">n</phrase><phrase role="special">),</phrase><phrase role="identifier">yield</phrase><phrase role="special">);</phrase>
<phrase role="special">}</phrase>
</programlisting>
</section>
<section id="coroutine.coroutine">
<title><link linkend="coroutine.coroutine">Coroutine</link></title>
<para>
<emphasis role="bold">Boost.Coroutine</emphasis> provides two interfaces -
one with uni- and one with bidirectional data transfer (deprecated).
</para>
<section id="coroutine.coroutine.unidirect">
<title><link linkend="coroutine.coroutine.unidirect">Unidirectional coroutine</link></title>
<note>
<para>
This is the default interface (macro BOOST_COROUTINES_UNIDIRECT).
</para>
</note>
<para>
Two coroutine types - <emphasis>coroutine&lt;&gt;::push_type</emphasis> and
<emphasis>coroutine&lt;&gt;::pull_type</emphasis> - providing a unidirectional
transfer of data.
</para>
<bridgehead renderas="sect4" id="coroutine.coroutine.unidirect.h0">
<phrase id="coroutine.coroutine.unidirect._emphasis_coroutine_lt__gt___pull_type__emphasis_"/><link
linkend="coroutine.coroutine.unidirect._emphasis_coroutine_lt__gt___pull_type__emphasis_"><emphasis>coroutine&lt;&gt;::pull_type</emphasis></link>
</bridgehead>
<para>
<emphasis>coroutine&lt;&gt;::pull_type</emphasis> transfers data from another
execution context (== pulled-from). The class has only one template parameter
defining the transferred parameter type. The constructor of <emphasis>coroutine&lt;&gt;::pull_type</emphasis>
takes a function (<emphasis>coroutine-function</emphasis>) accepting a reference
to a <emphasis>coroutine&lt;&gt;::push_type</emphasis> as argument. Instantiating
a <emphasis>coroutine&lt;&gt;::pull_type</emphasis> passes the control of
execution to <emphasis>coroutine-function</emphasis> and a complementary
<emphasis>coroutine&lt;&gt;::push_type</emphasis> is synthesized by the runtime
and passed as reference to <emphasis>coroutine-function</emphasis>.
</para>
<para>
This kind of coroutine provides <emphasis>boost::coroutines::coroutine&lt;&gt;::pull_type::operator()</emphasis>.
This method only switches context; it transfers no data.
</para>
<para>
<emphasis>coroutine&lt;&gt;::pull_type</emphasis> provides input iterators
(<emphasis>boost::coroutines::coroutine&lt;&gt;::pull_type::iterator</emphasis>)
and <emphasis>boost::begin()</emphasis>/<emphasis>boost::end()</emphasis>
are overloaded. The increment-operation switches the context and transfers
data.
</para>
<programlisting><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutines</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">int</phrase><phrase role="special">&gt;::</phrase><phrase role="identifier">pull_type</phrase> <phrase role="identifier">source</phrase><phrase role="special">(</phrase>
<phrase role="special">[&amp;](</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutines</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">int</phrase><phrase role="special">&gt;::</phrase><phrase role="identifier">push_type</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">sink</phrase><phrase role="special">){</phrase>
<phrase role="keyword">int</phrase> <phrase role="identifier">first</phrase><phrase role="special">=</phrase><phrase role="number">1</phrase><phrase role="special">,</phrase><phrase role="identifier">second</phrase><phrase role="special">=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
<phrase role="identifier">sink</phrase><phrase role="special">(</phrase><phrase role="identifier">first</phrase><phrase role="special">);</phrase>
<phrase role="identifier">sink</phrase><phrase role="special">(</phrase><phrase role="identifier">second</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">&lt;</phrase><phrase role="number">8</phrase><phrase role="special">;++</phrase><phrase role="identifier">i</phrase><phrase role="special">){</phrase>
<phrase role="keyword">int</phrase> <phrase role="identifier">third</phrase><phrase role="special">=</phrase><phrase role="identifier">first</phrase><phrase role="special">+</phrase><phrase role="identifier">second</phrase><phrase role="special">;</phrase>
<phrase role="identifier">first</phrase><phrase role="special">=</phrase><phrase role="identifier">second</phrase><phrase role="special">;</phrase>
<phrase role="identifier">second</phrase><phrase role="special">=</phrase><phrase role="identifier">third</phrase><phrase role="special">;</phrase>
<phrase role="identifier">sink</phrase><phrase role="special">(</phrase><phrase role="identifier">third</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">auto</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">cout</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">i</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="string">&quot; &quot;</phrase><phrase role="special">;</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="string">&quot;\nDone&quot;</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
<phrase role="identifier">output</phrase><phrase role="special">:</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> <phrase role="number">55</phrase>
<phrase role="identifier">Done</phrase>
</programlisting>
<para>
In this example a <emphasis>coroutine&lt;&gt;::pull_type</emphasis> is created
in the main execution context taking a lambda function (== <emphasis>coroutine-function</emphasis>)
which calculates Fibonacci numbers in a simple <emphasis>for</emphasis>-loop).
The <emphasis>coroutine-function</emphasis> is executed in a newly created
execution context which is managed by the instance of <emphasis>coroutine&lt;&gt;::pull_type</emphasis>.
A <emphasis>coroutine&lt;&gt;::push_type</emphasis> is automatically generated
by the runtime and passed as reference to the lambda function. Each time
the lambda function calls <emphasis>boost::coroutines::coroutine&lt;&gt;::push_type::operator()</emphasis>
with another Fibonacci number, <emphasis>coroutine&lt;&gt;::push_type</emphasis>
transfers it back to the main execution context. The local state of <emphasis>coroutine-function</emphasis>
is preserved and will be restored upon transferring execution control back
to <emphasis>coroutine-function</emphasis> to calculate the next Fibonacci
number. Because <emphasis>coroutine&lt;&gt;::pull_type</emphasis> provides
input iterators and <emphasis>boost::begin()</emphasis>/<emphasis>boost::end()</emphasis>
are overloaded, a <emphasis>range-based for</emphasis>-loop can be used to
iterate over the generated Fibonacci numbers.
</para>
<bridgehead renderas="sect4" id="coroutine.coroutine.unidirect.h1">
<phrase id="coroutine.coroutine.unidirect._emphasis_coroutine_lt__gt___push_type__emphasis_"/><link
linkend="coroutine.coroutine.unidirect._emphasis_coroutine_lt__gt___push_type__emphasis_"><emphasis>coroutine&lt;&gt;::push_type</emphasis></link>
</bridgehead>
<para>
<emphasis>coroutine&lt;&gt;::push_type</emphasis> transfers data to the other
execution context (== pushed-to). The class has only one template parameter
defining the transferred parameter type. The constructor of <emphasis>coroutine&lt;&gt;::push_type</emphasis>
takes a function (<emphasis>coroutine-function</emphasis>) accepting a reference
to a <emphasis>coroutine&lt;&gt;::pull_type</emphasis> as argument. In contrast
to <emphasis>coroutine&lt;&gt;::pull_type</emphasis>, instantiating a <emphasis>coroutine&lt;&gt;::push_type</emphasis>
does not pass the control of execution to <emphasis>coroutine-function</emphasis>
- instead the first call of <emphasis>boost::coroutines::coroutine&lt;&gt;::push_type::operator()</emphasis>
synthesizes a complementary <emphasis>coroutine&lt;&gt;::pull_type</emphasis>
and passes it as reference to <emphasis>coroutine-function</emphasis>.
</para>
<para>
The interface does not contain a <emphasis>get()</emphasis>-function: you
can not retrieve values from another execution context with this kind of
coroutine.
</para>
<para>
<emphasis>coroutine&lt;&gt;::push_type</emphasis> provides output iterators
(__push_coro__iterator) and <emphasis>boost::begin()</emphasis>/<emphasis>boost::end()</emphasis>
are overloaded. The increment-operation switches the context and transfers
data.
</para>
<programlisting><phrase role="keyword">struct</phrase> <phrase role="identifier">FinalEOL</phrase><phrase role="special">{</phrase>
<phrase role="special">~</phrase><phrase role="identifier">FinalEOL</phrase><phrase role="special">(){</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
<phrase role="special">}</phrase>
<phrase role="special">};</phrase>
<phrase role="keyword">const</phrase> <phrase role="keyword">int</phrase> <phrase role="identifier">num</phrase><phrase role="special">=</phrase><phrase role="number">5</phrase><phrase role="special">,</phrase> <phrase role="identifier">width</phrase><phrase role="special">=</phrase><phrase role="number">15</phrase><phrase role="special">;</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutines</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">&gt;::</phrase><phrase role="identifier">push_type</phrase> <phrase role="identifier">writer</phrase><phrase role="special">(</phrase>
<phrase role="special">[&amp;](</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutines</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">&gt;::</phrase><phrase role="identifier">pull_type</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">in</phrase><phrase role="special">){</phrase>
<phrase role="comment">// finish the last line when we leave by whatever means</phrase>
<phrase role="identifier">FinalEOL</phrase> <phrase role="identifier">eol</phrase><phrase role="special">;</phrase>
<phrase role="comment">// pull values from upstream, lay them out 'num' to a line</phrase>
<phrase role="keyword">for</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">&lt;</phrase><phrase role="identifier">num</phrase><phrase role="special">;++</phrase><phrase role="identifier">i</phrase><phrase role="special">){</phrase>
<phrase role="comment">// when we exhaust the input, stop</phrase>
<phrase role="keyword">if</phrase><phrase role="special">(!</phrase><phrase role="identifier">in</phrase><phrase role="special">)</phrase> <phrase role="keyword">return</phrase><phrase role="special">;</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">setw</phrase><phrase role="special">(</phrase><phrase role="identifier">width</phrase><phrase role="special">)</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">in</phrase><phrase role="special">.</phrase><phrase role="identifier">get</phrase><phrase role="special">();</phrase>
<phrase role="comment">// now that we've handled this item, advance to next</phrase>
<phrase role="identifier">in</phrase><phrase role="special">();</phrase>
<phrase role="special">}</phrase>
<phrase role="comment">// after 'num' items, line break</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
<phrase role="special">}</phrase>
<phrase role="special">});</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">vector</phrase><phrase role="special">&lt;</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">&gt;</phrase> <phrase role="identifier">words</phrase><phrase role="special">{</phrase>
<phrase role="string">&quot;peas&quot;</phrase><phrase role="special">,</phrase> <phrase role="string">&quot;porridge&quot;</phrase><phrase role="special">,</phrase> <phrase role="string">&quot;hot&quot;</phrase><phrase role="special">,</phrase> <phrase role="string">&quot;peas&quot;</phrase><phrase role="special">,</phrase>
<phrase role="string">&quot;porridge&quot;</phrase><phrase role="special">,</phrase> <phrase role="string">&quot;cold&quot;</phrase><phrase role="special">,</phrase> <phrase role="string">&quot;peas&quot;</phrase><phrase role="special">,</phrase> <phrase role="string">&quot;porridge&quot;</phrase><phrase role="special">,</phrase>
<phrase role="string">&quot;in&quot;</phrase><phrase role="special">,</phrase> <phrase role="string">&quot;the&quot;</phrase><phrase role="special">,</phrase> <phrase role="string">&quot;pot&quot;</phrase><phrase role="special">,</phrase> <phrase role="string">&quot;nine&quot;</phrase><phrase role="special">,</phrase>
<phrase role="string">&quot;days&quot;</phrase><phrase role="special">,</phrase> <phrase role="string">&quot;old&quot;</phrase> <phrase role="special">};</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">copy</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">begin</phrase><phrase role="special">(</phrase><phrase role="identifier">words</phrase><phrase role="special">),</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">end</phrase><phrase role="special">(</phrase><phrase role="identifier">words</phrase><phrase role="special">),</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">begin</phrase><phrase role="special">(</phrase><phrase role="identifier">writer</phrase><phrase role="special">));</phrase>
<phrase role="identifier">output</phrase><phrase role="special">:</phrase>
<phrase role="identifier">peas</phrase> <phrase role="identifier">porridge</phrase> <phrase role="identifier">hot</phrase> <phrase role="identifier">peas</phrase> <phrase role="identifier">porridge</phrase>
<phrase role="identifier">cold</phrase> <phrase role="identifier">peas</phrase> <phrase role="identifier">porridge</phrase> <phrase role="identifier">in</phrase> <phrase role="identifier">the</phrase>
<phrase role="identifier">pot</phrase> <phrase role="identifier">nine</phrase> <phrase role="identifier">days</phrase> <phrase role="identifier">old</phrase>
</programlisting>
<para>
In this example a <emphasis>coroutine&lt;&gt;::push_type</emphasis> is created
in the main execution context accepting a lambda function (== <emphasis>coroutine-function</emphasis>)
which requests strings and lays out 'num' of them on each line. This demonstrates
the inversion of control permitted by coroutines. Without coroutines, a utility
function to perform the same job would necessarily accept each new value
as a function parameter, returning after processing that single value. That
function would depend on a static state variable. A <emphasis>coroutine-function</emphasis>,
however, can request each new value as if by calling a function -- even though
its caller also passes values as if by calling a function. The <emphasis>coroutine-function</emphasis>
is executed in a newly created execution context which is managed by the
instance of <emphasis>coroutine&lt;&gt;::push_type</emphasis>. The main execution
context passes the strings to the <emphasis>coroutine-function</emphasis>
by calling <emphasis>boost::coroutines::coroutine&lt;&gt;::push_type::operator()</emphasis>.
A <emphasis>coroutine&lt;&gt;::pull_type</emphasis> is automatically generated
by the runtime and passed as reference to the lambda function. The <emphasis>coroutine-function</emphasis>
accesses the strings passed from the main execution context by calling <emphasis>boost::coroutines::coroutine&lt;&gt;::pull_type::get()</emphasis>
and lays those strings out on <emphasis>std::cout</emphasis> according the
parameters 'num' and 'width'. The local state of <emphasis>coroutine-function</emphasis>
is preserved and will be restored after transferring execution control back
to <emphasis>coroutine-function</emphasis>. Because <emphasis>coroutine&lt;&gt;::push_type</emphasis>
provides output iterators and <emphasis>boost::begin()</emphasis>/<emphasis>boost::end()</emphasis>
are overloaded, the <emphasis>std::copy</emphasis> algorithm can be used
to iterate over the vector containing the strings and pass them one by one
to the coroutine.
</para>
<bridgehead renderas="sect4" id="coroutine.coroutine.unidirect.h2">
<phrase id="coroutine.coroutine.unidirect.stackful"/><link linkend="coroutine.coroutine.unidirect.stackful">stackful</link>
</bridgehead>
<para>
Each instance of a coroutine has its own stack.
</para>
<para>
In contrast to stackless coroutines, stackful coroutines allow invoking the
suspend operation out of arbitrary sub-stackframes, enabling escape-and-reenter
recursive operations.
</para>
<bridgehead renderas="sect4" id="coroutine.coroutine.unidirect.h3">
<phrase id="coroutine.coroutine.unidirect.move_only"/><link linkend="coroutine.coroutine.unidirect.move_only">move-only</link>
</bridgehead>
<para>
A coroutine is moveable-only.
</para>
<para>
If it were copyable, then its stack with all the objects allocated on it
would be copied too. That would force undefined behaviour if some of these
objects were RAII-classes (manage a resource via RAII pattern). When the
first of the coroutine copies terminates (unwinds its stack), the RAII class
destructors will release their managed resources. When the second copy terminates,
the same destructors will try to doubly-release the same resources, leading
to undefined behavior.
</para>
<bridgehead renderas="sect4" id="coroutine.coroutine.unidirect.h4">
<phrase id="coroutine.coroutine.unidirect.clean_up"/><link linkend="coroutine.coroutine.unidirect.clean_up">clean-up</link>
</bridgehead>
<para>
On coroutine destruction the associated stack will be unwound.
</para>
<para>
The constructor of coroutine allows to pass an customized <emphasis>stack-allocator</emphasis>.
<emphasis>stack-allocator</emphasis> is free to deallocate the stack or cache
it for future usage (for coroutines created later).
</para>
<bridgehead renderas="sect4" id="coroutine.coroutine.unidirect.h5">
<phrase id="coroutine.coroutine.unidirect.segmented_stack"/><link linkend="coroutine.coroutine.unidirect.segmented_stack">segmented
stack</link>
</bridgehead>
<para>
<emphasis>coroutine&lt;&gt;::push_type</emphasis> and <emphasis>coroutine&lt;&gt;::pull_type</emphasis>
does support segmented stacks (growing on demand).
</para>
<para>
It is not always possible to estimated the required stack size - in most
cases too much memory is allocated (waste of virtual address-space).
</para>
<para>
At construction a coroutine starts with a default (minimal) stack size. This
minimal stack size is the maximum of page size and the canonical size for
signal stack (macro SIGSTKSZ on POSIX).
</para>
<para>
At this time of writing only GCC (4.7)\cite{gccsplit} is known to support
segmented stacks. With version 1.54 <emphasis role="bold">Boost.Coroutine</emphasis>
provides support for segmented stacks.
</para>
<para>
The destructor releases the associated stack. The implementer is free to
deallocate the stack or to cache it for later usage.
</para>
<bridgehead renderas="sect4" id="coroutine.coroutine.unidirect.h6">
<phrase id="coroutine.coroutine.unidirect.context_switch"/><link linkend="coroutine.coroutine.unidirect.context_switch">context
switch</link>
</bridgehead>
<para>
A coroutine saves and restores registers according to the underlying ABI
on each context switch.
</para>
<para>
Some applications do not use floating-point registers and can disable preserving
fpu registers for performance reasons.
</para>
<note>
<para>
According to the calling convention the FPU registers are preserved by
default.
</para>
</note>
<para>
On POSIX systems, the coroutine context switch does not preserve signal masks
for performance reasons.
</para>
<para>
A context switch is done via <emphasis>boost::coroutines::coroutine&lt;&gt;::push_type::operator()</emphasis>
and <emphasis>boost::coroutines::coroutine&lt;&gt;::pull_type::operator()</emphasis>.
</para>
<warning>
<para>
Calling <emphasis>boost::coroutines::coroutine&lt;&gt;::push_type::operator()</emphasis>/<emphasis>boost::coroutines::coroutine&lt;&gt;::pull_type::operator()</emphasis>
from inside the <emphasis role="underline">same</emphasis> coroutine results
in undefined behaviour.
</para>
</warning>
<bridgehead renderas="sect4" id="coroutine.coroutine.unidirect.h7">
<phrase id="coroutine.coroutine.unidirect.coroutine_function"/><link linkend="coroutine.coroutine.unidirect.coroutine_function">coroutine-function</link>
</bridgehead>
<para>
The <emphasis>coroutine-function</emphasis> returns <emphasis>void</emphasis>
and takes its counterpart-coroutine as argument, so that using the coroutine
passed as argument to <emphasis>coroutine-function</emphasis> is the only
way to transfer data and execution control back to the caller. Both coroutine
types take the same template argument. For <emphasis>coroutine&lt;&gt;::pull_type</emphasis>
the <emphasis>coroutine-function</emphasis> is entered at <emphasis>coroutine&lt;&gt;::pull_type</emphasis>
construction. For <emphasis>coroutine&lt;&gt;::push_type</emphasis> the
<emphasis>coroutine-function</emphasis> is not entered at <emphasis>coroutine&lt;&gt;::push_type</emphasis>
construction but entered by the first invocation of <emphasis>boost::coroutines::coroutine&lt;&gt;::push_type::operator()</emphasis>.
After execution control is returned from <emphasis>coroutine-function</emphasis>
the state of the coroutine can be checked via <emphasis>boost::coroutines::coroutine&lt;&gt;::pull_type::operator
bool</emphasis> returning true if the coroutine is still valid (<emphasis>coroutine-function</emphasis>
has not terminated). Unless T is void, true also implies that a data value
is available.
</para>
<bridgehead renderas="sect4" id="coroutine.coroutine.unidirect.h8">
<phrase id="coroutine.coroutine.unidirect.passing_data_from_a_pull_coroutine_to_main_context"/><link
linkend="coroutine.coroutine.unidirect.passing_data_from_a_pull_coroutine_to_main_context">passing
data from a pull-coroutine to main-context</link>
</bridgehead>
<para>
In order to transfer data from a <emphasis>coroutine&lt;&gt;::pull_type</emphasis>
to the main-context the framework synthesizes a <emphasis>coroutine&lt;&gt;::push_type</emphasis>
associated with the <emphasis>coroutine&lt;&gt;::pull_type</emphasis> instance
in the main-context. The synthesized <emphasis>coroutine&lt;&gt;::push_type</emphasis>
is passed as argument to <emphasis>coroutine-function</emphasis>.\ The <emphasis>coroutine-function</emphasis>
must call this <emphasis>boost::coroutines::coroutine&lt;&gt;::push_type::operator()</emphasis>
in order to transfer each data value back to the main-context. In the main-context,
the <emphasis>boost::coroutines::coroutine&lt;&gt;::pull_type::operator bool</emphasis>
determines whether the coroutine is still valid and a data value is available
or <emphasis>coroutine-function</emphasis> has terminated (<emphasis>coroutine&lt;&gt;::pull_type</emphasis>
is invalid; no data value available). Access to the transferred data value
is given by <emphasis>boost::coroutines::coroutine&lt;&gt;::pull_type::get()</emphasis>.
</para>
<programlisting><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutines</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">int</phrase><phrase role="special">&gt;::</phrase><phrase role="identifier">pull_type</phrase> <phrase role="identifier">source</phrase><phrase role="special">(</phrase> <phrase role="comment">// constructor enters coroutine-function</phrase>
<phrase role="special">[&amp;](</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutines</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">int</phrase><phrase role="special">&gt;::</phrase><phrase role="identifier">push_type</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">sink</phrase><phrase role="special">){</phrase>
<phrase role="identifier">sink</phrase><phrase role="special">(</phrase><phrase role="number">1</phrase><phrase role="special">);</phrase> <phrase role="comment">// push {1} back to main-context</phrase>
<phrase role="identifier">sink</phrase><phrase role="special">(</phrase><phrase role="number">1</phrase><phrase role="special">);</phrase> <phrase role="comment">// push {1} back to main-context</phrase>
<phrase role="identifier">sink</phrase><phrase role="special">(</phrase><phrase role="number">2</phrase><phrase role="special">);</phrase> <phrase role="comment">// push {2} back to main-context</phrase>
<phrase role="identifier">sink</phrase><phrase role="special">(</phrase><phrase role="number">3</phrase><phrase role="special">);</phrase> <phrase role="comment">// push {3} back to main-context</phrase>
<phrase role="identifier">sink</phrase><phrase role="special">(</phrase><phrase role="number">5</phrase><phrase role="special">);</phrase> <phrase role="comment">// push {5} back to main-context</phrase>
<phrase role="identifier">sink</phrase><phrase role="special">(</phrase><phrase role="number">8</phrase><phrase role="special">);</phrase> <phrase role="comment">// push {8} back to main-context</phrase>
<phrase role="special">});</phrase>
<phrase role="keyword">while</phrase><phrase role="special">(</phrase><phrase role="identifier">source</phrase><phrase role="special">){</phrase> <phrase role="comment">// test if pull-coroutine is valid</phrase>
<phrase role="keyword">int</phrase> <phrase role="identifier">ret</phrase><phrase role="special">=</phrase><phrase role="identifier">source</phrase><phrase role="special">.</phrase><phrase role="identifier">get</phrase><phrase role="special">();</phrase> <phrase role="comment">// access data value</phrase>
<phrase role="identifier">source</phrase><phrase role="special">();</phrase> <phrase role="comment">// context-switch to coroutine-function</phrase>
<phrase role="special">}</phrase>
</programlisting>
<bridgehead renderas="sect4" id="coroutine.coroutine.unidirect.h9">
<phrase id="coroutine.coroutine.unidirect.passing_data_from_main_context_to_a_push_coroutine"/><link
linkend="coroutine.coroutine.unidirect.passing_data_from_main_context_to_a_push_coroutine">passing
data from main-context to a push-coroutine</link>
</bridgehead>
<para>
In order to transfer data to a <emphasis>coroutine&lt;&gt;::push_type</emphasis>
from the main-context the framework synthesizes a <emphasis>coroutine&lt;&gt;::pull_type</emphasis>
associated with the <emphasis>coroutine&lt;&gt;::push_type</emphasis> instance
in the main-context. The synthesized <emphasis>coroutine&lt;&gt;::pull_type</emphasis>
is passed as argument to <emphasis>coroutine-function</emphasis>. The main-context
must call this <emphasis>boost::coroutines::coroutine&lt;&gt;::push_type::operator()</emphasis>
in order to transfer each data value into the <emphasis>coroutine-function</emphasis>.
Access to the transferred data value is given by <emphasis>boost::coroutines::coroutine&lt;&gt;::pull_type::get()</emphasis>.
</para>
<programlisting><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutines</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">int</phrase><phrase role="special">&gt;::</phrase><phrase role="identifier">push_type</phrase> <phrase role="identifier">sink</phrase><phrase role="special">(</phrase> <phrase role="comment">// constructor does NOT enter coroutine-function</phrase>
<phrase role="special">[&amp;](</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutines</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">int</phrase><phrase role="special">&gt;::</phrase><phrase role="identifier">pull_type</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">source</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="identifier">source</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">i</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="string">&quot; &quot;</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">vector</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">int</phrase><phrase role="special">&gt;</phrase> <phrase role="identifier">v</phrase><phrase role="special">{</phrase><phrase role="number">1</phrase><phrase role="special">,</phrase><phrase role="number">1</phrase><phrase role="special">,</phrase><phrase role="number">2</phrase><phrase role="special">,</phrase><phrase role="number">3</phrase><phrase role="special">,</phrase><phrase role="number">5</phrase><phrase role="special">,</phrase><phrase role="number">8</phrase><phrase role="special">,</phrase><phrase role="number">13</phrase><phrase role="special">,</phrase><phrase role="number">21</phrase><phrase role="special">,</phrase><phrase role="number">34</phrase><phrase role="special">,</phrase><phrase role="number">55</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="identifier">v</phrase><phrase role="special">){</phrase>
<phrase role="identifier">sink</phrase><phrase role="special">(</phrase><phrase role="identifier">i</phrase><phrase role="special">);</phrase> <phrase role="comment">// push {i} to coroutine-function</phrase>
<phrase role="special">}</phrase>
</programlisting>
<bridgehead renderas="sect4" id="coroutine.coroutine.unidirect.h10">
<phrase id="coroutine.coroutine.unidirect.accessing_parameters"/><link linkend="coroutine.coroutine.unidirect.accessing_parameters">accessing
parameters</link>
</bridgehead>
<para>
Parameters returned from or transferred to the <emphasis>coroutine-function</emphasis>
can be accessed with <emphasis>boost::coroutines::coroutine&lt;&gt;::pull_type::get()</emphasis>.
</para>
<para>
Splitting-up the access of parameters from context switch function enables
to check if <emphasis>coroutine&lt;&gt;::pull_type</emphasis> is valid after
return from <emphasis>boost::coroutines::coroutine&lt;&gt;::pull_type::operator()</emphasis>,
e.g. <emphasis>coroutine&lt;&gt;::pull_type</emphasis> has values and <emphasis>coroutine-function</emphasis>
has not terminated.
</para>
<programlisting><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutines</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">tuple</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">int</phrase><phrase role="special">,</phrase><phrase role="keyword">int</phrase><phrase role="special">&gt;&gt;::</phrase><phrase role="identifier">push_type</phrase> <phrase role="identifier">sink</phrase><phrase role="special">(</phrase>
<phrase role="special">[&amp;](</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutines</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">tuple</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">int</phrase><phrase role="special">,</phrase><phrase role="keyword">int</phrase><phrase role="special">&gt;&gt;::</phrase><phrase role="identifier">pull_type</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">source</phrase><phrase role="special">){</phrase>
<phrase role="comment">// access tuple {7,11}; x==7 y==1</phrase>
<phrase role="keyword">int</phrase> <phrase role="identifier">x</phrase><phrase role="special">,</phrase><phrase role="identifier">y</phrase><phrase role="special">;</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">tie</phrase><phrase role="special">(</phrase><phrase role="identifier">x</phrase><phrase role="special">,</phrase><phrase role="identifier">y</phrase><phrase role="special">)=</phrase><phrase role="identifier">source</phrase><phrase role="special">.</phrase><phrase role="identifier">get</phrase><phrase role="special">();</phrase>
<phrase role="special">});</phrase>
<phrase role="identifier">sink</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">make_tuple</phrase><phrase role="special">(</phrase><phrase role="number">7</phrase><phrase role="special">,</phrase><phrase role="number">11</phrase><phrase role="special">));</phrase>
</programlisting>
<bridgehead renderas="sect4" id="coroutine.coroutine.unidirect.h11">
<phrase id="coroutine.coroutine.unidirect.exceptions"/><link linkend="coroutine.coroutine.unidirect.exceptions">exceptions</link>
</bridgehead>
<para>
An exception thrown inside a <emphasis>coroutine&lt;&gt;::pull_type</emphasis>'s
<emphasis>coroutine-function</emphasis> before its first call to <emphasis>boost::coroutines::coroutine&lt;&gt;::push_type::operator()</emphasis>
will be re-thrown by the <emphasis>coroutine&lt;&gt;::pull_type</emphasis>
constructor. After a <emphasis>coroutine&lt;&gt;::pull_type</emphasis>'s
<emphasis>coroutine-function</emphasis>'s first call to <emphasis>boost::coroutines::coroutine&lt;&gt;::push_type::operator()</emphasis>,
any subsequent exception inside that <emphasis>coroutine-function</emphasis>
will be re-thrown by <emphasis>boost::coroutines::coroutine&lt;&gt;::pull_type::operator()</emphasis>.
<emphasis>boost::coroutines::coroutine&lt;&gt;::pull_type::get()</emphasis>
does not throw.
</para>
<para>
An exception thrown inside a <emphasis>coroutine&lt;&gt;::push_type</emphasis>'s
<emphasis>coroutine-function</emphasis> will be re-thrown by <emphasis>boost::coroutines::coroutine&lt;&gt;::push_type::operator()</emphasis>.
</para>
<important>
<para>
Code executed by coroutine must not prevent the propagation of the <emphasis>boost::coroutines::detail::forced_unwind</emphasis>
exception. Absorbing that exception will cause stack unwinding to fail.
Thus, any code that catches all exceptions must re-throw the pending exception.
</para>
</important>
<programlisting><phrase role="keyword">try</phrase> <phrase role="special">{</phrase>
<phrase role="comment">// code that might throw</phrase>
<phrase role="special">}</phrase> <phrase role="keyword">catch</phrase><phrase role="special">(</phrase><phrase role="keyword">const</phrase> <phrase role="identifier">forced_unwind</phrase><phrase role="special">&amp;)</phrase> <phrase role="special">{</phrase>
<phrase role="keyword">throw</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">// possibly not re-throw pending exception</phrase>
<phrase role="special">}</phrase>
</programlisting>
<bridgehead renderas="sect4" id="coroutine.coroutine.unidirect.h12">
<phrase id="coroutine.coroutine.unidirect.stack_unwinding"/><link linkend="coroutine.coroutine.unidirect.stack_unwinding">Stack
unwinding</link>
</bridgehead>
<para>
Sometimes it is necessary to unwind the stack of an unfinished coroutine
to destroy local stack variables so they can release allocated resources
(RAII pattern). The third argument of the coroutine constructor, <code><phrase
role="identifier">do_unwind</phrase></code>, indicates whether the destructor
should unwind the stack (stack is unwound by default).
</para>
<para>
Stack unwinding assumes the following preconditions:
</para>
<itemizedlist>
<listitem>
<simpara>
The coroutine is not <emphasis>not-a-coroutine</emphasis>
</simpara>
</listitem>
<listitem>
<simpara>
The coroutine is not complete
</simpara>
</listitem>
<listitem>
<simpara>
The coroutine is not running
</simpara>
</listitem>
<listitem>
<simpara>
The coroutine owns a stack
</simpara>
</listitem>
</itemizedlist>
<para>
After unwinding, a <emphasis>coroutine</emphasis> is complete.
</para>
<programlisting><phrase role="keyword">struct</phrase> <phrase role="identifier">X</phrase> <phrase role="special">{</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">&lt;&lt;</phrase><phrase role="string">&quot;X()&quot;</phrase><phrase role="special">&lt;&lt;</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
<phrase role="special">}</phrase>
<phrase role="special">~</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">&lt;&lt;</phrase><phrase role="string">&quot;~X()&quot;</phrase><phrase role="special">&lt;&lt;</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
<phrase role="special">}</phrase>
<phrase role="special">};</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutines</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">void</phrase><phrase role="special">&gt;::</phrase><phrase role="identifier">push_type</phrase> <phrase role="identifier">sink</phrase><phrase role="special">(</phrase>
<phrase role="special">[&amp;](</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutines</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">void</phrase><phrase role="special">&gt;::</phrase><phrase role="identifier">pull_type</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">source</phrase><phrase role="special">){</phrase>
<phrase role="identifier">X</phrase> <phrase role="identifier">x</phrase><phrase role="special">;</phrase>
<phrase role="keyword">for</phrase><phrase role="special">(</phrase><phrase role="keyword">int</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="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase><phrase role="special">&lt;&lt;</phrase><phrase role="string">&quot;fn(): &quot;</phrase><phrase role="special">&lt;&lt;</phrase><phrase role="identifier">i</phrase><phrase role="special">&lt;&lt;</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
<phrase role="comment">// transfer execution control back to main()</phrase>
<phrase role="identifier">source</phrase><phrase role="special">();</phrase>
<phrase role="special">}</phrase>
<phrase role="special">});</phrase>
<phrase role="identifier">sink</phrase><phrase role="special">();</phrase>
<phrase role="identifier">sink</phrase><phrase role="special">();</phrase>
<phrase role="identifier">sink</phrase><phrase role="special">();</phrase>
<phrase role="identifier">sink</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">cout</phrase><phrase role="special">&lt;&lt;</phrase><phrase role="string">&quot;c is complete: &quot;</phrase><phrase role="special">&lt;&lt;</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">boolalpha</phrase><phrase role="special">&lt;&lt;</phrase><phrase role="identifier">c</phrase><phrase role="special">.</phrase><phrase role="identifier">is_complete</phrase><phrase role="special">()&lt;&lt;</phrase><phrase role="string">&quot;\n&quot;</phrase><phrase role="special">;</phrase>
<phrase role="special">}</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase><phrase role="special">&lt;&lt;</phrase><phrase role="string">&quot;Done&quot;</phrase><phrase role="special">&lt;&lt;</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
<phrase role="identifier">output</phrase><phrase role="special">:</phrase>
<phrase role="identifier">X</phrase><phrase role="special">()</phrase>
<phrase role="identifier">fn</phrase><phrase role="special">():</phrase> <phrase role="number">0</phrase>
<phrase role="identifier">fn</phrase><phrase role="special">():</phrase> <phrase role="number">1</phrase>
<phrase role="identifier">fn</phrase><phrase role="special">():</phrase> <phrase role="number">2</phrase>
<phrase role="identifier">fn</phrase><phrase role="special">():</phrase> <phrase role="number">3</phrase>
<phrase role="identifier">fn</phrase><phrase role="special">():</phrase> <phrase role="number">4</phrase>
<phrase role="identifier">fn</phrase><phrase role="special">():</phrase> <phrase role="number">5</phrase>
<phrase role="identifier">c</phrase> <phrase role="identifier">is</phrase> <phrase role="identifier">complete</phrase><phrase role="special">:</phrase> <phrase role="keyword">false</phrase>
<phrase role="special">~</phrase><phrase role="identifier">X</phrase><phrase role="special">()</phrase>
<phrase role="identifier">Done</phrase>
</programlisting>
<bridgehead renderas="sect4" id="coroutine.coroutine.unidirect.h13">
<phrase id="coroutine.coroutine.unidirect.range_iterators"/><link linkend="coroutine.coroutine.unidirect.range_iterators">Range
iterators</link>
</bridgehead>
<para>
<emphasis role="bold">Boost.Coroutine</emphasis> provides output- and input-iterators
using <emphasis role="bold">Boost.Range</emphasis>. <emphasis>coroutine&lt;&gt;::pull_type</emphasis>
can be used via input-iterators using <emphasis>boost::begin()</emphasis>
and <emphasis>boost::end()</emphasis>.
</para>
<programlisting><phrase role="keyword">int</phrase> <phrase role="identifier">number</phrase><phrase role="special">=</phrase><phrase role="number">2</phrase><phrase role="special">,</phrase><phrase role="identifier">exponent</phrase><phrase role="special">=</phrase><phrase role="number">8</phrase><phrase role="special">;</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutines</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">int</phrase> <phrase role="special">&gt;::</phrase><phrase role="identifier">pull_type</phrase> <phrase role="identifier">source</phrase><phrase role="special">(</phrase>
<phrase role="special">[&amp;](</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutines</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">int</phrase> <phrase role="special">&gt;::</phrase><phrase role="identifier">push_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">sink</phrase><phrase role="special">){</phrase>
<phrase role="keyword">int</phrase> <phrase role="identifier">counter</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="number">1</phrase><phrase role="special">;</phrase>
<phrase role="keyword">while</phrase><phrase role="special">(</phrase><phrase role="identifier">counter</phrase><phrase role="special">++&lt;</phrase><phrase role="identifier">exponent</phrase><phrase role="special">){</phrase>
<phrase role="identifier">result</phrase><phrase role="special">=</phrase><phrase role="identifier">result</phrase><phrase role="special">*</phrase><phrase role="identifier">number</phrase><phrase role="special">;</phrase>
<phrase role="identifier">sink</phrase><phrase role="special">(</phrase><phrase role="identifier">result</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">auto</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">cout</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">i</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="string">&quot; &quot;</phrase><phrase role="special">;</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="string">&quot;\nDone&quot;</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
<phrase role="identifier">output</phrase><phrase role="special">:</phrase>
<phrase role="number">2</phrase> <phrase role="number">4</phrase> <phrase role="number">8</phrase> <phrase role="number">16</phrase> <phrase role="number">32</phrase> <phrase role="number">64</phrase> <phrase role="number">128</phrase> <phrase role="number">256</phrase>
<phrase role="identifier">Done</phrase>
</programlisting>
<para>
Output-iterators can be created from <emphasis>coroutine&lt;&gt;::push_type</emphasis>.
</para>
<programlisting><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutines</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">int</phrase><phrase role="special">&gt;::</phrase><phrase role="identifier">push_type</phrase> <phrase role="identifier">sink</phrase><phrase role="special">(</phrase>
<phrase role="special">[&amp;](</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutines</phrase><phrase role="special">::</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">int</phrase><phrase role="special">&gt;::</phrase><phrase role="identifier">pull_type</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">source</phrase><phrase role="special">){</phrase>
<phrase role="keyword">while</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">cout</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">source</phrase><phrase role="special">.</phrase><phrase role="identifier">get</phrase><phrase role="special">()</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="string">&quot; &quot;</phrase><phrase role="special">;</phrase>
<phrase role="identifier">source</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">vector</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">int</phrase><phrase role="special">&gt;</phrase> <phrase role="identifier">v</phrase><phrase role="special">{</phrase><phrase role="number">1</phrase><phrase role="special">,</phrase><phrase role="number">1</phrase><phrase role="special">,</phrase><phrase role="number">2</phrase><phrase role="special">,</phrase><phrase role="number">3</phrase><phrase role="special">,</phrase><phrase role="number">5</phrase><phrase role="special">,</phrase><phrase role="number">8</phrase><phrase role="special">,</phrase><phrase role="number">13</phrase><phrase role="special">,</phrase><phrase role="number">21</phrase><phrase role="special">,</phrase><phrase role="number">34</phrase><phrase role="special">,</phrase><phrase role="number">55</phrase><phrase role="special">};</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">copy</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">begin</phrase><phrase role="special">(</phrase><phrase role="identifier">v</phrase><phrase role="special">),</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">end</phrase><phrase role="special">(</phrase><phrase role="identifier">v</phrase><phrase role="special">),</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">begin</phrase><phrase role="special">(</phrase><phrase role="identifier">sink</phrase><phrase role="special">));</phrase>
</programlisting>
<bridgehead renderas="sect4" id="coroutine.coroutine.unidirect.h14">
<phrase id="coroutine.coroutine.unidirect.exit_a__emphasis_coroutine_function__emphasis_"/><link
linkend="coroutine.coroutine.unidirect.exit_a__emphasis_coroutine_function__emphasis_">Exit
a <emphasis>coroutine-function</emphasis></link>
</bridgehead>
<para>
<emphasis>coroutine-function</emphasis> is exited with a simple return statement
jumping back to the calling routine. The <emphasis>coroutine&lt;&gt;::pull_type</emphasis>/<emphasis>coroutine&lt;&gt;::push_type</emphasis>
becomes complete, e.g. <emphasis>boost::coroutines::coroutine&lt;&gt;::operator
bool</emphasis> will return 'false'.
</para>
<important>
<para>
After returning from <emphasis>coroutine-function</emphasis> the <emphasis>coroutine</emphasis>
is complete (can not resumed with <emphasis>boost::coroutines::coroutine&lt;&gt;::operator()</emphasis>).
</para>
</important>
<section id="coroutine.coroutine.unidirect.pull_coro">
<title><link linkend="coroutine.coroutine.unidirect.pull_coro">Class <code><phrase
role="identifier">coroutine</phrase><phrase role="special">&lt;&gt;::</phrase><phrase
role="identifier">pull_type</phrase></code></link></title>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">/</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">coroutine</phrase><phrase role="special">&lt;&gt;::</phrase><phrase role="identifier">pull_type</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="identifier">pull_type</phrase><phrase role="special">();</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase>
<phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase>
<phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase> <phrase role="special">=</phrase> <phrase role="identifier">stack_allocator</phrase><phrase role="special">,</phrase>
<phrase role="keyword">typename</phrase> <phrase role="identifier">Allocator</phrase> <phrase role="special">=</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">coroutine</phrase> <phrase role="special">&gt;</phrase>
<phrase role="special">&gt;</phrase>
<phrase role="identifier">pull_type</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">attr</phrase> <phrase role="special">=</phrase> <phrase role="identifier">attributes</phrase><phrase role="special">(),</phrase>
<phrase role="identifier">StackAllocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">stack_alloc</phrase> <phrase role="special">=</phrase> <phrase role="identifier">StackAllocator</phrase><phrase role="special">(),</phrase>
<phrase role="identifier">Allocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">alloc</phrase> <phrase role="special">=</phrase> <phrase role="identifier">Allocator</phrase><phrase role="special">()</phrase> <phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase>
<phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase>
<phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase> <phrase role="special">=</phrase> <phrase role="identifier">stack_allocator</phrase><phrase role="special">,</phrase>
<phrase role="keyword">typename</phrase> <phrase role="identifier">Allocator</phrase> <phrase role="special">=</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">coroutine</phrase> <phrase role="special">&gt;</phrase>
<phrase role="special">&gt;</phrase>
<phrase role="identifier">pull_type</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">attr</phrase> <phrase role="special">=</phrase> <phrase role="identifier">attributes</phrase><phrase role="special">(),</phrase>
<phrase role="identifier">StackAllocator</phrase> <phrase role="identifier">stack_alloc</phrase> <phrase role="special">=</phrase> <phrase role="identifier">StackAllocator</phrase><phrase role="special">(),</phrase>
<phrase role="identifier">Allocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">alloc</phrase> <phrase role="special">=</phrase> <phrase role="identifier">Allocator</phrase><phrase role="special">()</phrase> <phrase role="special">);</phrase>
<phrase role="identifier">pull_type</phrase><phrase role="special">(</phrase> <phrase role="identifier">pull_type</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">);</phrase>
<phrase role="identifier">pull_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">pull_type</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">);</phrase>
<phrase role="keyword">operator</phrase> <phrase role="identifier">unspecified</phrase><phrase role="special">-</phrase><phrase role="keyword">bool</phrase><phrase role="special">-</phrase><phrase role="identifier">type</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</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="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">swap</phrase><phrase role="special">(</phrase> <phrase role="identifier">pull_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">);</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">empty</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
<phrase role="identifier">pull_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()();</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">has_result</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
<phrase role="identifier">R</phrase> <phrase role="identifier">get</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
<phrase role="special">};</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">swap</phrase><phrase role="special">(</phrase> <phrase role="identifier">pull_type</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">l</phrase><phrase role="special">,</phrase> <phrase role="identifier">pull_type</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">r</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">range_iterator</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">pull_type</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&gt;::</phrase><phrase role="identifier">type</phrase> <phrase role="identifier">begin</phrase><phrase role="special">(</phrase> <phrase role="identifier">pull_type</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">range_iterator</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">pull_type</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&gt;::</phrase><phrase role="identifier">type</phrase> <phrase role="identifier">end</phrase><phrase role="special">(</phrase> <phrase role="identifier">pull_type</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;);</phrase>
</programlisting>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.pull_coro.h0">
<phrase id="coroutine.coroutine.unidirect.pull_coro._code__phrase_role__identifier__pull_type__phrase__phrase_role__special______phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.pull_coro._code__phrase_role__identifier__pull_type__phrase__phrase_role__special______phrase___code_"><code><phrase
role="identifier">pull_type</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Creates a coroutine representing <emphasis>not-a-coroutine</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.pull_coro.h1">
<phrase id="coroutine.coroutine.unidirect.pull_coro._code__phrase_role__keyword__template__phrase__phrase_role__special___lt___phrase___phrase_role__keyword__typename__phrase___phrase_role__identifier__fn__phrase__phrase_role__special_____phrase___phrase_role__keyword__typename__phrase___phrase_role__identifier__stackallocator__phrase__phrase_role__special_____phrase___phrase_role__keyword__typename__phrase___phrase_role__identifier__allocator__phrase___phrase_role__special___gt___phrase_____________phrase_role__identifier__pull_type__phrase__phrase_role__special_____phrase___phrase_role__identifier__fn__phrase___phrase_role__identifier__fn__phrase__phrase_role__special_____phrase___phrase_role__identifier__attributes__phrase___phrase_role__keyword__const__phrase__phrase_role__special___amp___phrase___phrase_role__identifier__attr__phrase__phrase_role__special_____phrase___phrase_role__identifier__stackallocator__phrase___phrase_role__keyword__const__phrase__phrase_role__special___amp___phrase___phrase_role__identifier__stack_alloc__phrase__phrase_role__special_____phrase___phrase_role__identifier__allocator__phrase___phrase_role__keyword__const__phrase__phrase_role__special___amp___phrase___phrase_role__identifier__alloc__phrase__phrase_role__special_____phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.pull_coro._code__phrase_role__keyword__template__phrase__phrase_role__special___lt___phrase___phrase_role__keyword__typename__phrase___phrase_role__identifier__fn__phrase__phrase_role__special_____phrase___phrase_role__keyword__typename__phrase___phrase_role__identifier__stackallocator__phrase__phrase_role__special_____phrase___phrase_role__keyword__typename__phrase___phrase_role__identifier__allocator__phrase___phrase_role__special___gt___phrase_____________phrase_role__identifier__pull_type__phrase__phrase_role__special_____phrase___phrase_role__identifier__fn__phrase___phrase_role__identifier__fn__phrase__phrase_role__special_____phrase___phrase_role__identifier__attributes__phrase___phrase_role__keyword__const__phrase__phrase_role__special___amp___phrase___phrase_role__identifier__attr__phrase__phrase_role__special_____phrase___phrase_role__identifier__stackallocator__phrase___phrase_role__keyword__const__phrase__phrase_role__special___amp___phrase___phrase_role__identifier__stack_alloc__phrase__phrase_role__special_____phrase___phrase_role__identifier__allocator__phrase___phrase_role__keyword__const__phrase__phrase_role__special___amp___phrase___phrase_role__identifier__alloc__phrase__phrase_role__special_____phrase___code_"><code><phrase
role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase
role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase
role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase
role="identifier">StackAllocator</phrase><phrase role="special">,</phrase>
<phrase role="keyword">typename</phrase> <phrase role="identifier">Allocator</phrase>
<phrase role="special">&gt;</phrase> <phrase role="identifier">pull_type</phrase><phrase
role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase
role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase
role="identifier">attributes</phrase> <phrase role="keyword">const</phrase><phrase
role="special">&amp;</phrase> <phrase role="identifier">attr</phrase><phrase
role="special">,</phrase> <phrase role="identifier">StackAllocator</phrase>
<phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase>
<phrase role="identifier">stack_alloc</phrase><phrase role="special">,</phrase>
<phrase role="identifier">Allocator</phrase> <phrase role="keyword">const</phrase><phrase
role="special">&amp;</phrase> <phrase role="identifier">alloc</phrase><phrase
role="special">)</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
<code><phrase role="identifier">size</phrase></code> &gt; minimum_stacksize(),
<code><phrase role="identifier">size</phrase></code> &lt; maximum_stacksize()
when ! is_stack_unbound().
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Creates a coroutine which will execute <code><phrase role="identifier">fn</phrase></code>.
Argument <code><phrase role="identifier">attr</phrase></code> determines
stack clean-up and preserving floating-point registers. For allocating/deallocating
the stack <code><phrase role="identifier">stack_alloc</phrase></code>
is used and internal data are allocated by Allocator.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Exceptions thrown inside <emphasis>coroutine-function</emphasis>.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.pull_coro.h2">
<phrase id="coroutine.coroutine.unidirect.pull_coro._code__phrase_role__keyword__template__phrase__phrase_role__special___lt___phrase___phrase_role__keyword__typename__phrase___phrase_role__identifier__fn__phrase__phrase_role__special_____phrase___phrase_role__keyword__typename__phrase___phrase_role__identifier__stackallocator__phrase__phrase_role__special_____phrase___phrase_role__keyword__typename__phrase___phrase_role__identifier__allocator__phrase___phrase_role__special___gt___phrase_____________phrase_role__identifier__pull_type__phrase__phrase_role__special_____phrase___phrase_role__identifier__fn__phrase___phrase_role__special___amp__amp___phrase___phrase_role__identifier__fn__phrase__phrase_role__special_____phrase___phrase_role__identifier__attributes__phrase___phrase_role__keyword__const__phrase__phrase_role__special___amp___phrase___phrase_role__identifier__attr__phrase__phrase_role__special_____phrase___phrase_role__identifier__stackallocator__phrase___phrase_role__keyword__const__phrase__phrase_role__special___amp___phrase___phrase_role__identifier__stack_alloc__phrase__phrase_role__special_____phrase___phrase_role__identifier__allocator__phrase___phrase_role__keyword__const__phrase__phrase_role__special___amp___phrase___phrase_role__identifier__alloc__phrase__phrase_role__special_____phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.pull_coro._code__phrase_role__keyword__template__phrase__phrase_role__special___lt___phrase___phrase_role__keyword__typename__phrase___phrase_role__identifier__fn__phrase__phrase_role__special_____phrase___phrase_role__keyword__typename__phrase___phrase_role__identifier__stackallocator__phrase__phrase_role__special_____phrase___phrase_role__keyword__typename__phrase___phrase_role__identifier__allocator__phrase___phrase_role__special___gt___phrase_____________phrase_role__identifier__pull_type__phrase__phrase_role__special_____phrase___phrase_role__identifier__fn__phrase___phrase_role__special___amp__amp___phrase___phrase_role__identifier__fn__phrase__phrase_role__special_____phrase___phrase_role__identifier__attributes__phrase___phrase_role__keyword__const__phrase__phrase_role__special___amp___phrase___phrase_role__identifier__attr__phrase__phrase_role__special_____phrase___phrase_role__identifier__stackallocator__phrase___phrase_role__keyword__const__phrase__phrase_role__special___amp___phrase___phrase_role__identifier__stack_alloc__phrase__phrase_role__special_____phrase___phrase_role__identifier__allocator__phrase___phrase_role__keyword__const__phrase__phrase_role__special___amp___phrase___phrase_role__identifier__alloc__phrase__phrase_role__special_____phrase___code_"><code><phrase
role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase
role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase
role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase
role="identifier">StackAllocator</phrase><phrase role="special">,</phrase>
<phrase role="keyword">typename</phrase> <phrase role="identifier">Allocator</phrase>
<phrase role="special">&gt;</phrase> <phrase role="identifier">pull_type</phrase><phrase
role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase
role="special">&amp;&amp;</phrase> <phrase role="identifier">fn</phrase><phrase
role="special">,</phrase> <phrase role="identifier">attributes</phrase>
<phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase>
<phrase role="identifier">attr</phrase><phrase role="special">,</phrase>
<phrase role="identifier">StackAllocator</phrase> <phrase role="keyword">const</phrase><phrase
role="special">&amp;</phrase> <phrase role="identifier">stack_alloc</phrase><phrase
role="special">,</phrase> <phrase role="identifier">Allocator</phrase>
<phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase>
<phrase role="identifier">alloc</phrase><phrase role="special">)</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
<code><phrase role="identifier">size</phrase></code> &gt; minimum_stacksize(),
<code><phrase role="identifier">size</phrase></code> &lt; maximum_stacksize()
when ! is_stack_unbound().
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Creates a coroutine which will execute <code><phrase role="identifier">fn</phrase></code>.
Argument <code><phrase role="identifier">attr</phrase></code> determines
stack clean-up and preserving floating-point registers. For allocating/deallocating
the stack <code><phrase role="identifier">stack_alloc</phrase></code>
is used and internal data are allocated by Allocator.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Exceptions thrown inside <emphasis>coroutine-function</emphasis>.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.pull_coro.h3">
<phrase id="coroutine.coroutine.unidirect.pull_coro._code__phrase_role__identifier__pull_type__phrase__phrase_role__special_____phrase___phrase_role__identifier__pull_type__phrase___phrase_role__special___amp__amp___phrase___phrase_role__identifier__other__phrase__phrase_role__special_____phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.pull_coro._code__phrase_role__identifier__pull_type__phrase__phrase_role__special_____phrase___phrase_role__identifier__pull_type__phrase___phrase_role__special___amp__amp___phrase___phrase_role__identifier__other__phrase__phrase_role__special_____phrase___code_"><code><phrase
role="identifier">pull_type</phrase><phrase role="special">(</phrase>
<phrase role="identifier">pull_type</phrase> <phrase role="special">&amp;&amp;</phrase>
<phrase role="identifier">other</phrase><phrase role="special">)</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Moves the internal data of <code><phrase role="identifier">other</phrase></code>
to <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>.
<code><phrase role="identifier">other</phrase></code> becomes <emphasis>not-a-coroutine</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.pull_coro.h4">
<phrase id="coroutine.coroutine.unidirect.pull_coro._code__phrase_role__identifier__pull_type__phrase___phrase_role__special___amp___phrase___phrase_role__keyword__operator__phrase__phrase_role__special______phrase___phrase_role__identifier__pull_type__phrase___phrase_role__special___amp__amp___phrase___phrase_role__identifier__other__phrase__phrase_role__special_____phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.pull_coro._code__phrase_role__identifier__pull_type__phrase___phrase_role__special___amp___phrase___phrase_role__keyword__operator__phrase__phrase_role__special______phrase___phrase_role__identifier__pull_type__phrase___phrase_role__special___amp__amp___phrase___phrase_role__identifier__other__phrase__phrase_role__special_____phrase___code_"><code><phrase
role="identifier">pull_type</phrase> <phrase role="special">&amp;</phrase>
<phrase role="keyword">operator</phrase><phrase role="special">=(</phrase>
<phrase role="identifier">pull_type</phrase> <phrase role="special">&amp;&amp;</phrase>
<phrase role="identifier">other</phrase><phrase role="special">)</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Destroys the internal data of <code><phrase role="special">*</phrase><phrase
role="keyword">this</phrase></code> and moves the internal data of
<code><phrase role="identifier">other</phrase></code> to <code><phrase
role="special">*</phrase><phrase role="keyword">this</phrase></code>.
<code><phrase role="identifier">other</phrase></code> becomes <emphasis>not-a-coroutine</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.pull_coro.h5">
<phrase id="coroutine.coroutine.unidirect.pull_coro._code__phrase_role__keyword__operator__phrase___phrase_role__identifier__unspecified__phrase__phrase_role__special_____phrase__phrase_role__keyword__bool__phrase__phrase_role__special_____phrase__phrase_role__identifier__type__phrase__phrase_role__special______phrase___phrase_role__keyword__const__phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.pull_coro._code__phrase_role__keyword__operator__phrase___phrase_role__identifier__unspecified__phrase__phrase_role__special_____phrase__phrase_role__keyword__bool__phrase__phrase_role__special_____phrase__phrase_role__identifier__type__phrase__phrase_role__special______phrase___phrase_role__keyword__const__phrase___code_"><code><phrase
role="keyword">operator</phrase> <phrase role="identifier">unspecified</phrase><phrase
role="special">-</phrase><phrase role="keyword">bool</phrase><phrase role="special">-</phrase><phrase
role="identifier">type</phrase><phrase role="special">()</phrase> <phrase
role="keyword">const</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
If <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
refers to <emphasis>not-a-coroutine</emphasis> or the coroutine-function
has returned (completed), the function returns false. Otherwise true.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.pull_coro.h6">
<phrase id="coroutine.coroutine.unidirect.pull_coro._code__phrase_role__keyword__bool__phrase___phrase_role__keyword__operator__phrase__phrase_role__special_______phrase___phrase_role__keyword__const__phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.pull_coro._code__phrase_role__keyword__bool__phrase___phrase_role__keyword__operator__phrase__phrase_role__special_______phrase___phrase_role__keyword__const__phrase___code_"><code><phrase
role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase
role="special">!()</phrase> <phrase role="keyword">const</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
If <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
refers to <emphasis>not-a-coroutine</emphasis> or the coroutine-function
has returned (completed), the function returns true. Otherwise false.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.pull_coro.h7">
<phrase id="coroutine.coroutine.unidirect.pull_coro._code__phrase_role__keyword__bool__phrase___phrase_role__identifier__empty__phrase__phrase_role__special______phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.pull_coro._code__phrase_role__keyword__bool__phrase___phrase_role__identifier__empty__phrase__phrase_role__special______phrase___code_"><code><phrase
role="keyword">bool</phrase> <phrase role="identifier">empty</phrase><phrase
role="special">()</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
If <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
refers to <emphasis>not-a-coroutine</emphasis>, the function returns
true. Otherwise false.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.pull_coro.h8">
<phrase id="coroutine.coroutine.unidirect.pull_coro._code__phrase_role__identifier__pull_type__phrase__phrase_role__special___lt__gt___phrase___phrase_role__special___amp___phrase___phrase_role__keyword__operator__phrase__phrase_role__special________phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.pull_coro._code__phrase_role__identifier__pull_type__phrase__phrase_role__special___lt__gt___phrase___phrase_role__special___amp___phrase___phrase_role__keyword__operator__phrase__phrase_role__special________phrase___code_"><code><phrase
role="identifier">pull_type</phrase><phrase role="special">&lt;&gt;</phrase>
<phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase
role="special">()()</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
<code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
is not a <emphasis>not-a-coroutine</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Execution control is transferred to <emphasis>coroutine-function</emphasis>
(no parameter are passed to the coroutine-function).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Exceptions thrown inside <emphasis>coroutine-function</emphasis>.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.pull_coro.h9">
<phrase id="coroutine.coroutine.unidirect.pull_coro._code__phrase_role__keyword__bool__phrase___phrase_role__identifier__has_result__phrase__phrase_role__special______phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.pull_coro._code__phrase_role__keyword__bool__phrase___phrase_role__identifier__has_result__phrase__phrase_role__special______phrase___code_"><code><phrase
role="keyword">bool</phrase> <phrase role="identifier">has_result</phrase><phrase
role="special">()</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
<code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
is not a <emphasis>not-a-coroutine</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
If <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
has a, the function returns true. Otherwise false.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.pull_coro.h10">
<phrase id="coroutine.coroutine.unidirect.pull_coro._code__phrase_role__identifier__r__phrase___phrase_role__identifier__get__phrase__phrase_role__special________phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.pull_coro._code__phrase_role__identifier__r__phrase___phrase_role__identifier__get__phrase__phrase_role__special________phrase___code_"><code><phrase
role="identifier">R</phrase> <phrase role="identifier">get</phrase><phrase
role="special">()()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="identifier">R</phrase> <phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="identifier">R</phrase><phrase role="special">&gt;::</phrase><phrase role="identifier">pull_type</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special">();</phrase>
<phrase role="identifier">R</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="identifier">R</phrase><phrase role="special">&amp;&gt;::</phrase><phrase role="identifier">pull_type</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">void</phrase><phrase role="special">&gt;</phrase><phrase role="identifier">pull_type</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special">()=</phrase><phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
<code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
is not a <emphasis>not-a-coroutine</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
Returns data transferred from coroutine-function via <emphasis>boost::coroutines::coroutine&lt;&gt;::push_type::operator()</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.pull_coro.h11">
<phrase id="coroutine.coroutine.unidirect.pull_coro._code__phrase_role__keyword__void__phrase___phrase_role__identifier__swap__phrase__phrase_role__special_____phrase___phrase_role__identifier__pull_type__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__other__phrase__phrase_role__special_____phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.pull_coro._code__phrase_role__keyword__void__phrase___phrase_role__identifier__swap__phrase__phrase_role__special_____phrase___phrase_role__identifier__pull_type__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__other__phrase__phrase_role__special_____phrase___code_"><code><phrase
role="keyword">void</phrase> <phrase role="identifier">swap</phrase><phrase
role="special">(</phrase> <phrase role="identifier">pull_type</phrase>
<phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase
role="special">)</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Swaps the internal data from <code><phrase role="special">*</phrase><phrase
role="keyword">this</phrase></code> with the values of <code><phrase
role="identifier">other</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.pull_coro.h12">
<phrase id="coroutine.coroutine.unidirect.pull_coro.non_member_function__code__phrase_role__identifier__swap__phrase__phrase_role__special______phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.pull_coro.non_member_function__code__phrase_role__identifier__swap__phrase__phrase_role__special______phrase___code_">Non-member
function <code><phrase role="identifier">swap</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">swap</phrase><phrase role="special">(</phrase> <phrase role="identifier">pull_type</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">l</phrase><phrase role="special">,</phrase> <phrase role="identifier">pull_type</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">r</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
As if 'l.swap( r)'.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.pull_coro.h13">
<phrase id="coroutine.coroutine.unidirect.pull_coro.non_member_function__code__phrase_role__identifier__begin__phrase__phrase_role__special_____phrase___phrase_role__identifier__pull_type__phrase__phrase_role__special___lt___phrase___phrase_role__identifier__r__phrase___phrase_role__special___gt___phrase___phrase_role__special___amp____phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.pull_coro.non_member_function__code__phrase_role__identifier__begin__phrase__phrase_role__special_____phrase___phrase_role__identifier__pull_type__phrase__phrase_role__special___lt___phrase___phrase_role__identifier__r__phrase___phrase_role__special___gt___phrase___phrase_role__special___amp____phrase___code_">Non-member
function <code><phrase role="identifier">begin</phrase><phrase role="special">(</phrase>
<phrase role="identifier">pull_type</phrase><phrase role="special">&lt;</phrase>
<phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase>
<phrase role="special">&amp;)</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">range_iterator</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">pull_type</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&gt;::</phrase><phrase role="identifier">type</phrase> <phrase role="identifier">begin</phrase><phrase role="special">(</phrase> <phrase role="identifier">pull_type</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
Returns a range-iterator (input-iterator).
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.pull_coro.h14">
<phrase id="coroutine.coroutine.unidirect.pull_coro.non_member_function__code__phrase_role__identifier__end__phrase__phrase_role__special_____phrase___phrase_role__identifier__pull_type__phrase__phrase_role__special___lt___phrase___phrase_role__identifier__r__phrase___phrase_role__special___gt___phrase___phrase_role__special___amp____phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.pull_coro.non_member_function__code__phrase_role__identifier__end__phrase__phrase_role__special_____phrase___phrase_role__identifier__pull_type__phrase__phrase_role__special___lt___phrase___phrase_role__identifier__r__phrase___phrase_role__special___gt___phrase___phrase_role__special___amp____phrase___code_">Non-member
function <code><phrase role="identifier">end</phrase><phrase role="special">(</phrase>
<phrase role="identifier">pull_type</phrase><phrase role="special">&lt;</phrase>
<phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase>
<phrase role="special">&amp;)</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">range_iterator</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">pull_type</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&gt;::</phrase><phrase role="identifier">type</phrase> <phrase role="identifier">end</phrase><phrase role="special">(</phrase> <phrase role="identifier">pull_type</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
Returns a end range-iterator (input-iterator).
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section id="coroutine.coroutine.unidirect.push_coro">
<title><link linkend="coroutine.coroutine.unidirect.push_coro">Class <code><phrase
role="identifier">coroutine</phrase><phrase role="special">&lt;&gt;::</phrase><phrase
role="identifier">push_type</phrase></code></link></title>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">/</phrase><phrase role="identifier">coroutine</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">coroutine</phrase><phrase role="special">&lt;&gt;::</phrase><phrase role="identifier">push_type</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="identifier">push_type</phrase><phrase role="special">();</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase>
<phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase>
<phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase> <phrase role="special">=</phrase> <phrase role="identifier">stack_allocator</phrase><phrase role="special">,</phrase>
<phrase role="keyword">typename</phrase> <phrase role="identifier">Allocator</phrase> <phrase role="special">=</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">coroutine</phrase> <phrase role="special">&gt;</phrase>
<phrase role="special">&gt;</phrase>
<phrase role="identifier">push_type</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">attr</phrase> <phrase role="special">=</phrase> <phrase role="identifier">attributes</phrase><phrase role="special">(),</phrase>
<phrase role="identifier">StackAllocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">stack_alloc</phrase> <phrase role="special">=</phrase> <phrase role="identifier">StackAllocator</phrase><phrase role="special">(),</phrase>
<phrase role="identifier">Allocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">alloc</phrase> <phrase role="special">=</phrase> <phrase role="identifier">Allocator</phrase><phrase role="special">()</phrase> <phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase>
<phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase>
<phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase> <phrase role="special">=</phrase> <phrase role="identifier">stack_allocator</phrase><phrase role="special">,</phrase>
<phrase role="keyword">typename</phrase> <phrase role="identifier">Allocator</phrase> <phrase role="special">=</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">coroutine</phrase> <phrase role="special">&gt;</phrase>
<phrase role="special">&gt;</phrase>
<phrase role="identifier">push_type</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">attr</phrase> <phrase role="special">=</phrase> <phrase role="identifier">attributes</phrase><phrase role="special">(),</phrase>
<phrase role="identifier">StackAllocator</phrase> <phrase role="identifier">stack_alloc</phrase> <phrase role="special">=</phrase> <phrase role="identifier">StackAllocator</phrase><phrase role="special">(),</phrase>
<phrase role="identifier">Allocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">alloc</phrase> <phrase role="special">=</phrase> <phrase role="identifier">Allocator</phrase><phrase role="special">()</phrase> <phrase role="special">);</phrase>
<phrase role="identifier">push_type</phrase><phrase role="special">(</phrase> <phrase role="identifier">push_type</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">);</phrase>
<phrase role="identifier">push_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">push_type</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">);</phrase>
<phrase role="keyword">operator</phrase> <phrase role="identifier">unspecified</phrase><phrase role="special">-</phrase><phrase role="keyword">bool</phrase><phrase role="special">-</phrase><phrase role="identifier">type</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</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="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">swap</phrase><phrase role="special">(</phrase> <phrase role="identifier">push_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">);</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">empty</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
<phrase role="identifier">push_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="identifier">Arg</phrase><phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">arg</phrase><phrase role="special">);</phrase>
<phrase role="special">};</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">swap</phrase><phrase role="special">(</phrase> <phrase role="identifier">push_type</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">l</phrase><phrase role="special">,</phrase> <phrase role="identifier">push_type</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">r</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">range_iterator</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">push_type</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&gt;::</phrase><phrase role="identifier">type</phrase> <phrase role="identifier">begin</phrase><phrase role="special">(</phrase> <phrase role="identifier">push_type</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">range_iterator</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">push_type</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&gt;::</phrase><phrase role="identifier">type</phrase> <phrase role="identifier">end</phrase><phrase role="special">(</phrase> <phrase role="identifier">push_type</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;);</phrase>
</programlisting>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.push_coro.h0">
<phrase id="coroutine.coroutine.unidirect.push_coro._code__phrase_role__identifier__push_type__phrase__phrase_role__special______phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.push_coro._code__phrase_role__identifier__push_type__phrase__phrase_role__special______phrase___code_"><code><phrase
role="identifier">push_type</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Creates a coroutine representing <emphasis>not-a-coroutine</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.push_coro.h1">
<phrase id="coroutine.coroutine.unidirect.push_coro._code__phrase_role__keyword__template__phrase__phrase_role__special___lt___phrase___phrase_role__keyword__typename__phrase___phrase_role__identifier__fn__phrase__phrase_role__special_____phrase___phrase_role__keyword__typename__phrase___phrase_role__identifier__stackallocator__phrase__phrase_role__special_____phrase___phrase_role__keyword__typename__phrase___phrase_role__identifier__allocator__phrase___phrase_role__special___gt___phrase_____________phrase_role__identifier__push_type__phrase__phrase_role__special_____phrase___phrase_role__identifier__fn__phrase___phrase_role__identifier__fn__phrase__phrase_role__special_____phrase___phrase_role__identifier__attributes__phrase___phrase_role__keyword__const__phrase__phrase_role__special___amp___phrase___phrase_role__identifier__attr__phrase__phrase_role__special_____phrase___phrase_role__identifier__stackallocator__phrase___phrase_role__keyword__const__phrase__phrase_role__special___amp___phrase___phrase_role__identifier__stack_alloc__phrase__phrase_role__special_____phrase___phrase_role__identifier__allocator__phrase___phrase_role__keyword__const__phrase__phrase_role__special___amp___phrase___phrase_role__identifier__alloc__phrase__phrase_role__special_____phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.push_coro._code__phrase_role__keyword__template__phrase__phrase_role__special___lt___phrase___phrase_role__keyword__typename__phrase___phrase_role__identifier__fn__phrase__phrase_role__special_____phrase___phrase_role__keyword__typename__phrase___phrase_role__identifier__stackallocator__phrase__phrase_role__special_____phrase___phrase_role__keyword__typename__phrase___phrase_role__identifier__allocator__phrase___phrase_role__special___gt___phrase_____________phrase_role__identifier__push_type__phrase__phrase_role__special_____phrase___phrase_role__identifier__fn__phrase___phrase_role__identifier__fn__phrase__phrase_role__special_____phrase___phrase_role__identifier__attributes__phrase___phrase_role__keyword__const__phrase__phrase_role__special___amp___phrase___phrase_role__identifier__attr__phrase__phrase_role__special_____phrase___phrase_role__identifier__stackallocator__phrase___phrase_role__keyword__const__phrase__phrase_role__special___amp___phrase___phrase_role__identifier__stack_alloc__phrase__phrase_role__special_____phrase___phrase_role__identifier__allocator__phrase___phrase_role__keyword__const__phrase__phrase_role__special___amp___phrase___phrase_role__identifier__alloc__phrase__phrase_role__special_____phrase___code_"><code><phrase
role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase
role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase
role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase
role="identifier">StackAllocator</phrase><phrase role="special">,</phrase>
<phrase role="keyword">typename</phrase> <phrase role="identifier">Allocator</phrase>
<phrase role="special">&gt;</phrase> <phrase role="identifier">push_type</phrase><phrase
role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase
role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase
role="identifier">attributes</phrase> <phrase role="keyword">const</phrase><phrase
role="special">&amp;</phrase> <phrase role="identifier">attr</phrase><phrase
role="special">,</phrase> <phrase role="identifier">StackAllocator</phrase>
<phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase>
<phrase role="identifier">stack_alloc</phrase><phrase role="special">,</phrase>
<phrase role="identifier">Allocator</phrase> <phrase role="keyword">const</phrase><phrase
role="special">&amp;</phrase> <phrase role="identifier">alloc</phrase><phrase
role="special">)</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
<code><phrase role="identifier">size</phrase></code> &gt; minimum_stacksize(),
<code><phrase role="identifier">size</phrase></code> &lt; maximum_stacksize()
when ! is_stack_unbound().
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Creates a coroutine which will execute <code><phrase role="identifier">fn</phrase></code>.
Argument <code><phrase role="identifier">attr</phrase></code> determines
stack clean-up and preserving floating-point registers. For allocating/deallocating
the stack <code><phrase role="identifier">stack_alloc</phrase></code>
is used and internal data are allocated by Allocator.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.push_coro.h2">
<phrase id="coroutine.coroutine.unidirect.push_coro._code__phrase_role__keyword__template__phrase__phrase_role__special___lt___phrase___phrase_role__keyword__typename__phrase___phrase_role__identifier__fn__phrase__phrase_role__special_____phrase___phrase_role__keyword__typename__phrase___phrase_role__identifier__stackallocator__phrase__phrase_role__special_____phrase___phrase_role__keyword__typename__phrase___phrase_role__identifier__allocator__phrase___phrase_role__special___gt___phrase_____________phrase_role__identifier__push_type__phrase__phrase_role__special_____phrase___phrase_role__identifier__fn__phrase___phrase_role__special___amp__amp___phrase___phrase_role__identifier__fn__phrase__phrase_role__special_____phrase___phrase_role__identifier__attributes__phrase___phrase_role__keyword__const__phrase__phrase_role__special___amp___phrase___phrase_role__identifier__attr__phrase__phrase_role__special_____phrase___phrase_role__identifier__stackallocator__phrase___phrase_role__keyword__const__phrase__phrase_role__special___amp___phrase___phrase_role__identifier__stack_alloc__phrase__phrase_role__special_____phrase___phrase_role__identifier__allocator__phrase___phrase_role__keyword__const__phrase__phrase_role__special___amp___phrase___phrase_role__identifier__alloc__phrase__phrase_role__special_____phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.push_coro._code__phrase_role__keyword__template__phrase__phrase_role__special___lt___phrase___phrase_role__keyword__typename__phrase___phrase_role__identifier__fn__phrase__phrase_role__special_____phrase___phrase_role__keyword__typename__phrase___phrase_role__identifier__stackallocator__phrase__phrase_role__special_____phrase___phrase_role__keyword__typename__phrase___phrase_role__identifier__allocator__phrase___phrase_role__special___gt___phrase_____________phrase_role__identifier__push_type__phrase__phrase_role__special_____phrase___phrase_role__identifier__fn__phrase___phrase_role__special___amp__amp___phrase___phrase_role__identifier__fn__phrase__phrase_role__special_____phrase___phrase_role__identifier__attributes__phrase___phrase_role__keyword__const__phrase__phrase_role__special___amp___phrase___phrase_role__identifier__attr__phrase__phrase_role__special_____phrase___phrase_role__identifier__stackallocator__phrase___phrase_role__keyword__const__phrase__phrase_role__special___amp___phrase___phrase_role__identifier__stack_alloc__phrase__phrase_role__special_____phrase___phrase_role__identifier__allocator__phrase___phrase_role__keyword__const__phrase__phrase_role__special___amp___phrase___phrase_role__identifier__alloc__phrase__phrase_role__special_____phrase___code_"><code><phrase
role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase
role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase
role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase
role="identifier">StackAllocator</phrase><phrase role="special">,</phrase>
<phrase role="keyword">typename</phrase> <phrase role="identifier">Allocator</phrase>
<phrase role="special">&gt;</phrase> <phrase role="identifier">push_type</phrase><phrase
role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase
role="special">&amp;&amp;</phrase> <phrase role="identifier">fn</phrase><phrase
role="special">,</phrase> <phrase role="identifier">attributes</phrase>
<phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase>
<phrase role="identifier">attr</phrase><phrase role="special">,</phrase>
<phrase role="identifier">StackAllocator</phrase> <phrase role="keyword">const</phrase><phrase
role="special">&amp;</phrase> <phrase role="identifier">stack_alloc</phrase><phrase
role="special">,</phrase> <phrase role="identifier">Allocator</phrase>
<phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase>
<phrase role="identifier">alloc</phrase><phrase role="special">)</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
<code><phrase role="identifier">size</phrase></code> &gt; minimum_stacksize(),
<code><phrase role="identifier">size</phrase></code> &lt; maximum_stacksize()
when ! is_stack_unbound().
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Creates a coroutine which will execute <code><phrase role="identifier">fn</phrase></code>.
Argument <code><phrase role="identifier">attr</phrase></code> determines
stack clean-up and preserving floating-point registers. For allocating/deallocating
the stack <code><phrase role="identifier">stack_alloc</phrase></code>
is used and internal data are allocated by Allocator.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.push_coro.h3">
<phrase id="coroutine.coroutine.unidirect.push_coro._code__phrase_role__identifier__push_type__phrase__phrase_role__special_____phrase___phrase_role__identifier__push_type__phrase___phrase_role__special___amp__amp___phrase___phrase_role__identifier__other__phrase__phrase_role__special_____phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.push_coro._code__phrase_role__identifier__push_type__phrase__phrase_role__special_____phrase___phrase_role__identifier__push_type__phrase___phrase_role__special___amp__amp___phrase___phrase_role__identifier__other__phrase__phrase_role__special_____phrase___code_"><code><phrase
role="identifier">push_type</phrase><phrase role="special">(</phrase>
<phrase role="identifier">push_type</phrase> <phrase role="special">&amp;&amp;</phrase>
<phrase role="identifier">other</phrase><phrase role="special">)</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Moves the internal data of <code><phrase role="identifier">other</phrase></code>
to <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>.
<code><phrase role="identifier">other</phrase></code> becomes <emphasis>not-a-coroutine</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.push_coro.h4">
<phrase id="coroutine.coroutine.unidirect.push_coro._code__phrase_role__identifier__push_type__phrase___phrase_role__special___amp___phrase___phrase_role__keyword__operator__phrase__phrase_role__special______phrase___phrase_role__identifier__push_type__phrase___phrase_role__special___amp__amp___phrase___phrase_role__identifier__other__phrase__phrase_role__special_____phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.push_coro._code__phrase_role__identifier__push_type__phrase___phrase_role__special___amp___phrase___phrase_role__keyword__operator__phrase__phrase_role__special______phrase___phrase_role__identifier__push_type__phrase___phrase_role__special___amp__amp___phrase___phrase_role__identifier__other__phrase__phrase_role__special_____phrase___code_"><code><phrase
role="identifier">push_type</phrase> <phrase role="special">&amp;</phrase>
<phrase role="keyword">operator</phrase><phrase role="special">=(</phrase>
<phrase role="identifier">push_type</phrase> <phrase role="special">&amp;&amp;</phrase>
<phrase role="identifier">other</phrase><phrase role="special">)</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Destroys the internal data of <code><phrase role="special">*</phrase><phrase
role="keyword">this</phrase></code> and moves the internal data of
<code><phrase role="identifier">other</phrase></code> to <code><phrase
role="special">*</phrase><phrase role="keyword">this</phrase></code>.
<code><phrase role="identifier">other</phrase></code> becomes <emphasis>not-a-coroutine</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.push_coro.h5">
<phrase id="coroutine.coroutine.unidirect.push_coro._code__phrase_role__keyword__operator__phrase___phrase_role__identifier__unspecified__phrase__phrase_role__special_____phrase__phrase_role__keyword__bool__phrase__phrase_role__special_____phrase__phrase_role__identifier__type__phrase__phrase_role__special______phrase___phrase_role__keyword__const__phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.push_coro._code__phrase_role__keyword__operator__phrase___phrase_role__identifier__unspecified__phrase__phrase_role__special_____phrase__phrase_role__keyword__bool__phrase__phrase_role__special_____phrase__phrase_role__identifier__type__phrase__phrase_role__special______phrase___phrase_role__keyword__const__phrase___code_"><code><phrase
role="keyword">operator</phrase> <phrase role="identifier">unspecified</phrase><phrase
role="special">-</phrase><phrase role="keyword">bool</phrase><phrase role="special">-</phrase><phrase
role="identifier">type</phrase><phrase role="special">()</phrase> <phrase
role="keyword">const</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
If <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
refers to <emphasis>not-a-coroutine</emphasis> or the coroutine-function
has returned (completed), the function returns false. Otherwise true.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.push_coro.h6">
<phrase id="coroutine.coroutine.unidirect.push_coro._code__phrase_role__keyword__bool__phrase___phrase_role__keyword__operator__phrase__phrase_role__special_______phrase___phrase_role__keyword__const__phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.push_coro._code__phrase_role__keyword__bool__phrase___phrase_role__keyword__operator__phrase__phrase_role__special_______phrase___phrase_role__keyword__const__phrase___code_"><code><phrase
role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase
role="special">!()</phrase> <phrase role="keyword">const</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
If <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
refers to <emphasis>not-a-coroutine</emphasis> or the coroutine-function
has returned (completed), the function returns true. Otherwise false.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.push_coro.h7">
<phrase id="coroutine.coroutine.unidirect.push_coro._code__phrase_role__keyword__bool__phrase___phrase_role__identifier__empty__phrase__phrase_role__special______phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.push_coro._code__phrase_role__keyword__bool__phrase___phrase_role__identifier__empty__phrase__phrase_role__special______phrase___code_"><code><phrase
role="keyword">bool</phrase> <phrase role="identifier">empty</phrase><phrase
role="special">()</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
If <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
refers to <emphasis>not-a-coroutine</emphasis>, the function returns
true. Otherwise false.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.push_coro.h8">
<phrase id="coroutine.coroutine.unidirect.push_coro._code__phrase_role__identifier__push_type__phrase__phrase_role__special___lt__gt___phrase___phrase_role__special___amp___phrase___phrase_role__keyword__operator__phrase__phrase_role__special_______phrase__phrase_role__identifier__arg__phrase__phrase_role__special___amp__amp___phrase___phrase_role__identifier__arg__phrase__phrase_role__special_____phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.push_coro._code__phrase_role__identifier__push_type__phrase__phrase_role__special___lt__gt___phrase___phrase_role__special___amp___phrase___phrase_role__keyword__operator__phrase__phrase_role__special_______phrase__phrase_role__identifier__arg__phrase__phrase_role__special___amp__amp___phrase___phrase_role__identifier__arg__phrase__phrase_role__special_____phrase___code_"><code><phrase
role="identifier">push_type</phrase><phrase role="special">&lt;&gt;</phrase>
<phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase
role="special">()(</phrase><phrase role="identifier">Arg</phrase><phrase
role="special">&amp;&amp;</phrase> <phrase role="identifier">arg</phrase><phrase
role="special">)</phrase></code></link>
</bridgehead>
<programlisting><phrase role="identifier">push_type</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="identifier">Arg</phrase><phrase role="special">&gt;::</phrase><phrase role="identifier">push_type</phrase><phrase role="special">::</phrase><phrase role="keyword">operator</phrase><phrase role="special">()(</phrase><phrase role="keyword">const</phrase> <phrase role="identifier">Arg</phrase><phrase role="special">&amp;);</phrase>
<phrase role="identifier">push_type</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="identifier">Arg</phrase><phrase role="special">&gt;::</phrase><phrase role="identifier">push_type</phrase><phrase role="special">::</phrase><phrase role="keyword">operator</phrase><phrase role="special">()(</phrase><phrase role="identifier">Arg</phrase><phrase role="special">&amp;&amp;);</phrase>
<phrase role="identifier">push_type</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="identifier">Arg</phrase><phrase role="special">&amp;&gt;::</phrase><phrase role="identifier">push_type</phrase><phrase role="special">::</phrase><phrase role="keyword">operator</phrase><phrase role="special">()(</phrase><phrase role="identifier">Arg</phrase><phrase role="special">&amp;);</phrase>
<phrase role="identifier">push_type</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">coroutine</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">void</phrase><phrase role="special">&gt;::</phrase><phrase role="identifier">push_type</phrase><phrase role="special">::</phrase><phrase role="keyword">operator</phrase><phrase role="special">()();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
operator unspecified-bool-type() returns true for <code><phrase role="special">*</phrase><phrase
role="keyword">this</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Execution control is transferred to <emphasis>coroutine-function</emphasis>
and the argument <code><phrase role="identifier">arg</phrase></code>
is passed to the coroutine-function.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Exceptions thrown inside <emphasis>coroutine-function</emphasis>.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.push_coro.h9">
<phrase id="coroutine.coroutine.unidirect.push_coro._code__phrase_role__keyword__void__phrase___phrase_role__identifier__swap__phrase__phrase_role__special_____phrase___phrase_role__identifier__push_type__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__other__phrase__phrase_role__special_____phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.push_coro._code__phrase_role__keyword__void__phrase___phrase_role__identifier__swap__phrase__phrase_role__special_____phrase___phrase_role__identifier__push_type__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__other__phrase__phrase_role__special_____phrase___code_"><code><phrase
role="keyword">void</phrase> <phrase role="identifier">swap</phrase><phrase
role="special">(</phrase> <phrase role="identifier">push_type</phrase>
<phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase
role="special">)</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Swaps the internal data from <code><phrase role="special">*</phrase><phrase
role="keyword">this</phrase></code> with the values of <code><phrase
role="identifier">other</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.push_coro.h10">
<phrase id="coroutine.coroutine.unidirect.push_coro._code__phrase_role__identifier__t__phrase___phrase_role__identifier__caller_type__phrase__phrase_role__special______phrase__phrase_role__keyword__operator__phrase__phrase_role__special_______phrase___phrase_role__identifier__r__phrase__phrase_role__special_____phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.push_coro._code__phrase_role__identifier__t__phrase___phrase_role__identifier__caller_type__phrase__phrase_role__special______phrase__phrase_role__keyword__operator__phrase__phrase_role__special_______phrase___phrase_role__identifier__r__phrase__phrase_role__special_____phrase___code_"><code><phrase
role="identifier">T</phrase> <phrase role="identifier">caller_type</phrase><phrase
role="special">::</phrase><phrase role="keyword">operator</phrase><phrase
role="special">()(</phrase> <phrase role="identifier">R</phrase><phrase
role="special">)</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Gives execution control back to calling context by returning a value
of type R. The return type of this function is a <emphasis>boost::tuple&lt;&gt;</emphasis>
containing the arguments passed to <emphasis>boost::coroutines::coroutine&lt;&gt;::operator()</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.push_coro.h11">
<phrase id="coroutine.coroutine.unidirect.push_coro.non_member_function__code__phrase_role__identifier__swap__phrase__phrase_role__special______phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.push_coro.non_member_function__code__phrase_role__identifier__swap__phrase__phrase_role__special______phrase___code_">Non-member
function <code><phrase role="identifier">swap</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">swap</phrase><phrase role="special">(</phrase> <phrase role="identifier">push_type</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">l</phrase><phrase role="special">,</phrase> <phrase role="identifier">push_type</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">r</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
As if 'l.swap( r)'.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.push_coro.h12">
<phrase id="coroutine.coroutine.unidirect.push_coro.non_member_function__code__phrase_role__identifier__begin__phrase__phrase_role__special_____phrase___phrase_role__identifier__push_type__phrase__phrase_role__special___lt___phrase___phrase_role__identifier__arg__phrase___phrase_role__special___gt___phrase___phrase_role__special___amp____phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.push_coro.non_member_function__code__phrase_role__identifier__begin__phrase__phrase_role__special_____phrase___phrase_role__identifier__push_type__phrase__phrase_role__special___lt___phrase___phrase_role__identifier__arg__phrase___phrase_role__special___gt___phrase___phrase_role__special___amp____phrase___code_">Non-member
function <code><phrase role="identifier">begin</phrase><phrase role="special">(</phrase>
<phrase role="identifier">push_type</phrase><phrase role="special">&lt;</phrase>
<phrase role="identifier">Arg</phrase> <phrase role="special">&gt;</phrase>
<phrase role="special">&amp;)</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">range_iterator</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">push_type</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&gt;::</phrase><phrase role="identifier">type</phrase> <phrase role="identifier">begin</phrase><phrase role="special">(</phrase> <phrase role="identifier">push_type</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
Returns a range-iterator (output-iterator).
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="coroutine.coroutine.unidirect.push_coro.h13">
<phrase id="coroutine.coroutine.unidirect.push_coro.non_member_function__code__phrase_role__identifier__end__phrase__phrase_role__special_____phrase___phrase_role__identifier__push_type__phrase__phrase_role__special___lt___phrase___phrase_role__identifier__arg__phrase___phrase_role__special___gt___phrase___phrase_role__special___amp____phrase___code_"/><link
linkend="coroutine.coroutine.unidirect.push_coro.non_member_function__code__phrase_role__identifier__end__phrase__phrase_role__special_____phrase___phrase_role__identifier__push_type__phrase__phrase_role__special___lt___phrase___phrase_role__identifier__arg__phrase___phrase_role__special___gt___phrase___phrase_role__special___amp____phrase___code_">Non-member
function <code><phrase role="identifier">end</phrase><phrase role="special">(</phrase>
<phrase role="identifier">push_type</phrase><phrase role="special">&lt;</phrase>
<phrase role="identifier">Arg</phrase> <phrase role="special">&gt;</phrase>
<phrase role="special">&amp;)</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">range_iterator</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">push_type</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&gt;::</phrase><phrase role="identifier">type</phrase> <phrase role="identifier">end</phrase><phrase role="special">(</phrase> <phrase role="identifier">push_type</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
Returns a end range-iterator (output-iterator).
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
</section>
</section>
<section id="coroutine.attributes">
<title><link linkend="coroutine.attributes">Attributes</link></title>
<para>
Class <code><phrase role="identifier">attributes</phrase></code> is used to
transfers parameters required to setup a coroutines's context.
</para>
<programlisting><phrase role="keyword">struct</phrase> <phrase role="identifier">attributes</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">flag_unwind_t</phrase> <phrase role="identifier">do_unwind</phrase><phrase role="special">;</phrase>
<phrase role="identifier">flag_fpu_t</phrase> <phrase role="identifier">preserve_fpu</phrase><phrase role="special">;</phrase>
<phrase role="identifier">attributes</phrase><phrase role="special">()</phrase> <phrase role="identifier">BOOST_NOEXCEPT</phrase><phrase role="special">;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">attributes</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">BOOST_NOEXCEPT</phrase><phrase role="special">;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">attributes</phrase><phrase role="special">(</phrase> <phrase role="identifier">flag_unwind_t</phrase> <phrase role="identifier">do_unwind_</phrase><phrase role="special">)</phrase> <phrase role="identifier">BOOST_NOEXCEPT</phrase><phrase role="special">;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">attributes</phrase><phrase role="special">(</phrase> <phrase role="identifier">flag_fpu_t</phrase> <phrase role="identifier">preserve_fpu_</phrase><phrase role="special">)</phrase> <phrase role="identifier">BOOST_NOEXCEPT</phrase><phrase role="special">;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">attributes</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">flag_unwind_t</phrase> <phrase role="identifier">do_unwind_</phrase><phrase role="special">)</phrase> <phrase role="identifier">BOOST_NOEXCEPT</phrase><phrase role="special">;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">attributes</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">flag_fpu_t</phrase> <phrase role="identifier">preserve_fpu_</phrase><phrase role="special">)</phrase> <phrase role="identifier">BOOST_NOEXCEPT</phrase><phrase role="special">;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">attributes</phrase><phrase role="special">(</phrase> <phrase role="identifier">flag_unwind_t</phrase> <phrase role="identifier">do_unwind_</phrase><phrase role="special">,</phrase> <phrase role="identifier">flag_fpu_t</phrase> <phrase role="identifier">preserve_fpu_</phrase><phrase role="special">)</phrase> <phrase role="identifier">BOOST_NOEXCEPT</phrase><phrase role="special">;</phrase>
<phrase role="special">};</phrase>
</programlisting>
<bridgehead renderas="sect3" id="coroutine.attributes.h0">
<phrase id="coroutine.attributes._code__phrase_role__identifier__attributes__phrase__phrase_role__special______phrase___code_"/><link
linkend="coroutine.attributes._code__phrase_role__identifier__attributes__phrase__phrase_role__special______phrase___code_"><code><phrase
role="identifier">attributes</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Default constructor using <code><phrase role="identifier">ctx</phrase><phrase
role="special">::</phrase><phrase role="identifier">default_stacksize</phrase><phrase
role="special">()</phrase></code>, does unwind the stack after coroutine/generator
is complete and preserves FPU registers.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect3" id="coroutine.attributes.h1">
<phrase id="coroutine.attributes._code__phrase_role__identifier__attributes__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___code_"/><link
linkend="coroutine.attributes._code__phrase_role__identifier__attributes__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___code_"><code><phrase
role="identifier">attributes</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></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Argument <code><phrase role="identifier">size</phrase></code> defines
stack size of the inner <code><phrase role="identifier">context</phrase></code>.
Stack unwinding after termination and preserving FPU registers is set
by default.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect3" id="coroutine.attributes.h2">
<phrase id="coroutine.attributes._code__phrase_role__identifier__attributes__phrase__phrase_role__special_____phrase___phrase_role__identifier__flag_unwind_t__phrase___phrase_role__identifier__do_unwind__phrase__phrase_role__special_____phrase___code_"/><link
linkend="coroutine.attributes._code__phrase_role__identifier__attributes__phrase__phrase_role__special_____phrase___phrase_role__identifier__flag_unwind_t__phrase___phrase_role__identifier__do_unwind__phrase__phrase_role__special_____phrase___code_"><code><phrase
role="identifier">attributes</phrase><phrase role="special">(</phrase> <phrase
role="identifier">flag_unwind_t</phrase> <phrase role="identifier">do_unwind</phrase><phrase
role="special">)</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Argument <code><phrase role="identifier">do_unwind</phrase></code> determines
if stack will be unwound after termination or not. The default stacksize
is used for the inner <code><phrase role="identifier">context</phrase></code>
and FPU registers are preserved.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect3" id="coroutine.attributes.h3">
<phrase id="coroutine.attributes._code__phrase_role__identifier__attributes__phrase__phrase_role__special_____phrase___phrase_role__identifier__flag_fpu_t__phrase___phrase_role__identifier__preserve_fpu__phrase__phrase_role__special_____phrase___code_"/><link
linkend="coroutine.attributes._code__phrase_role__identifier__attributes__phrase__phrase_role__special_____phrase___phrase_role__identifier__flag_fpu_t__phrase___phrase_role__identifier__preserve_fpu__phrase__phrase_role__special_____phrase___code_"><code><phrase
role="identifier">attributes</phrase><phrase role="special">(</phrase> <phrase
role="identifier">flag_fpu_t</phrase> <phrase role="identifier">preserve_fpu</phrase><phrase
role="special">)</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Argument <code><phrase role="identifier">preserve_fpu</phrase></code>
determines if FPU register have to be preserved if a <code><phrase role="identifier">context</phrase></code>
switches. THe default stacksize is used for the inner <code><phrase role="identifier">context</phrase></code>
and the stack will be unwound after termination.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect3" id="coroutine.attributes.h4">
<phrase id="coroutine.attributes._code__phrase_role__identifier__attributes__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__flag_unwind_t__phrase___phrase_role__identifier__do_unwind__phrase__phrase_role__special_____phrase___code_"/><link
linkend="coroutine.attributes._code__phrase_role__identifier__attributes__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__flag_unwind_t__phrase___phrase_role__identifier__do_unwind__phrase__phrase_role__special_____phrase___code_"><code><phrase
role="identifier">attributes</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">flag_unwind_t</phrase> <phrase role="identifier">do_unwind</phrase><phrase
role="special">)</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Arguments <code><phrase role="identifier">size</phrase></code> and <code><phrase
role="identifier">do_unwind</phrase></code> are given by the user. FPU
registers preserved during each <code><phrase role="identifier">context</phrase></code>
switch.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect3" id="coroutine.attributes.h5">
<phrase id="coroutine.attributes._code__phrase_role__identifier__attributes__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__flag_fpu_t__phrase___phrase_role__identifier__preserve_fpu__phrase__phrase_role__special_____phrase___code_"/><link
linkend="coroutine.attributes._code__phrase_role__identifier__attributes__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__flag_fpu_t__phrase___phrase_role__identifier__preserve_fpu__phrase__phrase_role__special_____phrase___code_"><code><phrase
role="identifier">attributes</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">flag_fpu_t</phrase> <phrase role="identifier">preserve_fpu</phrase><phrase
role="special">)</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Arguments <code><phrase role="identifier">size</phrase></code> and <code><phrase
role="identifier">preserve_fpu</phrase></code> are given by the user.
The stack is automatically unwound after coroutine/generator terminates.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect3" id="coroutine.attributes.h6">
<phrase id="coroutine.attributes._code__phrase_role__identifier__attributes__phrase__phrase_role__special_____phrase___phrase_role__identifier__flag_unwind_t__phrase___phrase_role__identifier__do_unwind__phrase__phrase_role__special_____phrase___phrase_role__identifier__flag_fpu_t__phrase___phrase_role__identifier__preserve_fpu__phrase__phrase_role__special_____phrase___code_"/><link
linkend="coroutine.attributes._code__phrase_role__identifier__attributes__phrase__phrase_role__special_____phrase___phrase_role__identifier__flag_unwind_t__phrase___phrase_role__identifier__do_unwind__phrase__phrase_role__special_____phrase___phrase_role__identifier__flag_fpu_t__phrase___phrase_role__identifier__preserve_fpu__phrase__phrase_role__special_____phrase___code_"><code><phrase
role="identifier">attributes</phrase><phrase role="special">(</phrase> <phrase
role="identifier">flag_unwind_t</phrase> <phrase role="identifier">do_unwind</phrase><phrase
role="special">,</phrase> <phrase role="identifier">flag_fpu_t</phrase> <phrase
role="identifier">preserve_fpu</phrase><phrase role="special">)</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Arguments <code><phrase role="identifier">do_unwind</phrase></code> and
<code><phrase role="identifier">preserve_fpu</phrase></code> are given
by the user. The stack gets a default value of <code><phrase role="identifier">ctx</phrase><phrase
role="special">::</phrase><phrase role="identifier">default_stacksize</phrase><phrase
role="special">()</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section id="coroutine.stack">
<title><link linkend="coroutine.stack">Stack allocation</link></title>
<para>
A <emphasis>coroutine</emphasis> uses internally a <emphasis>context</emphasis>
which manages a set of registers and a stack. The memory used by the stack
is allocated/deallocated via a <emphasis>stack-allocator</emphasis> which is
required to model a <emphasis>stack-allocator concept</emphasis>.
</para>
<bridgehead renderas="sect3" id="coroutine.stack.h0">
<phrase id="coroutine.stack._emphasis_stack_allocator_concept__emphasis_"/><link
linkend="coroutine.stack._emphasis_stack_allocator_concept__emphasis_"><emphasis>stack-allocator
concept</emphasis></link>
</bridgehead>
<para>
A <emphasis>stack-allocator</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>stack-allocator</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">allocate</phrase><phrase role="special">(</phrase>
<phrase role="identifier">sctx</phrase><phrase role="special">,</phrase>
<phrase role="identifier">size</phrase><phrase role="special">)</phrase></code>
</para>
</entry>
<entry>
<para>
<code><phrase role="keyword">void</phrase></code>
</para>
</entry>
<entry>
<para>
creates a stack of at least <code><phrase role="identifier">size</phrase></code>
bytes and stores both values in <code><phrase role="identifier">sctx</phrase></code>
</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 pointer not returned 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>coroutine</emphasis>.
</para>
</note>
<note>
<para>
Depending on the architecture <code><phrase role="identifier">allocate</phrase><phrase
role="special">()</phrase></code> returns an address from the top of the
stack (growing downwards) or the bottom of the stack (growing upwards).
</para>
</note>
<para>
class <emphasis>boost::coroutines::stack_allocator</emphasis> is a typedef
of <emphasis>boost::coroutines::standard_stack_allocator</emphasis>.
</para>
<section id="coroutine.stack.protected_stack_allocator">
<title><link linkend="coroutine.stack.protected_stack_allocator">Class <emphasis>protected_stack_allocator</emphasis></link></title>
<para>
<emphasis role="bold">Boost.Coroutine</emphasis> provides the class <emphasis>boost::coroutines::protected_stack_allocator</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>boost::coroutines::protected_stack_allocator</emphasis>
is expensive.
</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="keyword">class</phrase> <phrase role="identifier">protected_stack_allocator</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">static</phrase> <phrase role="keyword">bool</phrase> <phrase role="identifier">is_stack_unbound</phrase><phrase role="special">();</phrase>
<phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">maximum_stacksize</phrase><phrase role="special">();</phrase>
<phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">default_stacksize</phrase><phrase role="special">();</phrase>
<phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">minimum_stacksize</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&amp;,</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="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&amp;);</phrase>
<phrase role="special">}</phrase>
</programlisting>
<bridgehead renderas="sect4" id="coroutine.stack.protected_stack_allocator.h0">
<phrase id="coroutine.stack.protected_stack_allocator._code__phrase_role__keyword__static__phrase___phrase_role__keyword__bool__phrase___phrase_role__identifier__is_stack_unbound__phrase__phrase_role__special______phrase___code_"/><link
linkend="coroutine.stack.protected_stack_allocator._code__phrase_role__keyword__static__phrase___phrase_role__keyword__bool__phrase___phrase_role__identifier__is_stack_unbound__phrase__phrase_role__special______phrase___code_"><code><phrase
role="keyword">static</phrase> <phrase role="keyword">bool</phrase> <phrase
role="identifier">is_stack_unbound</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
Returns <code><phrase role="keyword">true</phrase></code> if the environment
defines no limit for the size of a stack.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect4" id="coroutine.stack.protected_stack_allocator.h1">
<phrase id="coroutine.stack.protected_stack_allocator._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__maximum_stacksize__phrase__phrase_role__special______phrase___code_"/><link
linkend="coroutine.stack.protected_stack_allocator._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__maximum_stacksize__phrase__phrase_role__special______phrase___code_"><code><phrase
role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase
role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase
role="identifier">maximum_stacksize</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
<code><phrase role="identifier">is_stack_unbound</phrase><phrase role="special">()</phrase></code>
returns <code><phrase role="keyword">false</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
Returns the maximum size in bytes of stack defined by the environment.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect4" id="coroutine.stack.protected_stack_allocator.h2">
<phrase id="coroutine.stack.protected_stack_allocator._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__default_stacksize__phrase__phrase_role__special______phrase___code_"/><link
linkend="coroutine.stack.protected_stack_allocator._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__default_stacksize__phrase__phrase_role__special______phrase___code_"><code><phrase
role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase
role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase
role="identifier">default_stacksize</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
Returns a default stack size, which may be platform specific. If the
stack is unbound then the present implementation returns the maximum
of <code><phrase role="number">64</phrase> <phrase role="identifier">kB</phrase></code>
and <code><phrase role="identifier">minimum_stacksize</phrase><phrase
role="special">()</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect4" id="coroutine.stack.protected_stack_allocator.h3">
<phrase id="coroutine.stack.protected_stack_allocator._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__minimum_stacksize__phrase__phrase_role__special______phrase___code_"/><link
linkend="coroutine.stack.protected_stack_allocator._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__minimum_stacksize__phrase__phrase_role__special______phrase___code_"><code><phrase
role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase
role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase
role="identifier">minimum_stacksize</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
Returns the minimum size in bytes of stack defined by the environment
(Win32 4kB/Win64 8kB, defined by rlimit on POSIX).
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect4" id="coroutine.stack.protected_stack_allocator.h4">
<phrase id="coroutine.stack.protected_stack_allocator._code__phrase_role__keyword__void__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__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___code_"/><link
linkend="coroutine.stack.protected_stack_allocator._code__phrase_role__keyword__void__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__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___code_"><code><phrase
role="keyword">void</phrase> <phrase role="identifier">allocate</phrase><phrase
role="special">(</phrase> <phrase role="identifier">stack_context</phrase>
<phrase role="special">&amp;</phrase> <phrase role="identifier">sctx</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></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
<code><phrase role="identifier">minimum_stacksize</phrase><phrase role="special">()</phrase>
<phrase role="special">&gt;</phrase> <phrase role="identifier">size</phrase></code>
and <code><phrase role="special">!</phrase> <phrase role="identifier">is_stack_unbound</phrase><phrase
role="special">()</phrase> <phrase role="special">&amp;&amp;</phrase>
<phrase role="special">(</phrase> <phrase role="identifier">maximum_stacksize</phrase><phrase
role="special">()</phrase> <phrase role="special">&lt;</phrase> <phrase
role="identifier">size</phrase><phrase role="special">)</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Allocates memory of at least <code><phrase role="identifier">size</phrase></code>
Bytes and stores a pointer to the stack and its actual size in <code><phrase
role="identifier">sctx</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
Returns pointer to the start address of the new stack. Depending on
the architecture the stack grows downwards/upwards the returned address
is the highest/lowest address of the stack.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect4" id="coroutine.stack.protected_stack_allocator.h5">
<phrase id="coroutine.stack.protected_stack_allocator._code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__phrase__phrase_role__special_____phrase___code_"/><link
linkend="coroutine.stack.protected_stack_allocator._code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__phrase__phrase_role__special_____phrase___code_"><code><phrase
role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase
role="special">(</phrase> <phrase role="identifier">stack_context</phrase>
<phrase role="special">&amp;</phrase> <phrase role="identifier">sctx</phrase><phrase
role="special">)</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
<code><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
role="identifier">sp</phrase></code> is valid, <code><phrase role="identifier">minimum_stacksize</phrase><phrase
role="special">()</phrase> <phrase role="special">&gt;</phrase> <phrase
role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
role="identifier">size</phrase></code> and <code><phrase role="special">!</phrase>
<phrase role="identifier">is_stack_unbound</phrase><phrase role="special">()</phrase>
<phrase role="special">&amp;&amp;</phrase> <phrase role="special">(</phrase>
<phrase role="identifier">maximum_stacksize</phrase><phrase role="special">()</phrase>
<phrase role="special">&lt;</phrase> <phrase role="identifier">size</phrase><phrase
role="special">)</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Deallocates the stack space.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section id="coroutine.stack.standard_stack_allocator">
<title><link linkend="coroutine.stack.standard_stack_allocator">Class <emphasis>standard_stack_allocator</emphasis></link></title>
<para>
<emphasis role="bold">Boost.Coroutine</emphasis> provides the class <emphasis>boost::coroutines::standard_stack_allocator</emphasis>
which models the <emphasis>stack-allocator concept</emphasis>. In contrast
to <emphasis>boost::coroutines::protected_stack_allocator</emphasis> it does
not append a guard page at the end of each stack. The memory is simply managed
by <code><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
role="identifier">malloc</phrase><phrase role="special">()</phrase></code>
and <code><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
role="identifier">free</phrase><phrase role="special">()</phrase></code>.
</para>
<programlisting><phrase role="keyword">class</phrase> <phrase role="identifier">standard_stack_allocator</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">static</phrase> <phrase role="keyword">bool</phrase> <phrase role="identifier">is_stack_unbound</phrase><phrase role="special">();</phrase>
<phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">maximum_stacksize</phrase><phrase role="special">();</phrase>
<phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">default_stacksize</phrase><phrase role="special">();</phrase>
<phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">minimum_stacksize</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&amp;,</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="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&amp;);</phrase>
<phrase role="special">}</phrase>
</programlisting>
<bridgehead renderas="sect4" id="coroutine.stack.standard_stack_allocator.h0">
<phrase id="coroutine.stack.standard_stack_allocator._code__phrase_role__keyword__static__phrase___phrase_role__keyword__bool__phrase___phrase_role__identifier__is_stack_unbound__phrase__phrase_role__special______phrase___code_"/><link
linkend="coroutine.stack.standard_stack_allocator._code__phrase_role__keyword__static__phrase___phrase_role__keyword__bool__phrase___phrase_role__identifier__is_stack_unbound__phrase__phrase_role__special______phrase___code_"><code><phrase
role="keyword">static</phrase> <phrase role="keyword">bool</phrase> <phrase
role="identifier">is_stack_unbound</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
Returns <code><phrase role="keyword">true</phrase></code> if the environment
defines no limit for the size of a stack.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect4" id="coroutine.stack.standard_stack_allocator.h1">
<phrase id="coroutine.stack.standard_stack_allocator._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__maximum_stacksize__phrase__phrase_role__special______phrase___code_"/><link
linkend="coroutine.stack.standard_stack_allocator._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__maximum_stacksize__phrase__phrase_role__special______phrase___code_"><code><phrase
role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase
role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase
role="identifier">maximum_stacksize</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
<code><phrase role="identifier">is_stack_unbound</phrase><phrase role="special">()</phrase></code>
returns <code><phrase role="keyword">false</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
Returns the maximum size in bytes of stack defined by the environment.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect4" id="coroutine.stack.standard_stack_allocator.h2">
<phrase id="coroutine.stack.standard_stack_allocator._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__default_stacksize__phrase__phrase_role__special______phrase___code_"/><link
linkend="coroutine.stack.standard_stack_allocator._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__default_stacksize__phrase__phrase_role__special______phrase___code_"><code><phrase
role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase
role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase
role="identifier">default_stacksize</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
Returns a default stack size, which may be platform specific. If the
stack is unbound then the present implementation returns the maximum
of <code><phrase role="number">64</phrase> <phrase role="identifier">kB</phrase></code>
and <code><phrase role="identifier">minimum_stacksize</phrase><phrase
role="special">()</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect4" id="coroutine.stack.standard_stack_allocator.h3">
<phrase id="coroutine.stack.standard_stack_allocator._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__minimum_stacksize__phrase__phrase_role__special______phrase___code_"/><link
linkend="coroutine.stack.standard_stack_allocator._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__minimum_stacksize__phrase__phrase_role__special______phrase___code_"><code><phrase
role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase
role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase
role="identifier">minimum_stacksize</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
Returns the minimum size in bytes of stack defined by the environment
(Win32 4kB/Win64 8kB, defined by rlimit on POSIX).
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect4" id="coroutine.stack.standard_stack_allocator.h4">
<phrase id="coroutine.stack.standard_stack_allocator._code__phrase_role__keyword__void__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__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___code_"/><link
linkend="coroutine.stack.standard_stack_allocator._code__phrase_role__keyword__void__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__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___code_"><code><phrase
role="keyword">void</phrase> <phrase role="identifier">allocate</phrase><phrase
role="special">(</phrase> <phrase role="identifier">stack_context</phrase>
<phrase role="special">&amp;</phrase> <phrase role="identifier">sctx</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></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
<code><phrase role="identifier">minimum_stacksize</phrase><phrase role="special">()</phrase>
<phrase role="special">&gt;</phrase> <phrase role="identifier">size</phrase></code>
and <code><phrase role="special">!</phrase> <phrase role="identifier">is_stack_unbound</phrase><phrase
role="special">()</phrase> <phrase role="special">&amp;&amp;</phrase>
<phrase role="special">(</phrase> <phrase role="identifier">maximum_stacksize</phrase><phrase
role="special">()</phrase> <phrase role="special">&lt;</phrase> <phrase
role="identifier">size</phrase><phrase role="special">)</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Allocates memory of at least <code><phrase role="identifier">size</phrase></code>
Bytes and stores a pointer to the stack and its actual size in <code><phrase
role="identifier">sctx</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
Returns pointer to the start address of the new stack. Depending on
the architecture the stack grows downwards/upwards the returned address
is the highest/lowest address of the stack.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect4" id="coroutine.stack.standard_stack_allocator.h5">
<phrase id="coroutine.stack.standard_stack_allocator._code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__phrase__phrase_role__special_____phrase___code_"/><link
linkend="coroutine.stack.standard_stack_allocator._code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__phrase__phrase_role__special_____phrase___code_"><code><phrase
role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase
role="special">(</phrase> <phrase role="identifier">stack_context</phrase>
<phrase role="special">&amp;</phrase> <phrase role="identifier">sctx</phrase><phrase
role="special">)</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
<code><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
role="identifier">sp</phrase></code> is valid, <code><phrase role="identifier">minimum_stacksize</phrase><phrase
role="special">()</phrase> <phrase role="special">&gt;</phrase> <phrase
role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
role="identifier">size</phrase></code> and <code><phrase role="special">!</phrase>
<phrase role="identifier">is_stack_unbound</phrase><phrase role="special">()</phrase>
<phrase role="special">&amp;&amp;</phrase> <phrase role="special">(</phrase>
<phrase role="identifier">maximum_stacksize</phrase><phrase role="special">()</phrase>
<phrase role="special">&lt;</phrase> <phrase role="identifier">size</phrase><phrase
role="special">)</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Deallocates the stack space.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section id="coroutine.stack.stack_context">
<title><link linkend="coroutine.stack.stack_context">Class <emphasis>stack_context</emphasis></link></title>
<para>
<emphasis role="bold">Boost.Coroutine</emphasis> provides the class <emphasis>boost::coroutines::stack_context</emphasis>
which will contain the stack pointer and the size of the stack. In case of
a <emphasis>segemented-stack</emphasis> <emphasis>boost::coroutines::stack_context</emphasis>
contains some extra controll structures.
</para>
<programlisting><phrase role="keyword">struct</phrase> <phrase role="identifier">stack_context</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="comment">// might contain addition controll structures</phrase>
<phrase role="comment">// for instance for segmented stacks</phrase>
<phrase role="special">}</phrase>
</programlisting>
<bridgehead renderas="sect4" id="coroutine.stack.stack_context.h0">
<phrase id="coroutine.stack.stack_context._code__phrase_role__keyword__void__phrase___phrase_role__special_____phrase___phrase_role__identifier__sp__phrase___code_"/><link
linkend="coroutine.stack.stack_context._code__phrase_role__keyword__void__phrase___phrase_role__special_____phrase___phrase_role__identifier__sp__phrase___code_"><code><phrase
role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Value:</term>
<listitem>
<para>
Pointer to the beginning of the stack.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect4" id="coroutine.stack.stack_context.h1">
<phrase id="coroutine.stack.stack_context._code__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__size__phrase___code_"/><link
linkend="coroutine.stack.stack_context._code__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__size__phrase___code_"><code><phrase
role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase>
<phrase role="identifier">size</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Value:</term>
<listitem>
<para>
Actual size of the stack.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section id="coroutine.stack.segmented_stack">
<title><link linkend="coroutine.stack.segmented_stack">Segmented stacks</link></title>
<para>
<emphasis role="bold">Boost.Coroutine</emphasis> supports usage of a <emphasis>segemented-stack</emphasis>,
e. g. the size of the stack grows on demand. The coroutine is created with
an minimal stack size and will be increased as required.
</para>
<para>
Segmented stacks are currently only supported by <emphasis role="bold">gcc</emphasis>
from version <emphasis role="bold">4.7</emphasis> onwards. In order to use
a <emphasis>segemented-stack</emphasis> <emphasis role="bold">Boost.Coroutine</emphasis>
must be build with <emphasis role="bold">toolset=gcc segmented-stacks=on</emphasis>
at b2/bjam command-line. Applications must be compiled with compiler-flags
<emphasis role="bold">-fsplit-stack -DBOOST_USE_SEGMENTED_STACKS</emphasis>.
</para>
</section>
</section>
<section id="coroutine.performance">
<title><link linkend="coroutine.performance">Performance</link></title>
<para>
Performance of <emphasis role="bold">Boost.Coroutine</emphasis> was measured
on the platforms shown in the following table. Performance measurements were
taken using <code><phrase role="identifier">rdtsc</phrase></code> and <code><phrase
role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">chrono</phrase><phrase
role="special">::</phrase><phrase role="identifier">high_resolution_clock</phrase></code>,
with overhead corrections, on x86 platforms. In each case, cache warm-up was
accounted for, and the one running thread was pinned to a single CPU. The code
was compiled using the build options, 'variant = release cxxflags = -DBOOST_DISABLE_ASSERTS'.
</para>
<table frame="all" id="coroutine.performance.perfomance_of_coroutine">
<title>Perfomance of coroutine</title>
<tgroup cols="5">
<thead>
<row>
<entry>
<para>
Platform
</para>
</entry>
<entry>
<para>
switch
</para>
</entry>
<entry>
<para>
construction (protected stack-allocator)
</para>
</entry>
<entry>
<para>
construction (simple stack-allocator)
</para>
</entry>
<entry>
<para>
construction (preallocated stack-allocator)
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>
i386 <footnote id="coroutine.performance.f0">
<para>
AMD Athlon 64 DualCore 4400+
</para>
</footnote>
</para>
</entry>
<entry>
<para>
78 ns / 77 cycles
</para>
</entry>
<entry>
<para>
188868 ns / 245093 cycles
</para>
</entry>
<entry>
<para>
31860 ns / 31812 cycles
</para>
</entry>
<entry>
<para>
13127 ns / 19764 cycles
</para>
</entry>
</row>
<row>
<entry>
<para>
x86_64 <footnote id="coroutine.performance.f1">
<para>
Intel Core2 Q6700
</para>
</footnote>
</para>
</entry>
<entry>
<para>
28 ns / 74 cycles
</para>
</entry>
<entry>
<para>
46916 ns / 109569 cycles
</para>
</entry>
<entry>
<para>
14368 ns / 22705 cycles
</para>
</entry>
<entry>
<para>
6114 ns / 16728 cycles
</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
</section>
<section id="coroutine.architextues">
<title><link linkend="coroutine.architextues">Architectures</link></title>
<para>
<emphasis role="bold">Boost.Coroutine</emphasis> depends on <emphasis role="bold">Boost.Context</emphasis>
witch supports this <ulink url="boost:/libs/context/architectures.html">architectures</ulink>.
</para>
</section>
<section id="coroutine.acknowledgements">
<title><link linkend="coroutine.acknowledgements">Acknowledgments</link></title>
<para>
I'd like to thank Alex Hagen-Zanker, Christopher Kormanyos, Conrad Poelman,
Eugene Yakubovich, Giovanni Piero Deretta, Hartmut Kaiser, Jeffrey Lee Hellrung,
Nat Goodspeed, Robert Stewart, Vicente J. Botet Escriba and Yuriy Krasnoschek.
</para>
<para>
Especially Eugene Yakubovich, Giovanni Piero Deretta and Vicente J. Botet Escriba
contributed many good ideas during the review.
</para>
</section>
</library>