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"> 5 <libraryinfo> 6 <authorgroup> 7 <author> 8 <firstname>Oliver</firstname> <surname>Kowalke</surname> 9 </author> 10 </authorgroup> 11 <copyright> 12 <year>2014</year> <holder>Oliver Kowalke</holder> 13 </copyright> 14 <legalnotice id="context.legal"> 15 <para> 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>) 18 </para> 19 </legalnotice> 20 <librarypurpose> 21 C++ Library for swiching different user ctx 22 </librarypurpose> 23 <librarycategory name="category:text"></librarycategory> 24 </libraryinfo> 25 <title>Context</title> 26 <section id="context.overview"> 27 <title><link linkend="context.overview">Overview</link></title> 28 <para> 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++. 38 </para> 39 <para> 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 47 time. 48 </para> 49 <para> 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. 56 </para> 57 <para> 58 All functions and classes are contained in the namespace <emphasis>boost::context</emphasis>. 59 </para> 60 <note> 61 <para> 62 This library requires C++11! 63 </para> 64 </note> 65 <important> 66 <para> 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). 71 </para> 72 </important> 73 </section> 74 <section id="context.requirements"> 75 <title><link linkend="context.requirements">Requirements</link></title> 76 <para> 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. 83 </para> 84 <note> 85 <para> 86 MASM64 (ml64.exe) is a part of Microsoft's Windows Driver Kit. 87 </para> 88 </note> 89 <important> 90 <para> 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. 96 </para> 97 </important> 98 <important> 99 <para> 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>. 108 </para> 109 </important> 110 <important> 111 <para> 112 Windows using fcontext_t: for safe SEH the property 'asmflags=\safeseh' must 113 be specified at bjam command line. 114 </para> 115 </important> 116 <important> 117 <para> 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). 122 </para> 123 </important> 124 <para> 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. 131 </para> 132 </section> 133 <section id="context.ff"> 134 <title><anchor id="ff"/><link linkend="context.ff">Context switching with fibers</link></title> 135 <note> 136 <para> 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>. 140 </para> 141 </note> 142 <para> 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. 146 </para> 147 <para> 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. 153 </para> 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> 158 </bridgehead> 159 <para> 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. 167 </para> 168 <para> 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>). 174 </para> 175 <para> 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. 179 </para> 180 <para> 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>. 185 </para> 186 <note> 187 <para> 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>. 191 </para> 192 </note> 193 <para> 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. 199 </para> 200 <para> 201 <link linkend="ff"><emphasis>fiber</emphasis></link> is only move-constructible 202 and move-assignable. 203 </para> 204 <para> 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 207 in a container. 208 </para> 209 <para> 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>. 213 </para> 214 <bridgehead renderas="sect3" id="context.ff.h1"> 215 <phrase id="context.ff.usage"/><link linkend="context.ff.usage">Usage</link> 216 </bridgehead> 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> 234 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> 237</programlisting> 238 <para> 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. 245 </para> 246 <para> 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>. 257 </para> 258 <para> 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). 263 </para> 264 <para> 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. 269 </para> 270 <bridgehead renderas="sect3" id="context.ff.h2"> 271 <phrase id="context.ff.parameter_passing"/><link linkend="context.ff.parameter_passing">Parameter 272 passing</link> 273 </bridgehead> 274 <para> 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. 278 </para> 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> 288 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> 292</programlisting> 293 <para> 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>. 307 </para> 308 <bridgehead renderas="sect3" id="context.ff.h3"> 309 <phrase id="context.ff.exception_handling"/><link linkend="context.ff.exception_handling">Exception 310 handling</link> 311 </bridgehead> 312 <para> 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. 319 </para> 320 <important> 321 <para> 322 Do not jump from inside a catch block and then re-throw the exception in 323 another fiber. 324 </para> 325 </important> 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> 330 </bridgehead> 331 <para> 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>. 336 </para> 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> 361 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> 370</programlisting> 371 <para> 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>. 380 </para> 381 <para> 382 Another option is to execute a function on top of the fiber that throws an 383 exception. 384 </para> 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> 393 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> 409 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> 413</programlisting> 414 <para> 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. 418 </para> 419 <bridgehead renderas="sect3" id="context.ff.h5"> 420 <phrase id="context.ff.stack_unwinding"/><link linkend="context.ff.stack_unwinding">Stack 421 unwinding</link> 422 </bridgehead> 423 <para> 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 430 too. 431 </para> 432 <important> 433 <para> 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> 438 exception. 439 </para> 440 </important> 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> 446 </bridgehead> 447 <para> 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. 451 </para> 452 <note> 453 <para> 454 The user is responsible for destructing the control structure at the top 455 of the stack. 456 </para> 457 </note> 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> 475 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> 483</programlisting> 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> 487 </bridgehead> 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">/* 490 * grammar: 491 * P ---> E '\0' 492 * E ---> T {('+'|'-') T} 493 * T ---> S {('*'|'/') S} 494 * S ---> digit | '(' E ')' 495 */</phrase> 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> 500 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> 504 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> 511 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> 516 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> 521 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> 531 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> 540 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> 562 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> 589 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> 594</programlisting> 595 <para> 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). 600 </para> 601 <para> 602 The data (character) is transferred between the two fibers. 603 </para> 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> 610 </bridgehead> 611 <para> 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>. 617 </para> 618 <note> 619 <para> 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. 623 </para> 624 </note> 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> 628 </bridgehead> 629 <para> 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). 637 </para> 638 <note> 639 <para> 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 642 implementation. 643 </para> 644 </note> 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> 648 </bridgehead> 649 <para> 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>. 654 </para> 655 <note> 656 <para> 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). 663 </para> 664 </note> 665 </section> 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> 669 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> 673 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> 676 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> 679 680 <phrase role="special">~</phrase><phrase role="identifier">fiber</phrase><phrase role="special">();</phrase> 681 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> 683 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> 685 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> 688 689 <phrase role="identifier">fiber</phrase> <phrase role="identifier">resume</phrase><phrase role="special">()</phrase> <phrase role="special">&&;</phrase> 690 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> 693 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> 695 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> 697 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> 699 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> 701 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> 703 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> 705 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> 707 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> 709 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> 713 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> 716</programlisting> 717 <para> 718 <bridgehead renderas="sect4" id="ff_constructor1_bridgehead"> 719 <phrase id="ff_constructor1"/> 720 <link linkend="ff_constructor1">Constructor</link> 721</bridgehead> 722 </para> 723<programlisting><phrase role="identifier">fiber</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> 724</programlisting> 725 <variablelist> 726 <title></title> 727 <varlistentry> 728 <term>Effects:</term> 729 <listitem> 730 <para> 731 Creates a invalid fiber. 732 </para> 733 </listitem> 734 </varlistentry> 735 <varlistentry> 736 <term>Throws:</term> 737 <listitem> 738 <para> 739 Nothing. 740 </para> 741 </listitem> 742 </varlistentry> 743 </variablelist> 744 <para> 745 <bridgehead renderas="sect4" id="ff_constructor2_bridgehead"> 746 <phrase id="ff_constructor2"/> 747 <link linkend="ff_constructor2">Constructor</link> 748</bridgehead> 749 </para> 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> 752 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> 755</programlisting> 756 <variablelist> 757 <title></title> 758 <varlistentry> 759 <term>Effects:</term> 760 <listitem> 761 <para> 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. 768 </para> 769 </listitem> 770 </varlistentry> 771 </variablelist> 772 <para> 773 <bridgehead renderas="sect4" id="ff_destructor destructor_bridgehead"> 774 <phrase id="ff_destructor destructor"/> 775 <link linkend="ff_destructor 776 destructor">Destructor</link> 777</bridgehead> 778 </para> 779<programlisting><phrase role="special">~</phrase><phrase role="identifier">fiber</phrase><phrase role="special">();</phrase> 780</programlisting> 781 <variablelist> 782 <title></title> 783 <varlistentry> 784 <term>Effects:</term> 785 <listitem> 786 <para> 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>. 790 </para> 791 </listitem> 792 </varlistentry> 793 <varlistentry> 794 <term>Throws:</term> 795 <listitem> 796 <para> 797 Nothing. 798 </para> 799 </listitem> 800 </varlistentry> 801 </variablelist> 802 <para> 803 <bridgehead renderas="sect4" id="ff_move constructor_bridgehead"> 804 <phrase id="ff_move constructor"/> 805 <link linkend="ff_move constructor">Move 806 constructor</link> 807</bridgehead> 808 </para> 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> 810</programlisting> 811 <variablelist> 812 <title></title> 813 <varlistentry> 814 <term>Effects:</term> 815 <listitem> 816 <para> 817 Moves underlying capture fiber to <code><phrase role="special">*</phrase><phrase 818 role="keyword">this</phrase></code>. 819 </para> 820 </listitem> 821 </varlistentry> 822 <varlistentry> 823 <term>Throws:</term> 824 <listitem> 825 <para> 826 Nothing. 827 </para> 828 </listitem> 829 </varlistentry> 830 </variablelist> 831 <para> 832 <bridgehead renderas="sect4" id="ff_move assignment_bridgehead"> 833 <phrase id="ff_move assignment"/> 834 <link linkend="ff_move assignment">Move assignment 835 operator</link> 836</bridgehead> 837 </para> 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> 839</programlisting> 840 <variablelist> 841 <title></title> 842 <varlistentry> 843 <term>Effects:</term> 844 <listitem> 845 <para> 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. 849 </para> 850 </listitem> 851 </varlistentry> 852 <varlistentry> 853 <term>Throws:</term> 854 <listitem> 855 <para> 856 Nothing. 857 </para> 858 </listitem> 859 </varlistentry> 860 </variablelist> 861 <para> 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> 866</bridgehead> 867 </para> 868<programlisting><phrase role="identifier">fiber</phrase> <phrase role="identifier">resume</phrase><phrase role="special">()</phrase> <phrase role="special">&&;</phrase> 869 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> 872</programlisting> 873 <variablelist> 874 <title></title> 875 <varlistentry> 876 <term>Effects:</term> 877 <listitem> 878 <para> 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>). 886 </para> 887 </listitem> 888 </varlistentry> 889 <varlistentry> 890 <term>Returns:</term> 891 <listitem> 892 <para> 893 The fiber representing the fiber that has been suspended. 894 </para> 895 </listitem> 896 </varlistentry> 897 <varlistentry> 898 <term>Note:</term> 899 <listitem> 900 <para> 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 905 only to rvalues. 906 </para> 907 </listitem> 908 </varlistentry> 909 <varlistentry> 910 <term>Note:</term> 911 <listitem> 912 <para> 913 Function <code><phrase role="identifier">fn</phrase></code> needs to 914 return <code><phrase role="identifier">fiber</phrase></code>. 915 </para> 916 </listitem> 917 </varlistentry> 918 <varlistentry> 919 <term>Note:</term> 920 <listitem> 921 <para> 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>. 925 </para> 926 </listitem> 927 </varlistentry> 928 </variablelist> 929 <para> 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> 934</bridgehead> 935 </para> 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> 937</programlisting> 938 <variablelist> 939 <title></title> 940 <varlistentry> 941 <term>Returns:</term> 942 <listitem> 943 <para> 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. 947 </para> 948 </listitem> 949 </varlistentry> 950 <varlistentry> 951 <term>Throws:</term> 952 <listitem> 953 <para> 954 Nothing. 955 </para> 956 </listitem> 957 </varlistentry> 958 </variablelist> 959 <para> 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> 963</bridgehead> 964 </para> 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> 966</programlisting> 967 <variablelist> 968 <title></title> 969 <varlistentry> 970 <term>Returns:</term> 971 <listitem> 972 <para> 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. 976 </para> 977 </listitem> 978 </varlistentry> 979 <varlistentry> 980 <term>Throws:</term> 981 <listitem> 982 <para> 983 Nothing. 984 </para> 985 </listitem> 986 </varlistentry> 987 </variablelist> 988 <para> 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> 993</bridgehead> 994 </para> 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> 996</programlisting> 997 <variablelist> 998 <title></title> 999 <varlistentry> 1000 <term>Returns:</term> 1001 <listitem> 1002 <para> 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> 1007 otherwise. 1008 </para> 1009 </listitem> 1010 </varlistentry> 1011 <varlistentry> 1012 <term>Throws:</term> 1013 <listitem> 1014 <para> 1015 Nothing. 1016 </para> 1017 </listitem> 1018 </varlistentry> 1019 </variablelist> 1020 <para> 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> 1025</bridgehead> 1026 </para> 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> 1028</programlisting> 1029 <variablelist> 1030 <title></title> 1031 <varlistentry> 1032 <term>Returns:</term> 1033 <listitem> 1034 <para> 1035 <code>! (other == * this)</code> 1036 </para> 1037 </listitem> 1038 </varlistentry> 1039 <varlistentry> 1040 <term>Throws:</term> 1041 <listitem> 1042 <para> 1043 Nothing. 1044 </para> 1045 </listitem> 1046 </varlistentry> 1047 </variablelist> 1048 <para> 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> 1053</bridgehead> 1054 </para> 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> 1056</programlisting> 1057 <variablelist> 1058 <title></title> 1059 <varlistentry> 1060 <term>Returns:</term> 1061 <listitem> 1062 <para> 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 1070 otherwise. 1071 </para> 1072 </listitem> 1073 </varlistentry> 1074 <varlistentry> 1075 <term>Throws:</term> 1076 <listitem> 1077 <para> 1078 Nothing. 1079 </para> 1080 </listitem> 1081 </varlistentry> 1082 </variablelist> 1083 <para> 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> 1088</bridgehead> 1089 </para> 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> 1091</programlisting> 1092 <variablelist> 1093 <title></title> 1094 <varlistentry> 1095 <term>Returns:</term> 1096 <listitem> 1097 <para> 1098 <code><phrase role="identifier">other</phrase> <phrase role="special"><</phrase> 1099 <phrase role="special">*</phrase> <phrase role="keyword">this</phrase></code> 1100 </para> 1101 </listitem> 1102 </varlistentry> 1103 <varlistentry> 1104 <term>Throws:</term> 1105 <listitem> 1106 <para> 1107 Nothing. 1108 </para> 1109 </listitem> 1110 </varlistentry> 1111 </variablelist> 1112 <para> 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> 1117</bridgehead> 1118 </para> 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> 1120</programlisting> 1121 <variablelist> 1122 <title></title> 1123 <varlistentry> 1124 <term>Returns:</term> 1125 <listitem> 1126 <para> 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> 1131 </para> 1132 </listitem> 1133 </varlistentry> 1134 <varlistentry> 1135 <term>Throws:</term> 1136 <listitem> 1137 <para> 1138 Nothing. 1139 </para> 1140 </listitem> 1141 </varlistentry> 1142 </variablelist> 1143 <para> 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> 1148</bridgehead> 1149 </para> 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> 1151</programlisting> 1152 <variablelist> 1153 <title></title> 1154 <varlistentry> 1155 <term>Returns:</term> 1156 <listitem> 1157 <para> 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> 1161 </para> 1162 </listitem> 1163 </varlistentry> 1164 <varlistentry> 1165 <term>Throws:</term> 1166 <listitem> 1167 <para> 1168 Nothing. 1169 </para> 1170 </listitem> 1171 </varlistentry> 1172 </variablelist> 1173 <para> 1174 <bridgehead renderas="sect4" id="ff__bridgehead"> 1175 <phrase id="ff_"/> 1176 <link linkend="ff_">Non-member function <code>operator<<()</code></link> 1177</bridgehead> 1178 </para> 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> 1182</programlisting> 1183 <variablelist> 1184 <title></title> 1185 <varlistentry> 1186 <term>Effects:</term> 1187 <listitem> 1188 <para> 1189 Writes the representation of <code><phrase role="identifier">other</phrase></code> 1190 to stream <code><phrase role="identifier">os</phrase></code>. 1191 </para> 1192 </listitem> 1193 </varlistentry> 1194 <varlistentry> 1195 <term>Returns:</term> 1196 <listitem> 1197 <para> 1198 <code><phrase role="identifier">os</phrase></code> 1199 </para> 1200 </listitem> 1201 </varlistentry> 1202 </variablelist> 1203 </section> 1204 </section> 1205 <section id="context.cc"> 1206 <title><anchor id="cc"/><link linkend="context.cc">Context switching with call/cc</link></title> 1207 <note> 1208 <para> 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 1212 switching</ulink>. 1213 </para> 1214 </note> 1215 <para> 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. 1220 </para> 1221 <para> 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 1225 program. 1226 </para> 1227 <para> 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. 1233 </para> 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> 1238 </bridgehead> 1239 <para> 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. 1249 </para> 1250 <para> 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>). 1256 </para> 1257 <para> 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 1261 continuation. 1262 </para> 1263 <para> 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>. 1268 </para> 1269 <note> 1270 <para> 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>. 1274 </para> 1275 </note> 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> 1280 </bridgehead> 1281 <para> 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. 1287 </para> 1288 <para> 1289 <link linkend="cc"><emphasis>continuation</emphasis></link> is only move-constructible 1290 and move-assignable. 1291 </para> 1292 <para> 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 1295 in a container. 1296 </para> 1297 <para> 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>. 1301 </para> 1302 <bridgehead renderas="sect3" id="context.cc.h2"> 1303 <phrase id="context.cc.usage"/><link linkend="context.cc.usage">Usage</link> 1304 </bridgehead> 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> 1323 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> 1326</programlisting> 1327 <para> 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. 1335 </para> 1336 <para> 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. 1341 </para> 1342 <para> 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). 1347 </para> 1348 <para> 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. 1353 </para> 1354 <bridgehead renderas="sect3" id="context.cc.h3"> 1355 <phrase id="context.cc.parameter_passing"/><link linkend="context.cc.parameter_passing">Parameter 1356 passing</link> 1357 </bridgehead> 1358 <para> 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. 1362 </para> 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> 1371 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> 1375</programlisting> 1376 <para> 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>. 1390 </para> 1391 <bridgehead renderas="sect3" id="context.cc.h4"> 1392 <phrase id="context.cc.exception_handling"/><link linkend="context.cc.exception_handling">Exception 1393 handling</link> 1394 </bridgehead> 1395 <para> 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. 1402 </para> 1403 <important> 1404 <para> 1405 Do not jump from inside a catch block and then re-throw the exception in 1406 another continuation. 1407 </para> 1408 </important> 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> 1414 </bridgehead> 1415 <para> 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>. 1421 </para> 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> 1445 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> 1454</programlisting> 1455 <para> 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>. 1464 </para> 1465 <para> 1466 Another option is to execute a function on top of the continuation that throws 1467 an exception. 1468 </para> 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> 1477 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> 1495 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> 1499</programlisting> 1500 <para> 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. 1504 </para> 1505 <bridgehead renderas="sect3" id="context.cc.h6"> 1506 <phrase id="context.cc.stack_unwinding"/><link linkend="context.cc.stack_unwinding">Stack 1507 unwinding</link> 1508 </bridgehead> 1509 <para> 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 1516 be destructed too. 1517 </para> 1518 <important> 1519 <para> 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> 1524 exception. 1525 </para> 1526 </important> 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> 1532 </bridgehead> 1533 <para> 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. 1537 </para> 1538 <note> 1539 <para> 1540 The user is responsible for destructing the control structure at the top 1541 of the stack. 1542 </para> 1543 </note> 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> 1561 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> 1570</programlisting> 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> 1574 </bridgehead> 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">/* 1577 * grammar: 1578 * P ---> E '\0' 1579 * E ---> T {('+'|'-') T} 1580 * T ---> S {('*'|'/') S} 1581 * S ---> digit | '(' E ')' 1582 */</phrase> 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> 1587 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> 1591 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> 1598 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> 1603 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> 1608 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> 1618 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> 1627 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> 1649 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> 1677 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> 1682</programlisting> 1683 <para> 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). 1688 </para> 1689 <para> 1690 The data (character) is transferred between the two continuations. 1691 </para> 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> 1698 </bridgehead> 1699 <para> 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>. 1705 </para> 1706 <note> 1707 <para> 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. 1711 </para> 1712 </note> 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> 1716 </bridgehead> 1717 <para> 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). 1725 </para> 1726 <note> 1727 <para> 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. 1731 </para> 1732 </note> 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> 1736 </bridgehead> 1737 <para> 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>. 1742 </para> 1743 <note> 1744 <para> 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). 1751 </para> 1752 </note> 1753 </section> 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> 1758 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> 1762 1763 <phrase role="special">~</phrase><phrase role="identifier">continuation</phrase><phrase role="special">();</phrase> 1764 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> 1766 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> 1768 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> 1771 1772 <phrase role="identifier">continuation</phrase> <phrase role="identifier">resume</phrase><phrase role="special">();</phrase> 1773 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> 1776 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> 1778 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> 1780 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> 1782 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> 1784 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> 1786 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> 1788 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> 1790 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> 1792 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> 1796 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> 1799</programlisting> 1800 <para> 1801 <bridgehead renderas="sect4" id="cc_constructor_bridgehead"> 1802 <phrase id="cc_constructor"/> 1803 <link linkend="cc_constructor">Constructor</link> 1804</bridgehead> 1805 </para> 1806<programlisting><phrase role="identifier">continuation</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> 1807</programlisting> 1808 <variablelist> 1809 <title></title> 1810 <varlistentry> 1811 <term>Effects:</term> 1812 <listitem> 1813 <para> 1814 Creates a invalid continuation. 1815 </para> 1816 </listitem> 1817 </varlistentry> 1818 <varlistentry> 1819 <term>Throws:</term> 1820 <listitem> 1821 <para> 1822 Nothing. 1823 </para> 1824 </listitem> 1825 </varlistentry> 1826 </variablelist> 1827 <para> 1828 <bridgehead renderas="sect4" id="cc_destructor destructor_bridgehead"> 1829 <phrase id="cc_destructor destructor"/> 1830 <link linkend="cc_destructor 1831 destructor">Destructor</link> 1832</bridgehead> 1833 </para> 1834<programlisting><phrase role="special">~</phrase><phrase role="identifier">continuation</phrase><phrase role="special">();</phrase> 1835</programlisting> 1836 <variablelist> 1837 <title></title> 1838 <varlistentry> 1839 <term>Effects:</term> 1840 <listitem> 1841 <para> 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>. 1846 </para> 1847 </listitem> 1848 </varlistentry> 1849 <varlistentry> 1850 <term>Throws:</term> 1851 <listitem> 1852 <para> 1853 Nothing. 1854 </para> 1855 </listitem> 1856 </varlistentry> 1857 </variablelist> 1858 <para> 1859 <bridgehead renderas="sect4" id="cc_move constructor_bridgehead"> 1860 <phrase id="cc_move constructor"/> 1861 <link linkend="cc_move constructor">Move 1862 constructor</link> 1863</bridgehead> 1864 </para> 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> 1866</programlisting> 1867 <variablelist> 1868 <title></title> 1869 <varlistentry> 1870 <term>Effects:</term> 1871 <listitem> 1872 <para> 1873 Moves underlying capture continuation to <code><phrase role="special">*</phrase><phrase 1874 role="keyword">this</phrase></code>. 1875 </para> 1876 </listitem> 1877 </varlistentry> 1878 <varlistentry> 1879 <term>Throws:</term> 1880 <listitem> 1881 <para> 1882 Nothing. 1883 </para> 1884 </listitem> 1885 </varlistentry> 1886 </variablelist> 1887 <para> 1888 <bridgehead renderas="sect4" id="cc_move assignment_bridgehead"> 1889 <phrase id="cc_move assignment"/> 1890 <link linkend="cc_move assignment">Move assignment 1891 operator</link> 1892</bridgehead> 1893 </para> 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> 1895</programlisting> 1896 <variablelist> 1897 <title></title> 1898 <varlistentry> 1899 <term>Effects:</term> 1900 <listitem> 1901 <para> 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. 1905 </para> 1906 </listitem> 1907 </varlistentry> 1908 <varlistentry> 1909 <term>Throws:</term> 1910 <listitem> 1911 <para> 1912 Nothing. 1913 </para> 1914 </listitem> 1915 </varlistentry> 1916 </variablelist> 1917 <para> 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> 1922</bridgehead> 1923 </para> 1924<programlisting><phrase role="identifier">continuation</phrase> <phrase role="identifier">resume</phrase><phrase role="special">();</phrase> 1925 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> 1928</programlisting> 1929 <variablelist> 1930 <title></title> 1931 <varlistentry> 1932 <term>Effects:</term> 1933 <listitem> 1934 <para> 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>). 1942 </para> 1943 </listitem> 1944 </varlistentry> 1945 <varlistentry> 1946 <term>Returns:</term> 1947 <listitem> 1948 <para> 1949 The continuation representing the continuation that has been suspended. 1950 </para> 1951 </listitem> 1952 </varlistentry> 1953 <varlistentry> 1954 <term>Note:</term> 1955 <listitem> 1956 <para> 1957 Function <code><phrase role="identifier">fn</phrase></code> needs to 1958 return <code><phrase role="identifier">continuation</phrase></code>. 1959 </para> 1960 </listitem> 1961 </varlistentry> 1962 <varlistentry> 1963 <term>Note:</term> 1964 <listitem> 1965 <para> 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>. 1969 </para> 1970 </listitem> 1971 </varlistentry> 1972 </variablelist> 1973 <para> 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> 1978</bridgehead> 1979 </para> 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> 1981</programlisting> 1982 <variablelist> 1983 <title></title> 1984 <varlistentry> 1985 <term>Returns:</term> 1986 <listitem> 1987 <para> 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. 1991 </para> 1992 </listitem> 1993 </varlistentry> 1994 <varlistentry> 1995 <term>Throws:</term> 1996 <listitem> 1997 <para> 1998 Nothing. 1999 </para> 2000 </listitem> 2001 </varlistentry> 2002 </variablelist> 2003 <para> 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> 2007</bridgehead> 2008 </para> 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> 2010</programlisting> 2011 <variablelist> 2012 <title></title> 2013 <varlistentry> 2014 <term>Returns:</term> 2015 <listitem> 2016 <para> 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. 2020 </para> 2021 </listitem> 2022 </varlistentry> 2023 <varlistentry> 2024 <term>Throws:</term> 2025 <listitem> 2026 <para> 2027 Nothing. 2028 </para> 2029 </listitem> 2030 </varlistentry> 2031 </variablelist> 2032 <para> 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> 2037</bridgehead> 2038 </para> 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> 2040</programlisting> 2041 <variablelist> 2042 <title></title> 2043 <varlistentry> 2044 <term>Returns:</term> 2045 <listitem> 2046 <para> 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> 2051 otherwise. 2052 </para> 2053 </listitem> 2054 </varlistentry> 2055 <varlistentry> 2056 <term>Throws:</term> 2057 <listitem> 2058 <para> 2059 Nothing. 2060 </para> 2061 </listitem> 2062 </varlistentry> 2063 </variablelist> 2064 <para> 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> 2069</bridgehead> 2070 </para> 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> 2072</programlisting> 2073 <variablelist> 2074 <title></title> 2075 <varlistentry> 2076 <term>Returns:</term> 2077 <listitem> 2078 <para> 2079 <code>! (other == * this)</code> 2080 </para> 2081 </listitem> 2082 </varlistentry> 2083 <varlistentry> 2084 <term>Throws:</term> 2085 <listitem> 2086 <para> 2087 Nothing. 2088 </para> 2089 </listitem> 2090 </varlistentry> 2091 </variablelist> 2092 <para> 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> 2097</bridgehead> 2098 </para> 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> 2100</programlisting> 2101 <variablelist> 2102 <title></title> 2103 <varlistentry> 2104 <term>Returns:</term> 2105 <listitem> 2106 <para> 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 2114 otherwise. 2115 </para> 2116 </listitem> 2117 </varlistentry> 2118 <varlistentry> 2119 <term>Throws:</term> 2120 <listitem> 2121 <para> 2122 Nothing. 2123 </para> 2124 </listitem> 2125 </varlistentry> 2126 </variablelist> 2127 <para> 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> 2132</bridgehead> 2133 </para> 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> 2135</programlisting> 2136 <variablelist> 2137 <title></title> 2138 <varlistentry> 2139 <term>Returns:</term> 2140 <listitem> 2141 <para> 2142 <code><phrase role="identifier">other</phrase> <phrase role="special"><</phrase> 2143 <phrase role="special">*</phrase> <phrase role="keyword">this</phrase></code> 2144 </para> 2145 </listitem> 2146 </varlistentry> 2147 <varlistentry> 2148 <term>Throws:</term> 2149 <listitem> 2150 <para> 2151 Nothing. 2152 </para> 2153 </listitem> 2154 </varlistentry> 2155 </variablelist> 2156 <para> 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> 2161</bridgehead> 2162 </para> 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> 2164</programlisting> 2165 <variablelist> 2166 <title></title> 2167 <varlistentry> 2168 <term>Returns:</term> 2169 <listitem> 2170 <para> 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> 2175 </para> 2176 </listitem> 2177 </varlistentry> 2178 <varlistentry> 2179 <term>Throws:</term> 2180 <listitem> 2181 <para> 2182 Nothing. 2183 </para> 2184 </listitem> 2185 </varlistentry> 2186 </variablelist> 2187 <para> 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> 2192</bridgehead> 2193 </para> 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> 2195</programlisting> 2196 <variablelist> 2197 <title></title> 2198 <varlistentry> 2199 <term>Returns:</term> 2200 <listitem> 2201 <para> 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> 2205 </para> 2206 </listitem> 2207 </varlistentry> 2208 <varlistentry> 2209 <term>Throws:</term> 2210 <listitem> 2211 <para> 2212 Nothing. 2213 </para> 2214 </listitem> 2215 </varlistentry> 2216 </variablelist> 2217 <para> 2218 <bridgehead renderas="sect4" id="cc__bridgehead"> 2219 <phrase id="cc_"/> 2220 <link linkend="cc_">Non-member function <code>operator<<()</code></link> 2221</bridgehead> 2222 </para> 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> 2226</programlisting> 2227 <variablelist> 2228 <title></title> 2229 <varlistentry> 2230 <term>Effects:</term> 2231 <listitem> 2232 <para> 2233 Writes the representation of <code><phrase role="identifier">other</phrase></code> 2234 to stream <code><phrase role="identifier">os</phrase></code>. 2235 </para> 2236 </listitem> 2237 </varlistentry> 2238 <varlistentry> 2239 <term>Returns:</term> 2240 <listitem> 2241 <para> 2242 <code><phrase role="identifier">os</phrase></code> 2243 </para> 2244 </listitem> 2245 </varlistentry> 2246 </variablelist> 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> 2251 </bridgehead> 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> 2253 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> 2256 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> 2259 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> 2262</programlisting> 2263 <variablelist> 2264 <title></title> 2265 <varlistentry> 2266 <term>Effects:</term> 2267 <listitem> 2268 <para> 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. 2276 </para> 2277 </listitem> 2278 </varlistentry> 2279 <varlistentry> 2280 <term>Returns:</term> 2281 <listitem> 2282 <para> 2283 The continuation representing the contexcontinuation that has been 2284 suspended. 2285 </para> 2286 </listitem> 2287 </varlistentry> 2288 <varlistentry> 2289 <term>Note:</term> 2290 <listitem> 2291 <para> 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>. 2295 </para> 2296 </listitem> 2297 </varlistentry> 2298 </variablelist> 2299 </section> 2300 </section> 2301 <section id="context.stack"> 2302 <title><anchor id="stack"/><link linkend="context.stack">Stack allocation</link></title> 2303 <para> 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>. 2306 </para> 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> 2311 </bridgehead> 2312 <para> 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>: 2320 </para> 2321 <informaltable frame="all"> 2322 <tgroup cols="3"> 2323 <thead> 2324 <row> 2325 <entry> 2326 <para> 2327 expression 2328 </para> 2329 </entry> 2330 <entry> 2331 <para> 2332 return type 2333 </para> 2334 </entry> 2335 <entry> 2336 <para> 2337 notes 2338 </para> 2339 </entry> 2340 </row> 2341 </thead> 2342 <tbody> 2343 <row> 2344 <entry> 2345 <para> 2346 <code><phrase role="identifier">a</phrase><phrase role="special">(</phrase><phrase 2347 role="identifier">size</phrase><phrase role="special">)</phrase></code> 2348 </para> 2349 </entry> 2350 <entry> 2351 </entry> 2352 <entry> 2353 <para> 2354 creates a stack allocator 2355 </para> 2356 </entry> 2357 </row> 2358 <row> 2359 <entry> 2360 <para> 2361 <code><phrase role="identifier">a</phrase><phrase role="special">.</phrase><phrase 2362 role="identifier">allocate</phrase><phrase role="special">()</phrase></code> 2363 </para> 2364 </entry> 2365 <entry> 2366 <para> 2367 <code><phrase role="identifier">stack_context</phrase></code> 2368 </para> 2369 </entry> 2370 <entry> 2371 <para> 2372 creates a stack 2373 </para> 2374 </entry> 2375 </row> 2376 <row> 2377 <entry> 2378 <para> 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> 2382 </para> 2383 </entry> 2384 <entry> 2385 <para> 2386 <code><phrase role="keyword">void</phrase></code> 2387 </para> 2388 </entry> 2389 <entry> 2390 <para> 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> 2394 </para> 2395 </entry> 2396 </row> 2397 </tbody> 2398 </tgroup> 2399 </informaltable> 2400 <important> 2401 <para> 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 2405 behaviour. 2406 </para> 2407 </important> 2408 <important> 2409 <para> 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. 2414 </para> 2415 </important> 2416 <note> 2417 <para> 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). 2421 </para> 2422 </note> 2423 <section id="context.stack.protected_fixedsize"> 2424 <title><link linkend="context.stack.protected_fixedsize">Class <emphasis>protected_fixedsize</emphasis></link></title> 2425 <para> 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. 2431 </para> 2432 <important> 2433 <para> 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. 2437 </para> 2438 </important> 2439 <note> 2440 <para> 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. 2444 </para> 2445 </note> 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> 2447 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> 2451 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> 2453 2454 <phrase role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">();</phrase> 2455 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> 2458 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> 2460</programlisting> 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> 2466 </bridgehead> 2467 <variablelist> 2468 <title></title> 2469 <varlistentry> 2470 <term>Preconditions:</term> 2471 <listitem> 2472 <para> 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>. 2485 </para> 2486 </listitem> 2487 </varlistentry> 2488 <varlistentry> 2489 <term>Effects:</term> 2490 <listitem> 2491 <para> 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. 2497 </para> 2498 </listitem> 2499 </varlistentry> 2500 </variablelist> 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> 2508 </bridgehead> 2509 <variablelist> 2510 <title></title> 2511 <varlistentry> 2512 <term>Preconditions:</term> 2513 <listitem> 2514 <para> 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>. 2531 </para> 2532 </listitem> 2533 </varlistentry> 2534 <varlistentry> 2535 <term>Effects:</term> 2536 <listitem> 2537 <para> 2538 Deallocates the stack space. 2539 </para> 2540 </listitem> 2541 </varlistentry> 2542 </variablelist> 2543 </section> 2544 <section id="context.stack.pooled_fixedsize"> 2545 <title><link linkend="context.stack.pooled_fixedsize">Class <emphasis>pooled_fixedsize_stack</emphasis></link></title> 2546 <para> 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>. 2554 </para> 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> 2556 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> 2560 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> 2562 2563 <phrase role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">();</phrase> 2564 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> 2567 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> 2569</programlisting> 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> 2581 </bridgehead> 2582 <variablelist> 2583 <title></title> 2584 <varlistentry> 2585 <term>Preconditions:</term> 2586 <listitem> 2587 <para> 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>. 2598 </para> 2599 </listitem> 2600 </varlistentry> 2601 <varlistentry> 2602 <term>Effects:</term> 2603 <listitem> 2604 <para> 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. 2615 </para> 2616 </listitem> 2617 </varlistentry> 2618 </variablelist> 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> 2624 </bridgehead> 2625 <variablelist> 2626 <title></title> 2627 <varlistentry> 2628 <term>Preconditions:</term> 2629 <listitem> 2630 <para> 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>. 2639 </para> 2640 </listitem> 2641 </varlistentry> 2642 <varlistentry> 2643 <term>Effects:</term> 2644 <listitem> 2645 <para> 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. 2651 </para> 2652 </listitem> 2653 </varlistentry> 2654 </variablelist> 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> 2662 </bridgehead> 2663 <variablelist> 2664 <title></title> 2665 <varlistentry> 2666 <term>Preconditions:</term> 2667 <listitem> 2668 <para> 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>. 2680 </para> 2681 </listitem> 2682 </varlistentry> 2683 <varlistentry> 2684 <term>Effects:</term> 2685 <listitem> 2686 <para> 2687 Deallocates the stack space. 2688 </para> 2689 </listitem> 2690 </varlistentry> 2691 </variablelist> 2692 </section> 2693 <section id="context.stack.fixedsize"> 2694 <title><link linkend="context.stack.fixedsize">Class <emphasis>fixedsize_stack</emphasis></link></title> 2695 <para> 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>. 2704 </para> 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> 2706 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> 2710 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> 2712 2713 <phrase role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">();</phrase> 2714 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> 2717 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> 2719</programlisting> 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> 2725 </bridgehead> 2726 <variablelist> 2727 <title></title> 2728 <varlistentry> 2729 <term>Preconditions:</term> 2730 <listitem> 2731 <para> 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>. 2744 </para> 2745 </listitem> 2746 </varlistentry> 2747 <varlistentry> 2748 <term>Effects:</term> 2749 <listitem> 2750 <para> 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. 2756 </para> 2757 </listitem> 2758 </varlistentry> 2759 </variablelist> 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> 2767 </bridgehead> 2768 <variablelist> 2769 <title></title> 2770 <varlistentry> 2771 <term>Preconditions:</term> 2772 <listitem> 2773 <para> 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>. 2790 </para> 2791 </listitem> 2792 </varlistentry> 2793 <varlistentry> 2794 <term>Effects:</term> 2795 <listitem> 2796 <para> 2797 Deallocates the stack space. 2798 </para> 2799 </listitem> 2800 </varlistentry> 2801 </variablelist> 2802 </section> 2803 <section id="context.stack.segmented"> 2804 <title><anchor id="segmented"/><link linkend="context.stack.segmented">Class 2805 <emphasis>segmented_stack</emphasis></link></title> 2806 <para> 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. 2814 </para> 2815 <note> 2816 <para> 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. 2826 </para> 2827 </note> 2828 <note> 2829 <para> 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>) 2832 </para> 2833 </note> 2834 <para> 2835 . 2836 </para> 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> 2838 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> 2842 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> 2844 2845 <phrase role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">();</phrase> 2846 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> 2849 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> 2851</programlisting> 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> 2857 </bridgehead> 2858 <variablelist> 2859 <title></title> 2860 <varlistentry> 2861 <term>Preconditions:</term> 2862 <listitem> 2863 <para> 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>. 2876 </para> 2877 </listitem> 2878 </varlistentry> 2879 <varlistentry> 2880 <term>Effects:</term> 2881 <listitem> 2882 <para> 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. 2888 </para> 2889 </listitem> 2890 </varlistentry> 2891 </variablelist> 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> 2899 </bridgehead> 2900 <variablelist> 2901 <title></title> 2902 <varlistentry> 2903 <term>Preconditions:</term> 2904 <listitem> 2905 <para> 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>. 2922 </para> 2923 </listitem> 2924 </varlistentry> 2925 <varlistentry> 2926 <term>Effects:</term> 2927 <listitem> 2928 <para> 2929 Deallocates the stack space. 2930 </para> 2931 </listitem> 2932 </varlistentry> 2933 </variablelist> 2934 <note> 2935 <para> 2936 If the library is compiled for segmented stacks, <emphasis>segmented_stack</emphasis> 2937 is the only available stack allocator. 2938 </para> 2939 </note> 2940 </section> 2941 <section id="context.stack.stack_traits"> 2942 <title><link linkend="context.stack.stack_traits">Class <emphasis>stack_traits</emphasis></link></title> 2943 <para> 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. 2947 </para> 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> 2949 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> 2952 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> 2954 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> 2956 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> 2958 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> 2961</programlisting> 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> 2967 </bridgehead> 2968 <variablelist> 2969 <title></title> 2970 <varlistentry> 2971 <term>Returns:</term> 2972 <listitem> 2973 <para> 2974 Returns <code><phrase role="keyword">true</phrase></code> if the environment 2975 defines no limit for the size of a stack. 2976 </para> 2977 </listitem> 2978 </varlistentry> 2979 <varlistentry> 2980 <term>Throws:</term> 2981 <listitem> 2982 <para> 2983 Nothing. 2984 </para> 2985 </listitem> 2986 </varlistentry> 2987 </variablelist> 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> 2994 </bridgehead> 2995 <variablelist> 2996 <title></title> 2997 <varlistentry> 2998 <term>Returns:</term> 2999 <listitem> 3000 <para> 3001 Returns the page size in bytes. 3002 </para> 3003 </listitem> 3004 </varlistentry> 3005 <varlistentry> 3006 <term>Throws:</term> 3007 <listitem> 3008 <para> 3009 Nothing. 3010 </para> 3011 </listitem> 3012 </varlistentry> 3013 </variablelist> 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> 3020 </bridgehead> 3021 <variablelist> 3022 <title></title> 3023 <varlistentry> 3024 <term>Returns:</term> 3025 <listitem> 3026 <para> 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>. 3031 </para> 3032 </listitem> 3033 </varlistentry> 3034 <varlistentry> 3035 <term>Throws:</term> 3036 <listitem> 3037 <para> 3038 Nothing. 3039 </para> 3040 </listitem> 3041 </varlistentry> 3042 </variablelist> 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> 3049 </bridgehead> 3050 <variablelist> 3051 <title></title> 3052 <varlistentry> 3053 <term>Returns:</term> 3054 <listitem> 3055 <para> 3056 Returns the minimum size in bytes of stack defined by the environment 3057 (Win32 4kB/Win64 8kB, defined by rlimit on POSIX). 3058 </para> 3059 </listitem> 3060 </varlistentry> 3061 <varlistentry> 3062 <term>Throws:</term> 3063 <listitem> 3064 <para> 3065 Nothing. 3066 </para> 3067 </listitem> 3068 </varlistentry> 3069 </variablelist> 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> 3076 </bridgehead> 3077 <variablelist> 3078 <title></title> 3079 <varlistentry> 3080 <term>Preconditions:</term> 3081 <listitem> 3082 <para> 3083 <code><phrase role="identifier">is_unbounded</phrase><phrase role="special">()</phrase></code> 3084 returns <code><phrase role="keyword">false</phrase></code>. 3085 </para> 3086 </listitem> 3087 </varlistentry> 3088 <varlistentry> 3089 <term>Returns:</term> 3090 <listitem> 3091 <para> 3092 Returns the maximum size in bytes of stack defined by the environment. 3093 </para> 3094 </listitem> 3095 </varlistentry> 3096 <varlistentry> 3097 <term>Throws:</term> 3098 <listitem> 3099 <para> 3100 Nothing. 3101 </para> 3102 </listitem> 3103 </varlistentry> 3104 </variablelist> 3105 </section> 3106 <section id="context.stack.stack_context"> 3107 <title><link linkend="context.stack.stack_context">Class <emphasis>stack_context</emphasis></link></title> 3108 <para> 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. 3113 </para> 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> 3117 3118 <phrase role="comment">// might contain additional control structures</phrase> 3119 <phrase role="comment">// for segmented stacks</phrase> 3120<phrase role="special">}</phrase> 3121</programlisting> 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> 3126 </bridgehead> 3127 <variablelist> 3128 <title></title> 3129 <varlistentry> 3130 <term>Value:</term> 3131 <listitem> 3132 <para> 3133 Pointer to the beginning of the stack. 3134 </para> 3135 </listitem> 3136 </varlistentry> 3137 </variablelist> 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> 3143 </bridgehead> 3144 <variablelist> 3145 <title></title> 3146 <varlistentry> 3147 <term>Value:</term> 3148 <listitem> 3149 <para> 3150 Actual size of the stack. 3151 </para> 3152 </listitem> 3153 </varlistentry> 3154 </variablelist> 3155 </section> 3156 <section id="context.stack.valgrind"> 3157 <title><link linkend="context.stack.valgrind">Support for valgrind</link></title> 3158 <para> 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>. 3167 </para> 3168 </section> 3169 <section id="context.stack.sanitizers"> 3170 <title><link linkend="context.stack.sanitizers">Support for sanitizers</link></title> 3171 <para> 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. 3178 </para> 3179 </section> 3180 </section> 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> 3187 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> 3190</programlisting> 3191 <bridgehead renderas="sect3" id="context.struct__preallocated_.h0"> 3192 <phrase id="context.struct__preallocated_.constructor"/><link linkend="context.struct__preallocated_.constructor">Constructor</link> 3193 </bridgehead> 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> 3195</programlisting> 3196 <variablelist> 3197 <title></title> 3198 <varlistentry> 3199 <term>Effects:</term> 3200 <listitem> 3201 <para> 3202 Creates an object of preallocated. 3203 </para> 3204 </listitem> 3205 </varlistentry> 3206 </variablelist> 3207 </section> 3208 <section id="context.performance"> 3209 <title><anchor id="performance"/><link linkend="context.performance">Performance</link></title> 3210 <para> 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). 3217 </para> 3218 <table frame="all" id="context.performance.performance_of_context_switch"> 3219 <title>Performance of context switch</title> 3220 <tgroup cols="3"> 3221 <thead> 3222 <row> 3223 <entry> 3224 <para> 3225 callcc()/continuation (fcontext_t) 3226 </para> 3227 </entry> 3228 <entry> 3229 <para> 3230 callcc()/continuation (ucontext_t) 3231 </para> 3232 </entry> 3233 <entry> 3234 <para> 3235 callcc()/continuation (Windows-Fiber) 3236 </para> 3237 </entry> 3238 </row> 3239 </thead> 3240 <tbody> 3241 <row> 3242 <entry> 3243 <para> 3244 9 ns / 19 CPU cycles 3245 </para> 3246 </entry> 3247 <entry> 3248 <para> 3249 547 ns / 1130 CPU cycles 3250 </para> 3251 </entry> 3252 <entry> 3253 <para> 3254 49 ns / 98 CPU cycles 3255 </para> 3256 </entry> 3257 </row> 3258 </tbody> 3259 </tgroup> 3260 </table> 3261 </section> 3262 <section id="context.architectures"> 3263 <title><link linkend="context.architectures">Architectures</link></title> 3264 <para> 3265 <emphasis role="bold">Boost.Context</emphasis>, using <link linkend="implementation"><emphasis>fcontext_t</emphasis></link>, 3266 supports following architectures: 3267 </para> 3268 <table frame="all" id="context.architectures.supported_architectures___abi_binary_format__"> 3269 <title>Supported architectures (<ABI|binary format>)</title> 3270 <tgroup cols="5"> 3271 <thead> 3272 <row> 3273 <entry> 3274 <para> 3275 Architecture 3276 </para> 3277 </entry> 3278 <entry> 3279 <para> 3280 LINUX (UNIX) 3281 </para> 3282 </entry> 3283 <entry> 3284 <para> 3285 Windows 3286 </para> 3287 </entry> 3288 <entry> 3289 <para> 3290 MacOS X 3291 </para> 3292 </entry> 3293 <entry> 3294 <para> 3295 iOS 3296 </para> 3297 </entry> 3298 </row> 3299 </thead> 3300 <tbody> 3301 <row> 3302 <entry> 3303 <para> 3304 arm (aarch32) 3305 </para> 3306 </entry> 3307 <entry> 3308 <para> 3309 AAPCS|ELF 3310 </para> 3311 </entry> 3312 <entry> 3313 <para> 3314 AAPCS|PE 3315 </para> 3316 </entry> 3317 <entry> 3318 <para> 3319 - 3320 </para> 3321 </entry> 3322 <entry> 3323 <para> 3324 AAPCS|MACH-O 3325 </para> 3326 </entry> 3327 </row> 3328 <row> 3329 <entry> 3330 <para> 3331 arm (aarch64) 3332 </para> 3333 </entry> 3334 <entry> 3335 <para> 3336 AAPCS|ELF 3337 </para> 3338 </entry> 3339 <entry> 3340 <para> 3341 - 3342 </para> 3343 </entry> 3344 <entry> 3345 <para> 3346 - 3347 </para> 3348 </entry> 3349 <entry> 3350 <para> 3351 AAPCS|MACH-O 3352 </para> 3353 </entry> 3354 </row> 3355 <row> 3356 <entry> 3357 <para> 3358 i386 3359 </para> 3360 </entry> 3361 <entry> 3362 <para> 3363 SYSV|ELF 3364 </para> 3365 </entry> 3366 <entry> 3367 <para> 3368 MS|PE 3369 </para> 3370 </entry> 3371 <entry> 3372 <para> 3373 SYSV|MACH-O 3374 </para> 3375 </entry> 3376 <entry> 3377 <para> 3378 - 3379 </para> 3380 </entry> 3381 </row> 3382 <row> 3383 <entry> 3384 <para> 3385 mips1 3386 </para> 3387 </entry> 3388 <entry> 3389 <para> 3390 O32|ELF 3391 </para> 3392 </entry> 3393 <entry> 3394 <para> 3395 - 3396 </para> 3397 </entry> 3398 <entry> 3399 <para> 3400 - 3401 </para> 3402 </entry> 3403 <entry> 3404 <para> 3405 - 3406 </para> 3407 </entry> 3408 </row> 3409 <row> 3410 <entry> 3411 <para> 3412 ppc32 3413 </para> 3414 </entry> 3415 <entry> 3416 <para> 3417 SYSV|ELF,XCOFF 3418 </para> 3419 </entry> 3420 <entry> 3421 <para> 3422 - 3423 </para> 3424 </entry> 3425 <entry> 3426 <para> 3427 SYSV|MACH-O 3428 </para> 3429 </entry> 3430 <entry> 3431 <para> 3432 - 3433 </para> 3434 </entry> 3435 </row> 3436 <row> 3437 <entry> 3438 <para> 3439 ppc64 3440 </para> 3441 </entry> 3442 <entry> 3443 <para> 3444 SYSV|ELF,XCOFF 3445 </para> 3446 </entry> 3447 <entry> 3448 <para> 3449 - 3450 </para> 3451 </entry> 3452 <entry> 3453 <para> 3454 SYSV|MACH-O 3455 </para> 3456 </entry> 3457 <entry> 3458 <para> 3459 - 3460 </para> 3461 </entry> 3462 </row> 3463 <row> 3464 <entry> 3465 <para> 3466 riscv64 3467 </para> 3468 </entry> 3469 <entry> 3470 <para> 3471 SYSV|ELF 3472 </para> 3473 </entry> 3474 <entry> 3475 <para> 3476 - 3477 </para> 3478 </entry> 3479 <entry> 3480 <para> 3481 SYSV 3482 </para> 3483 </entry> 3484 <entry> 3485 <para> 3486 - 3487 </para> 3488 </entry> 3489 </row> 3490 <row> 3491 <entry> 3492 <para> 3493 s390x 3494 </para> 3495 </entry> 3496 <entry> 3497 <para> 3498 SYSV|ELF 3499 </para> 3500 </entry> 3501 <entry> 3502 <para> 3503 - 3504 </para> 3505 </entry> 3506 <entry> 3507 <para> 3508 - 3509 </para> 3510 </entry> 3511 <entry> 3512 <para> 3513 - 3514 </para> 3515 </entry> 3516 </row> 3517 <row> 3518 <entry> 3519 <para> 3520 sparc 3521 </para> 3522 </entry> 3523 <entry> 3524 <para> 3525 - 3526 </para> 3527 </entry> 3528 <entry> 3529 <para> 3530 - 3531 </para> 3532 </entry> 3533 <entry> 3534 <para> 3535 - 3536 </para> 3537 </entry> 3538 <entry> 3539 <para> 3540 - 3541 </para> 3542 </entry> 3543 </row> 3544 <row> 3545 <entry> 3546 <para> 3547 x86_64 3548 </para> 3549 </entry> 3550 <entry> 3551 <para> 3552 SYSV,X32|ELF 3553 </para> 3554 </entry> 3555 <entry> 3556 <para> 3557 MS|PE 3558 </para> 3559 </entry> 3560 <entry> 3561 <para> 3562 SYSV|MACH-O 3563 </para> 3564 </entry> 3565 <entry> 3566 <para> 3567 - 3568 </para> 3569 </entry> 3570 </row> 3571 </tbody> 3572 </tgroup> 3573 </table> 3574 <note> 3575 <para> 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>. 3581 </para> 3582 </note> 3583 <section id="context.architectures.crosscompiling"> 3584 <title><link linkend="context.architectures.crosscompiling">Cross compiling</link></title> 3585 <para> 3586 Cross compiling the library requires to specify the build properties <architecture>, 3587 <address-model>, <binary-format> and <abi> at b2 command 3588 line. 3589 </para> 3590 </section> 3591 </section> 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> 3597 </bridgehead> 3598 <para> 3599 Some newer compiler (for instance MSVC 10 for x86_64 and itanium) do not support 3600 inline assembler. <footnote id="context.rationale.f0"> 3601 <para> 3602 <ulink url="http://msdn.microsoft.com/en-us/library/4ks26t93.aspx">MSDN article 3603 'Inline Assembler'</ulink> 3604 </para> 3605 </footnote>. Inlined assembler generates code bloating which is not welcome 3606 on embedded systems. 3607 </para> 3608 <bridgehead renderas="sect3" id="context.rationale.h1"> 3609 <phrase id="context.rationale.fcontext_t"/><link linkend="context.rationale.fcontext_t">fcontext_t</link> 3610 </bridgehead> 3611 <para> 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. 3615 </para> 3616 <note> 3617 <para> 3618 Context switches do not preserve the signal mask on UNIX systems. 3619 </para> 3620 </note> 3621 <para> 3622 <emphasis>fcontext_t</emphasis> is an opaque pointer. 3623 </para> 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> 3628 </bridgehead> 3629 <para> 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"> 3636 <para> 3637 ISO/IEC 9899:1999, 2005, 7.13.2.1:2 3638 </para> 3639 </footnote>. 3640 </para> 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> 3644 </bridgehead> 3645 <para> 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> 3649 is: 3650 </para> 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> 3652</programlisting> 3653 <para> 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"> 3658 <para> 3659 ISO/IEC 9899:1999, 2005, J.2 3660 </para> 3661 </footnote>. 3662 </para> 3663 <para> 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. 3667 </para> 3668 <para> 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>). 3673 </para> 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 3676 fibers</link> 3677 </bridgehead> 3678 <para> 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). 3689 </para> 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> 3696</programlisting> 3697 <para> 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>. 3706 </para> 3707 </section> 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> 3713 </bridgehead> 3714 <para> 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"> 3718 <para> 3719 'Calling Conventions', Agner Fog 3720 </para> 3721 </footnote>. 3722 </para> 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> 3725 </bridgehead> 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> 3729 </bridgehead> 3730 <para> 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"> 3735 <para> 3736 <ulink url="http://http://msdn.microsoft.com/en-us/library/yxty7t75.aspx">MSDN 3737 article 'MxCsr'</ulink> 3738 </para> 3739 </footnote>. 3740 </para> 3741 <para> 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"> 3746 <para> 3747 <ulink url="http://http://msdn.microsoft.com/en-us/library/ms235300.aspx">MSDN 3748 article 'FpCsr'</ulink> 3749 </para> 3750 </footnote>. 3751 </para> 3752 <para> 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"> 3756 <para> 3757 <ulink url="http://msdn.microsoft.com/en-us/library/a32tsf7t%28VS.80%29.aspx">MSDN 3758 article 'Legacy Floating-Point Support'</ulink> 3759 </para> 3760 </footnote>. 3761 </para> 3762 <para> 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"> 3765 <para> 3766 'Calling Conventions', Agner Fog 3767 </para> 3768 </footnote>. 3769 </para> 3770 <para> 3771 "XMM6-XMM15 must be preserved" <footnote id="context.rationale.x86_and_floating_point_env.f5"> 3772 <para> 3773 <ulink url="http://msdn.microsoft.com/en-us/library/9z1stfyw%28v=vs.100%29.aspx">MSDN 3774 article 'Register Usage'</ulink> 3775 </para> 3776 </footnote> 3777 </para> 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> 3780 </bridgehead> 3781 <para> 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"> 3786 <para> 3787 SysV ABI AMD64 Architecture Processor Supplement Draft Version 0.99.4, 3788 3.2.1 3789 </para> 3790 </footnote>. 3791 </para> 3792 </section> 3793 </section> 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> 3798 </bridgehead> 3799 <itemizedlist> 3800 <listitem> 3801 <simpara> 3802 AAPCS ABI: Procedure Call Standard for the ARM Architecture 3803 </simpara> 3804 </listitem> 3805 <listitem> 3806 <simpara> 3807 AAPCS/LINUX: ARM GNU/Linux Application Binary Interface Supplement 3808 </simpara> 3809 </listitem> 3810 </itemizedlist> 3811 <bridgehead renderas="sect3" id="context.reference.h1"> 3812 <phrase id="context.reference.mips"/><link linkend="context.reference.mips">MIPS</link> 3813 </bridgehead> 3814 <itemizedlist> 3815 <listitem> 3816 <simpara> 3817 O32 ABI: SYSTEM V APPLICATION BINARY INTERFACE, MIPS RISC Processor Supplement 3818 </simpara> 3819 </listitem> 3820 </itemizedlist> 3821 <bridgehead renderas="sect3" id="context.reference.h2"> 3822 <phrase id="context.reference.powerpc32"/><link linkend="context.reference.powerpc32">PowerPC32</link> 3823 </bridgehead> 3824 <itemizedlist> 3825 <listitem> 3826 <simpara> 3827 SYSV ABI: SYSTEM V APPLICATION BINARY INTERFACE PowerPC Processor Supplement 3828 </simpara> 3829 </listitem> 3830 </itemizedlist> 3831 <bridgehead renderas="sect3" id="context.reference.h3"> 3832 <phrase id="context.reference.powerpc64"/><link linkend="context.reference.powerpc64">PowerPC64</link> 3833 </bridgehead> 3834 <itemizedlist> 3835 <listitem> 3836 <simpara> 3837 SYSV ABI: PowerPC User Instruction Set Architecture, Book I 3838 </simpara> 3839 </listitem> 3840 </itemizedlist> 3841 <bridgehead renderas="sect3" id="context.reference.h4"> 3842 <phrase id="context.reference.x86_32"/><link linkend="context.reference.x86_32">X86-32</link> 3843 </bridgehead> 3844 <itemizedlist> 3845 <listitem> 3846 <simpara> 3847 SYSV ABI: SYSTEM V APPLICATION BINARY INTERFACE, Intel386TM Architecture 3848 Processor Supplement 3849 </simpara> 3850 </listitem> 3851 <listitem> 3852 <simpara> 3853 MS PE: <ulink url="http://msdn.microsoft.com/en-us/library/k2b2ssfy.aspx">Calling 3854 Conventions</ulink> 3855 </simpara> 3856 </listitem> 3857 </itemizedlist> 3858 <bridgehead renderas="sect3" id="context.reference.h5"> 3859 <phrase id="context.reference.x86_64"/><link linkend="context.reference.x86_64">X86-64</link> 3860 </bridgehead> 3861 <itemizedlist> 3862 <listitem> 3863 <simpara> 3864 SYSV ABI: System V Application Binary Interface, AMD64 Architecture Processor 3865 Supplement 3866 </simpara> 3867 </listitem> 3868 <listitem> 3869 <simpara> 3870 MS PE: <ulink url="http://msdn.microsoft.com/en-us/library/7kcdt6fy%28VS.80%29.aspx">x64 3871 Software Conventions</ulink> 3872 </simpara> 3873 </listitem> 3874 </itemizedlist> 3875 </section> 3876 <section id="context.acknowledgements"> 3877 <title><link linkend="context.acknowledgements">Acknowledgments</link></title> 3878 <para> 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. 3884 </para> 3885 </section> 3886</library> 3887