1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
3 <library id="context" name="Context" dirname="context" last-revision="$Date: 2019/10/02 06:15:27 $"
4 xmlns:xi="http://www.w3.org/2001/XInclude">
8 <firstname>Oliver</firstname> <surname>Kowalke</surname>
12 <year>2014</year> <holder>Oliver Kowalke</holder>
14 <legalnotice id="context.legal">
16 Distributed under the Boost Software License, Version 1.0. (See accompanying
17 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>)
21 C++ Library for swiching different user ctx
23 <librarycategory name="category:text"></librarycategory>
25 <title>Context</title>
26 <section id="context.overview">
27 <title><link linkend="context.overview">Overview</link></title>
29 <emphasis role="bold">Boost.Context</emphasis> is a foundational library that
30 provides a sort of cooperative multitasking on a single thread. By providing
31 an abstraction of the current execution state in the current thread, including
32 the stack (with local variables) and stack pointer, all registers and CPU flags,
33 and the instruction pointer, a execution context represents a specific point
34 in the application's execution path. This is useful for building higher-level
35 abstractions, like <emphasis>coroutines</emphasis>, <emphasis>cooperative threads
36 (userland threads)</emphasis> or an equivalent to <ulink url="http://msdn.microsoft.com/en-us/library/9k7k7cf0%28v=vs.80%29.aspx">C#
37 keyword <emphasis>yield</emphasis></ulink> in C++.
40 <link linkend="cc"><emphasis>callcc()</emphasis></link>/<link linkend="cc"><emphasis>continuation</emphasis></link>
41 provides the means to suspend the current execution path and to transfer execution
42 control, thereby permitting another context to run on the current thread. This
43 state full transfer mechanism enables a context to suspend execution from within
44 nested functions and, later, to resume from where it was suspended. While the
45 execution path represented by a <link linkend="cc"><emphasis>continuation</emphasis></link>
46 only runs on a single thread, it can be migrated to another thread at any given
50 A <ulink url="http://en.wikipedia.org/wiki/Context_switch">context switch</ulink>
51 between threads requires system calls (involving the OS kernel), which can
52 cost more than thousand CPU cycles on x86 CPUs. By contrast, transferring control
53 vias <link linkend="cc"><emphasis>callcc()</emphasis></link>/<link linkend="cc"><emphasis>continuation</emphasis></link>
54 requires only few CPU cycles because it does not involve system calls as it
55 is done within a single thread.
58 All functions and classes are contained in the namespace <emphasis>boost::context</emphasis>.
62 This library requires C++11!
67 Windows using fcontext_t: turn off global program optimization (/GL) and
68 change /EHsc (compiler assumes that functions declared as extern "C"
69 never throw a C++ exception) to /EHs (tells compiler assumes that functions
70 declared as extern "C" may throw an exception).
74 <section id="context.requirements">
75 <title><link linkend="context.requirements">Requirements</link></title>
77 If <emphasis role="bold">Boost.Context</emphasis> uses fcontext_t (the default)
78 as its implementation, it must be built for the particular compiler(s) and
79 CPU architecture(s) being targeted. Using <link linkend="implementation"><emphasis>fcontext_t</emphasis></link>,
80 <emphasis role="bold">Boost.Context</emphasis> includes assembly code and,
81 therefore, requires GNU as and GNU preprocessor for supported POSIX systems,
82 MASM for Windows/x86 systems and ARMasm for Windows/arm systems.
86 MASM64 (ml64.exe) is a part of Microsoft's Windows Driver Kit.
91 Please note that <code><phrase role="identifier">address</phrase><phrase
92 role="special">-</phrase><phrase role="identifier">model</phrase><phrase
93 role="special">=</phrase><phrase role="number">64</phrase></code> must be
94 given to bjam command line on 64bit Windows for 64bit build; otherwise 32bit
95 code will be generated.
100 For cross-compiling the lib you must specify certain additional properties
101 at bjam command line: <code><phrase role="identifier">target</phrase><phrase
102 role="special">-</phrase><phrase role="identifier">os</phrase></code>, <code><phrase
103 role="identifier">abi</phrase></code>, <code><phrase role="identifier">binary</phrase><phrase
104 role="special">-</phrase><phrase role="identifier">format</phrase></code>,
105 <code><phrase role="identifier">architecture</phrase></code> and <code><phrase
106 role="identifier">address</phrase><phrase role="special">-</phrase><phrase
107 role="identifier">model</phrase></code>.
112 Windows using fcontext_t: for safe SEH the property 'asmflags=\safeseh' must
113 be specified at bjam command line.
118 Windows using fcontext_t: turn off global program optimization (/GL) and
119 change /EHsc (compiler assumes that functions declared as extern "C"
120 never throw a C++ exception) to /EHs (tells compiler assumes that functions
121 declared as extern "C" may throw an exception).
125 Because this library uses C++11 extensively, it requires a compatible compiler.
126 Known minimum working versions are as follows: Microsoft Visual Studio 2015
127 (msvc-14.0), GCC 4.8 (with -std=c++11), Clang 3.4 (with -std=c++11). Other
128 compilers may work, if they support the following language features: auto declarations,
129 constexpr, defaulted functions, final, hdr thread, hdr tuple, lambdas, noexcept,
130 nullptr, rvalue references, template aliases. thread local, variadic templates.
133 <section id="context.ff">
134 <title><anchor id="ff"/><link linkend="context.ff">Context switching with fibers</link></title>
137 <emphasis>fiber</emphasis> is the reference implementation of C++ proposal
138 <ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0876r0.pdf">P0876R0:
139 fibers without scheduler</ulink>.
143 A <emphasis>fiber</emphasis> represents the state of the control flow of a
144 program at a given point in time. Fibers can be suspended and resumed later
145 in order to change the control flow of a program.
148 Modern micro-processors are registers machines; the content of processor registers
149 represent a fiber of the executed program at a given point in time. Operating
150 systems simulate parallel execution of programs on a single processor by switching
151 between programs (context switch) by preserving and restoring the fiber, e.g.
152 the content of all registers.
154 <bridgehead renderas="sect3" id="context.ff.h0">
155 <phrase id="context.ff._link_linkend__ff___emphasis_fiber__emphasis___link_"/><link
156 linkend="context.ff._link_linkend__ff___emphasis_fiber__emphasis___link_"><link
157 linkend="ff"><emphasis>fiber</emphasis></link></link>
160 <link linkend="ff"><emphasis>fiber</emphasis></link> captures the current fiber
161 (the rest of the computation; code after <link linkend="ff"><emphasis>fiber</emphasis></link>)
162 and triggers a context switch. The context switch is achieved by preserving
163 certain registers (including instruction and stack pointer), defined by the
164 calling convention of the ABI, of the current fiber and restoring those registers
165 of the resumed fiber. The control flow of the resumed fiber continues. The
166 current fiber is suspended and passed as argument to the resumed fiber.
169 <link linkend="ff"><emphasis>fiber</emphasis></link> expects a <emphasis>context-function</emphasis>
170 with signature <code><phrase role="char">'fiber(fiber && f)'</phrase></code>.
171 The parameter <code><phrase role="identifier">f</phrase></code> represents
172 the current fiber from which this fiber was resumed (e.g. that has called
173 <link linkend="ff"><emphasis>fiber</emphasis></link>).
176 On return the <emphasis>context-function</emphasis> of the current fiber has
177 to specify an <link linkend="ff"><emphasis>fiber</emphasis></link> to which
178 the execution control is transferred after termination of the current fiber.
181 If an instance with valid state goes out of scope and the <emphasis>context-function</emphasis>
182 has not yet returned, the stack is traversed in order to access the control
183 structure (address stored at the first stack frame) and fiber's stack is deallocated
184 via the <emphasis>StackAllocator</emphasis>.
188 <link linkend="segmented"><emphasis>Segmented stacks</emphasis></link> are
189 supported by <link linkend="ff"><emphasis>fiber</emphasis></link> using
190 <link linkend="implementation"><emphasis>ucontext_t</emphasis></link>.
194 <link linkend="ff"><emphasis>fiber</emphasis></link> represents a <emphasis>fiber</emphasis>;
195 it contains the content of preserved registers and manages the associated stack
196 (allocation/deallocation). <link linkend="ff"><emphasis>fiber</emphasis></link>
197 is a one-shot fiber - it can be used only once, after calling <emphasis>continuation::resume()</emphasis>
198 or <emphasis>continuation::resume_with()</emphasis> it is invalidated.
201 <link linkend="ff"><emphasis>fiber</emphasis></link> is only move-constructible
205 As a first-class object <link linkend="ff"><emphasis>fiber</emphasis></link>
206 can be applied to and returned from a function, assigned to a variable or stored
210 A fiber is continued by calling <code><phrase role="identifier">resume</phrase><phrase
211 role="special">()</phrase></code>/<code><phrase role="identifier">resume_with</phrase><phrase
212 role="special">()</phrase></code>.
214 <bridgehead renderas="sect3" id="context.ff.h1">
215 <phrase id="context.ff.usage"/><link linkend="context.ff.usage">Usage</link>
217 <programlisting><phrase role="keyword">namespace</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">=</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">;</phrase>
218 <phrase role="keyword">int</phrase> <phrase role="identifier">a</phrase><phrase role="special">;</phrase>
219 <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">source</phrase><phrase role="special">{[&</phrase><phrase role="identifier">a</phrase><phrase role="special">](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase><phrase role="special">&&</phrase> <phrase role="identifier">sink</phrase><phrase role="special">){</phrase>
220 <phrase role="identifier">a</phrase><phrase role="special">=</phrase><phrase role="number">0</phrase><phrase role="special">;</phrase>
221 <phrase role="keyword">int</phrase> <phrase role="identifier">b</phrase><phrase role="special">=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
222 <phrase role="keyword">for</phrase><phrase role="special">(;;){</phrase>
223 <phrase role="identifier">sink</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">sink</phrase><phrase role="special">).</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
224 <phrase role="keyword">int</phrase> <phrase role="identifier">next</phrase><phrase role="special">=</phrase><phrase role="identifier">a</phrase><phrase role="special">+</phrase><phrase role="identifier">b</phrase><phrase role="special">;</phrase>
225 <phrase role="identifier">a</phrase><phrase role="special">=</phrase><phrase role="identifier">b</phrase><phrase role="special">;</phrase>
226 <phrase role="identifier">b</phrase><phrase role="special">=</phrase><phrase role="identifier">next</phrase><phrase role="special">;</phrase>
227 <phrase role="special">}</phrase>
228 <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">sink</phrase><phrase role="special">);</phrase>
229 <phrase role="special">}};</phrase>
230 <phrase role="keyword">for</phrase> <phrase role="special">(</phrase><phrase role="keyword">int</phrase> <phrase role="identifier">j</phrase><phrase role="special">=</phrase><phrase role="number">0</phrase><phrase role="special">;</phrase><phrase role="identifier">j</phrase><phrase role="special"><</phrase><phrase role="number">10</phrase><phrase role="special">;++</phrase><phrase role="identifier">j</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
231 <phrase role="identifier">source</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">source</phrase><phrase role="special">).</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
232 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">a</phrase> <phrase role="special"><<</phrase> <phrase role="string">" "</phrase><phrase role="special">;</phrase>
233 <phrase role="special">}</phrase>
235 <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
236 <phrase role="number">0</phrase> <phrase role="number">1</phrase> <phrase role="number">1</phrase> <phrase role="number">2</phrase> <phrase role="number">3</phrase> <phrase role="number">5</phrase> <phrase role="number">8</phrase> <phrase role="number">13</phrase> <phrase role="number">21</phrase> <phrase role="number">34</phrase>
239 This simple example demonstrates the basic usage of <link linkend="ff"><emphasis>fiber</emphasis></link>
240 as a <emphasis>generator</emphasis>. The fiber <code><phrase role="identifier">sink</phrase></code>
241 represents the <emphasis>main</emphasis>-fiber (function <code><phrase role="identifier">main</phrase><phrase
242 role="special">()</phrase></code>). <code><phrase role="identifier">sink</phrase></code>
243 is captured (current-fiber) by invoking <link linkend="ff"><emphasis>fiber</emphasis></link>
244 and passed as parameter to the lambda.
247 Because the state is invalidated (one-shot fiber) by each call of <emphasis>continuation::resume()</emphasis>,
248 the new state of the <link linkend="ff"><emphasis>fiber</emphasis></link>,
249 returned by <emphasis>continuation::resume()</emphasis>, needs to be assigned
250 to <code><phrase role="identifier">sink</phrase></code> after each call. In
251 order to express the invalidation of the resumed fiber, the member functions
252 <code><phrase role="identifier">resume</phrase><phrase role="special">()</phrase></code>
253 and <code><phrase role="identifier">resume_with</phrase><phrase role="special">()</phrase></code>
254 are rvalue-ref qualified. Both functions bind only to rvalues. Thus an lvalue
255 fiber must be casted to an rvalue via <code><phrase role="identifier">std</phrase><phrase
256 role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">()</phrase></code>.
259 The lambda that calculates the Fibonacci numbers is executed inside the fiber
260 represented by <code><phrase role="identifier">source</phrase></code>. Calculated
261 Fibonacci numbers are transferred between the two fibers via variable <code><phrase
262 role="identifier">a</phrase></code> (lambda capture reference).
265 The locale variables <code><phrase role="identifier">b</phrase></code> and
266 <code> <phrase role="identifier">next</phrase></code> remain their values during
267 each context switch. This is possible due <code><phrase role="identifier">source</phrase></code>
268 has its own stack and the stack is exchanged by each context switch.
270 <bridgehead renderas="sect3" id="context.ff.h2">
271 <phrase id="context.ff.parameter_passing"/><link linkend="context.ff.parameter_passing">Parameter
275 Data can be transferred between two fibers via global pointers, calling wrappers
276 (like <code><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
277 role="identifier">bind</phrase></code>) or lambda captures.
279 <programlisting><phrase role="keyword">namespace</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">=</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">;</phrase>
280 <phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase><phrase role="special">=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
281 <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">f1</phrase><phrase role="special">{[&</phrase><phrase role="identifier">i</phrase><phrase role="special">](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase><phrase role="special">&&</phrase> <phrase role="identifier">f2</phrase><phrase role="special">){</phrase>
282 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">"inside f1,i==%d\n"</phrase><phrase role="special">,</phrase><phrase role="identifier">i</phrase><phrase role="special">);</phrase>
283 <phrase role="identifier">i</phrase><phrase role="special">+=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
284 <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">f2</phrase><phrase role="special">).</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
285 <phrase role="special">}};</phrase>
286 <phrase role="identifier">f1</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">f1</phrase><phrase role="special">).</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
287 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">"i==%d\n"</phrase><phrase role="special">,</phrase><phrase role="identifier">i</phrase><phrase role="special">);</phrase>
289 <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
290 <phrase role="identifier">inside</phrase> <phrase role="identifier">c1</phrase><phrase role="special">,</phrase><phrase role="identifier">i</phrase><phrase role="special">==</phrase><phrase role="number">1</phrase>
291 <phrase role="identifier">i</phrase><phrase role="special">==</phrase><phrase role="number">2</phrase>
294 <code><phrase role="identifier">f1</phrase><phrase role="special">.</phrase><phrase
295 role="identifier">resume</phrase><phrase role="special">()</phrase></code>
296 enters the lambda in fiber represented by <code><phrase role="identifier">f1</phrase></code>
297 with lambda capture reference <code><phrase role="identifier">i</phrase><phrase
298 role="special">=</phrase><phrase role="number">1</phrase></code>. The expression
299 <code><phrase role="identifier">f2</phrase><phrase role="special">.</phrase><phrase
300 role="identifier">resume</phrase><phrase role="special">()</phrase></code>
301 resumes the fiber <code><phrase role="identifier">f2</phrase></code>. On return
302 of <code><phrase role="identifier">f1</phrase><phrase role="special">.</phrase><phrase
303 role="identifier">resume</phrase><phrase role="special">()</phrase></code>,
304 the variable <code><phrase role="identifier">i</phrase></code> has the value
305 of <code><phrase role="identifier">i</phrase><phrase role="special">+</phrase><phrase
306 role="number">1</phrase></code>.
308 <bridgehead renderas="sect3" id="context.ff.h3">
309 <phrase id="context.ff.exception_handling"/><link linkend="context.ff.exception_handling">Exception
313 If the function executed inside a <emphasis>context-function</emphasis> emits
314 ans exception, the application is terminated by calling <code><phrase role="identifier">std</phrase><phrase
315 role="special">::</phrase><phrase role="identifier">terminate</phrase><phrase
316 role="special">()</phrase></code>. <code><phrase role="identifier">std</phrase><phrase
317 role="special">::</phrase><phrase role="identifier">exception_ptr</phrase></code>
318 can be used to transfer exceptions between different fibers.
322 Do not jump from inside a catch block and then re-throw the exception in
326 <anchor id="ff_ontop"/>
327 <bridgehead renderas="sect3" id="context.ff.h4">
328 <phrase id="context.ff.executing_function_on_top_of_a_fiber"/><link linkend="context.ff.executing_function_on_top_of_a_fiber">Executing
329 function on top of a fiber</link>
332 Sometimes it is useful to execute a new function on top of a resumed fiber.
333 For this purpose <emphasis>continuation::resume_with()</emphasis> has to be
334 used. The function passed as argument must accept a rvalue reference to <link
335 linkend="ff"><emphasis>fiber</emphasis></link> and return <code><phrase role="keyword">void</phrase></code>.
337 <programlisting><phrase role="keyword">namespace</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">=</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">;</phrase>
338 <phrase role="keyword">int</phrase> <phrase role="identifier">data</phrase><phrase role="special">=</phrase><phrase role="number">0</phrase><phrase role="special">;</phrase>
339 <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">f1</phrase><phrase role="special">{[&</phrase><phrase role="identifier">data</phrase><phrase role="special">](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase><phrase role="special">&&</phrase> <phrase role="identifier">f2</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
340 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f1: entered first time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
341 <phrase role="identifier">data</phrase><phrase role="special">+=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
342 <phrase role="identifier">f2</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">f2</phrase><phrase role="special">).</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
343 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f1: entered second time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
344 <phrase role="identifier">data</phrase><phrase role="special">+=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
345 <phrase role="identifier">f2</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">f2</phrase><phrase role="special">).</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
346 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f1: entered third time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
347 <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">f2</phrase><phrase role="special">);</phrase>
348 <phrase role="special">}};</phrase>
349 <phrase role="identifier">f1</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">f1</phrase><phrase role="special">).</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
350 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f1: returned first time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
351 <phrase role="identifier">data</phrase><phrase role="special">+=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
352 <phrase role="identifier">f1</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">f1</phrase><phrase role="special">).</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
353 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f1: returned second time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
354 <phrase role="identifier">data</phrase><phrase role="special">+=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
355 <phrase role="identifier">f1</phrase><phrase role="special">=</phrase><phrase role="identifier">f1</phrase><phrase role="special">.</phrase><phrase role="identifier">resume_with</phrase><phrase role="special">([&</phrase><phrase role="identifier">data</phrase><phrase role="special">](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase><phrase role="special">&&</phrase> <phrase role="identifier">f2</phrase><phrase role="special">){</phrase>
356 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f2: entered: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
357 <phrase role="identifier">data</phrase><phrase role="special">=-</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
358 <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">f2</phrase><phrase role="special">);</phrase>
359 <phrase role="special">});</phrase>
360 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f1: returned third time"</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
362 <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
363 <phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">entered</phrase> <phrase role="identifier">first</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="number">0</phrase>
364 <phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">returned</phrase> <phrase role="identifier">first</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase>
365 <phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">entered</phrase> <phrase role="identifier">second</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="number">2</phrase>
366 <phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">returned</phrase> <phrase role="identifier">second</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="number">3</phrase>
367 <phrase role="identifier">f2</phrase><phrase role="special">:</phrase> <phrase role="identifier">entered</phrase><phrase role="special">:</phrase> <phrase role="number">4</phrase>
368 <phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">entered</phrase> <phrase role="identifier">third</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="special">-</phrase><phrase role="number">1</phrase>
369 <phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">returned</phrase> <phrase role="identifier">third</phrase> <phrase role="identifier">time</phrase>
372 The expression <code><phrase role="identifier">f1</phrase><phrase role="special">.</phrase><phrase
373 role="identifier">resume_with</phrase><phrase role="special">(...)</phrase></code>
374 executes a lambda on top of fiber <code><phrase role="identifier">f1</phrase></code>,
375 e.g. an additional stack frame is allocated on top of the stack. This lambda
376 assigns <code><phrase role="special">-</phrase><phrase role="number">1</phrase></code>
377 to <code><phrase role="identifier">data</phrase></code> and returns to the
378 second invocation of <code><phrase role="identifier">f1</phrase><phrase role="special">.</phrase><phrase
379 role="identifier">resume</phrase><phrase role="special">()</phrase></code>.
382 Another option is to execute a function on top of the fiber that throws an
385 <programlisting><phrase role="keyword">namespace</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">=</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">;</phrase>
386 <phrase role="keyword">struct</phrase> <phrase role="identifier">my_exception</phrase> <phrase role="special">:</phrase> <phrase role="keyword">public</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">runtime_error</phrase> <phrase role="special">{</phrase>
387 <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">f</phrase><phrase role="special">;</phrase>
388 <phrase role="identifier">my_exception</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase><phrase role="special">&&</phrase> <phrase role="identifier">f_</phrase><phrase role="special">,</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">what</phrase><phrase role="special">)</phrase> <phrase role="special">:</phrase>
389 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">runtime_error</phrase><phrase role="special">{</phrase> <phrase role="identifier">what</phrase> <phrase role="special">},</phrase>
390 <phrase role="identifier">f</phrase><phrase role="special">{</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">f_</phrase><phrase role="special">)</phrase> <phrase role="special">}</phrase> <phrase role="special">{</phrase>
391 <phrase role="special">}</phrase>
392 <phrase role="special">};</phrase>
394 <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">f</phrase><phrase role="special">{[](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">f</phrase><phrase role="special">)</phrase> <phrase role="special">-></phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="special">{</phrase>
395 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"entered"</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
396 <phrase role="keyword">try</phrase> <phrase role="special">{</phrase>
397 <phrase role="identifier">f</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">f</phrase><phrase role="special">).</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
398 <phrase role="special">}</phrase> <phrase role="keyword">catch</phrase> <phrase role="special">(</phrase><phrase role="identifier">my_exception</phrase> <phrase role="special">&</phrase> <phrase role="identifier">ex</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
399 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cerr</phrase> <phrase role="special"><<</phrase> <phrase role="string">"my_exception: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">ex</phrase><phrase role="special">.</phrase><phrase role="identifier">what</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>
400 <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">ex</phrase><phrase role="special">.</phrase><phrase role="identifier">f</phrase><phrase role="special">);</phrase>
401 <phrase role="special">}</phrase>
402 <phrase role="keyword">return</phrase> <phrase role="special">{};</phrase>
403 <phrase role="special">});</phrase>
404 <phrase role="identifier">f</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">f</phrase><phrase role="special">).</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
405 <phrase role="identifier">f</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">f</phrase><phrase role="special">).</phrase><phrase role="identifier">resume_with</phrase><phrase role="special">([](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">f</phrase><phrase role="special">)</phrase> <phrase role="special">-></phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="special">{</phrase>
406 <phrase role="keyword">throw</phrase> <phrase role="identifier">my_exception</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">f</phrase><phrase role="special">),</phrase><phrase role="string">"abc"</phrase><phrase role="special">);</phrase>
407 <phrase role="keyword">return</phrase> <phrase role="special">{};</phrase>
408 <phrase role="special">});</phrase>
410 <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
411 <phrase role="identifier">entered</phrase>
412 <phrase role="identifier">my_exception</phrase><phrase role="special">:</phrase> <phrase role="identifier">abc</phrase>
415 In this exception <code><phrase role="identifier">my_exception</phrase></code>
416 is throw from a function invoked on-top of fiber <code><phrase role="identifier">f</phrase></code>
417 and catched inside the <code><phrase role="keyword">for</phrase></code>-loop.
419 <bridgehead renderas="sect3" id="context.ff.h5">
420 <phrase id="context.ff.stack_unwinding"/><link linkend="context.ff.stack_unwinding">Stack
424 On construction of <link linkend="ff"><emphasis>fiber</emphasis></link> a stack
425 is allocated. If the <emphasis>context-function</emphasis> returns the stack
426 will be destructed. If the <emphasis>context-function</emphasis> has not yet
427 returned and the destructor of an valid <link linkend="ff"><emphasis>fiber</emphasis></link>
428 instance (e.g. <emphasis>fiber::operator bool()</emphasis> returns <code><phrase
429 role="keyword">true</phrase></code>) is called, the stack will be destructed
434 Code executed by <emphasis>context-function</emphasis> must not prevent the
435 propagation ofs the <emphasis>detail::forced_unwind</emphasis> exception.
436 Absorbing that exception will cause stack unwinding to fail. Thus, any code
437 that catches all exceptions must re-throw any pending <emphasis>detail::forced_unwind</emphasis>
441 <anchor id="ff_prealloc"/>
442 <bridgehead renderas="sect3" id="context.ff.h6">
443 <phrase id="context.ff.allocating_control_structures_on_top_of_stack"/><link
444 linkend="context.ff.allocating_control_structures_on_top_of_stack">Allocating
445 control structures on top of stack</link>
448 Allocating control structures on top of the stack requires to allocated the
449 <emphasis>stack_context</emphasis> and create the control structure with placement
450 new before <link linkend="ff"><emphasis>fiber</emphasis></link> is created.
454 The user is responsible for destructing the control structure at the top
458 <programlisting><phrase role="keyword">namespace</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">=</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">;</phrase>
459 <phrase role="comment">// stack-allocator used for (de-)allocating stack</phrase>
460 <phrase role="identifier">fixedsize_stack</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">(</phrase><phrase role="number">4048</phrase><phrase role="special">);</phrase>
461 <phrase role="comment">// allocate stack space</phrase>
462 <phrase role="identifier">stack_context</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">(</phrase><phrase role="identifier">salloc</phrase><phrase role="special">.</phrase><phrase role="identifier">allocate</phrase><phrase role="special">());</phrase>
463 <phrase role="comment">// reserve space for control structure on top of the stack</phrase>
464 <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">=</phrase><phrase role="keyword">static_cast</phrase><phrase role="special"><</phrase><phrase role="keyword">char</phrase><phrase role="special">*>(</phrase><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase role="identifier">sp</phrase><phrase role="special">)-</phrase><phrase role="keyword">sizeof</phrase><phrase role="special">(</phrase><phrase role="identifier">my_control_structure</phrase><phrase role="special">);</phrase>
465 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">=</phrase><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase role="identifier">size</phrase><phrase role="special">-</phrase><phrase role="keyword">sizeof</phrase><phrase role="special">(</phrase><phrase role="identifier">my_control_structure</phrase><phrase role="special">);</phrase>
466 <phrase role="comment">// placement new creates control structure on reserved space</phrase>
467 <phrase role="identifier">my_control_structure</phrase> <phrase role="special">*</phrase> <phrase role="identifier">cs</phrase><phrase role="special">=</phrase><phrase role="keyword">new</phrase><phrase role="special">(</phrase><phrase role="identifier">sp</phrase><phrase role="special">)</phrase><phrase role="identifier">my_control_structure</phrase><phrase role="special">(</phrase><phrase role="identifier">sp</phrase><phrase role="special">,</phrase><phrase role="identifier">size</phrase><phrase role="special">,</phrase><phrase role="identifier">sctx</phrase><phrase role="special">,</phrase><phrase role="identifier">salloc</phrase><phrase role="special">);</phrase>
468 <phrase role="special">...</phrase>
469 <phrase role="comment">// destructing the control structure</phrase>
470 <phrase role="identifier">cs</phrase><phrase role="special">->~</phrase><phrase role="identifier">my_control_structure</phrase><phrase role="special">();</phrase>
471 <phrase role="special">...</phrase>
472 <phrase role="keyword">struct</phrase> <phrase role="identifier">my_control_structure</phrase> <phrase role="special">{</phrase>
473 <phrase role="comment">// captured fiber</phrase>
474 <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">f</phrase><phrase role="special">;</phrase>
476 <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase> <phrase role="special">></phrase>
477 <phrase role="identifier">my_control_structure</phrase><phrase role="special">(</phrase><phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">,</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">,</phrase><phrase role="identifier">stack_context</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">,</phrase><phrase role="identifier">StackAllocator</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">)</phrase> <phrase role="special">:</phrase>
478 <phrase role="comment">// create captured fiber</phrase>
479 <phrase role="identifier">f</phrase><phrase role="special">{</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg</phrase><phrase role="special">,</phrase><phrase role="identifier">preallocated</phrase><phrase role="special">(</phrase><phrase role="identifier">sp</phrase><phrase role="special">,</phrase><phrase role="identifier">size</phrase><phrase role="special">,</phrase><phrase role="identifier">sctx</phrase><phrase role="special">),</phrase><phrase role="identifier">salloc</phrase><phrase role="special">,</phrase><phrase role="identifier">entry_func</phrase><phrase role="special">}</phrase> <phrase role="special">{</phrase>
480 <phrase role="special">}</phrase>
481 <phrase role="special">...</phrase>
482 <phrase role="special">};</phrase>
484 <bridgehead renderas="sect3" id="context.ff.h7">
485 <phrase id="context.ff.inverting_the_control_flow"/><link linkend="context.ff.inverting_the_control_flow">Inverting
486 the control flow</link>
488 <programlisting><phrase role="keyword">namespace</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">=</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">;</phrase>
489 <phrase role="comment">/*
492 * E ---> T {('+'|'-') T}
493 * T ---> S {('*'|'/') S}
494 * S ---> digit | '(' E ')'
496 <phrase role="keyword">class</phrase> <phrase role="identifier">Parser</phrase><phrase role="special">{</phrase>
497 <phrase role="keyword">char</phrase> <phrase role="identifier">next</phrase><phrase role="special">;</phrase>
498 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">istream</phrase><phrase role="special">&</phrase> <phrase role="identifier">is</phrase><phrase role="special">;</phrase>
499 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">function</phrase><phrase role="special"><</phrase><phrase role="keyword">void</phrase><phrase role="special">(</phrase><phrase role="keyword">char</phrase><phrase role="special">)></phrase> <phrase role="identifier">cb</phrase><phrase role="special">;</phrase>
501 <phrase role="keyword">char</phrase> <phrase role="identifier">pull</phrase><phrase role="special">(){</phrase>
502 <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">char_traits</phrase><phrase role="special"><</phrase><phrase role="keyword">char</phrase><phrase role="special">>::</phrase><phrase role="identifier">to_char_type</phrase><phrase role="special">(</phrase><phrase role="identifier">is</phrase><phrase role="special">.</phrase><phrase role="identifier">get</phrase><phrase role="special">());</phrase>
503 <phrase role="special">}</phrase>
505 <phrase role="keyword">void</phrase> <phrase role="identifier">scan</phrase><phrase role="special">(){</phrase>
506 <phrase role="keyword">do</phrase><phrase role="special">{</phrase>
507 <phrase role="identifier">next</phrase><phrase role="special">=</phrase><phrase role="identifier">pull</phrase><phrase role="special">();</phrase>
508 <phrase role="special">}</phrase>
509 <phrase role="keyword">while</phrase><phrase role="special">(</phrase><phrase role="identifier">isspace</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">));</phrase>
510 <phrase role="special">}</phrase>
512 <phrase role="keyword">public</phrase><phrase role="special">:</phrase>
513 <phrase role="identifier">Parser</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">is_</phrase><phrase role="special">,</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">function</phrase><phrase role="special"><</phrase><phrase role="keyword">void</phrase><phrase role="special">(</phrase><phrase role="keyword">char</phrase><phrase role="special">)></phrase> <phrase role="identifier">cb_</phrase><phrase role="special">)</phrase> <phrase role="special">:</phrase>
514 <phrase role="identifier">next</phrase><phrase role="special">(),</phrase> <phrase role="identifier">is</phrase><phrase role="special">(</phrase><phrase role="identifier">is_</phrase><phrase role="special">),</phrase> <phrase role="identifier">cb</phrase><phrase role="special">(</phrase><phrase role="identifier">cb_</phrase><phrase role="special">)</phrase>
515 <phrase role="special">{}</phrase>
517 <phrase role="keyword">void</phrase> <phrase role="identifier">run</phrase><phrase role="special">()</phrase> <phrase role="special">{</phrase>
518 <phrase role="identifier">scan</phrase><phrase role="special">();</phrase>
519 <phrase role="identifier">E</phrase><phrase role="special">();</phrase>
520 <phrase role="special">}</phrase>
522 <phrase role="keyword">private</phrase><phrase role="special">:</phrase>
523 <phrase role="keyword">void</phrase> <phrase role="identifier">E</phrase><phrase role="special">(){</phrase>
524 <phrase role="identifier">T</phrase><phrase role="special">();</phrase>
525 <phrase role="keyword">while</phrase> <phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">==</phrase><phrase role="char">'+'</phrase><phrase role="special">||</phrase><phrase role="identifier">next</phrase><phrase role="special">==</phrase><phrase role="char">'-'</phrase><phrase role="special">){</phrase>
526 <phrase role="identifier">cb</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">);</phrase>
527 <phrase role="identifier">scan</phrase><phrase role="special">();</phrase>
528 <phrase role="identifier">T</phrase><phrase role="special">();</phrase>
529 <phrase role="special">}</phrase>
530 <phrase role="special">}</phrase>
532 <phrase role="keyword">void</phrase> <phrase role="identifier">T</phrase><phrase role="special">(){</phrase>
533 <phrase role="identifier">S</phrase><phrase role="special">();</phrase>
534 <phrase role="keyword">while</phrase> <phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">==</phrase><phrase role="char">'*'</phrase><phrase role="special">||</phrase><phrase role="identifier">next</phrase><phrase role="special">==</phrase><phrase role="char">'/'</phrase><phrase role="special">){</phrase>
535 <phrase role="identifier">cb</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">);</phrase>
536 <phrase role="identifier">scan</phrase><phrase role="special">();</phrase>
537 <phrase role="identifier">S</phrase><phrase role="special">();</phrase>
538 <phrase role="special">}</phrase>
539 <phrase role="special">}</phrase>
541 <phrase role="keyword">void</phrase> <phrase role="identifier">S</phrase><phrase role="special">(){</phrase>
542 <phrase role="keyword">if</phrase> <phrase role="special">(</phrase><phrase role="identifier">isdigit</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">)){</phrase>
543 <phrase role="identifier">cb</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">);</phrase>
544 <phrase role="identifier">scan</phrase><phrase role="special">();</phrase>
545 <phrase role="special">}</phrase>
546 <phrase role="keyword">else</phrase> <phrase role="keyword">if</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">==</phrase><phrase role="char">'('</phrase><phrase role="special">){</phrase>
547 <phrase role="identifier">cb</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">);</phrase>
548 <phrase role="identifier">scan</phrase><phrase role="special">();</phrase>
549 <phrase role="identifier">E</phrase><phrase role="special">();</phrase>
550 <phrase role="keyword">if</phrase> <phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">==</phrase><phrase role="char">')'</phrase><phrase role="special">){</phrase>
551 <phrase role="identifier">cb</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">);</phrase>
552 <phrase role="identifier">scan</phrase><phrase role="special">();</phrase>
553 <phrase role="special">}</phrase><phrase role="keyword">else</phrase><phrase role="special">{</phrase>
554 <phrase role="keyword">throw</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">runtime_error</phrase><phrase role="special">(</phrase><phrase role="string">"parsing failed"</phrase><phrase role="special">);</phrase>
555 <phrase role="special">}</phrase>
556 <phrase role="special">}</phrase>
557 <phrase role="keyword">else</phrase><phrase role="special">{</phrase>
558 <phrase role="keyword">throw</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">runtime_error</phrase><phrase role="special">(</phrase><phrase role="string">"parsing failed"</phrase><phrase role="special">);</phrase>
559 <phrase role="special">}</phrase>
560 <phrase role="special">}</phrase>
561 <phrase role="special">};</phrase>
563 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">istringstream</phrase> <phrase role="identifier">is</phrase><phrase role="special">(</phrase><phrase role="string">"1+1"</phrase><phrase role="special">);</phrase>
564 <phrase role="comment">// user-code pulls parsed data from parser</phrase>
565 <phrase role="comment">// invert control flow</phrase>
566 <phrase role="keyword">char</phrase> <phrase role="identifier">c</phrase><phrase role="special">;</phrase>
567 <phrase role="keyword">bool</phrase> <phrase role="identifier">done</phrase><phrase role="special">=</phrase><phrase role="keyword">false</phrase><phrase role="special">;</phrase>
568 <phrase role="comment">// execute parser in new fiber</phrase>
569 <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">source</phrase><phrase role="special">{[&</phrase><phrase role="identifier">is</phrase><phrase role="special">,&</phrase><phrase role="identifier">c</phrase><phrase role="special">,&</phrase><phrase role="identifier">done</phrase><phrase role="special">](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase><phrase role="special">&&</phrase> <phrase role="identifier">sink</phrase><phrase role="special">){</phrase>
570 <phrase role="comment">// create parser with callback function</phrase>
571 <phrase role="identifier">Parser</phrase> <phrase role="identifier">p</phrase><phrase role="special">(</phrase><phrase role="identifier">is</phrase><phrase role="special">,</phrase>
572 <phrase role="special">[&</phrase><phrase role="identifier">sink</phrase><phrase role="special">,&</phrase><phrase role="identifier">c</phrase><phrase role="special">](</phrase><phrase role="keyword">char</phrase> <phrase role="identifier">c_</phrase><phrase role="special">){</phrase>
573 <phrase role="comment">// resume main fiber</phrase>
574 <phrase role="identifier">c</phrase><phrase role="special">=</phrase><phrase role="identifier">c_</phrase><phrase role="special">;</phrase>
575 <phrase role="identifier">sink</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">sink</phrase><phrase role="special">).</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
576 <phrase role="special">});</phrase>
577 <phrase role="comment">// start recursive parsing</phrase>
578 <phrase role="identifier">p</phrase><phrase role="special">.</phrase><phrase role="identifier">run</phrase><phrase role="special">();</phrase>
579 <phrase role="comment">// signal termination</phrase>
580 <phrase role="identifier">done</phrase><phrase role="special">=</phrase><phrase role="keyword">true</phrase><phrase role="special">;</phrase>
581 <phrase role="comment">// resume main fiber</phrase>
582 <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">sink</phrase><phrase role="special">);</phrase>
583 <phrase role="special">}};</phrase>
584 <phrase role="identifier">source</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">source</phrase><phrase role="special">).</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
585 <phrase role="keyword">while</phrase><phrase role="special">(!</phrase><phrase role="identifier">done</phrase><phrase role="special">){</phrase>
586 <phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">"Parsed: %c\n"</phrase><phrase role="special">,</phrase><phrase role="identifier">c</phrase><phrase role="special">);</phrase>
587 <phrase role="identifier">source</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">Move</phrase><phrase role="special">(</phrase><phrase role="identifier">source</phrase><phrase role="special">).</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
588 <phrase role="special">}</phrase>
590 <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
591 <phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase>
592 <phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="special">+</phrase>
593 <phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase>
596 In this example a recursive descent parser uses a callback to emit a newly
597 passed symbol. Using <link linkend="ff"><emphasis>fiber</emphasis></link> the
598 control flow can be inverted, e.g. the user-code pulls parsed symbols from
599 the parser - instead to get pushed from the parser (via callback).
602 The data (character) is transferred between the two fibers.
604 <section id="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber">
605 <title><anchor id="implementation"/><link linkend="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber">Implementations:
606 fcontext_t, ucontext_t and WinFiber</link></title>
607 <bridgehead renderas="sect4" id="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber.h0">
608 <phrase id="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber.fcontext_t"/><link
609 linkend="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber.fcontext_t">fcontext_t</link>
612 The implementation uses <emphasis>fcontext_t</emphasis> per default. fcontext_t
613 is based on assembler and not available for all platforms. It provides a
614 much better performance than <emphasis>ucontext_t</emphasis> (the context
615 switch takes two magnitudes of order less CPU cycles; see section <link linkend="performance"><emphasis>performance</emphasis></link>)
616 and <emphasis>WinFiber</emphasis>.
620 Because the TIB (thread information block on Windows) is not fully described
621 in the MSDN, it might be possible that not all required TIB-parts are swapped.
622 Using WinFiber implementation migh be an alternative.
625 <bridgehead renderas="sect4" id="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber.h1">
626 <phrase id="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber.ucontext_t"/><link
627 linkend="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber.ucontext_t">ucontext_t</link>
630 As an alternative, <ulink url="https://en.wikipedia.org/wiki/Setcontext"><emphasis>ucontext_t</emphasis></ulink>
631 can be used by compiling with <code><phrase role="identifier">BOOST_USE_UCONTEXT</phrase></code>
632 and b2 property <code><phrase role="identifier">context</phrase><phrase role="special">-</phrase><phrase
633 role="identifier">impl</phrase><phrase role="special">=</phrase><phrase role="identifier">ucontext</phrase></code>.
634 <emphasis>ucontext_t</emphasis> might be available on a broader range of
635 POSIX-platforms but has some <link linkend="ucontext"><emphasis>disadvantages</emphasis></link>
636 (for instance deprecated since POSIX.1-2003, not C99 conform).
640 <link linkend="ff"><emphasis>fiber</emphasis></link> supports <link linkend="segmented"><emphasis>Segmented
641 stacks</emphasis></link> only with <emphasis>ucontext_t</emphasis> as its
645 <bridgehead renderas="sect4" id="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber.h2">
646 <phrase id="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber.winfiber"/><link
647 linkend="context.ff.implementations__fcontext_t__ucontext_t_and_winfiber.winfiber">WinFiber</link>
650 With <code><phrase role="identifier">BOOST_USE_WINFIB</phrase></code> and
651 b2 property <code><phrase role="identifier">context</phrase><phrase role="special">-</phrase><phrase
652 role="identifier">impl</phrase><phrase role="special">=</phrase><phrase role="identifier">winfib</phrase></code>
653 Win32-Fibers are used as implementation for <link linkend="ff"><emphasis>fiber</emphasis></link>.
657 The first call of <link linkend="ff"><emphasis>fiber</emphasis></link>
658 converts the thread into a Windows fiber by invoking <code><phrase role="identifier">ConvertThreadToFiber</phrase><phrase
659 role="special">()</phrase></code>. If desired, <code><phrase role="identifier">ConvertFiberToThread</phrase><phrase
660 role="special">()</phrase></code> has to be called by the user explicitly
661 in order to release resources allocated by <code><phrase role="identifier">ConvertThreadToFiber</phrase><phrase
662 role="special">()</phrase></code> (e.g. after using boost.context).
666 <section id="context.ff.class__fiber_">
667 <title><link linkend="context.ff.class__fiber_">Class <code><phrase role="identifier">fiber</phrase></code></link></title>
668 <programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">context</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">></phrase>
670 <phrase role="keyword">class</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">{</phrase>
671 <phrase role="keyword">public</phrase><phrase role="special">:</phrase>
672 <phrase role="identifier">fiber</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
674 <phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">></phrase>
675 <phrase role="identifier">fiber</phrase><phrase role="special">(</phrase><phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">);</phrase>
677 <phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">StackAlloc</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">></phrase>
678 <phrase role="identifier">fiber</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">StackAlloc</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">);</phrase>
680 <phrase role="special">~</phrase><phrase role="identifier">fiber</phrase><phrase role="special">();</phrase>
682 <phrase role="identifier">fiber</phrase><phrase role="special">(</phrase><phrase role="identifier">fiber</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
684 <phrase role="identifier">fiber</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase><phrase role="identifier">fiber</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
686 <phrase role="identifier">fiber</phrase><phrase role="special">(</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
687 <phrase role="identifier">fiber</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
689 <phrase role="identifier">fiber</phrase> <phrase role="identifier">resume</phrase><phrase role="special">()</phrase> <phrase role="special">&&;</phrase>
691 <phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">></phrase>
692 <phrase role="identifier">fiber</phrase> <phrase role="identifier">resume_with</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="special">&&;</phrase>
694 <phrase role="keyword">explicit</phrase> <phrase role="keyword">operator</phrase> <phrase role="keyword">bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
696 <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
698 <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">==(</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
700 <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!=(</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
702 <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><(</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
704 <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>(</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
706 <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><=(</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
708 <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>=(</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
710 <phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase><phrase role="keyword">class</phrase> <phrase role="identifier">traitsT</phrase><phrase role="special">></phrase>
711 <phrase role="keyword">friend</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase><phrase role="identifier">charT</phrase><phrase role="special">,</phrase><phrase role="identifier">traitsT</phrase><phrase role="special">></phrase> <phrase role="special">&</phrase>
712 <phrase role="keyword">operator</phrase><phrase role="special"><<(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase><phrase role="identifier">charT</phrase><phrase role="special">,</phrase><phrase role="identifier">traitsT</phrase><phrase role="special">></phrase> <phrase role="special">&</phrase> <phrase role="identifier">os</phrase><phrase role="special">,</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
714 <phrase role="keyword">void</phrase> <phrase role="identifier">swap</phrase><phrase role="special">(</phrase><phrase role="identifier">fiber</phrase> <phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
715 <phrase role="special">};</phrase>
718 <bridgehead renderas="sect4" id="ff_constructor1_bridgehead">
719 <phrase id="ff_constructor1"/>
720 <link linkend="ff_constructor1">Constructor</link>
723 <programlisting><phrase role="identifier">fiber</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
728 <term>Effects:</term>
731 Creates a invalid fiber.
745 <bridgehead renderas="sect4" id="ff_constructor2_bridgehead">
746 <phrase id="ff_constructor2"/>
747 <link linkend="ff_constructor2">Constructor</link>
750 <programlisting><phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">></phrase>
751 <phrase role="identifier">fiber</phrase><phrase role="special">(</phrase><phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">);</phrase>
753 <phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">StackAlloc</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">></phrase>
754 <phrase role="identifier">fiber</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">StackAlloc</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">);</phrase>
759 <term>Effects:</term>
762 Creates a new fiber and prepares the context to execute <code><phrase
763 role="identifier">fn</phrase></code>. <code><phrase role="identifier">fixedsize_stack</phrase></code>
764 is used as default stack allocator (stack size == fixedsize_stack::traits::default_size()).
765 The constructor with argument type <code><phrase role="identifier">preallocated</phrase></code>,
766 is used to create a user defined data <link linkend="ff_prealloc">(for
767 instance additional control structures)</link> on top of the stack.
773 <bridgehead renderas="sect4" id="ff_destructor destructor_bridgehead">
774 <phrase id="ff_destructor destructor"/>
775 <link linkend="ff_destructor
776 destructor">Destructor</link>
779 <programlisting><phrase role="special">~</phrase><phrase role="identifier">fiber</phrase><phrase role="special">();</phrase>
784 <term>Effects:</term>
787 Destructs the associated stack if <code><phrase role="special">*</phrase><phrase
788 role="keyword">this</phrase></code> is a valid fiber, e.g. <emphasis>fiber::operator
789 bool()</emphasis> returns <code><phrase role="keyword">true</phrase></code>.
803 <bridgehead renderas="sect4" id="ff_move constructor_bridgehead">
804 <phrase id="ff_move constructor"/>
805 <link linkend="ff_move constructor">Move
809 <programlisting><phrase role="identifier">fiber</phrase><phrase role="special">(</phrase><phrase role="identifier">fiber</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
814 <term>Effects:</term>
817 Moves underlying capture fiber to <code><phrase role="special">*</phrase><phrase
818 role="keyword">this</phrase></code>.
832 <bridgehead renderas="sect4" id="ff_move assignment_bridgehead">
833 <phrase id="ff_move assignment"/>
834 <link linkend="ff_move assignment">Move assignment
838 <programlisting><phrase role="identifier">fiber</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase><phrase role="identifier">fiber</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
843 <term>Effects:</term>
846 Moves the state of <code><phrase role="identifier">other</phrase></code>
847 to <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
848 using move semantics.
862 <bridgehead renderas="sect4" id="ff_operator_call_bridgehead">
863 <phrase id="ff_operator_call"/>
864 <link linkend="ff_operator_call">Member function
865 <code>operator()</code>()</link>
868 <programlisting><phrase role="identifier">fiber</phrase> <phrase role="identifier">resume</phrase><phrase role="special">()</phrase> <phrase role="special">&&;</phrase>
870 <phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">></phrase>
871 <phrase role="identifier">fiber</phrase> <phrase role="identifier">resume_with</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="special">&&;</phrase>
876 <term>Effects:</term>
879 Captures current fiber and resumes <code><phrase role="special">*</phrase><phrase
880 role="keyword">this</phrase></code>. The function <code><phrase role="identifier">resume_with</phrase></code>,
881 is used to execute function <code><phrase role="identifier">fn</phrase></code>
882 in the execution context of <code><phrase role="special">*</phrase><phrase
883 role="keyword">this</phrase></code> (e.g. the stack frame of <code><phrase
884 role="identifier">fn</phrase></code> is allocated on stack of <code><phrase
885 role="special">*</phrase><phrase role="keyword">this</phrase></code>).
890 <term>Returns:</term>
893 The fiber representing the fiber that has been suspended.
901 Because <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
902 gets invalidated, <code><phrase role="identifier">resume</phrase><phrase
903 role="special">()</phrase></code> and <code><phrase role="identifier">resume_with</phrase><phrase
904 role="special">()</phrase></code> are rvalue-ref qualified and bind
913 Function <code><phrase role="identifier">fn</phrase></code> needs to
914 return <code><phrase role="identifier">fiber</phrase></code>.
922 The returned fiber indicates if the suspended fiber has terminated
923 (return from context-function) via <code><phrase role="keyword">bool</phrase>
924 <phrase role="keyword">operator</phrase><phrase role="special">()</phrase></code>.
930 <bridgehead renderas="sect4" id="ff_operator_bool_bridgehead">
931 <phrase id="ff_operator_bool"/>
932 <link linkend="ff_operator_bool">Member function
933 <code>operator bool</code>()</link>
936 <programlisting><phrase role="keyword">explicit</phrase> <phrase role="keyword">operator</phrase> <phrase role="keyword">bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
941 <term>Returns:</term>
944 <code><phrase role="keyword">true</phrase></code> if <code><phrase
945 role="special">*</phrase><phrase role="keyword">this</phrase></code>
946 points to a captured fiber.
960 <bridgehead renderas="sect4" id="ff_operator_not_bridgehead">
961 <phrase id="ff_operator_not"/>
962 <link linkend="ff_operator_not">Member function <code>operator!</code>()</link>
965 <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
970 <term>Returns:</term>
973 <code><phrase role="keyword">true</phrase></code> if <code><phrase
974 role="special">*</phrase><phrase role="keyword">this</phrase></code>
975 does not point to a captured fiber.
989 <bridgehead renderas="sect4" id="ff_operator_equal_bridgehead">
990 <phrase id="ff_operator_equal"/>
991 <link linkend="ff_operator_equal">Member function
992 <code>operator==</code>()</link>
995 <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">==(</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
1000 <term>Returns:</term>
1003 <code><phrase role="keyword">true</phrase></code> if <code><phrase
1004 role="special">*</phrase><phrase role="keyword">this</phrase></code>
1005 and <code><phrase role="identifier">other</phrase></code> represent
1006 the same fiber, <code><phrase role="keyword">false</phrase></code>
1012 <term>Throws:</term>
1021 <bridgehead renderas="sect4" id="ff_operator_notequal_bridgehead">
1022 <phrase id="ff_operator_notequal"/>
1023 <link linkend="ff_operator_notequal">Member
1024 function <code>operator!=</code>()</link>
1027 <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!=(</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
1032 <term>Returns:</term>
1035 <code>! (other == * this)</code>
1040 <term>Throws:</term>
1049 <bridgehead renderas="sect4" id="ff_operator_less_bridgehead">
1050 <phrase id="ff_operator_less"/>
1051 <link linkend="ff_operator_less">Member function
1052 <code>operator<</code>()</link>
1055 <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><(</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
1060 <term>Returns:</term>
1063 <code><phrase role="keyword">true</phrase></code> if <code><phrase
1064 role="special">*</phrase><phrase role="keyword">this</phrase> <phrase
1065 role="special">!=</phrase> <phrase role="identifier">other</phrase></code>
1066 is true and the implementation-defined total order of <code><phrase
1067 role="identifier">fiber</phrase></code> values places <code><phrase
1068 role="special">*</phrase><phrase role="keyword">this</phrase></code>
1069 before <code><phrase role="identifier">other</phrase></code>, false
1075 <term>Throws:</term>
1084 <bridgehead renderas="sect4" id="ff_operator_greater_bridgehead">
1085 <phrase id="ff_operator_greater"/>
1086 <link linkend="ff_operator_greater">Member
1087 function <code>operator></code>()</link>
1090 <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>(</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
1095 <term>Returns:</term>
1098 <code><phrase role="identifier">other</phrase> <phrase role="special"><</phrase>
1099 <phrase role="special">*</phrase> <phrase role="keyword">this</phrase></code>
1104 <term>Throws:</term>
1113 <bridgehead renderas="sect4" id="ff_operator_lesseq_bridgehead">
1114 <phrase id="ff_operator_lesseq"/>
1115 <link linkend="ff_operator_lesseq">Member function
1116 <code>operator<=</code>()</link>
1119 <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><=(</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
1124 <term>Returns:</term>
1127 <code><phrase role="special">!</phrase> <phrase role="special">(</phrase><phrase
1128 role="identifier">other</phrase> <phrase role="special"><</phrase>
1129 <phrase role="special">*</phrase> <phrase role="keyword">this</phrase><phrase
1130 role="special">)</phrase></code>
1135 <term>Throws:</term>
1144 <bridgehead renderas="sect4" id="ff_operator_greatereq_bridgehead">
1145 <phrase id="ff_operator_greatereq"/>
1146 <link linkend="ff_operator_greatereq">Member
1147 function <code>operator>=</code>()</link>
1150 <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>=(</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
1155 <term>Returns:</term>
1158 <code><phrase role="special">!</phrase> <phrase role="special">(*</phrase>
1159 <phrase role="keyword">this</phrase> <phrase role="special"><</phrase>
1160 <phrase role="identifier">other</phrase><phrase role="special">)</phrase></code>
1165 <term>Throws:</term>
1174 <bridgehead renderas="sect4" id="ff__bridgehead">
1176 <link linkend="ff_">Non-member function <code>operator<<()</code></link>
1179 <programlisting><phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase><phrase role="keyword">class</phrase> <phrase role="identifier">traitsT</phrase><phrase role="special">></phrase>
1180 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase><phrase role="identifier">charT</phrase><phrase role="special">,</phrase><phrase role="identifier">traitsT</phrase><phrase role="special">></phrase> <phrase role="special">&</phrase>
1181 <phrase role="keyword">operator</phrase><phrase role="special"><<(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase><phrase role="identifier">charT</phrase><phrase role="special">,</phrase><phrase role="identifier">traitsT</phrase><phrase role="special">></phrase> <phrase role="special">&</phrase> <phrase role="identifier">os</phrase><phrase role="special">,</phrase><phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">);</phrase>
1186 <term>Effects:</term>
1189 Writes the representation of <code><phrase role="identifier">other</phrase></code>
1190 to stream <code><phrase role="identifier">os</phrase></code>.
1195 <term>Returns:</term>
1198 <code><phrase role="identifier">os</phrase></code>
1205 <section id="context.cc">
1206 <title><anchor id="cc"/><link linkend="context.cc">Context switching with call/cc</link></title>
1209 <emphasis>call/cc</emphasis> is the reference implementation of C++ proposal
1210 <ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0534r3.pdf">P0534R3:
1211 call/cc (call-with-current-continuation): A low-level API for stackful context
1216 <emphasis>call/cc</emphasis> (call with current continuation) is a universal
1217 control operator (well-known from the programming language Scheme) that captures
1218 the current continuation as a first-class object and pass it as an argument
1219 to another continuation.
1222 A continuation (abstract concept of functional programming languages) represents
1223 the state of the control flow of a program at a given point in time. Continuations
1224 can be suspended and resumed later in order to change the control flow of a
1228 Modern micro-processors are registers machines; the content of processor registers
1229 represent a continuation of the executed program at a given point in time.
1230 Operating systems simulate parallel execution of programs on a single processor
1231 by switching between programs (context switch) by preserving and restoring
1232 the continuation, e.g. the content of all registers.
1234 <bridgehead renderas="sect3" id="context.cc.h0">
1235 <phrase id="context.cc._link_linkend__cc___emphasis_callcc____emphasis___link_"/><link
1236 linkend="context.cc._link_linkend__cc___emphasis_callcc____emphasis___link_"><link
1237 linkend="cc"><emphasis>callcc()</emphasis></link></link>
1240 <link linkend="cc"><emphasis>callcc()</emphasis></link> is the C++ equivalent
1241 to Scheme's <emphasis>call/cc</emphasis> operator. It captures the current
1242 continuation (the rest of the computation; code after <link linkend="cc"><emphasis>callcc()</emphasis></link>)
1243 and triggers a context switch. The context switch is achieved by preserving
1244 certain registers (including instruction and stack pointer), defined by the
1245 calling convention of the ABI, of the current continuation and restoring those
1246 registers of the resumed continuation. The control flow of the resumed continuation
1247 continues. The current continuation is suspended and passed as argument to
1248 the resumed continuation.
1251 <link linkend="cc"><emphasis>callcc()</emphasis></link> expects a <emphasis>context-function</emphasis>
1252 with signature <code><phrase role="char">'continuation(continuation &&
1253 c)'</phrase></code>. The parameter <code><phrase role="identifier">c</phrase></code>
1254 represents the current continuation from which this continuation was resumed
1255 (e.g. that has called <link linkend="cc"><emphasis>callcc()</emphasis></link>).
1258 On return the <emphasis>context-function</emphasis> of the current continuation
1259 has to specify an <link linkend="cc"><emphasis>continuation</emphasis></link>
1260 to which the execution control is transferred after termination of the current
1264 If an instance with valid state goes out of scope and the <emphasis>context-function</emphasis>
1265 has not yet returned, the stack is traversed in order to access the control
1266 structure (address stored at the first stack frame) and continuation's stack
1267 is deallocated via the <emphasis>StackAllocator</emphasis>.
1271 <link linkend="segmented"><emphasis>Segmented stacks</emphasis></link> are
1272 supported by <link linkend="cc"><emphasis>callcc()</emphasis></link> using
1273 <link linkend="implementation"><emphasis>ucontext_t</emphasis></link>.
1276 <bridgehead renderas="sect3" id="context.cc.h1">
1277 <phrase id="context.cc._link_linkend__cc___emphasis_continuation__emphasis___link_"/><link
1278 linkend="context.cc._link_linkend__cc___emphasis_continuation__emphasis___link_"><link
1279 linkend="cc"><emphasis>continuation</emphasis></link></link>
1282 <link linkend="cc"><emphasis>continuation</emphasis></link> represents a continuation;
1283 it contains the content of preserved registers and manages the associated stack
1284 (allocation/deallocation). <link linkend="cc"><emphasis>continuation</emphasis></link>
1285 is a one-shot continuation - it can be used only once, after calling <emphasis>continuation::resume()</emphasis>
1286 or <emphasis>continuation::resume_with()</emphasis> it is invalidated.
1289 <link linkend="cc"><emphasis>continuation</emphasis></link> is only move-constructible
1290 and move-assignable.
1293 As a first-class object <link linkend="cc"><emphasis>continuation</emphasis></link>
1294 can be applied to and returned from a function, assigned to a variable or stored
1298 A continuation is continued by calling <code><phrase role="identifier">resume</phrase><phrase
1299 role="special">()</phrase></code>/<code><phrase role="identifier">resume_with</phrase><phrase
1300 role="special">()</phrase></code>.
1302 <bridgehead renderas="sect3" id="context.cc.h2">
1303 <phrase id="context.cc.usage"/><link linkend="context.cc.usage">Usage</link>
1305 <programlisting><phrase role="keyword">namespace</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">=</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">;</phrase>
1306 <phrase role="keyword">int</phrase> <phrase role="identifier">a</phrase><phrase role="special">;</phrase>
1307 <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="identifier">source</phrase><phrase role="special">=</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">callcc</phrase><phrase role="special">(</phrase>
1308 <phrase role="special">[&</phrase><phrase role="identifier">a</phrase><phrase role="special">](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">sink</phrase><phrase role="special">){</phrase>
1309 <phrase role="identifier">a</phrase><phrase role="special">=</phrase><phrase role="number">0</phrase><phrase role="special">;</phrase>
1310 <phrase role="keyword">int</phrase> <phrase role="identifier">b</phrase><phrase role="special">=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
1311 <phrase role="keyword">for</phrase><phrase role="special">(;;){</phrase>
1312 <phrase role="identifier">sink</phrase><phrase role="special">=</phrase><phrase role="identifier">sink</phrase><phrase role="special">.</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
1313 <phrase role="keyword">int</phrase> <phrase role="identifier">next</phrase><phrase role="special">=</phrase><phrase role="identifier">a</phrase><phrase role="special">+</phrase><phrase role="identifier">b</phrase><phrase role="special">;</phrase>
1314 <phrase role="identifier">a</phrase><phrase role="special">=</phrase><phrase role="identifier">b</phrase><phrase role="special">;</phrase>
1315 <phrase role="identifier">b</phrase><phrase role="special">=</phrase><phrase role="identifier">next</phrase><phrase role="special">;</phrase>
1316 <phrase role="special">}</phrase>
1317 <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">sink</phrase><phrase role="special">);</phrase>
1318 <phrase role="special">});</phrase>
1319 <phrase role="keyword">for</phrase> <phrase role="special">(</phrase><phrase role="keyword">int</phrase> <phrase role="identifier">j</phrase><phrase role="special">=</phrase><phrase role="number">0</phrase><phrase role="special">;</phrase><phrase role="identifier">j</phrase><phrase role="special"><</phrase><phrase role="number">10</phrase><phrase role="special">;++</phrase><phrase role="identifier">j</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
1320 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">a</phrase> <phrase role="special"><<</phrase> <phrase role="string">" "</phrase><phrase role="special">;</phrase>
1321 <phrase role="identifier">source</phrase><phrase role="special">=</phrase><phrase role="identifier">source</phrase><phrase role="special">.</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
1322 <phrase role="special">}</phrase>
1324 <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
1325 <phrase role="number">0</phrase> <phrase role="number">1</phrase> <phrase role="number">1</phrase> <phrase role="number">2</phrase> <phrase role="number">3</phrase> <phrase role="number">5</phrase> <phrase role="number">8</phrase> <phrase role="number">13</phrase> <phrase role="number">21</phrase> <phrase role="number">34</phrase>
1328 This simple example demonstrates the basic usage of <emphasis>call/cc</emphasis>
1329 as a <emphasis>generator</emphasis>. The continuation <code><phrase role="identifier">sink</phrase></code>
1330 represents the <emphasis>main</emphasis>-continuation (function <code><phrase
1331 role="identifier">main</phrase><phrase role="special">()</phrase></code>).
1332 <code><phrase role="identifier">sink</phrase></code> is captured (current-continuation)
1333 by invoking <link linkend="cc"><emphasis>callcc()</emphasis></link> and passed
1334 as parameter to the lambda.
1337 Because the state is invalidated (one-shot continuation) by each call of <emphasis>continuation::resume()</emphasis>,
1338 the new state of the <link linkend="cc"><emphasis>continuation</emphasis></link>,
1339 returned by <emphasis>continuation::resume()</emphasis>, needs to be assigned
1340 to <code><phrase role="identifier">sink</phrase></code> after each call.
1343 The lambda that calculates the Fibonacci numbers is executed inside the continuation
1344 represented by <code><phrase role="identifier">source</phrase></code>. Calculated
1345 Fibonacci numbers are transferred between the two continuations via variable
1346 <code><phrase role="identifier">a</phrase></code> (lambda capture reference).
1349 The locale variables <code><phrase role="identifier">b</phrase></code> and
1350 <code> <phrase role="identifier">next</phrase></code> remain their values during
1351 each context switch. This is possible due <code><phrase role="identifier">source</phrase></code>
1352 has its own stack and the stack is exchanged by each context switch.
1354 <bridgehead renderas="sect3" id="context.cc.h3">
1355 <phrase id="context.cc.parameter_passing"/><link linkend="context.cc.parameter_passing">Parameter
1359 Data can be transferred between two continuations via global pointers, calling
1360 wrappers (like <code><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
1361 role="identifier">bind</phrase></code>) or lambda captures.
1363 <programlisting><phrase role="keyword">namespace</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">=</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">;</phrase>
1364 <phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase><phrase role="special">=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
1365 <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="identifier">c1</phrase><phrase role="special">=</phrase><phrase role="identifier">callcc</phrase><phrase role="special">([&</phrase><phrase role="identifier">i</phrase><phrase role="special">](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">c2</phrase><phrase role="special">){</phrase>
1366 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">"inside c1,i==%d\n"</phrase><phrase role="special">,</phrase><phrase role="identifier">i</phrase><phrase role="special">);</phrase>
1367 <phrase role="identifier">i</phrase><phrase role="special">+=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
1368 <phrase role="keyword">return</phrase> <phrase role="identifier">c2</phrase><phrase role="special">.</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
1369 <phrase role="special">});</phrase>
1370 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">"i==%d\n"</phrase><phrase role="special">,</phrase><phrase role="identifier">i</phrase><phrase role="special">);</phrase>
1372 <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
1373 <phrase role="identifier">inside</phrase> <phrase role="identifier">c1</phrase><phrase role="special">,</phrase><phrase role="identifier">i</phrase><phrase role="special">==</phrase><phrase role="number">1</phrase>
1374 <phrase role="identifier">i</phrase><phrase role="special">==</phrase><phrase role="number">2</phrase>
1377 <code><phrase role="identifier">callcc</phrase><phrase role="special">(<</phrase><phrase
1378 role="identifier">lambda</phrase><phrase role="special">>)</phrase></code>
1379 enters the lambda in continuation represented by <code><phrase role="identifier">c1</phrase></code>
1380 with lambda capture reference <code><phrase role="identifier">i</phrase><phrase
1381 role="special">=</phrase><phrase role="number">1</phrase></code>. The expression
1382 <code><phrase role="identifier">c2</phrase><phrase role="special">.</phrase><phrase
1383 role="identifier">resume</phrase><phrase role="special">()</phrase></code>
1384 resumes the continuation <code><phrase role="identifier">c2</phrase></code>.
1385 On return of <code><phrase role="identifier">callcc</phrase><phrase role="special">(<</phrase><phrase
1386 role="identifier">lambda</phrase><phrase role="special">>)</phrase></code>,
1387 the variable <code><phrase role="identifier">i</phrase></code> has the value
1388 of <code><phrase role="identifier">i</phrase><phrase role="special">+</phrase><phrase
1389 role="number">1</phrase></code>.
1391 <bridgehead renderas="sect3" id="context.cc.h4">
1392 <phrase id="context.cc.exception_handling"/><link linkend="context.cc.exception_handling">Exception
1396 If the function executed inside a <emphasis>context-function</emphasis> emits
1397 an exception, the application is terminated by calling <code><phrase role="identifier">std</phrase><phrase
1398 role="special">::</phrase><phrase role="identifier">terminate</phrase><phrase
1399 role="special">()</phrase></code>. <code><phrase role="identifier">std</phrase><phrase
1400 role="special">::</phrase><phrase role="identifier">exception_ptr</phrase></code>
1401 can be used to transfer exceptions between different continuations.
1405 Do not jump from inside a catch block and then re-throw the exception in
1406 another continuation.
1409 <anchor id="cc_ontop"/>
1410 <bridgehead renderas="sect3" id="context.cc.h5">
1411 <phrase id="context.cc.executing_function_on_top_of_a_continuation"/><link
1412 linkend="context.cc.executing_function_on_top_of_a_continuation">Executing
1413 function on top of a continuation</link>
1416 Sometimes it is useful to execute a new function on top of a resumed continuation.
1417 For this purpose <emphasis>continuation::resume_with()</emphasis> has to be
1418 used. The function passed as argument must accept a rvalue reference to <link
1419 linkend="cc"><emphasis>continuation</emphasis></link> and return <code><phrase
1420 role="keyword">void</phrase></code>.
1422 <programlisting><phrase role="keyword">namespace</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">=</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">;</phrase>
1423 <phrase role="keyword">int</phrase> <phrase role="identifier">data</phrase><phrase role="special">=</phrase><phrase role="number">0</phrase><phrase role="special">;</phrase>
1424 <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="identifier">c</phrase><phrase role="special">=</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">callcc</phrase><phrase role="special">([&</phrase><phrase role="identifier">data</phrase><phrase role="special">](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">c</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
1425 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f1: entered first time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
1426 <phrase role="identifier">data</phrase><phrase role="special">+=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
1427 <phrase role="identifier">c</phrase><phrase role="special">=</phrase><phrase role="identifier">c</phrase><phrase role="special">.</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
1428 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f1: entered second time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
1429 <phrase role="identifier">data</phrase><phrase role="special">+=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
1430 <phrase role="identifier">c</phrase><phrase role="special">=</phrase><phrase role="identifier">c</phrase><phrase role="special">.</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
1431 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f1: entered third time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
1432 <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">c</phrase><phrase role="special">);</phrase>
1433 <phrase role="special">});</phrase>
1434 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f1: returned first time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
1435 <phrase role="identifier">data</phrase><phrase role="special">+=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
1436 <phrase role="identifier">c</phrase><phrase role="special">=</phrase><phrase role="identifier">c</phrase><phrase role="special">.</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
1437 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f1: returned second time: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
1438 <phrase role="identifier">data</phrase><phrase role="special">+=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
1439 <phrase role="identifier">c</phrase><phrase role="special">=</phrase><phrase role="identifier">c</phrase><phrase role="special">.</phrase><phrase role="identifier">resume_with</phrase><phrase role="special">([&</phrase><phrase role="identifier">data</phrase><phrase role="special">](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">c</phrase><phrase role="special">){</phrase>
1440 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f2: entered: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">data</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
1441 <phrase role="identifier">data</phrase><phrase role="special">=-</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase>
1442 <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase> <phrase role="identifier">c</phrase><phrase role="special">);</phrase>
1443 <phrase role="special">});</phrase>
1444 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f1: returned third time"</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
1446 <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
1447 <phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">entered</phrase> <phrase role="identifier">first</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="number">0</phrase>
1448 <phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">returned</phrase> <phrase role="identifier">first</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase>
1449 <phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">entered</phrase> <phrase role="identifier">second</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="number">2</phrase>
1450 <phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">returned</phrase> <phrase role="identifier">second</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="number">3</phrase>
1451 <phrase role="identifier">f2</phrase><phrase role="special">:</phrase> <phrase role="identifier">entered</phrase><phrase role="special">:</phrase> <phrase role="number">4</phrase>
1452 <phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">entered</phrase> <phrase role="identifier">third</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="special">-</phrase><phrase role="number">1</phrase>
1453 <phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">returned</phrase> <phrase role="identifier">third</phrase> <phrase role="identifier">time</phrase>
1456 The expression <code><phrase role="identifier">c</phrase><phrase role="special">.</phrase><phrase
1457 role="identifier">resume_with</phrase><phrase role="special">(...)</phrase></code>
1458 executes a lambda on top of continuation <code><phrase role="identifier">c</phrase></code>,
1459 e.g. an additional stack frame is allocated on top of the stack. This lambda
1460 assigns <code><phrase role="special">-</phrase><phrase role="number">1</phrase></code>
1461 to <code><phrase role="identifier">data</phrase></code> and returns to the
1462 second invocation of <code><phrase role="identifier">c</phrase><phrase role="special">.</phrase><phrase
1463 role="identifier">resume</phrase><phrase role="special">()</phrase></code>.
1466 Another option is to execute a function on top of the continuation that throws
1469 <programlisting><phrase role="keyword">namespace</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">=</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">;</phrase>
1470 <phrase role="keyword">struct</phrase> <phrase role="identifier">my_exception</phrase> <phrase role="special">:</phrase> <phrase role="keyword">public</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">runtime_error</phrase> <phrase role="special">{</phrase>
1471 <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="identifier">c</phrase><phrase role="special">;</phrase>
1472 <phrase role="identifier">my_exception</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">c_</phrase><phrase role="special">,</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">what</phrase><phrase role="special">)</phrase> <phrase role="special">:</phrase>
1473 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">runtime_error</phrase><phrase role="special">{</phrase> <phrase role="identifier">what</phrase> <phrase role="special">},</phrase>
1474 <phrase role="identifier">c</phrase><phrase role="special">{</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase> <phrase role="identifier">c_</phrase><phrase role="special">)</phrase> <phrase role="special">}</phrase> <phrase role="special">{</phrase>
1475 <phrase role="special">}</phrase>
1476 <phrase role="special">};</phrase>
1478 <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="identifier">c</phrase><phrase role="special">=</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">callcc</phrase><phrase role="special">([](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">c</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
1479 <phrase role="keyword">for</phrase> <phrase role="special">(;;)</phrase> <phrase role="special">{</phrase>
1480 <phrase role="keyword">try</phrase> <phrase role="special">{</phrase>
1481 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"entered"</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase>
1482 <phrase role="identifier">c</phrase><phrase role="special">=</phrase><phrase role="identifier">c</phrase><phrase role="special">.</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
1483 <phrase role="special">}</phrase> <phrase role="keyword">catch</phrase> <phrase role="special">(</phrase><phrase role="identifier">my_exception</phrase> <phrase role="special">&</phrase> <phrase role="identifier">ex</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
1484 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cerr</phrase> <phrase role="special"><<</phrase> <phrase role="string">"my_exception: "</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">ex</phrase><phrase role="special">.</phrase><phrase role="identifier">what</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>
1485 <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">ex</phrase><phrase role="special">.</phrase><phrase role="identifier">c</phrase><phrase role="special">);</phrase>
1486 <phrase role="special">}</phrase>
1487 <phrase role="special">}</phrase>
1488 <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">c</phrase><phrase role="special">);</phrase>
1489 <phrase role="special">});</phrase>
1490 <phrase role="identifier">c</phrase> <phrase role="special">=</phrase> <phrase role="identifier">c</phrase><phrase role="special">.</phrase><phrase role="identifier">resume_with</phrase><phrase role="special">(</phrase>
1491 <phrase role="special">[](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">c</phrase><phrase role="special">){</phrase>
1492 <phrase role="keyword">throw</phrase> <phrase role="identifier">my_exception</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">c</phrase><phrase role="special">),</phrase><phrase role="string">"abc"</phrase><phrase role="special">);</phrase>
1493 <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase> <phrase role="identifier">c</phrase><phrase role="special">);</phrase>
1494 <phrase role="special">});</phrase>
1496 <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
1497 <phrase role="identifier">entered</phrase>
1498 <phrase role="identifier">my_exception</phrase><phrase role="special">:</phrase> <phrase role="identifier">abc</phrase>
1501 In this exception <code><phrase role="identifier">my_exception</phrase></code>
1502 is throw from a function invoked on-top of continuation <code><phrase role="identifier">c</phrase></code>
1503 and catched inside the <code><phrase role="keyword">for</phrase></code>-loop.
1505 <bridgehead renderas="sect3" id="context.cc.h6">
1506 <phrase id="context.cc.stack_unwinding"/><link linkend="context.cc.stack_unwinding">Stack
1510 On construction of <link linkend="cc"><emphasis>continuation</emphasis></link>
1511 a stack is allocated. If the <emphasis>context-function</emphasis> returns
1512 the stack will be destructed. If the <emphasis>context-function</emphasis>
1513 has not yet returned and the destructor of an valid <link linkend="cc"><emphasis>continuation</emphasis></link>
1514 instance (e.g. <emphasis>continuation::operator bool()</emphasis> returns
1515 <code><phrase role="keyword">true</phrase></code>) is called, the stack will
1520 Code executed by <emphasis>context-function</emphasis> must not prevent the
1521 propagation ofs the <emphasis>detail::forced_unwind</emphasis> exception.
1522 Absorbing that exception will cause stack unwinding to fail. Thus, any code
1523 that catches all exceptions must re-throw any pending <emphasis>detail::forced_unwind</emphasis>
1527 <anchor id="cc_prealloc"/>
1528 <bridgehead renderas="sect3" id="context.cc.h7">
1529 <phrase id="context.cc.allocating_control_structures_on_top_of_stack"/><link
1530 linkend="context.cc.allocating_control_structures_on_top_of_stack">Allocating
1531 control structures on top of stack</link>
1534 Allocating control structures on top of the stack requires to allocated the
1535 <emphasis>stack_context</emphasis> and create the control structure with placement
1536 new before <link linkend="cc"><emphasis>continuation</emphasis></link> is created.
1540 The user is responsible for destructing the control structure at the top
1544 <programlisting><phrase role="keyword">namespace</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">=</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">;</phrase>
1545 <phrase role="comment">// stack-allocator used for (de-)allocating stack</phrase>
1546 <phrase role="identifier">fixedsize_stack</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">(</phrase><phrase role="number">4048</phrase><phrase role="special">);</phrase>
1547 <phrase role="comment">// allocate stack space</phrase>
1548 <phrase role="identifier">stack_context</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">(</phrase><phrase role="identifier">salloc</phrase><phrase role="special">.</phrase><phrase role="identifier">allocate</phrase><phrase role="special">());</phrase>
1549 <phrase role="comment">// reserve space for control structure on top of the stack</phrase>
1550 <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">=</phrase><phrase role="keyword">static_cast</phrase><phrase role="special"><</phrase><phrase role="keyword">char</phrase><phrase role="special">*>(</phrase><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase role="identifier">sp</phrase><phrase role="special">)-</phrase><phrase role="keyword">sizeof</phrase><phrase role="special">(</phrase><phrase role="identifier">my_control_structure</phrase><phrase role="special">);</phrase>
1551 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">=</phrase><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase role="identifier">size</phrase><phrase role="special">-</phrase><phrase role="keyword">sizeof</phrase><phrase role="special">(</phrase><phrase role="identifier">my_control_structure</phrase><phrase role="special">);</phrase>
1552 <phrase role="comment">// placement new creates control structure on reserved space</phrase>
1553 <phrase role="identifier">my_control_structure</phrase> <phrase role="special">*</phrase> <phrase role="identifier">cs</phrase><phrase role="special">=</phrase><phrase role="keyword">new</phrase><phrase role="special">(</phrase><phrase role="identifier">sp</phrase><phrase role="special">)</phrase><phrase role="identifier">my_control_structure</phrase><phrase role="special">(</phrase><phrase role="identifier">sp</phrase><phrase role="special">,</phrase><phrase role="identifier">size</phrase><phrase role="special">,</phrase><phrase role="identifier">sctx</phrase><phrase role="special">,</phrase><phrase role="identifier">salloc</phrase><phrase role="special">);</phrase>
1554 <phrase role="special">...</phrase>
1555 <phrase role="comment">// destructing the control structure</phrase>
1556 <phrase role="identifier">cs</phrase><phrase role="special">->~</phrase><phrase role="identifier">my_control_structure</phrase><phrase role="special">();</phrase>
1557 <phrase role="special">...</phrase>
1558 <phrase role="keyword">struct</phrase> <phrase role="identifier">my_control_structure</phrase> <phrase role="special">{</phrase>
1559 <phrase role="comment">// captured continuation</phrase>
1560 <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="identifier">c</phrase><phrase role="special">;</phrase>
1562 <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase> <phrase role="special">></phrase>
1563 <phrase role="identifier">my_control_structure</phrase><phrase role="special">(</phrase><phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">,</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">,</phrase><phrase role="identifier">stack_context</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">,</phrase><phrase role="identifier">StackAllocator</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">)</phrase> <phrase role="special">:</phrase>
1564 <phrase role="comment">// create captured continuation</phrase>
1565 <phrase role="identifier">c</phrase><phrase role="special">{}</phrase> <phrase role="special">{</phrase>
1566 <phrase role="identifier">c</phrase><phrase role="special">=</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">callcc</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg</phrase><phrase role="special">,</phrase><phrase role="identifier">preallocated</phrase><phrase role="special">(</phrase><phrase role="identifier">sp</phrase><phrase role="special">,</phrase><phrase role="identifier">size</phrase><phrase role="special">,</phrase><phrase role="identifier">sctx</phrase><phrase role="special">),</phrase><phrase role="identifier">salloc</phrase><phrase role="special">,</phrase><phrase role="identifier">entry_func</phrase><phrase role="special">);</phrase>
1567 <phrase role="special">}</phrase>
1568 <phrase role="special">...</phrase>
1569 <phrase role="special">};</phrase>
1571 <bridgehead renderas="sect3" id="context.cc.h8">
1572 <phrase id="context.cc.inverting_the_control_flow"/><link linkend="context.cc.inverting_the_control_flow">Inverting
1573 the control flow</link>
1575 <programlisting><phrase role="keyword">namespace</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">=</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">;</phrase>
1576 <phrase role="comment">/*
1579 * E ---> T {('+'|'-') T}
1580 * T ---> S {('*'|'/') S}
1581 * S ---> digit | '(' E ')'
1583 <phrase role="keyword">class</phrase> <phrase role="identifier">Parser</phrase><phrase role="special">{</phrase>
1584 <phrase role="keyword">char</phrase> <phrase role="identifier">next</phrase><phrase role="special">;</phrase>
1585 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">istream</phrase><phrase role="special">&</phrase> <phrase role="identifier">is</phrase><phrase role="special">;</phrase>
1586 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">function</phrase><phrase role="special"><</phrase><phrase role="keyword">void</phrase><phrase role="special">(</phrase><phrase role="keyword">char</phrase><phrase role="special">)></phrase> <phrase role="identifier">cb</phrase><phrase role="special">;</phrase>
1588 <phrase role="keyword">char</phrase> <phrase role="identifier">pull</phrase><phrase role="special">(){</phrase>
1589 <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">char_traits</phrase><phrase role="special"><</phrase><phrase role="keyword">char</phrase><phrase role="special">>::</phrase><phrase role="identifier">to_char_type</phrase><phrase role="special">(</phrase><phrase role="identifier">is</phrase><phrase role="special">.</phrase><phrase role="identifier">get</phrase><phrase role="special">());</phrase>
1590 <phrase role="special">}</phrase>
1592 <phrase role="keyword">void</phrase> <phrase role="identifier">scan</phrase><phrase role="special">(){</phrase>
1593 <phrase role="keyword">do</phrase><phrase role="special">{</phrase>
1594 <phrase role="identifier">next</phrase><phrase role="special">=</phrase><phrase role="identifier">pull</phrase><phrase role="special">();</phrase>
1595 <phrase role="special">}</phrase>
1596 <phrase role="keyword">while</phrase><phrase role="special">(</phrase><phrase role="identifier">isspace</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">));</phrase>
1597 <phrase role="special">}</phrase>
1599 <phrase role="keyword">public</phrase><phrase role="special">:</phrase>
1600 <phrase role="identifier">Parser</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">is_</phrase><phrase role="special">,</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">function</phrase><phrase role="special"><</phrase><phrase role="keyword">void</phrase><phrase role="special">(</phrase><phrase role="keyword">char</phrase><phrase role="special">)></phrase> <phrase role="identifier">cb_</phrase><phrase role="special">)</phrase> <phrase role="special">:</phrase>
1601 <phrase role="identifier">next</phrase><phrase role="special">(),</phrase> <phrase role="identifier">is</phrase><phrase role="special">(</phrase><phrase role="identifier">is_</phrase><phrase role="special">),</phrase> <phrase role="identifier">cb</phrase><phrase role="special">(</phrase><phrase role="identifier">cb_</phrase><phrase role="special">)</phrase>
1602 <phrase role="special">{}</phrase>
1604 <phrase role="keyword">void</phrase> <phrase role="identifier">run</phrase><phrase role="special">()</phrase> <phrase role="special">{</phrase>
1605 <phrase role="identifier">scan</phrase><phrase role="special">();</phrase>
1606 <phrase role="identifier">E</phrase><phrase role="special">();</phrase>
1607 <phrase role="special">}</phrase>
1609 <phrase role="keyword">private</phrase><phrase role="special">:</phrase>
1610 <phrase role="keyword">void</phrase> <phrase role="identifier">E</phrase><phrase role="special">(){</phrase>
1611 <phrase role="identifier">T</phrase><phrase role="special">();</phrase>
1612 <phrase role="keyword">while</phrase> <phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">==</phrase><phrase role="char">'+'</phrase><phrase role="special">||</phrase><phrase role="identifier">next</phrase><phrase role="special">==</phrase><phrase role="char">'-'</phrase><phrase role="special">){</phrase>
1613 <phrase role="identifier">cb</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">);</phrase>
1614 <phrase role="identifier">scan</phrase><phrase role="special">();</phrase>
1615 <phrase role="identifier">T</phrase><phrase role="special">();</phrase>
1616 <phrase role="special">}</phrase>
1617 <phrase role="special">}</phrase>
1619 <phrase role="keyword">void</phrase> <phrase role="identifier">T</phrase><phrase role="special">(){</phrase>
1620 <phrase role="identifier">S</phrase><phrase role="special">();</phrase>
1621 <phrase role="keyword">while</phrase> <phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">==</phrase><phrase role="char">'*'</phrase><phrase role="special">||</phrase><phrase role="identifier">next</phrase><phrase role="special">==</phrase><phrase role="char">'/'</phrase><phrase role="special">){</phrase>
1622 <phrase role="identifier">cb</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">);</phrase>
1623 <phrase role="identifier">scan</phrase><phrase role="special">();</phrase>
1624 <phrase role="identifier">S</phrase><phrase role="special">();</phrase>
1625 <phrase role="special">}</phrase>
1626 <phrase role="special">}</phrase>
1628 <phrase role="keyword">void</phrase> <phrase role="identifier">S</phrase><phrase role="special">(){</phrase>
1629 <phrase role="keyword">if</phrase> <phrase role="special">(</phrase><phrase role="identifier">isdigit</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">)){</phrase>
1630 <phrase role="identifier">cb</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">);</phrase>
1631 <phrase role="identifier">scan</phrase><phrase role="special">();</phrase>
1632 <phrase role="special">}</phrase>
1633 <phrase role="keyword">else</phrase> <phrase role="keyword">if</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">==</phrase><phrase role="char">'('</phrase><phrase role="special">){</phrase>
1634 <phrase role="identifier">cb</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">);</phrase>
1635 <phrase role="identifier">scan</phrase><phrase role="special">();</phrase>
1636 <phrase role="identifier">E</phrase><phrase role="special">();</phrase>
1637 <phrase role="keyword">if</phrase> <phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">==</phrase><phrase role="char">')'</phrase><phrase role="special">){</phrase>
1638 <phrase role="identifier">cb</phrase><phrase role="special">(</phrase><phrase role="identifier">next</phrase><phrase role="special">);</phrase>
1639 <phrase role="identifier">scan</phrase><phrase role="special">();</phrase>
1640 <phrase role="special">}</phrase><phrase role="keyword">else</phrase><phrase role="special">{</phrase>
1641 <phrase role="keyword">throw</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">runtime_error</phrase><phrase role="special">(</phrase><phrase role="string">"parsing failed"</phrase><phrase role="special">);</phrase>
1642 <phrase role="special">}</phrase>
1643 <phrase role="special">}</phrase>
1644 <phrase role="keyword">else</phrase><phrase role="special">{</phrase>
1645 <phrase role="keyword">throw</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">runtime_error</phrase><phrase role="special">(</phrase><phrase role="string">"parsing failed"</phrase><phrase role="special">);</phrase>
1646 <phrase role="special">}</phrase>
1647 <phrase role="special">}</phrase>
1648 <phrase role="special">};</phrase>
1650 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">istringstream</phrase> <phrase role="identifier">is</phrase><phrase role="special">(</phrase><phrase role="string">"1+1"</phrase><phrase role="special">);</phrase>
1651 <phrase role="comment">// execute parser in new continuation</phrase>
1652 <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="identifier">source</phrase><phrase role="special">;</phrase>
1653 <phrase role="comment">// user-code pulls parsed data from parser</phrase>
1654 <phrase role="comment">// invert control flow</phrase>
1655 <phrase role="keyword">char</phrase> <phrase role="identifier">c</phrase><phrase role="special">;</phrase>
1656 <phrase role="keyword">bool</phrase> <phrase role="identifier">done</phrase><phrase role="special">=</phrase><phrase role="keyword">false</phrase><phrase role="special">;</phrase>
1657 <phrase role="identifier">source</phrase><phrase role="special">=</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">callcc</phrase><phrase role="special">(</phrase>
1658 <phrase role="special">[&</phrase><phrase role="identifier">is</phrase><phrase role="special">,&</phrase><phrase role="identifier">c</phrase><phrase role="special">,&</phrase><phrase role="identifier">done</phrase><phrase role="special">](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">continuation</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">sink</phrase><phrase role="special">){</phrase>
1659 <phrase role="comment">// create parser with callback function</phrase>
1660 <phrase role="identifier">Parser</phrase> <phrase role="identifier">p</phrase><phrase role="special">(</phrase><phrase role="identifier">is</phrase><phrase role="special">,</phrase>
1661 <phrase role="special">[&</phrase><phrase role="identifier">sink</phrase><phrase role="special">,&</phrase><phrase role="identifier">c</phrase><phrase role="special">](</phrase><phrase role="keyword">char</phrase> <phrase role="identifier">c_</phrase><phrase role="special">){</phrase>
1662 <phrase role="comment">// resume main continuation</phrase>
1663 <phrase role="identifier">c</phrase><phrase role="special">=</phrase><phrase role="identifier">c_</phrase><phrase role="special">;</phrase>
1664 <phrase role="identifier">sink</phrase><phrase role="special">=</phrase><phrase role="identifier">sink</phrase><phrase role="special">.</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
1665 <phrase role="special">});</phrase>
1666 <phrase role="comment">// start recursive parsing</phrase>
1667 <phrase role="identifier">p</phrase><phrase role="special">.</phrase><phrase role="identifier">run</phrase><phrase role="special">();</phrase>
1668 <phrase role="comment">// signal termination</phrase>
1669 <phrase role="identifier">done</phrase><phrase role="special">=</phrase><phrase role="keyword">true</phrase><phrase role="special">;</phrase>
1670 <phrase role="comment">// resume main continuation</phrase>
1671 <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">sink</phrase><phrase role="special">);</phrase>
1672 <phrase role="special">});</phrase>
1673 <phrase role="keyword">while</phrase><phrase role="special">(!</phrase><phrase role="identifier">done</phrase><phrase role="special">){</phrase>
1674 <phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">"Parsed: %c\n"</phrase><phrase role="special">,</phrase><phrase role="identifier">c</phrase><phrase role="special">);</phrase>
1675 <phrase role="identifier">source</phrase><phrase role="special">=</phrase><phrase role="identifier">source</phrase><phrase role="special">.</phrase><phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
1676 <phrase role="special">}</phrase>
1678 <phrase role="identifier">output</phrase><phrase role="special">:</phrase>
1679 <phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase>
1680 <phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="special">+</phrase>
1681 <phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase>
1684 In this example a recursive descent parser uses a callback to emit a newly
1685 passed symbol. Using <emphasis>call/cc</emphasis> the control flow can be inverted,
1686 e.g. the user-code pulls parsed symbols from the parser - instead to get pushed
1687 from the parser (via callback).
1690 The data (character) is transferred between the two continuations.
1692 <section id="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber">
1693 <title><anchor id="implementation0"/><link linkend="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber">Implementations:
1694 fcontext_t, ucontext_t and WinFiber</link></title>
1695 <bridgehead renderas="sect4" id="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber.h0">
1696 <phrase id="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber.fcontext_t"/><link
1697 linkend="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber.fcontext_t">fcontext_t</link>
1700 The implementation uses <emphasis>fcontext_t</emphasis> per default. fcontext_t
1701 is based on assembler and not available for all platforms. It provides a
1702 much better performance than <emphasis>ucontext_t</emphasis> (the context
1703 switch takes two magnitudes of order less CPU cycles; see section <link linkend="performance"><emphasis>performance</emphasis></link>)
1704 and <emphasis>WinFiber</emphasis>.
1708 Because the TIB (thread information block on Windows) is not fully described
1709 in the MSDN, it might be possible that not all required TIB-parts are swapped.
1710 Using WinFiber implementation migh be an alternative.
1713 <bridgehead renderas="sect4" id="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber.h1">
1714 <phrase id="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber.ucontext_t"/><link
1715 linkend="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber.ucontext_t">ucontext_t</link>
1718 As an alternative, <ulink url="https://en.wikipedia.org/wiki/Setcontext"><emphasis>ucontext_t</emphasis></ulink>
1719 can be used by compiling with <code><phrase role="identifier">BOOST_USE_UCONTEXT</phrase></code>
1720 and b2 property <code><phrase role="identifier">context</phrase><phrase role="special">-</phrase><phrase
1721 role="identifier">impl</phrase><phrase role="special">=</phrase><phrase role="identifier">ucontext</phrase></code>.
1722 <emphasis>ucontext_t</emphasis> might be available on a broader range of
1723 POSIX-platforms but has some <link linkend="ucontext"><emphasis>disadvantages</emphasis></link>
1724 (for instance deprecated since POSIX.1-2003, not C99 conform).
1728 <link linkend="cc"><emphasis>callcc()</emphasis></link> supports <link
1729 linkend="segmented"><emphasis>Segmented stacks</emphasis></link> only with
1730 <emphasis>ucontext_t</emphasis> as its implementation.
1733 <bridgehead renderas="sect4" id="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber.h2">
1734 <phrase id="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber.winfiber"/><link
1735 linkend="context.cc.implementations__fcontext_t__ucontext_t_and_winfiber.winfiber">WinFiber</link>
1738 With <code><phrase role="identifier">BOOST_USE_WINFIB</phrase></code> and
1739 b2 property <code><phrase role="identifier">context</phrase><phrase role="special">-</phrase><phrase
1740 role="identifier">impl</phrase><phrase role="special">=</phrase><phrase role="identifier">winfib</phrase></code>
1741 Win32-Fibers are used as implementation for <link linkend="cc"><emphasis>callcc()</emphasis></link>.
1745 The first call of <link linkend="cc"><emphasis>callcc()</emphasis></link>
1746 converts the thread into a Windows fiber by invoking <code><phrase role="identifier">ConvertThreadToFiber</phrase><phrase
1747 role="special">()</phrase></code>. If desired, <code><phrase role="identifier">ConvertFiberToThread</phrase><phrase
1748 role="special">()</phrase></code> has to be called by the user explicitly
1749 in order to release resources allocated by <code><phrase role="identifier">ConvertThreadToFiber</phrase><phrase
1750 role="special">()</phrase></code> (e.g. after using boost.context).
1754 <section id="context.cc.class__continuation_">
1755 <title><link linkend="context.cc.class__continuation_">Class <code><phrase
1756 role="identifier">continuation</phrase></code></link></title>
1757 <programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">context</phrase><phrase role="special">/</phrase><phrase role="identifier">continuation</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">></phrase>
1759 <phrase role="keyword">class</phrase> <phrase role="identifier">continuation</phrase> <phrase role="special">{</phrase>
1760 <phrase role="keyword">public</phrase><phrase role="special">:</phrase>
1761 <phrase role="identifier">continuation</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase> <phrase role="special">=</phrase> <phrase role="keyword">default</phrase><phrase role="special">;</phrase>
1763 <phrase role="special">~</phrase><phrase role="identifier">continuation</phrase><phrase role="special">();</phrase>
1765 <phrase role="identifier">continuation</phrase><phrase role="special">(</phrase><phrase role="identifier">continuation</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
1767 <phrase role="identifier">continuation</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase><phrase role="identifier">continuation</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
1769 <phrase role="identifier">continuation</phrase><phrase role="special">(</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
1770 <phrase role="identifier">continuation</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
1772 <phrase role="identifier">continuation</phrase> <phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
1774 <phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">></phrase>
1775 <phrase role="identifier">continuation</phrase> <phrase role="identifier">resume_with</phrase><phrase role="special">(</phrase><phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">);</phrase>
1777 <phrase role="keyword">explicit</phrase> <phrase role="keyword">operator</phrase> <phrase role="keyword">bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
1779 <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
1781 <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">==(</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
1783 <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!=(</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
1785 <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><(</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
1787 <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>(</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
1789 <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><=(</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
1791 <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>=(</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
1793 <phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase><phrase role="keyword">class</phrase> <phrase role="identifier">traitsT</phrase><phrase role="special">></phrase>
1794 <phrase role="keyword">friend</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase><phrase role="identifier">charT</phrase><phrase role="special">,</phrase><phrase role="identifier">traitsT</phrase><phrase role="special">></phrase> <phrase role="special">&</phrase>
1795 <phrase role="keyword">operator</phrase><phrase role="special"><<(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase><phrase role="identifier">charT</phrase><phrase role="special">,</phrase><phrase role="identifier">traitsT</phrase><phrase role="special">></phrase> <phrase role="special">&</phrase> <phrase role="identifier">os</phrase><phrase role="special">,</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase>
1797 <phrase role="keyword">void</phrase> <phrase role="identifier">swap</phrase><phrase role="special">(</phrase><phrase role="identifier">continuation</phrase> <phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
1798 <phrase role="special">};</phrase>
1801 <bridgehead renderas="sect4" id="cc_constructor_bridgehead">
1802 <phrase id="cc_constructor"/>
1803 <link linkend="cc_constructor">Constructor</link>
1806 <programlisting><phrase role="identifier">continuation</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
1811 <term>Effects:</term>
1814 Creates a invalid continuation.
1819 <term>Throws:</term>
1828 <bridgehead renderas="sect4" id="cc_destructor destructor_bridgehead">
1829 <phrase id="cc_destructor destructor"/>
1830 <link linkend="cc_destructor
1831 destructor">Destructor</link>
1834 <programlisting><phrase role="special">~</phrase><phrase role="identifier">continuation</phrase><phrase role="special">();</phrase>
1839 <term>Effects:</term>
1842 Destructs the associated stack if <code><phrase role="special">*</phrase><phrase
1843 role="keyword">this</phrase></code> is a valid continuation, e.g.
1844 <emphasis>continuation::operator bool()</emphasis> returns <code><phrase
1845 role="keyword">true</phrase></code>.
1850 <term>Throws:</term>
1859 <bridgehead renderas="sect4" id="cc_move constructor_bridgehead">
1860 <phrase id="cc_move constructor"/>
1861 <link linkend="cc_move constructor">Move
1865 <programlisting><phrase role="identifier">continuation</phrase><phrase role="special">(</phrase><phrase role="identifier">continuation</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
1870 <term>Effects:</term>
1873 Moves underlying capture continuation to <code><phrase role="special">*</phrase><phrase
1874 role="keyword">this</phrase></code>.
1879 <term>Throws:</term>
1888 <bridgehead renderas="sect4" id="cc_move assignment_bridgehead">
1889 <phrase id="cc_move assignment"/>
1890 <link linkend="cc_move assignment">Move assignment
1894 <programlisting><phrase role="identifier">continuation</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase><phrase role="identifier">continuation</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
1899 <term>Effects:</term>
1902 Moves the state of <code><phrase role="identifier">other</phrase></code>
1903 to <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
1904 using move semantics.
1909 <term>Throws:</term>
1918 <bridgehead renderas="sect4" id="cc_operator_call_bridgehead">
1919 <phrase id="cc_operator_call"/>
1920 <link linkend="cc_operator_call">Member function
1921 <code>operator()</code>()</link>
1924 <programlisting><phrase role="identifier">continuation</phrase> <phrase role="identifier">resume</phrase><phrase role="special">();</phrase>
1926 <phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">></phrase>
1927 <phrase role="identifier">continuation</phrase> <phrase role="identifier">resume_with</phrase><phrase role="special">(</phrase><phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">);</phrase>
1932 <term>Effects:</term>
1935 Captures current continuation and resumes <code><phrase role="special">*</phrase><phrase
1936 role="keyword">this</phrase></code>. The function <code><phrase role="identifier">resume_with</phrase></code>,
1937 is used to execute function <code><phrase role="identifier">fn</phrase></code>
1938 in the execution context of <code><phrase role="special">*</phrase><phrase
1939 role="keyword">this</phrase></code> (e.g. the stack frame of <code><phrase
1940 role="identifier">fn</phrase></code> is allocated on stack of <code><phrase
1941 role="special">*</phrase><phrase role="keyword">this</phrase></code>).
1946 <term>Returns:</term>
1949 The continuation representing the continuation that has been suspended.
1957 Function <code><phrase role="identifier">fn</phrase></code> needs to
1958 return <code><phrase role="identifier">continuation</phrase></code>.
1966 The returned continuation indicates if the suspended continuation has
1967 terminated (return from context-function) via <code><phrase role="keyword">bool</phrase>
1968 <phrase role="keyword">operator</phrase><phrase role="special">()</phrase></code>.
1974 <bridgehead renderas="sect4" id="cc_operator_bool_bridgehead">
1975 <phrase id="cc_operator_bool"/>
1976 <link linkend="cc_operator_bool">Member function
1977 <code>operator bool</code>()</link>
1980 <programlisting><phrase role="keyword">explicit</phrase> <phrase role="keyword">operator</phrase> <phrase role="keyword">bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
1985 <term>Returns:</term>
1988 <code><phrase role="keyword">true</phrase></code> if <code><phrase
1989 role="special">*</phrase><phrase role="keyword">this</phrase></code>
1990 points to a captured continuation.
1995 <term>Throws:</term>
2004 <bridgehead renderas="sect4" id="cc_operator_not_bridgehead">
2005 <phrase id="cc_operator_not"/>
2006 <link linkend="cc_operator_not">Member function <code>operator!</code>()</link>
2009 <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
2014 <term>Returns:</term>
2017 <code><phrase role="keyword">true</phrase></code> if <code><phrase
2018 role="special">*</phrase><phrase role="keyword">this</phrase></code>
2019 does not point to a captured continuation.
2024 <term>Throws:</term>
2033 <bridgehead renderas="sect4" id="cc_operator_equal_bridgehead">
2034 <phrase id="cc_operator_equal"/>
2035 <link linkend="cc_operator_equal">Member function
2036 <code>operator==</code>()</link>
2039 <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">==(</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
2044 <term>Returns:</term>
2047 <code><phrase role="keyword">true</phrase></code> if <code><phrase
2048 role="special">*</phrase><phrase role="keyword">this</phrase></code>
2049 and <code><phrase role="identifier">other</phrase></code> represent
2050 the same continuation, <code><phrase role="keyword">false</phrase></code>
2056 <term>Throws:</term>
2065 <bridgehead renderas="sect4" id="cc_operator_notequal_bridgehead">
2066 <phrase id="cc_operator_notequal"/>
2067 <link linkend="cc_operator_notequal">Member
2068 function <code>operator!=</code>()</link>
2071 <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!=(</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
2076 <term>Returns:</term>
2079 <code>! (other == * this)</code>
2084 <term>Throws:</term>
2093 <bridgehead renderas="sect4" id="cc_operator_less_bridgehead">
2094 <phrase id="cc_operator_less"/>
2095 <link linkend="cc_operator_less">Member function
2096 <code>operator<</code>()</link>
2099 <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><(</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
2104 <term>Returns:</term>
2107 <code><phrase role="keyword">true</phrase></code> if <code><phrase
2108 role="special">*</phrase><phrase role="keyword">this</phrase> <phrase
2109 role="special">!=</phrase> <phrase role="identifier">other</phrase></code>
2110 is true and the implementation-defined total order of <code><phrase
2111 role="identifier">continuation</phrase></code> values places <code><phrase
2112 role="special">*</phrase><phrase role="keyword">this</phrase></code>
2113 before <code><phrase role="identifier">other</phrase></code>, false
2119 <term>Throws:</term>
2128 <bridgehead renderas="sect4" id="cc_operator_greater_bridgehead">
2129 <phrase id="cc_operator_greater"/>
2130 <link linkend="cc_operator_greater">Member
2131 function <code>operator></code>()</link>
2134 <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>(</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
2139 <term>Returns:</term>
2142 <code><phrase role="identifier">other</phrase> <phrase role="special"><</phrase>
2143 <phrase role="special">*</phrase> <phrase role="keyword">this</phrase></code>
2148 <term>Throws:</term>
2157 <bridgehead renderas="sect4" id="cc_operator_lesseq_bridgehead">
2158 <phrase id="cc_operator_lesseq"/>
2159 <link linkend="cc_operator_lesseq">Member function
2160 <code>operator<=</code>()</link>
2163 <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><=(</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
2168 <term>Returns:</term>
2171 <code><phrase role="special">!</phrase> <phrase role="special">(</phrase><phrase
2172 role="identifier">other</phrase> <phrase role="special"><</phrase>
2173 <phrase role="special">*</phrase> <phrase role="keyword">this</phrase><phrase
2174 role="special">)</phrase></code>
2179 <term>Throws:</term>
2188 <bridgehead renderas="sect4" id="cc_operator_greatereq_bridgehead">
2189 <phrase id="cc_operator_greatereq"/>
2190 <link linkend="cc_operator_greatereq">Member
2191 function <code>operator>=</code>()</link>
2194 <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>=(</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
2199 <term>Returns:</term>
2202 <code><phrase role="special">!</phrase> <phrase role="special">(*</phrase>
2203 <phrase role="keyword">this</phrase> <phrase role="special"><</phrase>
2204 <phrase role="identifier">other</phrase><phrase role="special">)</phrase></code>
2209 <term>Throws:</term>
2218 <bridgehead renderas="sect4" id="cc__bridgehead">
2220 <link linkend="cc_">Non-member function <code>operator<<()</code></link>
2223 <programlisting><phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase><phrase role="keyword">class</phrase> <phrase role="identifier">traitsT</phrase><phrase role="special">></phrase>
2224 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase><phrase role="identifier">charT</phrase><phrase role="special">,</phrase><phrase role="identifier">traitsT</phrase><phrase role="special">></phrase> <phrase role="special">&</phrase>
2225 <phrase role="keyword">operator</phrase><phrase role="special"><<(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase><phrase role="identifier">charT</phrase><phrase role="special">,</phrase><phrase role="identifier">traitsT</phrase><phrase role="special">></phrase> <phrase role="special">&</phrase> <phrase role="identifier">os</phrase><phrase role="special">,</phrase><phrase role="identifier">continuation</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">);</phrase>
2230 <term>Effects:</term>
2233 Writes the representation of <code><phrase role="identifier">other</phrase></code>
2234 to stream <code><phrase role="identifier">os</phrase></code>.
2239 <term>Returns:</term>
2242 <code><phrase role="identifier">os</phrase></code>
2247 <bridgehead renderas="sect4" id="context.cc.class__continuation_.h0">
2248 <phrase id="context.cc.class__continuation_.call_with_current_continuation"/><link
2249 linkend="context.cc.class__continuation_.call_with_current_continuation">Call
2250 with current continuation</link>
2252 <programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">context</phrase><phrase role="special">/</phrase><phrase role="identifier">continuation</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">></phrase>
2254 <phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">></phrase>
2255 <phrase role="identifier">continuation</phrase> <phrase role="identifier">callcc</phrase><phrase role="special">(</phrase><phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">);</phrase>
2257 <phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">StackAlloc</phrase><phrase role="special">,</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">></phrase>
2258 <phrase role="identifier">continuation</phrase> <phrase role="identifier">callcc</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase><phrase role="identifier">StackAlloc</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase><phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">);</phrase>
2260 <phrase role="keyword">template</phrase><phrase role="special"><</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">StackAlloc</phrase><phrase role="special">,</phrase><phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">></phrase>
2261 <phrase role="identifier">continuation</phrase> <phrase role="identifier">callcc</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase><phrase role="identifier">preallocated</phrase> <phrase role="identifier">palloc</phrase><phrase role="special">,</phrase><phrase role="identifier">StackAlloc</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase><phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">);</phrase>
2266 <term>Effects:</term>
2269 Captures current continuation and creates a new continuation prepared
2270 to execute <code><phrase role="identifier">fn</phrase></code>. <code><phrase
2271 role="identifier">fixedsize_stack</phrase></code> is used as default
2272 stack allocator (stack size == fixedsize_stack::traits::default_size()).
2273 The function with argument type <code><phrase role="identifier">preallocated</phrase></code>,
2274 is used to create a user defined data <link linkend="cc_prealloc">(for
2275 instance additional control structures)</link> on top of the stack.
2280 <term>Returns:</term>
2283 The continuation representing the contexcontinuation that has been
2292 The returned continuation indicates if the suspended continuation has
2293 terminated (return from context-function) via <code><phrase role="keyword">bool</phrase>
2294 <phrase role="keyword">operator</phrase><phrase role="special">()</phrase></code>.
2301 <section id="context.stack">
2302 <title><anchor id="stack"/><link linkend="context.stack">Stack allocation</link></title>
2304 The memory used by the stack is allocated/deallocated via a <emphasis>StackAllocator</emphasis>
2305 which is required to model a <emphasis>stack-allocator concept</emphasis>.
2307 <bridgehead renderas="sect3" id="context.stack.h0">
2308 <phrase id="context.stack._emphasis_stack_allocator_concept__emphasis_"/><link
2309 linkend="context.stack._emphasis_stack_allocator_concept__emphasis_"><emphasis>stack-allocator
2310 concept</emphasis></link>
2313 A <emphasis>StackAllocator</emphasis> must satisfy the <emphasis>stack-allocator
2314 concept</emphasis> requirements shown in the following table, in which <code><phrase
2315 role="identifier">a</phrase></code> is an object of a <emphasis>StackAllocator</emphasis>
2316 type, <code><phrase role="identifier">sctx</phrase></code> is a <code><phrase
2317 role="identifier">stack_context</phrase></code>, and <code><phrase role="identifier">size</phrase></code>
2318 is a <code><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
2319 role="identifier">size_t</phrase></code>:
2321 <informaltable frame="all">
2346 <code><phrase role="identifier">a</phrase><phrase role="special">(</phrase><phrase
2347 role="identifier">size</phrase><phrase role="special">)</phrase></code>
2354 creates a stack allocator
2361 <code><phrase role="identifier">a</phrase><phrase role="special">.</phrase><phrase
2362 role="identifier">allocate</phrase><phrase role="special">()</phrase></code>
2367 <code><phrase role="identifier">stack_context</phrase></code>
2379 <code><phrase role="identifier">a</phrase><phrase role="special">.</phrase><phrase
2380 role="identifier">deallocate</phrase><phrase role="special">(</phrase>
2381 <phrase role="identifier">sctx</phrase><phrase role="special">)</phrase></code>
2386 <code><phrase role="keyword">void</phrase></code>
2391 deallocates the stack created by <code><phrase role="identifier">a</phrase><phrase
2392 role="special">.</phrase><phrase role="identifier">allocate</phrase><phrase
2393 role="special">()</phrase></code>
2402 The implementation of <code><phrase role="identifier">allocate</phrase><phrase
2403 role="special">()</phrase></code> might include logic to protect against
2404 exceeding the context's available stack size rather than leaving it as undefined
2410 Calling <code><phrase role="identifier">deallocate</phrase><phrase role="special">()</phrase></code>
2411 with a <code><phrase role="identifier">stack_context</phrase></code> not
2412 set by <code><phrase role="identifier">allocate</phrase><phrase role="special">()</phrase></code>
2413 results in undefined behaviour.
2418 Depending on the architecture <code><phrase role="identifier">allocate</phrase><phrase
2419 role="special">()</phrase></code> stores an address from the top of the stack
2420 (growing downwards) or the bottom of the stack (growing upwards).
2423 <section id="context.stack.protected_fixedsize">
2424 <title><link linkend="context.stack.protected_fixedsize">Class <emphasis>protected_fixedsize</emphasis></link></title>
2426 <emphasis role="bold">Boost.Context</emphasis> provides the class <emphasis>protected_fixedsize_stack</emphasis>
2427 which models the <emphasis>stack-allocator concept</emphasis>. It appends
2428 a guard page at the end of each stack to protect against exceeding the stack.
2429 If the guard page is accessed (read or write operation) a segmentation fault/access
2430 violation is generated by the operating system.
2434 Using <emphasis>protected_fixedsize_stack</emphasis> is expensive. That
2435 is, launching a new coroutine with a new stack is expensive; the allocated
2436 stack is just as efficient to use as any other stack.
2441 The appended <code><phrase role="identifier">guard</phrase> <phrase role="identifier">page</phrase></code>
2442 is <emphasis role="bold">not</emphasis> mapped to physical memory, only
2443 virtual addresses are used.
2446 <programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">context</phrase><phrase role="special">/</phrase><phrase role="identifier">protected_fixedsize</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">></phrase>
2448 <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase>
2449 <phrase role="keyword">struct</phrase> <phrase role="identifier">basic_protected_fixedsize</phrase> <phrase role="special">{</phrase>
2450 <phrase role="keyword">typedef</phrase> <phrase role="identifier">traitT</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">;</phrase>
2452 <phrase role="identifier">basic_protected_fixesize</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase> <phrase role="special">=</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase role="identifier">default_size</phrase><phrase role="special">());</phrase>
2454 <phrase role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">();</phrase>
2456 <phrase role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&);</phrase>
2457 <phrase role="special">}</phrase>
2459 <phrase role="keyword">typedef</phrase> <phrase role="identifier">basic_protected_fixedsize</phrase><phrase role="special"><</phrase> <phrase role="identifier">stack_traits</phrase> <phrase role="special">></phrase> <phrase role="identifier">protected_fixedsize</phrase>
2461 <bridgehead renderas="sect4" id="context.stack.protected_fixedsize.h0">
2462 <phrase id="context.stack.protected_fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"/><link
2463 linkend="context.stack.protected_fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"><code><phrase
2464 role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase
2465 role="special">()</phrase></code></link>
2470 <term>Preconditions:</term>
2473 <code><phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
2474 role="identifier">minimum</phrase><phrase role="special">:</phrase><phrase
2475 role="identifier">size</phrase><phrase role="special">()</phrase>
2476 <phrase role="special"><=</phrase> <phrase role="identifier">size</phrase></code>
2477 and <code><phrase role="special">!</phrase> <phrase role="identifier">traits_type</phrase><phrase
2478 role="special">::</phrase><phrase role="identifier">is_unbounded</phrase><phrase
2479 role="special">()</phrase> <phrase role="special">&&</phrase>
2480 <phrase role="special">(</phrase> <phrase role="identifier">traits_type</phrase><phrase
2481 role="special">::</phrase><phrase role="identifier">maximum</phrase><phrase
2482 role="special">:</phrase><phrase role="identifier">size</phrase><phrase
2483 role="special">()</phrase> <phrase role="special">>=</phrase> <phrase
2484 role="identifier">size</phrase><phrase role="special">)</phrase></code>.
2489 <term>Effects:</term>
2492 Allocates memory of at least <code><phrase role="identifier">size</phrase></code>
2493 Bytes and stores a pointer to the stack and its actual size in <code><phrase
2494 role="identifier">sctx</phrase></code>. Depending on the architecture
2495 (the stack grows downwards/upwards) the stored address is the highest/lowest
2496 address of the stack.
2501 <bridgehead renderas="sect4" id="context.stack.protected_fixedsize.h1">
2502 <phrase id="context.stack.protected_fixedsize._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
2503 linkend="context.stack.protected_fixedsize._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
2504 role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase
2505 role="special">(</phrase> <phrase role="identifier">stack_context</phrase>
2506 <phrase role="special">&</phrase> <phrase role="identifier">sctx</phrase><phrase
2507 role="special">)</phrase></code></link>
2512 <term>Preconditions:</term>
2515 <code><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
2516 role="identifier">sp</phrase></code> is valid, <code><phrase role="identifier">traits_type</phrase><phrase
2517 role="special">::</phrase><phrase role="identifier">minimum</phrase><phrase
2518 role="special">:</phrase><phrase role="identifier">size</phrase><phrase
2519 role="special">()</phrase> <phrase role="special"><=</phrase> <phrase
2520 role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
2521 role="identifier">size</phrase></code> and <code><phrase role="special">!</phrase>
2522 <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
2523 role="identifier">is_unbounded</phrase><phrase role="special">()</phrase>
2524 <phrase role="special">&&</phrase> <phrase role="special">(</phrase>
2525 <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
2526 role="identifier">maximum</phrase><phrase role="special">:</phrase><phrase
2527 role="identifier">size</phrase><phrase role="special">()</phrase>
2528 <phrase role="special">>=</phrase> <phrase role="identifier">sctx</phrase><phrase
2529 role="special">.</phrase><phrase role="identifier">size</phrase><phrase
2530 role="special">)</phrase></code>.
2535 <term>Effects:</term>
2538 Deallocates the stack space.
2544 <section id="context.stack.pooled_fixedsize">
2545 <title><link linkend="context.stack.pooled_fixedsize">Class <emphasis>pooled_fixedsize_stack</emphasis></link></title>
2547 <emphasis role="bold">Boost.Context</emphasis> provides the class <emphasis>pooled_fixedsize_stack</emphasis>
2548 which models the <emphasis>stack-allocator concept</emphasis>. In contrast
2549 to <emphasis>protected_fixedsize_stack</emphasis> it does not append a guard
2550 page at the end of each stack. The memory is managed internally by <ulink
2551 url="http://www.boost.org/doc/libs/release/libs/pool/doc/html/boost/pool.html"><code><phrase
2552 role="identifier">boost</phrase><phrase role="special">::</phrase><phrase
2553 role="identifier">pool</phrase><phrase role="special"><></phrase></code></ulink>.
2555 <programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">context</phrase><phrase role="special">/</phrase><phrase role="identifier">pooled_fixedsize_stack</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">></phrase>
2557 <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase>
2558 <phrase role="keyword">struct</phrase> <phrase role="identifier">basic_pooled_fixedsize_stack</phrase> <phrase role="special">{</phrase>
2559 <phrase role="keyword">typedef</phrase> <phrase role="identifier">traitT</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">;</phrase>
2561 <phrase role="identifier">basic_pooled_fixedsize_stack</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">stack_size</phrase> <phrase role="special">=</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase role="identifier">default_size</phrase><phrase role="special">(),</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">next_size</phrase> <phrase role="special">=</phrase> <phrase role="number">32</phrase><phrase role="special">,</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">max_size</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">);</phrase>
2563 <phrase role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">();</phrase>
2565 <phrase role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&);</phrase>
2566 <phrase role="special">}</phrase>
2568 <phrase role="keyword">typedef</phrase> <phrase role="identifier">basic_pooled_fixedsize_stack</phrase><phrase role="special"><</phrase> <phrase role="identifier">stack_traits</phrase> <phrase role="special">></phrase> <phrase role="identifier">pooled_fixedsize_stack</phrase><phrase role="special">;</phrase>
2570 <bridgehead renderas="sect4" id="context.stack.pooled_fixedsize.h0">
2571 <phrase id="context.stack.pooled_fixedsize._code__phrase_role__identifier__basic_pooled_fixedsize_stack__phrase__phrase_role__special_____phrase__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__stack_size__phrase__phrase_role__special_____phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__next_size__phrase__phrase_role__special_____phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__max_size__phrase__phrase_role__special_____phrase___code_"/><link
2572 linkend="context.stack.pooled_fixedsize._code__phrase_role__identifier__basic_pooled_fixedsize_stack__phrase__phrase_role__special_____phrase__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__stack_size__phrase__phrase_role__special_____phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__next_size__phrase__phrase_role__special_____phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__max_size__phrase__phrase_role__special_____phrase___code_"><code><phrase
2573 role="identifier">basic_pooled_fixedsize_stack</phrase><phrase role="special">(</phrase><phrase
2574 role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase>
2575 <phrase role="identifier">stack_size</phrase><phrase role="special">,</phrase>
2576 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
2577 role="identifier">size_t</phrase> <phrase role="identifier">next_size</phrase><phrase
2578 role="special">,</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
2579 role="identifier">size_t</phrase> <phrase role="identifier">max_size</phrase><phrase
2580 role="special">)</phrase></code></link>
2585 <term>Preconditions:</term>
2588 <code><phrase role="special">!</phrase> <phrase role="identifier">traits_type</phrase><phrase
2589 role="special">::</phrase><phrase role="identifier">is_unbounded</phrase><phrase
2590 role="special">()</phrase> <phrase role="special">&&</phrase>
2591 <phrase role="special">(</phrase> <phrase role="identifier">traits_type</phrase><phrase
2592 role="special">::</phrase><phrase role="identifier">maximum</phrase><phrase
2593 role="special">:</phrase><phrase role="identifier">size</phrase><phrase
2594 role="special">()</phrase> <phrase role="special">>=</phrase> <phrase
2595 role="identifier">stack_size</phrase><phrase role="special">)</phrase></code>
2596 and <code><phrase role="number">0</phrase> <phrase role="special"><</phrase>
2597 <phrase role="identifier">nest_size</phrase></code>.
2602 <term>Effects:</term>
2605 Allocates memory of at least <code><phrase role="identifier">stack_size</phrase></code>
2606 Bytes and stores a pointer to the stack and its actual size in <code><phrase
2607 role="identifier">sctx</phrase></code>. Depending on the architecture
2608 (the stack grows downwards/upwards) the stored address is the highest/lowest
2609 address of the stack. Argument <code><phrase role="identifier">next_size</phrase></code>
2610 determines the number of stacks to request from the system the first
2611 time that <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
2612 needs to allocate system memory. The third argument <code><phrase role="identifier">max_size</phrase></code>
2613 controls how many memory might be allocated for stacks - a value of
2614 zero means no uper limit.
2619 <bridgehead renderas="sect4" id="context.stack.pooled_fixedsize.h1">
2620 <phrase id="context.stack.pooled_fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"/><link
2621 linkend="context.stack.pooled_fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"><code><phrase
2622 role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase
2623 role="special">()</phrase></code></link>
2628 <term>Preconditions:</term>
2631 <code><phrase role="special">!</phrase> <phrase role="identifier">traits_type</phrase><phrase
2632 role="special">::</phrase><phrase role="identifier">is_unbounded</phrase><phrase
2633 role="special">()</phrase> <phrase role="special">&&</phrase>
2634 <phrase role="special">(</phrase> <phrase role="identifier">traits_type</phrase><phrase
2635 role="special">::</phrase><phrase role="identifier">maximum</phrase><phrase
2636 role="special">:</phrase><phrase role="identifier">size</phrase><phrase
2637 role="special">()</phrase> <phrase role="special">>=</phrase> <phrase
2638 role="identifier">stack_size</phrase><phrase role="special">)</phrase></code>.
2643 <term>Effects:</term>
2646 Allocates memory of at least <code><phrase role="identifier">stack_size</phrase></code>
2647 Bytes and stores a pointer to the stack and its actual size in <code><phrase
2648 role="identifier">sctx</phrase></code>. Depending on the architecture
2649 (the stack grows downwards/upwards) the stored address is the highest/lowest
2650 address of the stack.
2655 <bridgehead renderas="sect4" id="context.stack.pooled_fixedsize.h2">
2656 <phrase id="context.stack.pooled_fixedsize._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
2657 linkend="context.stack.pooled_fixedsize._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
2658 role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase
2659 role="special">(</phrase> <phrase role="identifier">stack_context</phrase>
2660 <phrase role="special">&</phrase> <phrase role="identifier">sctx</phrase><phrase
2661 role="special">)</phrase></code></link>
2666 <term>Preconditions:</term>
2669 <code><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
2670 role="identifier">sp</phrase></code> is valid, <code><phrase role="special">!</phrase>
2671 <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
2672 role="identifier">is_unbounded</phrase><phrase role="special">()</phrase>
2673 <phrase role="special">&&</phrase> <phrase role="special">(</phrase>
2674 <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
2675 role="identifier">maximum</phrase><phrase role="special">:</phrase><phrase
2676 role="identifier">size</phrase><phrase role="special">()</phrase>
2677 <phrase role="special">>=</phrase> <phrase role="identifier">sctx</phrase><phrase
2678 role="special">.</phrase><phrase role="identifier">size</phrase><phrase
2679 role="special">)</phrase></code>.
2684 <term>Effects:</term>
2687 Deallocates the stack space.
2693 <section id="context.stack.fixedsize">
2694 <title><link linkend="context.stack.fixedsize">Class <emphasis>fixedsize_stack</emphasis></link></title>
2696 <emphasis role="bold">Boost.Context</emphasis> provides the class <emphasis>fixedsize_stack</emphasis>
2697 which models the <emphasis>stack-allocator concept</emphasis>. In contrast
2698 to <emphasis>protected_fixedsize_stack</emphasis> it does not append a guard
2699 page at the end of each stack. The memory is simply managed by <code><phrase
2700 role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">malloc</phrase><phrase
2701 role="special">()</phrase></code> and <code><phrase role="identifier">std</phrase><phrase
2702 role="special">::</phrase><phrase role="identifier">free</phrase><phrase
2703 role="special">()</phrase></code>.
2705 <programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">context</phrase><phrase role="special">/</phrase><phrase role="identifier">fixedsize_stack</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">></phrase>
2707 <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase>
2708 <phrase role="keyword">struct</phrase> <phrase role="identifier">basic_fixedsize_stack</phrase> <phrase role="special">{</phrase>
2709 <phrase role="keyword">typedef</phrase> <phrase role="identifier">traitT</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">;</phrase>
2711 <phrase role="identifier">basic_fixesize_stack</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase> <phrase role="special">=</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase role="identifier">default_size</phrase><phrase role="special">());</phrase>
2713 <phrase role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">();</phrase>
2715 <phrase role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&);</phrase>
2716 <phrase role="special">}</phrase>
2718 <phrase role="keyword">typedef</phrase> <phrase role="identifier">basic_fixedsize_stack</phrase><phrase role="special"><</phrase> <phrase role="identifier">stack_traits</phrase> <phrase role="special">></phrase> <phrase role="identifier">fixedsize_stack</phrase><phrase role="special">;</phrase>
2720 <bridgehead renderas="sect4" id="context.stack.fixedsize.h0">
2721 <phrase id="context.stack.fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"/><link
2722 linkend="context.stack.fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"><code><phrase
2723 role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase
2724 role="special">()</phrase></code></link>
2729 <term>Preconditions:</term>
2732 <code><phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
2733 role="identifier">minimum</phrase><phrase role="special">:</phrase><phrase
2734 role="identifier">size</phrase><phrase role="special">()</phrase>
2735 <phrase role="special"><=</phrase> <phrase role="identifier">size</phrase></code>
2736 and <code><phrase role="special">!</phrase> <phrase role="identifier">traits_type</phrase><phrase
2737 role="special">::</phrase><phrase role="identifier">is_unbounded</phrase><phrase
2738 role="special">()</phrase> <phrase role="special">&&</phrase>
2739 <phrase role="special">(</phrase> <phrase role="identifier">traits_type</phrase><phrase
2740 role="special">::</phrase><phrase role="identifier">maximum</phrase><phrase
2741 role="special">:</phrase><phrase role="identifier">size</phrase><phrase
2742 role="special">()</phrase> <phrase role="special">>=</phrase> <phrase
2743 role="identifier">size</phrase><phrase role="special">)</phrase></code>.
2748 <term>Effects:</term>
2751 Allocates memory of at least <code><phrase role="identifier">size</phrase></code>
2752 Bytes and stores a pointer to the stack and its actual size in <code><phrase
2753 role="identifier">sctx</phrase></code>. Depending on the architecture
2754 (the stack grows downwards/upwards) the stored address is the highest/lowest
2755 address of the stack.
2760 <bridgehead renderas="sect4" id="context.stack.fixedsize.h1">
2761 <phrase id="context.stack.fixedsize._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
2762 linkend="context.stack.fixedsize._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
2763 role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase
2764 role="special">(</phrase> <phrase role="identifier">stack_context</phrase>
2765 <phrase role="special">&</phrase> <phrase role="identifier">sctx</phrase><phrase
2766 role="special">)</phrase></code></link>
2771 <term>Preconditions:</term>
2774 <code><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
2775 role="identifier">sp</phrase></code> is valid, <code><phrase role="identifier">traits_type</phrase><phrase
2776 role="special">::</phrase><phrase role="identifier">minimum</phrase><phrase
2777 role="special">:</phrase><phrase role="identifier">size</phrase><phrase
2778 role="special">()</phrase> <phrase role="special"><=</phrase> <phrase
2779 role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
2780 role="identifier">size</phrase></code> and <code><phrase role="special">!</phrase>
2781 <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
2782 role="identifier">is_unbounded</phrase><phrase role="special">()</phrase>
2783 <phrase role="special">&&</phrase> <phrase role="special">(</phrase>
2784 <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
2785 role="identifier">maximum</phrase><phrase role="special">:</phrase><phrase
2786 role="identifier">size</phrase><phrase role="special">()</phrase>
2787 <phrase role="special">>=</phrase> <phrase role="identifier">sctx</phrase><phrase
2788 role="special">.</phrase><phrase role="identifier">size</phrase><phrase
2789 role="special">)</phrase></code>.
2794 <term>Effects:</term>
2797 Deallocates the stack space.
2803 <section id="context.stack.segmented">
2804 <title><anchor id="segmented"/><link linkend="context.stack.segmented">Class
2805 <emphasis>segmented_stack</emphasis></link></title>
2807 <emphasis role="bold">Boost.Context</emphasis> supports usage of a <link
2808 linkend="segmented"><emphasis>segmented_stack</emphasis></link>, e. g. the
2809 size of the stack grows on demand. The coroutine is created with a minimal
2810 stack size and will be increased as required. Class <link linkend="segmented"><emphasis>segmented_stack</emphasis></link>
2811 models the <emphasis>stack-allocator concept</emphasis>. In contrast to
2812 <emphasis>protected_fixedsize_stack</emphasis> and <emphasis>fixedsize_stack</emphasis>
2813 it creates a stack which grows on demand.
2817 Segmented stacks are currently only supported by <emphasis role="bold">gcc</emphasis>
2818 from version <emphasis role="bold">4.7</emphasis> <emphasis role="bold">clang</emphasis>
2819 from version <emphasis role="bold">3.4</emphasis> onwards. In order to
2820 use a <emphasis>segmented_stack</emphasis> <emphasis role="bold">Boost.Context</emphasis>
2821 must be built with property <code><phrase role="identifier">segmented</phrase><phrase
2822 role="special">-</phrase><phrase role="identifier">stacks</phrase></code>,
2823 e.g. <emphasis role="bold">toolset=gcc segmented-stacks=on</emphasis> and
2824 applying <code><phrase role="identifier">BOOST_USE_SEGMENTED_STACKS</phrase></code>
2825 at b2/bjam command line.
2830 Segmented stacks can only be used with <link linkend="cc"><emphasis>callcc()</emphasis></link>
2831 (using <link linkend="implementation"><emphasis>ucontext_t</emphasis></link>)
2837 <programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">context</phrase><phrase role="special">/</phrase><phrase role="identifier">segmented_stack</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">></phrase>
2839 <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase>
2840 <phrase role="keyword">struct</phrase> <phrase role="identifier">basic_segmented_stack</phrase> <phrase role="special">{</phrase>
2841 <phrase role="keyword">typedef</phrase> <phrase role="identifier">traitT</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">;</phrase>
2843 <phrase role="identifier">basic_segmented_stack</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase> <phrase role="special">=</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase role="identifier">default_size</phrase><phrase role="special">());</phrase>
2845 <phrase role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">();</phrase>
2847 <phrase role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&);</phrase>
2848 <phrase role="special">}</phrase>
2850 <phrase role="keyword">typedef</phrase> <phrase role="identifier">basic_segmented_stack</phrase><phrase role="special"><</phrase> <phrase role="identifier">stack_traits</phrase> <phrase role="special">></phrase> <phrase role="identifier">segmented_stack</phrase><phrase role="special">;</phrase>
2852 <bridgehead renderas="sect4" id="context.stack.segmented.h0">
2853 <phrase id="context.stack.segmented._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"/><link
2854 linkend="context.stack.segmented._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"><code><phrase
2855 role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase
2856 role="special">()</phrase></code></link>
2861 <term>Preconditions:</term>
2864 <code><phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
2865 role="identifier">minimum</phrase><phrase role="special">:</phrase><phrase
2866 role="identifier">size</phrase><phrase role="special">()</phrase>
2867 <phrase role="special"><=</phrase> <phrase role="identifier">size</phrase></code>
2868 and <code><phrase role="special">!</phrase> <phrase role="identifier">traits_type</phrase><phrase
2869 role="special">::</phrase><phrase role="identifier">is_unbounded</phrase><phrase
2870 role="special">()</phrase> <phrase role="special">&&</phrase>
2871 <phrase role="special">(</phrase> <phrase role="identifier">traits_type</phrase><phrase
2872 role="special">::</phrase><phrase role="identifier">maximum</phrase><phrase
2873 role="special">:</phrase><phrase role="identifier">size</phrase><phrase
2874 role="special">()</phrase> <phrase role="special">>=</phrase> <phrase
2875 role="identifier">size</phrase><phrase role="special">)</phrase></code>.
2880 <term>Effects:</term>
2883 Allocates memory of at least <code><phrase role="identifier">size</phrase></code>
2884 Bytes and stores a pointer to the stack and its actual size in <code><phrase
2885 role="identifier">sctx</phrase></code>. Depending on the architecture
2886 (the stack grows downwards/upwards) the stored address is the highest/lowest
2887 address of the stack.
2892 <bridgehead renderas="sect4" id="context.stack.segmented.h1">
2893 <phrase id="context.stack.segmented._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
2894 linkend="context.stack.segmented._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
2895 role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase
2896 role="special">(</phrase> <phrase role="identifier">stack_context</phrase>
2897 <phrase role="special">&</phrase> <phrase role="identifier">sctx</phrase><phrase
2898 role="special">)</phrase></code></link>
2903 <term>Preconditions:</term>
2906 <code><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
2907 role="identifier">sp</phrase></code> is valid, <code><phrase role="identifier">traits_type</phrase><phrase
2908 role="special">::</phrase><phrase role="identifier">minimum</phrase><phrase
2909 role="special">:</phrase><phrase role="identifier">size</phrase><phrase
2910 role="special">()</phrase> <phrase role="special"><=</phrase> <phrase
2911 role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
2912 role="identifier">size</phrase></code> and <code><phrase role="special">!</phrase>
2913 <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
2914 role="identifier">is_unbounded</phrase><phrase role="special">()</phrase>
2915 <phrase role="special">&&</phrase> <phrase role="special">(</phrase>
2916 <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase
2917 role="identifier">maximum</phrase><phrase role="special">:</phrase><phrase
2918 role="identifier">size</phrase><phrase role="special">()</phrase>
2919 <phrase role="special">>=</phrase> <phrase role="identifier">sctx</phrase><phrase
2920 role="special">.</phrase><phrase role="identifier">size</phrase><phrase
2921 role="special">)</phrase></code>.
2926 <term>Effects:</term>
2929 Deallocates the stack space.
2936 If the library is compiled for segmented stacks, <emphasis>segmented_stack</emphasis>
2937 is the only available stack allocator.
2941 <section id="context.stack.stack_traits">
2942 <title><link linkend="context.stack.stack_traits">Class <emphasis>stack_traits</emphasis></link></title>
2944 <emphasis>stack_traits</emphasis> models a <emphasis>stack-traits</emphasis>
2945 providing a way to access certain properites defined by the enironment. Stack
2946 allocators use <emphasis>stack-traits</emphasis> to allocate stacks.
2948 <programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">context</phrase><phrase role="special">/</phrase><phrase role="identifier">stack_traits</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">></phrase>
2950 <phrase role="keyword">struct</phrase> <phrase role="identifier">stack_traits</phrase> <phrase role="special">{</phrase>
2951 <phrase role="keyword">static</phrase> <phrase role="keyword">bool</phrase> <phrase role="identifier">is_unbounded</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
2953 <phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">page_size</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
2955 <phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">default_size</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
2957 <phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">minimum_size</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
2959 <phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">maximum_size</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
2960 <phrase role="special">}</phrase>
2962 <bridgehead renderas="sect4" id="context.stack.stack_traits.h0">
2963 <phrase id="context.stack.stack_traits._code__phrase_role__keyword__static__phrase___phrase_role__keyword__bool__phrase___phrase_role__identifier__is_unbounded__phrase__phrase_role__special______phrase___code_"/><link
2964 linkend="context.stack.stack_traits._code__phrase_role__keyword__static__phrase___phrase_role__keyword__bool__phrase___phrase_role__identifier__is_unbounded__phrase__phrase_role__special______phrase___code_"><code><phrase
2965 role="keyword">static</phrase> <phrase role="keyword">bool</phrase> <phrase
2966 role="identifier">is_unbounded</phrase><phrase role="special">()</phrase></code></link>
2971 <term>Returns:</term>
2974 Returns <code><phrase role="keyword">true</phrase></code> if the environment
2975 defines no limit for the size of a stack.
2980 <term>Throws:</term>
2988 <bridgehead renderas="sect4" id="context.stack.stack_traits.h1">
2989 <phrase id="context.stack.stack_traits._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__page_size__phrase__phrase_role__special______phrase___code_"/><link
2990 linkend="context.stack.stack_traits._code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__page_size__phrase__phrase_role__special______phrase___code_"><code><phrase
2991 role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase
2992 role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase
2993 role="identifier">page_size</phrase><phrase role="special">()</phrase></code></link>
2998 <term>Returns:</term>
3001 Returns the page size in bytes.
3006 <term>Throws:</term>
3014 <bridgehead renderas="sect4" id="context.stack.stack_traits.h2">
3015 <phrase id="context.stack.stack_traits._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_size__phrase__phrase_role__special______phrase___code_"/><link
3016 linkend="context.stack.stack_traits._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_size__phrase__phrase_role__special______phrase___code_"><code><phrase
3017 role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase
3018 role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase
3019 role="identifier">default_size</phrase><phrase role="special">()</phrase></code></link>
3024 <term>Returns:</term>
3027 Returns a default stack size, which may be platform specific. If the
3028 stack is unbounded then the present implementation returns the maximum
3029 of <code><phrase role="number">64</phrase> <phrase role="identifier">kB</phrase></code>
3030 and <code><phrase role="identifier">minimum_size</phrase><phrase role="special">()</phrase></code>.
3035 <term>Throws:</term>
3043 <bridgehead renderas="sect4" id="context.stack.stack_traits.h3">
3044 <phrase id="context.stack.stack_traits._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_size__phrase__phrase_role__special______phrase___code_"/><link
3045 linkend="context.stack.stack_traits._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_size__phrase__phrase_role__special______phrase___code_"><code><phrase
3046 role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase
3047 role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase
3048 role="identifier">minimum_size</phrase><phrase role="special">()</phrase></code></link>
3053 <term>Returns:</term>
3056 Returns the minimum size in bytes of stack defined by the environment
3057 (Win32 4kB/Win64 8kB, defined by rlimit on POSIX).
3062 <term>Throws:</term>
3070 <bridgehead renderas="sect4" id="context.stack.stack_traits.h4">
3071 <phrase id="context.stack.stack_traits._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_size__phrase__phrase_role__special______phrase___code_"/><link
3072 linkend="context.stack.stack_traits._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_size__phrase__phrase_role__special______phrase___code_"><code><phrase
3073 role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase
3074 role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase
3075 role="identifier">maximum_size</phrase><phrase role="special">()</phrase></code></link>
3080 <term>Preconditions:</term>
3083 <code><phrase role="identifier">is_unbounded</phrase><phrase role="special">()</phrase></code>
3084 returns <code><phrase role="keyword">false</phrase></code>.
3089 <term>Returns:</term>
3092 Returns the maximum size in bytes of stack defined by the environment.
3097 <term>Throws:</term>
3106 <section id="context.stack.stack_context">
3107 <title><link linkend="context.stack.stack_context">Class <emphasis>stack_context</emphasis></link></title>
3109 <emphasis role="bold">Boost.Context</emphasis> provides the class <emphasis>stack_context</emphasis>
3110 which will contain the stack pointer and the size of the stack. In case of
3111 a <link linkend="segmented"><emphasis>segmented_stack</emphasis></link>,
3112 <emphasis>stack_context</emphasis> contains some extra control structures.
3114 <programlisting><phrase role="keyword">struct</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">{</phrase>
3115 <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">;</phrase>
3116 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">;</phrase>
3118 <phrase role="comment">// might contain additional control structures</phrase>
3119 <phrase role="comment">// for segmented stacks</phrase>
3120 <phrase role="special">}</phrase>
3122 <bridgehead renderas="sect4" id="context.stack.stack_context.h0">
3123 <phrase id="context.stack.stack_context._code__phrase_role__keyword__void__phrase___phrase_role__special_____phrase___phrase_role__identifier__sp__phrase___code_"/><link
3124 linkend="context.stack.stack_context._code__phrase_role__keyword__void__phrase___phrase_role__special_____phrase___phrase_role__identifier__sp__phrase___code_"><code><phrase
3125 role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase></code></link>
3133 Pointer to the beginning of the stack.
3138 <bridgehead renderas="sect4" id="context.stack.stack_context.h1">
3139 <phrase id="context.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
3140 linkend="context.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
3141 role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase>
3142 <phrase role="identifier">size</phrase></code></link>
3150 Actual size of the stack.
3156 <section id="context.stack.valgrind">
3157 <title><link linkend="context.stack.valgrind">Support for valgrind</link></title>
3159 Running programs that switch stacks under valgrind causes problems. Property
3160 (b2 command-line) <code><phrase role="identifier">valgrind</phrase><phrase
3161 role="special">=</phrase><phrase role="identifier">on</phrase></code> let
3162 valgrind treat the memory regions as stack space which suppresses the errors.
3163 Users must define <code><phrase role="identifier">BOOST_USE_VALGRIND</phrase></code>
3164 before including any Boost.Context headers when linking against Boost binaries
3165 compiled with <code><phrase role="identifier">valgrind</phrase><phrase role="special">=</phrase><phrase
3166 role="identifier">on</phrase></code>.
3169 <section id="context.stack.sanitizers">
3170 <title><link linkend="context.stack.sanitizers">Support for sanitizers</link></title>
3172 Sanitizers (GCC/Clang) are confused by the stack switches. The library is
3173 required to be compiled with property (b2 command-line) <code><phrase role="identifier">context</phrase><phrase
3174 role="special">-</phrase><phrase role="identifier">impl</phrase><phrase role="special">=</phrase><phrase
3175 role="identifier">ucontext</phrase></code> and compilers santizer options.
3176 Users must define <code><phrase role="identifier">BOOST_USE_ASAN</phrase></code>
3177 before including any Boost.Context headers when linking against Boost binaries.
3181 <section id="context.struct__preallocated_">
3182 <title><link linkend="context.struct__preallocated_">Struct <code><phrase role="identifier">preallocated</phrase></code></link></title>
3183 <programlisting><phrase role="keyword">struct</phrase> <phrase role="identifier">preallocated</phrase> <phrase role="special">{</phrase>
3184 <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">;</phrase>
3185 <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">;</phrase>
3186 <phrase role="identifier">stack_context</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">;</phrase>
3188 <phrase role="identifier">preallocated</phrase><phrase role="special">(</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">,</phrase> <phrase role="identifier">std</phrase><phrase role="special">:</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">,</phrase> <phrase role="identifier">stack_allocator</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
3189 <phrase role="special">};</phrase>
3191 <bridgehead renderas="sect3" id="context.struct__preallocated_.h0">
3192 <phrase id="context.struct__preallocated_.constructor"/><link linkend="context.struct__preallocated_.constructor">Constructor</link>
3194 <programlisting><phrase role="identifier">preallocated</phrase><phrase role="special">(</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">,</phrase> <phrase role="identifier">std</phrase><phrase role="special">:</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">,</phrase> <phrase role="identifier">stack_allocator</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
3199 <term>Effects:</term>
3202 Creates an object of preallocated.
3208 <section id="context.performance">
3209 <title><anchor id="performance"/><link linkend="context.performance">Performance</link></title>
3211 Performance measurements were taken using <code><phrase role="identifier">std</phrase><phrase
3212 role="special">::</phrase><phrase role="identifier">chrono</phrase><phrase
3213 role="special">::</phrase><phrase role="identifier">highresolution_clock</phrase></code>,
3214 with overhead corrections. The code was compiled with gcc-6.3.1, using build
3215 options: variant = release, optimization = speed. Tests were executed on dual
3216 Intel XEON E5 2620v4 2.2GHz, 16C/32T, 64GB RAM, running Linux (x86_64).
3218 <table frame="all" id="context.performance.performance_of_context_switch">
3219 <title>Performance of context switch</title>
3225 callcc()/continuation (fcontext_t)
3230 callcc()/continuation (ucontext_t)
3235 callcc()/continuation (Windows-Fiber)
3244 9 ns / 19 CPU cycles
3249 547 ns / 1130 CPU cycles
3254 49 ns / 98 CPU cycles
3262 <section id="context.architectures">
3263 <title><link linkend="context.architectures">Architectures</link></title>
3265 <emphasis role="bold">Boost.Context</emphasis>, using <link linkend="implementation"><emphasis>fcontext_t</emphasis></link>,
3266 supports following architectures:
3268 <table frame="all" id="context.architectures.supported_architectures___abi_binary_format__">
3269 <title>Supported architectures (<ABI|binary format>)</title>
3576 If the architecture is not supported but the platform provides <link linkend="implementation"><emphasis>ucontext_t</emphasis></link>,
3577 <emphasis role="bold">Boost.Context</emphasis> should be compiled with <code><phrase
3578 role="identifier">BOOST_USE_UCONTEXT</phrase></code> and b2 property <code><phrase
3579 role="identifier">context</phrase><phrase role="special">-</phrase><phrase
3580 role="identifier">impl</phrase><phrase role="special">=</phrase><phrase role="identifier">ucontext</phrase></code>.
3583 <section id="context.architectures.crosscompiling">
3584 <title><link linkend="context.architectures.crosscompiling">Cross compiling</link></title>
3586 Cross compiling the library requires to specify the build properties <architecture>,
3587 <address-model>, <binary-format> and <abi> at b2 command
3592 <section id="context.rationale">
3593 <title><link linkend="context.rationale">Rationale</link></title>
3594 <bridgehead renderas="sect3" id="context.rationale.h0">
3595 <phrase id="context.rationale.no_inline_assembler"/><link linkend="context.rationale.no_inline_assembler">No
3596 inline-assembler</link>
3599 Some newer compiler (for instance MSVC 10 for x86_64 and itanium) do not support
3600 inline assembler. <footnote id="context.rationale.f0">
3602 <ulink url="http://msdn.microsoft.com/en-us/library/4ks26t93.aspx">MSDN article
3603 'Inline Assembler'</ulink>
3605 </footnote>. Inlined assembler generates code bloating which is not welcome
3606 on embedded systems.
3608 <bridgehead renderas="sect3" id="context.rationale.h1">
3609 <phrase id="context.rationale.fcontext_t"/><link linkend="context.rationale.fcontext_t">fcontext_t</link>
3612 <emphasis role="bold">Boost.Context</emphasis> provides the low level API fcontext_t
3613 which is implemented in assembler to provide context swapping operations. fcontext_t
3614 is the part to port to new platforms.
3618 Context switches do not preserve the signal mask on UNIX systems.
3622 <emphasis>fcontext_t</emphasis> is an opaque pointer.
3624 <section id="context.rationale.other_apis_">
3625 <title><link linkend="context.rationale.other_apis_">Other APIs </link></title>
3626 <bridgehead renderas="sect4" id="context.rationale.other_apis_.h0">
3627 <phrase id="context.rationale.other_apis_.setjmp___longjmp__"/><link linkend="context.rationale.other_apis_.setjmp___longjmp__">setjmp()/longjmp()</link>
3630 C99 defines <code><phrase role="identifier">setjmp</phrase><phrase role="special">()</phrase></code>/<code><phrase
3631 role="identifier">longjmp</phrase><phrase role="special">()</phrase></code>
3632 to provide non-local jumps but it does not require that <emphasis>longjmp()</emphasis>
3633 preserves the current stack frame. Therefore, jumping into a function which
3634 was exited via a call to <emphasis>longjmp()</emphasis> is undefined <footnote
3635 id="context.rationale.other_apis_.f0">
3637 ISO/IEC 9899:1999, 2005, 7.13.2.1:2
3641 <anchor id="ucontext"/>
3642 <bridgehead renderas="sect4" id="context.rationale.other_apis_.h1">
3643 <phrase id="context.rationale.other_apis_.ucontext_t"/><link linkend="context.rationale.other_apis_.ucontext_t">ucontext_t</link>
3646 Since POSIX.1-2004 <code><phrase role="identifier">ucontext_t</phrase></code>
3647 is deprecated and was removed in POSIX.1-2008! The function signature of
3648 <code><phrase role="identifier">makecontext</phrase><phrase role="special">()</phrase></code>
3651 <programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">makecontext</phrase><phrase role="special">(</phrase><phrase role="identifier">ucontext_t</phrase> <phrase role="special">*</phrase><phrase role="identifier">ucp</phrase><phrase role="special">,</phrase> <phrase role="keyword">void</phrase> <phrase role="special">(*</phrase><phrase role="identifier">func</phrase><phrase role="special">)(),</phrase> <phrase role="keyword">int</phrase> <phrase role="identifier">argc</phrase><phrase role="special">,</phrase> <phrase role="special">...);</phrase>
3654 The third argument of <code><phrase role="identifier">makecontext</phrase><phrase
3655 role="special">()</phrase></code> specifies the number of integer arguments
3656 that follow which will require function pointer cast if <code><phrase role="identifier">func</phrase></code>
3657 will accept those arguments which is undefined in C99 <footnote id="context.rationale.other_apis_.f1">
3659 ISO/IEC 9899:1999, 2005, J.2
3664 The arguments in the var-arg list are required to be integers, passing pointers
3665 in var-arg list is not guaranteed to work, especially it will fail for architectures
3666 where pointers are larger than integers.
3669 <code><phrase role="identifier">ucontext_t</phrase></code> preserves signal
3670 mask between context switches which involves system calls consuming a lot
3671 of CPU cycles (ucontext_t is slower; a context switch takes <link linkend="performance"><emphasis>two
3672 magnitutes of order more CPU cycles</emphasis></link> more than <emphasis>fcontext_t</emphasis>).
3674 <bridgehead renderas="sect4" id="context.rationale.other_apis_.h2">
3675 <phrase id="context.rationale.other_apis_.windows_fibers"/><link linkend="context.rationale.other_apis_.windows_fibers">Windows
3679 A drawback of Windows Fiber API is that <code><phrase role="identifier">CreateFiber</phrase><phrase
3680 role="special">()</phrase></code> does not accept a pointer to user allocated
3681 stack space preventing the reuse of stacks for other context instances. Because
3682 the Windows Fiber API requires to call <code><phrase role="identifier">ConvertThreadToFiber</phrase><phrase
3683 role="special">()</phrase></code> if <code><phrase role="identifier">SwitchFiber</phrase><phrase
3684 role="special">()</phrase></code> is called for a thread which has not been
3685 converted to a fiber. For the same reason <code><phrase role="identifier">ConvertFiberToThread</phrase><phrase
3686 role="special">()</phrase></code> must be called after return from <code><phrase
3687 role="identifier">SwitchFiber</phrase><phrase role="special">()</phrase></code>
3688 if the thread was forced to be converted to a fiber before (which is inefficient).
3690 <programlisting><phrase role="keyword">if</phrase> <phrase role="special">(</phrase> <phrase role="special">!</phrase> <phrase role="identifier">is_a_fiber</phrase><phrase role="special">()</phrase> <phrase role="special">)</phrase>
3691 <phrase role="special">{</phrase>
3692 <phrase role="identifier">ConvertThreadToFiber</phrase><phrase role="special">(</phrase> <phrase role="number">0</phrase><phrase role="special">);</phrase>
3693 <phrase role="identifier">SwitchToFiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">);</phrase>
3694 <phrase role="identifier">ConvertFiberToThread</phrase><phrase role="special">();</phrase>
3695 <phrase role="special">}</phrase>
3698 If the condition <code><phrase role="identifier">_WIN32_WINNT</phrase> <phrase
3699 role="special">>=</phrase> <phrase role="identifier">_WIN32_WINNT_VISTA</phrase></code>
3700 is met function <code><phrase role="identifier">IsThreadAFiber</phrase><phrase
3701 role="special">()</phrase></code> is provided in order to detect if the current
3702 thread was already converted. Unfortunately Windows XP + SP 2/3 defines
3703 <code><phrase role="identifier">_WIN32_WINNT</phrase> <phrase role="special">>=</phrase>
3704 <phrase role="identifier">_WIN32_WINNT_VISTA</phrase></code> without providing
3705 <code><phrase role="identifier">IsThreadAFiber</phrase><phrase role="special">()</phrase></code>.
3708 <section id="context.rationale.x86_and_floating_point_env">
3709 <title><link linkend="context.rationale.x86_and_floating_point_env">x86 and
3710 floating-point env</link></title>
3711 <bridgehead renderas="sect4" id="context.rationale.x86_and_floating_point_env.h0">
3712 <phrase id="context.rationale.x86_and_floating_point_env.i386"/><link linkend="context.rationale.x86_and_floating_point_env.i386">i386</link>
3715 "The FpCsr and the MxCsr register must be saved and restored before
3716 any call or return by any procedure that needs to modify them ..."
3717 <footnote id="context.rationale.x86_and_floating_point_env.f0">
3719 'Calling Conventions', Agner Fog
3723 <bridgehead renderas="sect4" id="context.rationale.x86_and_floating_point_env.h1">
3724 <phrase id="context.rationale.x86_and_floating_point_env.x86_64"/><link linkend="context.rationale.x86_and_floating_point_env.x86_64">x86_64</link>
3726 <bridgehead renderas="sect4" id="context.rationale.x86_and_floating_point_env.h2">
3727 <phrase id="context.rationale.x86_and_floating_point_env.windows"/><link
3728 linkend="context.rationale.x86_and_floating_point_env.windows">Windows</link>
3731 MxCsr - "A callee that modifies any of the non-volatile fields within
3732 MxCsr must restore them before returning to its caller. Furthermore, a caller
3733 that has modified any of these fields must restore them to their standard
3734 values before invoking a callee ..." <footnote id="context.rationale.x86_and_floating_point_env.f1">
3736 <ulink url="http://http://msdn.microsoft.com/en-us/library/yxty7t75.aspx">MSDN
3737 article 'MxCsr'</ulink>
3742 FpCsr - "A callee that modifies any of the fields within FpCsr must
3743 restore them before returning to its caller. Furthermore, a caller that has
3744 modified any of these fields must restore them to their standard values before
3745 invoking a callee ..." <footnote id="context.rationale.x86_and_floating_point_env.f2">
3747 <ulink url="http://http://msdn.microsoft.com/en-us/library/ms235300.aspx">MSDN
3748 article 'FpCsr'</ulink>
3753 "The MMX and floating-point stack registers (MM0-MM7/ST0-ST7) are preserved
3754 across context switches. There is no explicit calling convention for these
3755 registers." <footnote id="context.rationale.x86_and_floating_point_env.f3">
3757 <ulink url="http://msdn.microsoft.com/en-us/library/a32tsf7t%28VS.80%29.aspx">MSDN
3758 article 'Legacy Floating-Point Support'</ulink>
3763 "The 64-bit Microsoft compiler does not use ST(0)-ST(7)/MM0-MM7".
3764 <footnote id="context.rationale.x86_and_floating_point_env.f4">
3766 'Calling Conventions', Agner Fog
3771 "XMM6-XMM15 must be preserved" <footnote id="context.rationale.x86_and_floating_point_env.f5">
3773 <ulink url="http://msdn.microsoft.com/en-us/library/9z1stfyw%28v=vs.100%29.aspx">MSDN
3774 article 'Register Usage'</ulink>
3778 <bridgehead renderas="sect4" id="context.rationale.x86_and_floating_point_env.h3">
3779 <phrase id="context.rationale.x86_and_floating_point_env.sysv"/><link linkend="context.rationale.x86_and_floating_point_env.sysv">SysV</link>
3782 "The control bits of the MxCsr register are callee-saved (preserved
3783 across calls), while the status bits are caller-saved (not preserved). The
3784 x87 status word register is caller-saved, whereas the x87 control word (FpCsr)
3785 is callee-saved." <footnote id="context.rationale.x86_and_floating_point_env.f6">
3787 SysV ABI AMD64 Architecture Processor Supplement Draft Version 0.99.4,
3794 <section id="context.reference">
3795 <title><link linkend="context.reference">Reference</link></title>
3796 <bridgehead renderas="sect3" id="context.reference.h0">
3797 <phrase id="context.reference.arm"/><link linkend="context.reference.arm">ARM</link>
3802 AAPCS ABI: Procedure Call Standard for the ARM Architecture
3807 AAPCS/LINUX: ARM GNU/Linux Application Binary Interface Supplement
3811 <bridgehead renderas="sect3" id="context.reference.h1">
3812 <phrase id="context.reference.mips"/><link linkend="context.reference.mips">MIPS</link>
3817 O32 ABI: SYSTEM V APPLICATION BINARY INTERFACE, MIPS RISC Processor Supplement
3821 <bridgehead renderas="sect3" id="context.reference.h2">
3822 <phrase id="context.reference.powerpc32"/><link linkend="context.reference.powerpc32">PowerPC32</link>
3827 SYSV ABI: SYSTEM V APPLICATION BINARY INTERFACE PowerPC Processor Supplement
3831 <bridgehead renderas="sect3" id="context.reference.h3">
3832 <phrase id="context.reference.powerpc64"/><link linkend="context.reference.powerpc64">PowerPC64</link>
3837 SYSV ABI: PowerPC User Instruction Set Architecture, Book I
3841 <bridgehead renderas="sect3" id="context.reference.h4">
3842 <phrase id="context.reference.x86_32"/><link linkend="context.reference.x86_32">X86-32</link>
3847 SYSV ABI: SYSTEM V APPLICATION BINARY INTERFACE, Intel386TM Architecture
3848 Processor Supplement
3853 MS PE: <ulink url="http://msdn.microsoft.com/en-us/library/k2b2ssfy.aspx">Calling
3858 <bridgehead renderas="sect3" id="context.reference.h5">
3859 <phrase id="context.reference.x86_64"/><link linkend="context.reference.x86_64">X86-64</link>
3864 SYSV ABI: System V Application Binary Interface, AMD64 Architecture Processor
3870 MS PE: <ulink url="http://msdn.microsoft.com/en-us/library/7kcdt6fy%28VS.80%29.aspx">x64
3871 Software Conventions</ulink>
3876 <section id="context.acknowledgements">
3877 <title><link linkend="context.acknowledgements">Acknowledgments</link></title>
3879 I'd like to thank Adreas Fett, Artyom Beilis, Daniel Larimer, David Deakins,
3880 Evgeny Shapovalov, Fernando Pelliccioni, Giovanni Piero Deretta, Gordon Woodhull,
3881 Helge Bahmann, Holger Grund, Jeffrey Lee Hellrung (Jr.), Keith Jeffery, Martin
3882 Husemann, Phil Endecott, Robert Stewart, Sergey Cheban, Steven Watanabe, Vicente
3883 J. Botet Escriba, Wayne Piekarski.