mirror of
https://github.com/boostorg/coroutine.git
synced 2026-02-02 08:42:16 +00:00
3058 lines
268 KiB
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"><</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">></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.. "Design of a Separable Transition-Diagram Compiler".
|
|
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). "Fundamental Algorithms. The Art of Computer
|
|
Programming 1", (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. "Revisiting coroutines".
|
|
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<>::push_type</emphasis>
|
|
and <emphasis>coroutine<>::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<>::push_type</emphasis>.
|
|
<emphasis>coroutine<>::push_type</emphasis> suspends the recursive computation
|
|
and transfers the data value to the main execution context. <emphasis>boost::coroutines::coroutine<>::pull_type::iterator</emphasis>,
|
|
created from <emphasis>coroutine<>::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<>::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"><</phrase><phrase role="identifier">node</phrase><phrase role="special">></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">&</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">&</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">&</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">&</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">&</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">"a"</phrase><phrase role="special">),</phrase>
|
|
<phrase role="string">"b"</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">"c"</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">"e"</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">&</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">"a"</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">"c"</phrase><phrase role="special">),</phrase>
|
|
<phrase role="string">"d"</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">"e"</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"><</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">>::</phrase><phrase role="identifier">push_type</phrase><phrase role="special">&</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">-></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">-></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">-></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">-></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">-></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">"d"</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"><</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">>::</phrase><phrase role="identifier">pull_type</phrase> <phrase role="identifier">left_d_reader</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"><</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">>::</phrase><phrase role="identifier">push_type</phrase> <phrase role="special">&</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">"b"</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"><</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">>::</phrase><phrase role="identifier">pull_type</phrase> <phrase role="identifier">right_b_reader</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"><</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">>::</phrase><phrase role="identifier">push_type</phrase> <phrase role="special">&</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"><<</phrase> <phrase role="string">"left tree from d == right tree from b? "</phrase>
|
|
<phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">boolalpha</phrase>
|
|
<phrase role="special"><<</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"><<</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">"d"</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"><</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">>::</phrase><phrase role="identifier">pull_type</phrase> <phrase role="identifier">left_d_reader</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"><</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">>::</phrase><phrase role="identifier">push_type</phrase> <phrase role="special">&</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">"x"</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"><</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">>::</phrase><phrase role="identifier">pull_type</phrase> <phrase role="identifier">right_x_reader</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"><</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">>::</phrase><phrase role="identifier">push_type</phrase> <phrase role="special">&</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"><<</phrase> <phrase role="string">"left tree from d == right tree from x? "</phrase>
|
|
<phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">boolalpha</phrase>
|
|
<phrase role="special"><<</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"><<</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"><<</phrase> <phrase role="string">"Done"</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="identifier">output</phrase><phrase role="special">:</phrase>
|
|
<phrase role="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"><</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">></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">&</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">&</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">&</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">&</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"><</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">'"'</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"><</phrase> <phrase role="identifier">line</phrase><phrase role="special">.</phrase><phrase role="identifier">length</phrase><phrase role="special">()</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">'"'</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"><</phrase> <phrase role="identifier">line</phrase><phrase role="special">.</phrase><phrase role="identifier">length</phrase><phrase role="special">()</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">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">&</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">&</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">&&</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">&</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">&</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"><<</phrase> <phrase role="string">"trace: '"</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">token</phrase> <phrase role="special"><<</phrase> <phrase role="string">"'\n"</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"><<</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">&</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"><</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"><<</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"><<</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"><<</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">"This is the first line.\n"</phrase>
|
|
<phrase role="string">"This, the second.\n"</phrase>
|
|
<phrase role="string">"The third has \"a phrase\"!\n"</phrase>
|
|
<phrase role="special">);</phrase>
|
|
|
|
<phrase role="special">{</phrase>
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"\nfilter:\n"</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"><<</phrase> <phrase role="string">"\nlayout() as coroutine::push_type:\n"</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"><<</phrase> <phrase role="string">"\nfiltering output:\n"</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">&</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<>::push_type</emphasis> and
|
|
<emphasis>coroutine<>::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<>::pull_type</emphasis></link>
|
|
</bridgehead>
|
|
<para>
|
|
<emphasis>coroutine<>::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<>::pull_type</emphasis>
|
|
takes a function (<emphasis>coroutine-function</emphasis>) accepting a reference
|
|
to a <emphasis>coroutine<>::push_type</emphasis> as argument. Instantiating
|
|
a <emphasis>coroutine<>::pull_type</emphasis> passes the control of
|
|
execution to <emphasis>coroutine-function</emphasis> and a complementary
|
|
<emphasis>coroutine<>::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<>::pull_type::operator()</emphasis>.
|
|
This method only switches context; it transfers no data.
|
|
</para>
|
|
<para>
|
|
<emphasis>coroutine<>::pull_type</emphasis> provides input iterators
|
|
(<emphasis>boost::coroutines::coroutine<>::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"><</phrase><phrase role="keyword">int</phrase><phrase role="special">>::</phrase><phrase role="identifier">pull_type</phrase> <phrase role="identifier">source</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"><</phrase><phrase role="keyword">int</phrase><phrase role="special">>::</phrase><phrase role="identifier">push_type</phrase><phrase role="special">&</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"><</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"><<</phrase> <phrase role="identifier">i</phrase> <phrase role="special"><<</phrase> <phrase role="string">" "</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"\nDone"</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="identifier">output</phrase><phrase role="special">:</phrase>
|
|
<phrase role="number">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<>::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<>::pull_type</emphasis>.
|
|
A <emphasis>coroutine<>::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<>::push_type::operator()</emphasis>
|
|
with another Fibonacci number, <emphasis>coroutine<>::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<>::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<>::push_type</emphasis></link>
|
|
</bridgehead>
|
|
<para>
|
|
<emphasis>coroutine<>::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<>::push_type</emphasis>
|
|
takes a function (<emphasis>coroutine-function</emphasis>) accepting a reference
|
|
to a <emphasis>coroutine<>::pull_type</emphasis> as argument. In contrast
|
|
to <emphasis>coroutine<>::pull_type</emphasis>, instantiating a <emphasis>coroutine<>::push_type</emphasis>
|
|
does not pass the control of execution to <emphasis>coroutine-function</emphasis>
|
|
- instead the first call of <emphasis>boost::coroutines::coroutine<>::push_type::operator()</emphasis>
|
|
synthesizes a complementary <emphasis>coroutine<>::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<>::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"><<</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"><</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">>::</phrase><phrase role="identifier">push_type</phrase> <phrase role="identifier">writer</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"><</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">>::</phrase><phrase role="identifier">pull_type</phrase><phrase role="special">&</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"><</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"><<</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"><<</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"><<</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"><</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">></phrase> <phrase role="identifier">words</phrase><phrase role="special">{</phrase>
|
|
<phrase role="string">"peas"</phrase><phrase role="special">,</phrase> <phrase role="string">"porridge"</phrase><phrase role="special">,</phrase> <phrase role="string">"hot"</phrase><phrase role="special">,</phrase> <phrase role="string">"peas"</phrase><phrase role="special">,</phrase>
|
|
<phrase role="string">"porridge"</phrase><phrase role="special">,</phrase> <phrase role="string">"cold"</phrase><phrase role="special">,</phrase> <phrase role="string">"peas"</phrase><phrase role="special">,</phrase> <phrase role="string">"porridge"</phrase><phrase role="special">,</phrase>
|
|
<phrase role="string">"in"</phrase><phrase role="special">,</phrase> <phrase role="string">"the"</phrase><phrase role="special">,</phrase> <phrase role="string">"pot"</phrase><phrase role="special">,</phrase> <phrase role="string">"nine"</phrase><phrase role="special">,</phrase>
|
|
<phrase role="string">"days"</phrase><phrase role="special">,</phrase> <phrase role="string">"old"</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<>::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<>::push_type</emphasis>. The main execution
|
|
context passes the strings to the <emphasis>coroutine-function</emphasis>
|
|
by calling <emphasis>boost::coroutines::coroutine<>::push_type::operator()</emphasis>.
|
|
A <emphasis>coroutine<>::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<>::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<>::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<>::push_type</emphasis> and <emphasis>coroutine<>::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<>::push_type::operator()</emphasis>
|
|
and <emphasis>boost::coroutines::coroutine<>::pull_type::operator()</emphasis>.
|
|
</para>
|
|
<warning>
|
|
<para>
|
|
Calling <emphasis>boost::coroutines::coroutine<>::push_type::operator()</emphasis>/<emphasis>boost::coroutines::coroutine<>::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<>::pull_type</emphasis>
|
|
the <emphasis>coroutine-function</emphasis> is entered at <emphasis>coroutine<>::pull_type</emphasis>
|
|
construction. For <emphasis>coroutine<>::push_type</emphasis> the
|
|
<emphasis>coroutine-function</emphasis> is not entered at <emphasis>coroutine<>::push_type</emphasis>
|
|
construction but entered by the first invocation of <emphasis>boost::coroutines::coroutine<>::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<>::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<>::pull_type</emphasis>
|
|
to the main-context the framework synthesizes a <emphasis>coroutine<>::push_type</emphasis>
|
|
associated with the <emphasis>coroutine<>::pull_type</emphasis> instance
|
|
in the main-context. The synthesized <emphasis>coroutine<>::push_type</emphasis>
|
|
is passed as argument to <emphasis>coroutine-function</emphasis>.\ The <emphasis>coroutine-function</emphasis>
|
|
must call this <emphasis>boost::coroutines::coroutine<>::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<>::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<>::pull_type</emphasis>
|
|
is invalid; no data value available). Access to the transferred data value
|
|
is given by <emphasis>boost::coroutines::coroutine<>::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"><</phrase><phrase role="keyword">int</phrase><phrase role="special">>::</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">[&](</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"><</phrase><phrase role="keyword">int</phrase><phrase role="special">>::</phrase><phrase role="identifier">push_type</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="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<>::push_type</emphasis>
|
|
from the main-context the framework synthesizes a <emphasis>coroutine<>::pull_type</emphasis>
|
|
associated with the <emphasis>coroutine<>::push_type</emphasis> instance
|
|
in the main-context. The synthesized <emphasis>coroutine<>::pull_type</emphasis>
|
|
is passed as argument to <emphasis>coroutine-function</emphasis>. The main-context
|
|
must call this <emphasis>boost::coroutines::coroutine<>::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<>::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"><</phrase><phrase role="keyword">int</phrase><phrase role="special">>::</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">[&](</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"><</phrase><phrase role="keyword">int</phrase><phrase role="special">>::</phrase><phrase role="identifier">pull_type</phrase><phrase role="special">&</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"><<</phrase> <phrase role="identifier">i</phrase> <phrase role="special"><<</phrase> <phrase role="string">" "</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"><</phrase><phrase role="keyword">int</phrase><phrase role="special">></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<>::pull_type::get()</emphasis>.
|
|
</para>
|
|
<para>
|
|
Splitting-up the access of parameters from context switch function enables
|
|
to check if <emphasis>coroutine<>::pull_type</emphasis> is valid after
|
|
return from <emphasis>boost::coroutines::coroutine<>::pull_type::operator()</emphasis>,
|
|
e.g. <emphasis>coroutine<>::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"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">tuple</phrase><phrase role="special"><</phrase><phrase role="keyword">int</phrase><phrase role="special">,</phrase><phrase role="keyword">int</phrase><phrase role="special">>>::</phrase><phrase role="identifier">push_type</phrase> <phrase role="identifier">sink</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"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">tuple</phrase><phrase role="special"><</phrase><phrase role="keyword">int</phrase><phrase role="special">,</phrase><phrase role="keyword">int</phrase><phrase role="special">>>::</phrase><phrase role="identifier">pull_type</phrase><phrase role="special">&</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<>::pull_type</emphasis>'s
|
|
<emphasis>coroutine-function</emphasis> before its first call to <emphasis>boost::coroutines::coroutine<>::push_type::operator()</emphasis>
|
|
will be re-thrown by the <emphasis>coroutine<>::pull_type</emphasis>
|
|
constructor. After a <emphasis>coroutine<>::pull_type</emphasis>'s
|
|
<emphasis>coroutine-function</emphasis>'s first call to <emphasis>boost::coroutines::coroutine<>::push_type::operator()</emphasis>,
|
|
any subsequent exception inside that <emphasis>coroutine-function</emphasis>
|
|
will be re-thrown by <emphasis>boost::coroutines::coroutine<>::pull_type::operator()</emphasis>.
|
|
<emphasis>boost::coroutines::coroutine<>::pull_type::get()</emphasis>
|
|
does not throw.
|
|
</para>
|
|
<para>
|
|
An exception thrown inside a <emphasis>coroutine<>::push_type</emphasis>'s
|
|
<emphasis>coroutine-function</emphasis> will be re-thrown by <emphasis>boost::coroutines::coroutine<>::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">&)</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"><<</phrase><phrase role="string">"X()"</phrase><phrase role="special"><<</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
|
|
<phrase role="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"><<</phrase><phrase role="string">"~X()"</phrase><phrase role="special"><<</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
|
|
<phrase role="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"><</phrase><phrase role="keyword">void</phrase><phrase role="special">>::</phrase><phrase role="identifier">push_type</phrase> <phrase role="identifier">sink</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"><</phrase><phrase role="keyword">void</phrase><phrase role="special">>::</phrase><phrase role="identifier">pull_type</phrase><phrase role="special">&</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"><<</phrase><phrase role="string">"fn(): "</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">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"><<</phrase><phrase role="string">"c is complete: "</phrase><phrase role="special"><<</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">boolalpha</phrase><phrase role="special"><<</phrase><phrase role="identifier">c</phrase><phrase role="special">.</phrase><phrase role="identifier">is_complete</phrase><phrase role="special">()<<</phrase><phrase role="string">"\n"</phrase><phrase role="special">;</phrase>
|
|
<phrase role="special">}</phrase>
|
|
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase><phrase role="special"><<</phrase><phrase role="string">"Done"</phrase><phrase role="special"><<</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="identifier">output</phrase><phrase role="special">:</phrase>
|
|
<phrase role="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<>::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"><</phrase> <phrase role="keyword">int</phrase> <phrase role="special">>::</phrase><phrase role="identifier">pull_type</phrase> <phrase role="identifier">source</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"><</phrase> <phrase role="keyword">int</phrase> <phrase role="special">>::</phrase><phrase role="identifier">push_type</phrase> <phrase role="special">&</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">++<</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"><<</phrase> <phrase role="identifier">i</phrase> <phrase role="special"><<</phrase> <phrase role="string">" "</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"\nDone"</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
|
|
|
|
<phrase role="identifier">output</phrase><phrase role="special">:</phrase>
|
|
<phrase role="number">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<>::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"><</phrase><phrase role="keyword">int</phrase><phrase role="special">>::</phrase><phrase role="identifier">push_type</phrase> <phrase role="identifier">sink</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"><</phrase><phrase role="keyword">int</phrase><phrase role="special">>::</phrase><phrase role="identifier">pull_type</phrase><phrase role="special">&</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"><<</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="string">" "</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"><</phrase><phrase role="keyword">int</phrase><phrase role="special">></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<>::pull_type</emphasis>/<emphasis>coroutine<>::push_type</emphasis>
|
|
becomes complete, e.g. <emphasis>boost::coroutines::coroutine<>::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<>::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"><>::</phrase><phrase
|
|
role="identifier">pull_type</phrase></code></link></title>
|
|
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special"><</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">></phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">R</phrase> <phrase role="special">></phrase>
|
|
<phrase role="keyword">class</phrase> <phrase role="identifier">coroutine</phrase><phrase role="special"><>::</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"><</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"><</phrase> <phrase role="identifier">coroutine</phrase> <phrase role="special">></phrase>
|
|
<phrase role="special">></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">&</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">&</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">&</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"><</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"><</phrase> <phrase role="identifier">coroutine</phrase> <phrase role="special">></phrase>
|
|
<phrase role="special">></phrase>
|
|
<phrase role="identifier">pull_type</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</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">&</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">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">);</phrase>
|
|
|
|
<phrase role="identifier">pull_type</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">pull_type</phrase> <phrase role="special">&&</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">&</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">&</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"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">R</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"><</phrase> <phrase role="identifier">R</phrase> <phrase role="special">></phrase> <phrase role="special">&</phrase> <phrase role="identifier">l</phrase><phrase role="special">,</phrase> <phrase role="identifier">pull_type</phrase><phrase role="special"><</phrase> <phrase role="identifier">R</phrase> <phrase role="special">></phrase> <phrase role="special">&</phrase> <phrase role="identifier">r</phrase><phrase role="special">);</phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">R</phrase> <phrase role="special">></phrase>
|
|
<phrase role="identifier">range_iterator</phrase><phrase role="special"><</phrase> <phrase role="identifier">pull_type</phrase><phrase role="special"><</phrase> <phrase role="identifier">R</phrase> <phrase role="special">></phrase> <phrase role="special">>::</phrase><phrase role="identifier">type</phrase> <phrase role="identifier">begin</phrase><phrase role="special">(</phrase> <phrase role="identifier">pull_type</phrase><phrase role="special"><</phrase> <phrase role="identifier">R</phrase> <phrase role="special">></phrase> <phrase role="special">&);</phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">R</phrase> <phrase role="special">></phrase>
|
|
<phrase role="identifier">range_iterator</phrase><phrase role="special"><</phrase> <phrase role="identifier">pull_type</phrase><phrase role="special"><</phrase> <phrase role="identifier">R</phrase> <phrase role="special">></phrase> <phrase role="special">>::</phrase><phrase role="identifier">type</phrase> <phrase role="identifier">end</phrase><phrase role="special">(</phrase> <phrase role="identifier">pull_type</phrase><phrase role="special"><</phrase> <phrase role="identifier">R</phrase> <phrase role="special">></phrase> <phrase role="special">&);</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"><</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">></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">&</phrase> <phrase role="identifier">attr</phrase><phrase
|
|
role="special">,</phrase> <phrase role="identifier">StackAllocator</phrase>
|
|
<phrase role="keyword">const</phrase><phrase role="special">&</phrase>
|
|
<phrase role="identifier">stack_alloc</phrase><phrase role="special">,</phrase>
|
|
<phrase role="identifier">Allocator</phrase> <phrase role="keyword">const</phrase><phrase
|
|
role="special">&</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> > minimum_stacksize(),
|
|
<code><phrase role="identifier">size</phrase></code> < 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"><</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">></phrase> <phrase role="identifier">pull_type</phrase><phrase
|
|
role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase
|
|
role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase
|
|
role="special">,</phrase> <phrase role="identifier">attributes</phrase>
|
|
<phrase role="keyword">const</phrase><phrase role="special">&</phrase>
|
|
<phrase role="identifier">attr</phrase><phrase role="special">,</phrase>
|
|
<phrase role="identifier">StackAllocator</phrase> <phrase role="keyword">const</phrase><phrase
|
|
role="special">&</phrase> <phrase role="identifier">stack_alloc</phrase><phrase
|
|
role="special">,</phrase> <phrase role="identifier">Allocator</phrase>
|
|
<phrase role="keyword">const</phrase><phrase role="special">&</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> > minimum_stacksize(),
|
|
<code><phrase role="identifier">size</phrase></code> < 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">&&</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">&</phrase>
|
|
<phrase role="keyword">operator</phrase><phrase role="special">=(</phrase>
|
|
<phrase role="identifier">pull_type</phrase> <phrase role="special">&&</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"><></phrase>
|
|
<phrase role="special">&</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"><</phrase><phrase role="identifier">R</phrase><phrase role="special">>::</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">&</phrase> <phrase role="identifier">coroutine</phrase><phrase role="special"><</phrase><phrase role="identifier">R</phrase><phrase role="special">&>::</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"><</phrase><phrase role="keyword">void</phrase><phrase role="special">></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<>::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">&</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"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">R</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"><</phrase> <phrase role="identifier">R</phrase> <phrase role="special">></phrase> <phrase role="special">&</phrase> <phrase role="identifier">l</phrase><phrase role="special">,</phrase> <phrase role="identifier">pull_type</phrase><phrase role="special"><</phrase> <phrase role="identifier">R</phrase> <phrase role="special">></phrase> <phrase role="special">&</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"><</phrase>
|
|
<phrase role="identifier">R</phrase> <phrase role="special">></phrase>
|
|
<phrase role="special">&)</phrase></code></link>
|
|
</bridgehead>
|
|
<programlisting><phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">R</phrase> <phrase role="special">></phrase>
|
|
<phrase role="identifier">range_iterator</phrase><phrase role="special"><</phrase> <phrase role="identifier">pull_type</phrase><phrase role="special"><</phrase> <phrase role="identifier">R</phrase> <phrase role="special">></phrase> <phrase role="special">>::</phrase><phrase role="identifier">type</phrase> <phrase role="identifier">begin</phrase><phrase role="special">(</phrase> <phrase role="identifier">pull_type</phrase><phrase role="special"><</phrase> <phrase role="identifier">R</phrase> <phrase role="special">></phrase> <phrase role="special">&);</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"><</phrase>
|
|
<phrase role="identifier">R</phrase> <phrase role="special">></phrase>
|
|
<phrase role="special">&)</phrase></code></link>
|
|
</bridgehead>
|
|
<programlisting><phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">R</phrase> <phrase role="special">></phrase>
|
|
<phrase role="identifier">range_iterator</phrase><phrase role="special"><</phrase> <phrase role="identifier">pull_type</phrase><phrase role="special"><</phrase> <phrase role="identifier">R</phrase> <phrase role="special">></phrase> <phrase role="special">>::</phrase><phrase role="identifier">type</phrase> <phrase role="identifier">end</phrase><phrase role="special">(</phrase> <phrase role="identifier">pull_type</phrase><phrase role="special"><</phrase> <phrase role="identifier">R</phrase> <phrase role="special">></phrase> <phrase role="special">&);</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"><>::</phrase><phrase
|
|
role="identifier">push_type</phrase></code></link></title>
|
|
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special"><</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">></phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">></phrase>
|
|
<phrase role="keyword">class</phrase> <phrase role="identifier">coroutine</phrase><phrase role="special"><>::</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"><</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"><</phrase> <phrase role="identifier">coroutine</phrase> <phrase role="special">></phrase>
|
|
<phrase role="special">></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">&</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">&</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">&</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"><</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"><</phrase> <phrase role="identifier">coroutine</phrase> <phrase role="special">></phrase>
|
|
<phrase role="special">></phrase>
|
|
<phrase role="identifier">push_type</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</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">&</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">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">);</phrase>
|
|
|
|
<phrase role="identifier">push_type</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">push_type</phrase> <phrase role="special">&&</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">&</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">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="identifier">Arg</phrase><phrase role="special">&&</phrase> <phrase role="identifier">arg</phrase><phrase role="special">);</phrase>
|
|
<phrase role="special">};</phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Arg</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"><</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">></phrase> <phrase role="special">&</phrase> <phrase role="identifier">l</phrase><phrase role="special">,</phrase> <phrase role="identifier">push_type</phrase><phrase role="special"><</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">></phrase> <phrase role="special">&</phrase> <phrase role="identifier">r</phrase><phrase role="special">);</phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">></phrase>
|
|
<phrase role="identifier">range_iterator</phrase><phrase role="special"><</phrase> <phrase role="identifier">push_type</phrase><phrase role="special"><</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">></phrase> <phrase role="special">>::</phrase><phrase role="identifier">type</phrase> <phrase role="identifier">begin</phrase><phrase role="special">(</phrase> <phrase role="identifier">push_type</phrase><phrase role="special"><</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">></phrase> <phrase role="special">&);</phrase>
|
|
|
|
<phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">></phrase>
|
|
<phrase role="identifier">range_iterator</phrase><phrase role="special"><</phrase> <phrase role="identifier">push_type</phrase><phrase role="special"><</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">></phrase> <phrase role="special">>::</phrase><phrase role="identifier">type</phrase> <phrase role="identifier">end</phrase><phrase role="special">(</phrase> <phrase role="identifier">push_type</phrase><phrase role="special"><</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">></phrase> <phrase role="special">&);</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"><</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">></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">&</phrase> <phrase role="identifier">attr</phrase><phrase
|
|
role="special">,</phrase> <phrase role="identifier">StackAllocator</phrase>
|
|
<phrase role="keyword">const</phrase><phrase role="special">&</phrase>
|
|
<phrase role="identifier">stack_alloc</phrase><phrase role="special">,</phrase>
|
|
<phrase role="identifier">Allocator</phrase> <phrase role="keyword">const</phrase><phrase
|
|
role="special">&</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> > minimum_stacksize(),
|
|
<code><phrase role="identifier">size</phrase></code> < 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"><</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">></phrase> <phrase role="identifier">push_type</phrase><phrase
|
|
role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase
|
|
role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase
|
|
role="special">,</phrase> <phrase role="identifier">attributes</phrase>
|
|
<phrase role="keyword">const</phrase><phrase role="special">&</phrase>
|
|
<phrase role="identifier">attr</phrase><phrase role="special">,</phrase>
|
|
<phrase role="identifier">StackAllocator</phrase> <phrase role="keyword">const</phrase><phrase
|
|
role="special">&</phrase> <phrase role="identifier">stack_alloc</phrase><phrase
|
|
role="special">,</phrase> <phrase role="identifier">Allocator</phrase>
|
|
<phrase role="keyword">const</phrase><phrase role="special">&</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> > minimum_stacksize(),
|
|
<code><phrase role="identifier">size</phrase></code> < 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">&&</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">&</phrase>
|
|
<phrase role="keyword">operator</phrase><phrase role="special">=(</phrase>
|
|
<phrase role="identifier">push_type</phrase> <phrase role="special">&&</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"><></phrase>
|
|
<phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase
|
|
role="special">()(</phrase><phrase role="identifier">Arg</phrase><phrase
|
|
role="special">&&</phrase> <phrase role="identifier">arg</phrase><phrase
|
|
role="special">)</phrase></code></link>
|
|
</bridgehead>
|
|
<programlisting><phrase role="identifier">push_type</phrase><phrase role="special">&</phrase> <phrase role="identifier">coroutine</phrase><phrase role="special"><</phrase><phrase role="identifier">Arg</phrase><phrase role="special">>::</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">&);</phrase>
|
|
<phrase role="identifier">push_type</phrase><phrase role="special">&</phrase> <phrase role="identifier">coroutine</phrase><phrase role="special"><</phrase><phrase role="identifier">Arg</phrase><phrase role="special">>::</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">&&);</phrase>
|
|
<phrase role="identifier">push_type</phrase><phrase role="special">&</phrase> <phrase role="identifier">coroutine</phrase><phrase role="special"><</phrase><phrase role="identifier">Arg</phrase><phrase role="special">&>::</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">&);</phrase>
|
|
<phrase role="identifier">push_type</phrase><phrase role="special">&</phrase> <phrase role="identifier">coroutine</phrase><phrase role="special"><</phrase><phrase role="keyword">void</phrase><phrase role="special">>::</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">&</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<></emphasis>
|
|
containing the arguments passed to <emphasis>boost::coroutines::coroutine<>::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"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Arg</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"><</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">></phrase> <phrase role="special">&</phrase> <phrase role="identifier">l</phrase><phrase role="special">,</phrase> <phrase role="identifier">push_type</phrase><phrase role="special"><</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">></phrase> <phrase role="special">&</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"><</phrase>
|
|
<phrase role="identifier">Arg</phrase> <phrase role="special">></phrase>
|
|
<phrase role="special">&)</phrase></code></link>
|
|
</bridgehead>
|
|
<programlisting><phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">></phrase>
|
|
<phrase role="identifier">range_iterator</phrase><phrase role="special"><</phrase> <phrase role="identifier">push_type</phrase><phrase role="special"><</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">></phrase> <phrase role="special">>::</phrase><phrase role="identifier">type</phrase> <phrase role="identifier">begin</phrase><phrase role="special">(</phrase> <phrase role="identifier">push_type</phrase><phrase role="special"><</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">></phrase> <phrase role="special">&);</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"><</phrase>
|
|
<phrase role="identifier">Arg</phrase> <phrase role="special">></phrase>
|
|
<phrase role="special">&)</phrase></code></link>
|
|
</bridgehead>
|
|
<programlisting><phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">></phrase>
|
|
<phrase role="identifier">range_iterator</phrase><phrase role="special"><</phrase> <phrase role="identifier">push_type</phrase><phrase role="special"><</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">></phrase> <phrase role="special">>::</phrase><phrase role="identifier">type</phrase> <phrase role="identifier">end</phrase><phrase role="special">(</phrase> <phrase role="identifier">push_type</phrase><phrase role="special"><</phrase> <phrase role="identifier">Arg</phrase> <phrase role="special">></phrase> <phrase role="special">&);</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">&,</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">&);</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">&</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">></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">&&</phrase>
|
|
<phrase role="special">(</phrase> <phrase role="identifier">maximum_stacksize</phrase><phrase
|
|
role="special">()</phrase> <phrase role="special"><</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">&</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">></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">&&</phrase> <phrase role="special">(</phrase>
|
|
<phrase role="identifier">maximum_stacksize</phrase><phrase role="special">()</phrase>
|
|
<phrase role="special"><</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">&,</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">&);</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">&</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">></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">&&</phrase>
|
|
<phrase role="special">(</phrase> <phrase role="identifier">maximum_stacksize</phrase><phrase
|
|
role="special">()</phrase> <phrase role="special"><</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">&</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">></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">&&</phrase> <phrase role="special">(</phrase>
|
|
<phrase role="identifier">maximum_stacksize</phrase><phrase role="special">()</phrase>
|
|
<phrase role="special"><</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>
|