]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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: 2016/03/04 17:27:33 $" | |
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 <emphasis>execution_context</emphasis> represents | |
34 | a specific point in the application's execution path. This is useful for building | |
35 | higher-level abstractions, like <emphasis>coroutines</emphasis>, <emphasis>cooperative | |
36 | threads (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 | <emphasis>execution_context</emphasis> provides the means to suspend the current | |
41 | execution path and to transfer execution control, thereby permitting another | |
42 | context to run on the current thread. This state full transfer mechanism enables | |
43 | a context to suspend execution from within nested functions and, later, to | |
44 | resume from where it was suspended. While the execution path represented by | |
45 | a <emphasis>execution_context</emphasis> only runs on a single thread, it can | |
46 | be migrated to another thread at any given time. | |
47 | </para> | |
48 | <para> | |
49 | A context switch between threads requires system calls (involving the OS kernel), | |
50 | which can cost more than thousand CPU cycles on x86 CPUs. By contrast, transferring | |
51 | control among them requires only few CPU cycles because it does not involve | |
52 | system calls as it is done within a single thread. | |
53 | </para> | |
54 | <para> | |
55 | In order to use the classes and functions described here, you can either include | |
56 | the specific headers specified by the descriptions of each class or function, | |
57 | or include the master library header: | |
58 | </para> | |
59 | <programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">context</phrase><phrase role="special">/</phrase><phrase role="identifier">all</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">></phrase> | |
60 | </programlisting> | |
61 | <para> | |
62 | which includes all the other headers in turn. | |
63 | </para> | |
64 | <para> | |
65 | All functions and classes are contained in the namespace <emphasis>boost::context</emphasis>. | |
66 | </para> | |
67 | <important> | |
68 | <para> | |
69 | <emphasis>execution_context</emphasis> requires C++11! | |
70 | </para> | |
71 | </important> | |
72 | </section> | |
73 | <section id="context.requirements"> | |
74 | <title><link linkend="context.requirements">Requirements</link></title> | |
75 | <para> | |
76 | <emphasis role="bold">Boost.Context</emphasis> must be built for the particular | |
77 | compiler(s) and CPU architecture(s)s being targeted. <emphasis role="bold">Boost.Context</emphasis> | |
78 | includes assembly code and, therefore, requires GNU as and GNU preprocesspr | |
79 | for supported POSIX systems, MASM for Windows/x86 systems and ARMasm for Windows/arm | |
80 | systems. | |
81 | </para> | |
82 | <note> | |
83 | <para> | |
84 | MASM64 (ml64.exe) is a part of Microsoft's Windows Driver Kit. | |
85 | </para> | |
86 | </note> | |
87 | <important> | |
88 | <para> | |
89 | Please note that <code><phrase role="identifier">address</phrase><phrase | |
90 | role="special">-</phrase><phrase role="identifier">model</phrase><phrase | |
91 | role="special">=</phrase><phrase role="number">64</phrase></code> must be | |
92 | given to bjam command line on 64bit Windows for 64bit build; otherwise 32bit | |
93 | code will be generated. | |
94 | </para> | |
95 | </important> | |
96 | <important> | |
97 | <para> | |
98 | For cross-compiling the lib you must specify certain additional properties | |
99 | at bjam command line: <code><phrase role="identifier">target</phrase><phrase | |
100 | role="special">-</phrase><phrase role="identifier">os</phrase></code>, <code><phrase | |
101 | role="identifier">abi</phrase></code>, <code><phrase role="identifier">binary</phrase><phrase | |
102 | role="special">-</phrase><phrase role="identifier">format</phrase></code>, | |
103 | <code><phrase role="identifier">architecture</phrase></code> and <code><phrase | |
104 | role="identifier">address</phrase><phrase role="special">-</phrase><phrase | |
105 | role="identifier">model</phrase></code>. | |
106 | </para> | |
107 | </important> | |
108 | <important> | |
109 | <para> | |
110 | For safe SEH the property 'asmflags=\safeseh' must be specified at bjam command | |
111 | line. | |
112 | </para> | |
113 | </important> | |
114 | </section> | |
115 | <section id="context.ecv2"> | |
116 | <title><anchor id="ecv2"/><link linkend="context.ecv2">Class execution_context | |
117 | (version 2)</link></title> | |
118 | <note> | |
119 | <para> | |
120 | This class is enabled per default. | |
121 | </para> | |
122 | </note> | |
123 | <para> | |
124 | Class <emphasis>execution_context</emphasis> encapsulates context switching | |
125 | and manages the associated context' stack (allocation/deallocation). | |
126 | </para> | |
127 | <para> | |
128 | <emphasis>execution_context</emphasis> allocates the context stack (using its | |
129 | <link linkend="stack"><emphasis>StackAllocator</emphasis></link> argument) | |
130 | and creates a control structure on top of it. This structure is responsible | |
131 | for managing context' stack. The address of the control structure is stored | |
132 | in the first frame of context' stack (e.g. it can not directly accessed from | |
133 | within <emphasis>execution_context</emphasis>). In contrast to <link linkend="ecv1"><emphasis>execution_context</emphasis> | |
134 | (v1)</link> the ownership of the control structure is not shared (no member | |
135 | variable to control structure in <emphasis>execution_context</emphasis>). | |
136 | <emphasis>execution_context</emphasis> keeps internally a state that is moved | |
137 | by a call of <emphasis>execution_context::operator()</emphasis> (<code><phrase | |
138 | role="special">*</phrase><phrase role="keyword">this</phrase></code> will be | |
139 | invalidated), e.g. after a calling <emphasis>execution_context::operator()</emphasis>, | |
140 | <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code> | |
141 | can not be used for an additional context switch. | |
142 | </para> | |
143 | <para> | |
144 | <emphasis>execution_context</emphasis> is only move-constructible and move-assignable. | |
145 | </para> | |
146 | <para> | |
147 | The moved state is assigned to a new instance of <emphasis>execution_context</emphasis>. | |
148 | This object becomes the first argument of the context-function, if the context | |
149 | was resumed the first time, or the first element in a tuple returned by <emphasis>execution_context::operator()</emphasis> | |
150 | that has been called in the resumed context. In contrast to <link linkend="ecv1"><emphasis>execution_context</emphasis> | |
151 | (v1)</link>, the context switch is faster because no global pointer etc. is | |
152 | involved. | |
153 | </para> | |
154 | <important> | |
155 | <para> | |
156 | Segmented stacks are not supported by <emphasis>execution_context</emphasis> | |
157 | (v2). | |
158 | </para> | |
159 | </important> | |
160 | <para> | |
161 | On return the context-function of the current context has to specify an <emphasis>execution_context</emphasis> | |
162 | to which the execution control is transferred after termination of the current | |
163 | context. | |
164 | </para> | |
165 | <para> | |
166 | If an instance with valid state goes out of scope and the context-function | |
167 | has not yet returned, the stack is traversed in order to access the control | |
168 | structure (address stored at the first stack frame) and context' stack is deallocated | |
169 | via the <emphasis>StackAllocator</emphasis>. The stack walking makes the destruction | |
170 | of <emphasis>execution_context</emphasis> slow and should be prevented if possible. | |
171 | </para> | |
172 | <para> | |
173 | <emphasis>execution_context</emphasis> expects a <emphasis>context-function</emphasis> | |
174 | with signature <code><phrase role="identifier">execution_context</phrase><phrase | |
175 | role="special">(</phrase><phrase role="identifier">execution_context</phrase> | |
176 | <phrase role="identifier">ctx</phrase><phrase role="special">,</phrase> <phrase | |
177 | role="identifier">Args</phrase> <phrase role="special">...</phrase> <phrase | |
178 | role="identifier">args</phrase><phrase role="special">)</phrase></code>. The | |
179 | parameter <code><phrase role="identifier">ctx</phrase></code> represents the | |
180 | context from which this context was resumed (e.g. that has called <emphasis>execution_context::operator()</emphasis> | |
181 | on <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>) | |
182 | and <code><phrase role="identifier">args</phrase></code> are the data passed | |
183 | to <emphasis>execution_context::operator()</emphasis>. The return value represents | |
184 | the execution_context that has to be resumed, after termiantion of this context. | |
185 | </para> | |
186 | <para> | |
187 | Benefits of <link linkend="ecv2"><emphasis>execution_context</emphasis> (v2)</link> | |
188 | over <link linkend="ecv1"><emphasis>execution_context</emphasis> (v1)</link> | |
189 | are: faster context switch, type-safety of passed/returned arguments. | |
190 | </para> | |
191 | <bridgehead renderas="sect3" id="context.ecv2.h0"> | |
192 | <phrase id="context.ecv2.usage_of__emphasis_execution_context__emphasis_"/><link | |
193 | linkend="context.ecv2.usage_of__emphasis_execution_context__emphasis_">usage | |
194 | of <emphasis>execution_context</emphasis></link> | |
195 | </bridgehead> | |
196 | <programlisting><phrase role="keyword">int</phrase> <phrase role="identifier">n</phrase><phrase role="special">=</phrase><phrase role="number">35</phrase><phrase role="special">;</phrase> | |
197 | <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase><phrase role="keyword">int</phrase><phrase role="special">></phrase> <phrase role="identifier">source</phrase><phrase role="special">(</phrase> | |
198 | <phrase role="special">[</phrase><phrase role="identifier">n</phrase><phrase role="special">](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase><phrase role="keyword">int</phrase><phrase role="special">></phrase> <phrase role="identifier">sink</phrase><phrase role="special">,</phrase> <phrase role="keyword">int</phrase><phrase role="special">)</phrase> <phrase role="keyword">mutable</phrase> <phrase role="special">{</phrase> | |
199 | <phrase role="keyword">int</phrase> <phrase role="identifier">a</phrase><phrase role="special">=</phrase><phrase role="number">0</phrase><phrase role="special">;</phrase> | |
200 | <phrase role="keyword">int</phrase> <phrase role="identifier">b</phrase><phrase role="special">=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase> | |
201 | <phrase role="keyword">while</phrase><phrase role="special">(</phrase><phrase role="identifier">n</phrase><phrase role="special">--></phrase><phrase role="number">0</phrase><phrase role="special">){</phrase> | |
202 | <phrase role="keyword">auto</phrase> <phrase role="identifier">result</phrase><phrase role="special">=</phrase><phrase role="identifier">sink</phrase><phrase role="special">(</phrase><phrase role="identifier">a</phrase><phrase role="special">);</phrase> | |
203 | <phrase role="identifier">sink</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special"><</phrase><phrase role="number">0</phrase><phrase role="special">>(</phrase><phrase role="identifier">result</phrase><phrase role="special">));</phrase> | |
204 | <phrase role="keyword">auto</phrase> <phrase role="identifier">next</phrase><phrase role="special">=</phrase><phrase role="identifier">a</phrase><phrase role="special">+</phrase><phrase role="identifier">b</phrase><phrase role="special">;</phrase> | |
205 | <phrase role="identifier">a</phrase><phrase role="special">=</phrase><phrase role="identifier">b</phrase><phrase role="special">;</phrase> | |
206 | <phrase role="identifier">b</phrase><phrase role="special">=</phrase><phrase role="identifier">next</phrase><phrase role="special">;</phrase> | |
207 | <phrase role="special">}</phrase> | |
208 | <phrase role="keyword">return</phrase> <phrase role="identifier">sink</phrase><phrase role="special">;</phrase> | |
209 | <phrase role="special">});</phrase> | |
210 | <phrase role="keyword">for</phrase><phrase role="special">(</phrase><phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase><phrase role="special">=</phrase><phrase role="number">0</phrase><phrase role="special">;</phrase><phrase role="identifier">i</phrase><phrase role="special"><</phrase><phrase role="number">10</phrase><phrase role="special">;++</phrase><phrase role="identifier">i</phrase><phrase role="special">){</phrase> | |
211 | <phrase role="keyword">auto</phrase> <phrase role="identifier">result</phrase><phrase role="special">=</phrase><phrase role="identifier">source</phrase><phrase role="special">(</phrase><phrase role="identifier">i</phrase><phrase role="special">);</phrase> | |
212 | <phrase role="identifier">source</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special"><</phrase><phrase role="number">0</phrase><phrase role="special">>(</phrase><phrase role="identifier">result</phrase><phrase role="special">));</phrase> | |
213 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase><phrase role="special"><<</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special"><</phrase><phrase role="number">1</phrase><phrase role="special">>(</phrase><phrase role="identifier">result</phrase><phrase role="special">)<<</phrase><phrase role="string">" "</phrase><phrase role="special">;</phrase> | |
214 | <phrase role="special">}</phrase> | |
215 | ||
216 | <phrase role="identifier">output</phrase><phrase role="special">:</phrase> | |
217 | <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> | |
218 | </programlisting> | |
219 | <para> | |
220 | This simple example demonstrates the basic usage of <emphasis>execution_context</emphasis> | |
221 | as a generator. The context <code><phrase role="identifier">sink</phrase></code> | |
222 | represents the <emphasis>main</emphasis>-context (function <emphasis>main()</emphasis> | |
223 | running). <code><phrase role="identifier">sink</phrase></code> is generated | |
224 | by the framework (first element of lambda's parameter list). Because the state | |
225 | is invalidated (== changed) by each call of <emphasis>execution_context::operator()</emphasis>, | |
226 | the new state of the <emphasis>execution_context</emphasis>, returned by <emphasis>execution_context::operator()</emphasis>, | |
227 | needs to be assigned to <code><phrase role="identifier">sink</phrase></code> | |
228 | after each call. | |
229 | </para> | |
230 | <para> | |
231 | The lambda that calculates the Fibonacci numbers is executed inside the context | |
232 | represented by <code><phrase role="identifier">source</phrase></code>. Calculated | |
233 | Fibonacci numbers are transferred between the two context' via expression | |
234 | <emphasis>sink(a)</emphasis> (and returned by <emphasis>source()</emphasis>). | |
235 | Note that this example represents a <emphasis>generator</emphasis> thus the | |
236 | value transferred into the lambda via <emphasis>source()</emphasis> is not | |
237 | used. Using <emphasis>boost::optional<></emphasis> as transferred type, | |
238 | might also appropriate to express this fact. | |
239 | </para> | |
240 | <para> | |
241 | The locale variables <code><phrase role="identifier">a</phrase></code>, <code><phrase | |
242 | role="identifier">b</phrase></code> and <code> <phrase role="identifier">next</phrase></code> | |
243 | remain their values during each context switch (<emphasis>yield(a)</emphasis>). | |
244 | This is possible due <code><phrase role="identifier">source</phrase></code> | |
245 | has its own stack and the stack is exchanged by each context switch. | |
246 | </para> | |
247 | <bridgehead renderas="sect3" id="context.ecv2.h1"> | |
248 | <phrase id="context.ecv2.parameter_passing"/><link linkend="context.ecv2.parameter_passing">parameter | |
249 | passing</link> | |
250 | </bridgehead> | |
251 | <para> | |
252 | With <code><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase><phrase | |
253 | role="keyword">void</phrase><phrase role="special">></phrase></code> no | |
254 | data will be transferred, only the context switch is executed. | |
255 | </para> | |
256 | <programlisting><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase><phrase role="keyword">void</phrase><phrase role="special">></phrase> <phrase role="identifier">ctx1</phrase><phrase role="special">([](</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase><phrase role="keyword">void</phrase><phrase role="special">></phrase> <phrase role="identifier">ctx2</phrase><phrase role="special">){</phrase> | |
257 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">"inside ctx1\n"</phrase><phrase role="special">);</phrase> | |
258 | <phrase role="keyword">return</phrase> <phrase role="identifier">ctx2</phrase><phrase role="special">();</phrase> | |
259 | <phrase role="special">});</phrase> | |
260 | <phrase role="identifier">ctx1</phrase><phrase role="special">();</phrase> | |
261 | ||
262 | <phrase role="identifier">output</phrase><phrase role="special">:</phrase> | |
263 | <phrase role="identifier">inside</phrase> <phrase role="identifier">ctx1</phrase> | |
264 | </programlisting> | |
265 | <para> | |
266 | <code><phrase role="identifier">ctx1</phrase><phrase role="special">()</phrase></code> | |
267 | resumes <code><phrase role="identifier">ctx1</phrase></code>, e.g. the lambda | |
268 | passed at the constructor of <code><phrase role="identifier">ctx1</phrase></code> | |
269 | is entered. Argument <code><phrase role="identifier">ctx2</phrase></code> represents | |
270 | the context that has been suspended with the invocation of <code><phrase role="identifier">ctx1</phrase><phrase | |
271 | role="special">()</phrase></code>. When the lambda returns <code><phrase role="identifier">ctx2</phrase></code>, | |
272 | context <code><phrase role="identifier">ctx1</phrase></code> will be terminated | |
273 | while the context represented by <code><phrase role="identifier">ctx2</phrase></code> | |
274 | is resumed, hence the control of execution returns from <code><phrase role="identifier">ctx1</phrase><phrase | |
275 | role="special">()</phrase></code>. | |
276 | </para> | |
277 | <para> | |
278 | The arguments passed to <emphasis>execution_context::operator()</emphasis>, | |
279 | in one context, is passed as the last arguments of the <emphasis>context-function</emphasis> | |
280 | if the context is started for the first time. In all following invocations | |
281 | of <emphasis>execution_context::operator()</emphasis> the arguments passed | |
282 | to <emphasis>execution_context::operator()</emphasis>, in one context, is returned | |
283 | by <emphasis>execution_context::operator()</emphasis> in the other context. | |
284 | </para> | |
285 | <programlisting><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase><phrase role="keyword">int</phrase><phrase role="special">></phrase> <phrase role="identifier">ctx1</phrase><phrase role="special">([](</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase><phrase role="keyword">int</phrase><phrase role="special">></phrase> <phrase role="identifier">ctx2</phrase><phrase role="special">,</phrase> <phrase role="keyword">int</phrase> <phrase role="identifier">j</phrase><phrase role="special">){</phrase> | |
286 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">"inside ctx1, j == %d\n"</phrase><phrase role="special">,</phrase> <phrase role="identifier">j</phrase><phrase role="special">);</phrase> | |
287 | <phrase role="keyword">return</phrase> <phrase role="identifier">ctx2</phrase><phrase role="special">(</phrase><phrase role="identifier">j</phrase><phrase role="special">+</phrase><phrase role="number">1</phrase><phrase role="special">);</phrase> | |
288 | <phrase role="special">});</phrase> | |
289 | <phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase> <phrase role="special">=</phrase> <phrase role="number">1</phrase><phrase role="special">;</phrase> | |
290 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tie</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx1</phrase><phrase role="special">,</phrase> <phrase role="identifier">i</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx1</phrase><phrase role="special">(</phrase><phrase role="identifier">i</phrase><phrase role="special">);</phrase> | |
291 | <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> | |
292 | ||
293 | <phrase role="identifier">output</phrase><phrase role="special">:</phrase> | |
294 | <phrase role="identifier">inside</phrase> <phrase role="identifier">ctx1</phrase><phrase role="special">,</phrase> <phrase role="identifier">j</phrase> <phrase role="special">==</phrase> <phrase role="number">1</phrase> | |
295 | <phrase role="identifier">i</phrase> <phrase role="special">==</phrase> <phrase role="number">2</phrase> | |
296 | </programlisting> | |
297 | <para> | |
298 | <code><phrase role="identifier">ctx1</phrase><phrase role="special">(</phrase><phrase | |
299 | role="identifier">i</phrase><phrase role="special">)</phrase></code> enters | |
300 | the lambda in context <code><phrase role="identifier">ctx1</phrase></code> | |
301 | with argument <code><phrase role="identifier">j</phrase><phrase role="special">=</phrase><phrase | |
302 | role="number">1</phrase></code>. The expression <code><phrase role="identifier">ctx2</phrase><phrase | |
303 | role="special">(</phrase><phrase role="identifier">j</phrase><phrase role="special">+</phrase><phrase | |
304 | role="number">1</phrase><phrase role="special">)</phrase></code> resumes the | |
305 | context represented by <code><phrase role="identifier">ctx2</phrase></code> | |
306 | and transfers back an integer of <code><phrase role="identifier">j</phrase><phrase | |
307 | role="special">+</phrase><phrase role="number">1</phrase></code>. On return | |
308 | of <code><phrase role="identifier">ctx1</phrase><phrase role="special">(</phrase><phrase | |
309 | role="identifier">i</phrase><phrase role="special">)</phrase></code>, the variable | |
310 | <code><phrase role="identifier">i</phrase></code> contains the value of <code><phrase | |
311 | role="identifier">j</phrase><phrase role="special">+</phrase><phrase role="number">1</phrase></code>. | |
312 | </para> | |
313 | <para> | |
314 | If more than one argument has to be transferred, the signature of the context-function | |
315 | is simply extended. | |
316 | </para> | |
317 | <programlisting><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase><phrase role="keyword">int</phrase><phrase role="special">,</phrase><phrase role="keyword">int</phrase><phrase role="special">></phrase> <phrase role="identifier">ctx1</phrase><phrase role="special">([](</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase><phrase role="keyword">int</phrase><phrase role="special">,</phrase><phrase role="keyword">int</phrase><phrase role="special">></phrase> <phrase role="identifier">ctx2</phrase><phrase role="special">,</phrase> <phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase><phrase role="special">,</phrase> <phrase role="keyword">int</phrase> <phrase role="identifier">j</phrase><phrase role="special">){</phrase> | |
318 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">"inside ctx1, i == %d j == %d\n"</phrase><phrase role="special">,</phrase> <phrase role="identifier">i</phrase><phrase role="special">,</phrase> <phrase role="identifier">j</phrase><phrase role="special">);</phrase> | |
319 | <phrase role="keyword">return</phrase> <phrase role="identifier">ctx2</phrase><phrase role="special">(</phrase><phrase role="identifier">i</phrase><phrase role="special">+</phrase><phrase role="identifier">j</phrase><phrase role="special">,</phrase><phrase role="identifier">i</phrase><phrase role="special">-</phrase><phrase role="identifier">j</phrase><phrase role="special">);</phrase> | |
320 | <phrase role="special">});</phrase> | |
321 | <phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase> <phrase role="special">=</phrase> <phrase role="number">2</phrase><phrase role="special">,</phrase> <phrase role="identifier">j</phrase> <phrase role="special">=</phrase> <phrase role="number">1</phrase><phrase role="special">;</phrase> | |
322 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tie</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx1</phrase><phrase role="special">,</phrase> <phrase role="identifier">i</phrase><phrase role="special">,</phrase> <phrase role="identifier">j</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx1</phrase><phrase role="special">(</phrase><phrase role="identifier">i</phrase><phrase role="special">,</phrase><phrase role="identifier">j</phrase><phrase role="special">);</phrase> | |
323 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">"i == %d j == %d\n"</phrase><phrase role="special">,</phrase> <phrase role="identifier">i</phrase><phrase role="special">,</phrase> <phrase role="identifier">j</phrase><phrase role="special">);</phrase> | |
324 | ||
325 | <phrase role="identifier">output</phrase><phrase role="special">:</phrase> | |
326 | <phrase role="identifier">inside</phrase> <phrase role="identifier">ctx1</phrase><phrase role="special">,</phrase> <phrase role="identifier">i</phrase> <phrase role="special">==</phrase> <phrase role="number">2</phrase> <phrase role="identifier">j</phrase> <phrase role="special">==</phrase> <phrase role="number">1</phrase> | |
327 | <phrase role="identifier">i</phrase> <phrase role="special">==</phrase> <phrase role="number">3</phrase> <phrase role="identifier">j</phrase> <phrase role="special">==</phrase> <phrase role="number">1</phrase> | |
328 | </programlisting> | |
329 | <para> | |
330 | For use-cases, that require to transfer data of different type in each direction, | |
331 | <emphasis>boost::variant<></emphasis> could be used. | |
332 | </para> | |
333 | <programlisting><phrase role="keyword">class</phrase> <phrase role="identifier">X</phrase><phrase role="special">{</phrase> | |
334 | <phrase role="keyword">private</phrase><phrase role="special">:</phrase> | |
335 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">exception_ptr</phrase> <phrase role="identifier">excptr_</phrase><phrase role="special">;</phrase> | |
336 | <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">variant</phrase><phrase role="special"><</phrase><phrase role="keyword">int</phrase><phrase role="special">,</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">>></phrase> <phrase role="identifier">ctx_</phrase><phrase role="special">;</phrase> | |
337 | ||
338 | <phrase role="keyword">public</phrase><phrase role="special">:</phrase> | |
339 | <phrase role="identifier">X</phrase><phrase role="special">():</phrase> | |
340 | <phrase role="identifier">excptr_</phrase><phrase role="special">(),</phrase> | |
341 | <phrase role="identifier">ctx_</phrase><phrase role="special">(</phrase> | |
342 | <phrase role="special">[=](</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">variant</phrase><phrase role="special"><</phrase><phrase role="keyword">int</phrase><phrase role="special">,</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">>></phrase> <phrase role="identifier">ctx</phrase><phrase role="special">,</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">variant</phrase><phrase role="special"><</phrase><phrase role="keyword">int</phrase><phrase role="special">,</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">></phrase> <phrase role="identifier">data</phrase><phrase role="special">){</phrase> | |
343 | <phrase role="keyword">try</phrase> <phrase role="special">{</phrase> | |
344 | <phrase role="keyword">for</phrase> <phrase role="special">(;;)</phrase> <phrase role="special">{</phrase> | |
345 | <phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase> <phrase role="special">=</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special"><</phrase><phrase role="keyword">int</phrase><phrase role="special">>(</phrase><phrase role="identifier">data</phrase><phrase role="special">);</phrase> | |
346 | <phrase role="identifier">data</phrase> <phrase role="special">=</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">lexical_cast</phrase><phrase role="special"><</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">>(</phrase><phrase role="identifier">i</phrase><phrase role="special">);</phrase> | |
347 | <phrase role="keyword">auto</phrase> <phrase role="identifier">result</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">(</phrase> <phrase role="identifier">data</phrase><phrase role="special">);</phrase> | |
348 | <phrase role="identifier">ctx</phrase> <phrase role="special">=</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special"><</phrase><phrase role="number">0</phrase><phrase role="special">>(</phrase> <phrase role="identifier">result</phrase><phrase role="special">)</phrase> <phrase role="special">);</phrase> | |
349 | <phrase role="identifier">data</phrase> <phrase role="special">=</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special"><</phrase><phrase role="number">1</phrase><phrase role="special">>(</phrase> <phrase role="identifier">result</phrase><phrase role="special">);</phrase> | |
350 | <phrase role="special">}</phrase> <phrase role="keyword">catch</phrase> <phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">bad_cast</phrase> <phrase role="keyword">const</phrase><phrase role="special">&)</phrase> <phrase role="special">{</phrase> | |
351 | <phrase role="identifier">excptr_</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">current_exception</phrase><phrase role="special">();</phrase> | |
352 | <phrase role="special">}</phrase> | |
353 | <phrase role="keyword">return</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">;</phrase> | |
354 | <phrase role="special">})</phrase> | |
355 | <phrase role="special">{}</phrase> | |
356 | ||
357 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase><phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase><phrase role="special">){</phrase> | |
358 | <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">variant</phrase><phrase role="special"><</phrase><phrase role="keyword">int</phrase><phrase role="special">,</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">></phrase> <phrase role="identifier">data</phrase> <phrase role="special">=</phrase> <phrase role="identifier">i</phrase><phrase role="special">;</phrase> | |
359 | <phrase role="keyword">auto</phrase> <phrase role="identifier">result</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx_</phrase><phrase role="special">(</phrase> <phrase role="identifier">data</phrase><phrase role="special">);</phrase> | |
360 | <phrase role="identifier">ctx_</phrase> <phrase role="special">=</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special"><</phrase><phrase role="number">0</phrase><phrase role="special">>(</phrase> <phrase role="identifier">result</phrase><phrase role="special">)</phrase> <phrase role="special">);</phrase> | |
361 | <phrase role="identifier">data</phrase> <phrase role="special">=</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special"><</phrase><phrase role="number">1</phrase><phrase role="special">>(</phrase> <phrase role="identifier">result</phrase><phrase role="special">);</phrase> | |
362 | <phrase role="keyword">if</phrase><phrase role="special">(</phrase><phrase role="identifier">excptr_</phrase><phrase role="special">){</phrase> | |
363 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">rethrow_exception</phrase><phrase role="special">(</phrase><phrase role="identifier">excptr_</phrase><phrase role="special">);</phrase> | |
364 | <phrase role="special">}</phrase> | |
365 | <phrase role="keyword">return</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special"><</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">>(</phrase><phrase role="identifier">data</phrase><phrase role="special">);</phrase> | |
366 | <phrase role="special">}</phrase> | |
367 | <phrase role="special">};</phrase> | |
368 | ||
369 | <phrase role="identifier">X</phrase> <phrase role="identifier">x</phrase><phrase role="special">;</phrase> | |
370 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">x</phrase><phrase role="special">(</phrase> <phrase role="number">7</phrase><phrase role="special">)</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase> | |
371 | ||
372 | <phrase role="identifier">output</phrase><phrase role="special">:</phrase> | |
373 | <phrase role="number">7</phrase> | |
374 | </programlisting> | |
375 | <para> | |
376 | In the case of unidirectional transfer of data, <emphasis>boost::optional<></emphasis> | |
377 | or a pointer are appropriate. | |
378 | </para> | |
379 | <bridgehead renderas="sect3" id="context.ecv2.h2"> | |
380 | <phrase id="context.ecv2.exception_handling"/><link linkend="context.ecv2.exception_handling">exception | |
381 | handling</link> | |
382 | </bridgehead> | |
383 | <para> | |
384 | If the function executed inside a <emphasis>execution_context</emphasis> emits | |
385 | ans exception, the application is terminated by calling <emphasis>std::terminate()</emphasis>. | |
386 | <emphasis>std::exception_ptr</emphasis> can be used to transfer exceptions | |
387 | between different execution contexts. | |
388 | </para> | |
389 | <important> | |
390 | <para> | |
391 | Do not jump from inside a catch block and then re-throw the exception in | |
392 | another execution context. | |
393 | </para> | |
394 | </important> | |
395 | <anchor id="ecv2_ontop"/> | |
396 | <bridgehead renderas="sect3" id="context.ecv2.h3"> | |
397 | <phrase id="context.ecv2.executing_function_on_top_of_a_context"/><link linkend="context.ecv2.executing_function_on_top_of_a_context">Executing | |
398 | function on top of a context</link> | |
399 | </bridgehead> | |
400 | <para> | |
401 | Sometimes it is useful to execute a new function on top of a resumed context. | |
402 | For this purpose <emphasis>execution_context::operator()</emphasis> with first | |
403 | argument <code><phrase role="identifier">exec_ontop_arg</phrase></code> has | |
404 | to be used. The function passed as argument must return a tuple of execution_context | |
405 | and arguments. | |
406 | </para> | |
407 | <programlisting><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase><phrase role="keyword">int</phrase><phrase role="special">></phrase> <phrase role="identifier">f1</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase><phrase role="keyword">int</phrase><phrase role="special">></phrase> <phrase role="identifier">ctx</phrase><phrase role="special">,</phrase><phrase role="keyword">int</phrase> <phrase role="identifier">data</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase> | |
408 | <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> | |
409 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tie</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx</phrase><phrase role="special">,</phrase><phrase role="identifier">data</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">(</phrase><phrase role="identifier">data</phrase><phrase role="special">+</phrase><phrase role="number">1</phrase><phrase role="special">);</phrase> | |
410 | <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> | |
411 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tie</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx</phrase><phrase role="special">,</phrase><phrase role="identifier">data</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">(</phrase><phrase role="identifier">data</phrase><phrase role="special">+</phrase><phrase role="number">1</phrase><phrase role="special">);</phrase> | |
412 | <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> | |
413 | <phrase role="keyword">return</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">;</phrase> | |
414 | <phrase role="special">}</phrase> | |
415 | ||
416 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tuple</phrase><phrase role="special"><</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase><phrase role="keyword">int</phrase><phrase role="special">>,</phrase><phrase role="keyword">int</phrase><phrase role="special">></phrase> <phrase role="identifier">f2</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase><phrase role="keyword">int</phrase><phrase role="special">></phrase> <phrase role="identifier">ctx</phrase><phrase role="special">,</phrase><phrase role="keyword">int</phrase> <phrase role="identifier">data</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase> | |
417 | <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> | |
418 | <phrase role="keyword">return</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">make_tuple</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">ctx</phrase><phrase role="special">),-</phrase><phrase role="number">1</phrase><phrase role="special">);</phrase> | |
419 | <phrase role="special">}</phrase> | |
420 | ||
421 | <phrase role="keyword">int</phrase> <phrase role="identifier">data</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">;</phrase> | |
422 | <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase> <phrase role="keyword">int</phrase> <phrase role="special">></phrase> <phrase role="identifier">ctx</phrase><phrase role="special">(</phrase><phrase role="identifier">f1</phrase><phrase role="special">);</phrase> | |
423 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tie</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx</phrase><phrase role="special">,</phrase><phrase role="identifier">data</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">(</phrase><phrase role="identifier">data</phrase><phrase role="special">+</phrase><phrase role="number">1</phrase><phrase role="special">);</phrase> | |
424 | <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> | |
425 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tie</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx</phrase><phrase role="special">,</phrase><phrase role="identifier">data</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">(</phrase><phrase role="identifier">data</phrase><phrase role="special">+</phrase><phrase role="number">1</phrase><phrase role="special">);</phrase> | |
426 | <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> | |
427 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tie</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx</phrase><phrase role="special">,</phrase><phrase role="identifier">data</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">(</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">exec_ontop_arg</phrase><phrase role="special">,</phrase><phrase role="identifier">f2</phrase><phrase role="special">,</phrase><phrase role="identifier">data</phrase><phrase role="special">+</phrase><phrase role="number">1</phrase><phrase role="special">);</phrase> | |
428 | ||
429 | <phrase role="identifier">output</phrase><phrase role="special">:</phrase> | |
430 | <phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">entered</phrase> <phrase role="identifier">first</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase> | |
431 | <phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">returned</phrase> <phrase role="identifier">first</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="number">2</phrase> | |
432 | <phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">entered</phrase> <phrase role="identifier">second</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="number">3</phrase> | |
433 | <phrase role="identifier">f1</phrase><phrase role="special">:</phrase> <phrase role="identifier">returned</phrase> <phrase role="identifier">second</phrase> <phrase role="identifier">time</phrase><phrase role="special">:</phrase> <phrase role="number">4</phrase> | |
434 | <phrase role="identifier">f2</phrase><phrase role="special">:</phrase> <phrase role="identifier">entered</phrase><phrase role="special">:</phrase> <phrase role="number">5</phrase> | |
435 | <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> | |
436 | </programlisting> | |
437 | <para> | |
438 | The expression <code><phrase role="identifier">ctx</phrase><phrase role="special">(</phrase><phrase | |
439 | role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">exec_ontop_arg</phrase><phrase | |
440 | role="special">,</phrase><phrase role="identifier">f2</phrase><phrase role="special">,</phrase><phrase | |
441 | role="identifier">data</phrase><phrase role="special">+</phrase><phrase role="number">1</phrase><phrase | |
442 | role="special">)</phrase></code> executes <code><phrase role="identifier">f2</phrase><phrase | |
443 | role="special">()</phrase></code> on top of context <code><phrase role="identifier">ctx</phrase></code>, | |
444 | e.g. an additional stack frame is allocated on top of the context stack (in | |
445 | front of <code><phrase role="identifier">f1</phrase><phrase role="special">()</phrase></code>). | |
446 | <code><phrase role="identifier">f2</phrase><phrase role="special">()</phrase></code> | |
447 | returns argument <code><phrase role="special">-</phrase><phrase role="number">1</phrase></code> | |
448 | that will returned by the second invocation of <code><phrase role="identifier">ctx</phrase><phrase | |
449 | role="special">(</phrase><phrase role="identifier">data</phrase><phrase role="special">+</phrase><phrase | |
450 | role="number">1</phrase><phrase role="special">)</phrase></code> in <code><phrase | |
451 | role="identifier">f1</phrase><phrase role="special">()</phrase></code>. | |
452 | </para> | |
453 | <para> | |
454 | Another option is to execute a function on top of the context that throws an | |
455 | exception. | |
456 | </para> | |
457 | <programlisting><phrase role="keyword">struct</phrase> <phrase role="identifier">interrupt</phrase> <phrase role="special">{</phrase> | |
458 | <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase> <phrase role="keyword">void</phrase> <phrase role="special">></phrase> <phrase role="identifier">ctx</phrase><phrase role="special">;</phrase> | |
459 | ||
460 | <phrase role="identifier">interrupt</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase> <phrase role="keyword">void</phrase> <phrase role="special">></phrase> <phrase role="special">&&</phrase> <phrase role="identifier">ctx_</phrase><phrase role="special">)</phrase> <phrase role="special">:</phrase> | |
461 | <phrase role="identifier">ctx</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">forward</phrase><phrase role="special"><</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase> <phrase role="keyword">void</phrase> <phrase role="special">></phrase> <phrase role="special">>(</phrase> <phrase role="identifier">ctx_</phrase><phrase role="special">)</phrase> <phrase role="special">)</phrase> <phrase role="special">{</phrase> | |
462 | <phrase role="special">}</phrase> | |
463 | <phrase role="special">};</phrase> | |
464 | ||
465 | <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase><phrase role="keyword">void</phrase><phrase role="special">></phrase> <phrase role="identifier">f1</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase><phrase role="keyword">void</phrase><phrase role="special">></phrase> <phrase role="identifier">ctx</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase> | |
466 | <phrase role="keyword">try</phrase> <phrase role="special">{</phrase> | |
467 | <phrase role="keyword">for</phrase> <phrase role="special">(;;)</phrase> <phrase role="special">{</phrase> | |
468 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f1()"</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase> | |
469 | <phrase role="identifier">ctx</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">();</phrase> | |
470 | <phrase role="special">}</phrase> | |
471 | <phrase role="special">}</phrase> <phrase role="keyword">catch</phrase> <phrase role="special">(</phrase><phrase role="identifier">interrupt</phrase> <phrase role="special">&</phrase> <phrase role="identifier">e</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase> | |
472 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="string">"f1(): interrupted"</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase> | |
473 | <phrase role="identifier">ctx</phrase> <phrase role="special">=</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase> <phrase role="identifier">e</phrase><phrase role="special">.</phrase><phrase role="identifier">ctx</phrase><phrase role="special">);</phrase> | |
474 | <phrase role="special">}</phrase> | |
475 | <phrase role="keyword">return</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">;</phrase> | |
476 | <phrase role="special">}</phrase> | |
477 | ||
478 | <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase><phrase role="keyword">void</phrase><phrase role="special">></phrase> <phrase role="identifier">f2</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase><phrase role="keyword">void</phrase><phrase role="special">></phrase> <phrase role="identifier">ctx</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase> | |
479 | <phrase role="keyword">throw</phrase> <phrase role="identifier">interrupt</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">ctx</phrase><phrase role="special">));</phrase> | |
480 | <phrase role="keyword">return</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">;</phrase> | |
481 | <phrase role="special">}</phrase> | |
482 | ||
483 | <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase> <phrase role="keyword">void</phrase> <phrase role="special">></phrase> <phrase role="identifier">ctx</phrase><phrase role="special">(</phrase><phrase role="identifier">f1</phrase><phrase role="special">);</phrase> | |
484 | <phrase role="identifier">ctx</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">();</phrase> | |
485 | <phrase role="identifier">ctx</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">();</phrase> | |
486 | <phrase role="identifier">ctx</phrase> <phrase role="special">=</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">exec_ontop_arg</phrase><phrase role="special">,</phrase><phrase role="identifier">f2</phrase><phrase role="special">);</phrase> | |
487 | ||
488 | <phrase role="identifier">output</phrase><phrase role="special">:</phrase> | |
489 | <phrase role="identifier">f1</phrase><phrase role="special">()</phrase> | |
490 | <phrase role="identifier">f1</phrase><phrase role="special">()</phrase> | |
491 | <phrase role="identifier">f1</phrase><phrase role="special">():</phrase> <phrase role="identifier">interrupted</phrase> | |
492 | </programlisting> | |
493 | <para> | |
494 | In this example <code><phrase role="identifier">f2</phrase><phrase role="special">()</phrase></code> | |
495 | is used to interrupt the <code><phrase role="keyword">for</phrase></code>-loop | |
496 | in <code><phrase role="identifier">f1</phrase><phrase role="special">()</phrase></code>. | |
497 | </para> | |
498 | <bridgehead renderas="sect3" id="context.ecv2.h4"> | |
499 | <phrase id="context.ecv2.stack_destruction"/><link linkend="context.ecv2.stack_destruction">Stack | |
500 | destruction</link> | |
501 | </bridgehead> | |
502 | <para> | |
503 | On construction of <emphasis>execution_context</emphasis> a stack is allocated. | |
504 | If the <emphasis>context-function</emphasis> returns the stack will be destructed. | |
505 | If the <emphasis>context-function</emphasis> has not yet returned and the destructor | |
506 | of an valid <emphasis>execution_context</emphasis> instance (e.g. <emphasis>execution_context::operator | |
507 | bool()</emphasis> returns <code><phrase role="keyword">true</phrase></code>) | |
508 | is called, the stack will be destructed too. | |
509 | </para> | |
510 | <anchor id="ecv2_prealloc"/> | |
511 | <bridgehead renderas="sect3" id="context.ecv2.h5"> | |
512 | <phrase id="context.ecv2.allocating_control_structures_on_top_of_stack"/><link | |
513 | linkend="context.ecv2.allocating_control_structures_on_top_of_stack">allocating | |
514 | control structures on top of stack</link> | |
515 | </bridgehead> | |
516 | <para> | |
517 | Allocating control structures on top of the stack requires to allocated the | |
518 | <emphasis>stack_context</emphasis> and create the control structure with placement | |
519 | new before <emphasis>execution_context</emphasis> is created. | |
520 | </para> | |
521 | <note> | |
522 | <para> | |
523 | The user is responsible for destructing the control structure at the top | |
524 | of the stack. | |
525 | </para> | |
526 | </note> | |
527 | <programlisting><phrase role="comment">// stack-allocator used for (de-)allocating stack</phrase> | |
528 | <phrase role="identifier">fixedsize_stack</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">(</phrase> <phrase role="number">4048</phrase><phrase role="special">);</phrase> | |
529 | <phrase role="comment">// allocate stack space</phrase> | |
530 | <phrase role="identifier">stack_context</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">(</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">.</phrase><phrase role="identifier">allocate</phrase><phrase role="special">()</phrase> <phrase role="special">);</phrase> | |
531 | <phrase role="comment">// reserve space for control structure on top of the stack</phrase> | |
532 | <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase> <phrase role="special">=</phrase> <phrase role="keyword">static_cast</phrase><phrase role="special"><</phrase> <phrase role="keyword">char</phrase> <phrase role="special">*</phrase> <phrase role="special">>(</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase role="identifier">sp</phrase><phrase role="special">)</phrase> <phrase role="special">-</phrase> <phrase role="keyword">sizeof</phrase><phrase role="special">(</phrase> <phrase role="identifier">my_control_structure</phrase><phrase role="special">);</phrase> | |
533 | <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> | |
534 | <phrase role="comment">// placement new creates control structure on reserved space</phrase> | |
535 | <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> | |
536 | <phrase role="special">...</phrase> | |
537 | <phrase role="comment">// destructing the control structure</phrase> | |
538 | <phrase role="identifier">cs</phrase><phrase role="special">->~</phrase><phrase role="identifier">my_control_structure</phrase><phrase role="special">();</phrase> | |
539 | <phrase role="special">...</phrase> | |
540 | <phrase role="keyword">struct</phrase> <phrase role="identifier">my_control_structure</phrase> <phrase role="special">{</phrase> | |
541 | <phrase role="comment">// captured context</phrase> | |
542 | <phrase role="identifier">execution_context</phrase> <phrase role="identifier">cctx</phrase><phrase role="special">;</phrase> | |
543 | ||
544 | <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase> <phrase role="special">></phrase> | |
545 | <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> | |
546 | <phrase role="comment">// create captured context</phrase> | |
547 | <phrase role="identifier">cctx</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> | |
548 | <phrase role="special">}</phrase> | |
549 | <phrase role="special">...</phrase> | |
550 | <phrase role="special">};</phrase> | |
551 | </programlisting> | |
552 | <bridgehead renderas="sect3" id="context.ecv2.h6"> | |
553 | <phrase id="context.ecv2.inverting_the_control_flow"/><link linkend="context.ecv2.inverting_the_control_flow">inverting | |
554 | the control flow</link> | |
555 | </bridgehead> | |
556 | <programlisting><phrase role="comment">/* | |
557 | * grammar: | |
558 | * P ---> E '\0' | |
559 | * E ---> T {('+'|'-') T} | |
560 | * T ---> S {('*'|'/') S} | |
561 | * S ---> digit | '(' E ')' | |
562 | */</phrase> | |
563 | <phrase role="keyword">class</phrase> <phrase role="identifier">Parser</phrase><phrase role="special">{</phrase> | |
564 | <phrase role="comment">// implementation omitted; see examples directory</phrase> | |
565 | <phrase role="special">};</phrase> | |
566 | ||
567 | <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> | |
568 | <phrase role="keyword">bool</phrase> <phrase role="identifier">done</phrase><phrase role="special">=</phrase><phrase role="keyword">false</phrase><phrase role="special">;</phrase> | |
569 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">exception_ptr</phrase> <phrase role="identifier">except</phrase><phrase role="special">;</phrase> | |
570 | ||
571 | <phrase role="comment">// execute parser in new execution context</phrase> | |
572 | <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase><phrase role="keyword">char</phrase><phrase role="special">></phrase> <phrase role="identifier">source</phrase><phrase role="special">(</phrase> | |
573 | <phrase role="special">[&</phrase><phrase role="identifier">is</phrase><phrase role="special">,&</phrase><phrase role="identifier">done</phrase><phrase role="special">,&</phrase><phrase role="identifier">except</phrase><phrase role="special">](</phrase><phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase><phrase role="keyword">char</phrase><phrase role="special">></phrase> <phrase role="identifier">sink</phrase><phrase role="special">,</phrase><phrase role="keyword">char</phrase><phrase role="special">){</phrase> | |
574 | <phrase role="comment">// create parser with callback function</phrase> | |
575 | <phrase role="identifier">Parser</phrase> <phrase role="identifier">p</phrase><phrase role="special">(</phrase> <phrase role="identifier">is</phrase><phrase role="special">,</phrase> | |
576 | <phrase role="special">[&</phrase><phrase role="identifier">sink</phrase><phrase role="special">](</phrase><phrase role="keyword">char</phrase> <phrase role="identifier">ch</phrase><phrase role="special">){</phrase> | |
577 | <phrase role="comment">// resume main execution context</phrase> | |
578 | <phrase role="keyword">auto</phrase> <phrase role="identifier">result</phrase> <phrase role="special">=</phrase> <phrase role="identifier">sink</phrase><phrase role="special">(</phrase><phrase role="identifier">ch</phrase><phrase role="special">);</phrase> | |
579 | <phrase role="identifier">sink</phrase> <phrase role="special">=</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special"><</phrase><phrase role="number">0</phrase><phrase role="special">>(</phrase><phrase role="identifier">result</phrase><phrase role="special">));</phrase> | |
580 | <phrase role="special">});</phrase> | |
581 | <phrase role="keyword">try</phrase> <phrase role="special">{</phrase> | |
582 | <phrase role="comment">// start recursive parsing</phrase> | |
583 | <phrase role="identifier">p</phrase><phrase role="special">.</phrase><phrase role="identifier">run</phrase><phrase role="special">();</phrase> | |
584 | <phrase role="special">}</phrase> <phrase role="keyword">catch</phrase> <phrase role="special">(...)</phrase> <phrase role="special">{</phrase> | |
585 | <phrase role="comment">// store other exceptions in exception-pointer</phrase> | |
586 | <phrase role="identifier">except</phrase> <phrase role="special">=</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">current_exception</phrase><phrase role="special">();</phrase> | |
587 | <phrase role="special">}</phrase> | |
588 | <phrase role="comment">// set termination flag</phrase> | |
589 | <phrase role="identifier">done</phrase><phrase role="special">=</phrase><phrase role="keyword">true</phrase><phrase role="special">;</phrase> | |
590 | <phrase role="comment">// resume main execution context</phrase> | |
591 | <phrase role="keyword">return</phrase> <phrase role="identifier">sink</phrase><phrase role="special">;</phrase> | |
592 | <phrase role="special">});</phrase> | |
593 | ||
594 | <phrase role="comment">// user-code pulls parsed data from parser</phrase> | |
595 | <phrase role="comment">// invert control flow</phrase> | |
596 | <phrase role="keyword">auto</phrase> <phrase role="identifier">result</phrase> <phrase role="special">=</phrase> <phrase role="identifier">source</phrase><phrase role="special">(</phrase><phrase role="char">'\0'</phrase><phrase role="special">);</phrase> | |
597 | <phrase role="identifier">source</phrase> <phrase role="special">=</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special"><</phrase><phrase role="number">0</phrase><phrase role="special">>(</phrase><phrase role="identifier">result</phrase><phrase role="special">));</phrase> | |
598 | <phrase role="keyword">char</phrase> <phrase role="identifier">c</phrase> <phrase role="special">=</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special"><</phrase><phrase role="number">1</phrase><phrase role="special">>(</phrase><phrase role="identifier">result</phrase><phrase role="special">);</phrase> | |
599 | <phrase role="keyword">if</phrase> <phrase role="special">(</phrase> <phrase role="identifier">except</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase> | |
600 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">rethrow_exception</phrase><phrase role="special">(</phrase><phrase role="identifier">except</phrase><phrase role="special">);</phrase> | |
601 | <phrase role="special">}</phrase> | |
602 | <phrase role="keyword">while</phrase><phrase role="special">(</phrase> <phrase role="special">!</phrase> <phrase role="identifier">done</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase> | |
603 | <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> | |
604 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tie</phrase><phrase role="special">(</phrase><phrase role="identifier">source</phrase><phrase role="special">,</phrase><phrase role="identifier">c</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="identifier">source</phrase><phrase role="special">(</phrase><phrase role="char">'\0'</phrase><phrase role="special">);</phrase> | |
605 | <phrase role="keyword">if</phrase> <phrase role="special">(</phrase><phrase role="identifier">except</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase> | |
606 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">rethrow_exception</phrase><phrase role="special">(</phrase><phrase role="identifier">except</phrase><phrase role="special">);</phrase> | |
607 | <phrase role="special">}</phrase> | |
608 | <phrase role="special">}</phrase> | |
609 | ||
610 | <phrase role="identifier">output</phrase><phrase role="special">:</phrase> | |
611 | <phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase> | |
612 | <phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="special">+</phrase> | |
613 | <phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase> | |
614 | </programlisting> | |
615 | <para> | |
616 | In this example a recursive descent parser uses a callback to emit a newly | |
617 | passed symbol. Using <emphasis>execution_context</emphasis> the control flow | |
618 | can be inverted, e.g. the user-code pulls parsed symbols from the parser - | |
619 | instead to get pushed from the parser (via callback). | |
620 | </para> | |
621 | <para> | |
622 | The data (character) is transferred between the two <emphasis>execution_context</emphasis>. | |
623 | </para> | |
624 | <para> | |
625 | If the code executed by <emphasis>execution_context</emphasis> emits an exception, | |
626 | the application is terminated. <emphasis>std::exception_ptr</emphasis> can | |
627 | be used to transfer exceptions between different execution contexts. | |
628 | </para> | |
629 | <para> | |
630 | Sometimes it is necessary to unwind the stack of an unfinished context to destroy | |
631 | local stack variables so they can release allocated resources (RAII pattern). | |
632 | The user is responsible for this task. | |
633 | </para> | |
634 | <bridgehead renderas="sect3" id="context.ecv2.h7"> | |
635 | <phrase id="context.ecv2.class__code__phrase_role__identifier__execution_context__phrase___code_"/><link | |
636 | linkend="context.ecv2.class__code__phrase_role__identifier__execution_context__phrase___code_">Class | |
637 | <code><phrase role="identifier">execution_context</phrase></code></link> | |
638 | </bridgehead> | |
639 | <programlisting><phrase role="keyword">struct</phrase> <phrase role="identifier">exec_ontop_arg_t</phrase> <phrase role="special">{};</phrase> | |
640 | <phrase role="keyword">const</phrase> <phrase role="identifier">exec_ontop_arg_t</phrase> <phrase role="identifier">exec_ontop_arg</phrase><phrase role="special">{};</phrase> | |
641 | ||
642 | <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></phrase> | |
643 | <phrase role="keyword">class</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="special">{</phrase> | |
644 | <phrase role="keyword">public</phrase><phrase role="special">:</phrase> | |
645 | <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Params</phrase> <phrase role="special">></phrase> | |
646 | <phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Params</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">params</phrase><phrase role="special">);</phrase> | |
647 | ||
648 | <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAlloc</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Params</phrase> <phrase role="special">></phrase> | |
649 | <phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">StackAlloc</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Params</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">params</phrase><phrase role="special">);</phrase> | |
650 | ||
651 | <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAlloc</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Params</phrase> <phrase role="special">></phrase> | |
652 | <phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">preallocated</phrase> <phrase role="identifier">palloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">StackAlloc</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Params</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">params</phrase><phrase role="special">);</phrase> | |
653 | ||
654 | <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Params</phrase> <phrase role="special">></phrase> | |
655 | <phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">segemented_stack</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Params</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">params</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase> | |
656 | ||
657 | <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Params</phrase> <phrase role="special">></phrase> | |
658 | <phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">preallocated</phrase> <phrase role="identifier">palloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">segmented</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Params</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">params</phrase><phrase role="special">)=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase> | |
659 | ||
660 | <phrase role="special">~</phrase><phrase role="identifier">execution_context</phrase><phrase role="special">();</phrase> | |
661 | ||
662 | <phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
663 | <phrase role="identifier">execution_context</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
664 | ||
665 | <phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase> | |
666 | <phrase role="identifier">execution_context</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase> | |
667 | ||
668 | <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> | |
669 | <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> | |
670 | ||
671 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tuple</phrase><phrase role="special"><</phrase> <phrase role="identifier">execution_context</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">...</phrase> <phrase role="special">></phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase> | |
672 | ||
673 | <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">></phrase> | |
674 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tuple</phrase><phrase role="special"><</phrase> <phrase role="identifier">execution_context</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">...</phrase> <phrase role="special">></phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="identifier">exec_ontop_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase> | |
675 | ||
676 | <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">==(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
677 | ||
678 | <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
679 | ||
680 | <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
681 | ||
682 | <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
683 | ||
684 | <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
685 | ||
686 | <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
687 | ||
688 | <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> | |
689 | <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> | |
690 | <phrase role="keyword">operator</phrase><phrase role="special"><<(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase> <phrase role="special">&</phrase> <phrase role="identifier">os</phrase><phrase role="special">,</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">);</phrase> | |
691 | <phrase role="special">};</phrase> | |
692 | </programlisting> | |
693 | <para> | |
694 | <bridgehead renderas="sect4" id="ecv2_constructor_bridgehead"> | |
695 | <phrase id="ecv2_constructor"/> | |
696 | <link linkend="ecv2_constructor">Constructor</link> | |
697 | </bridgehead> | |
698 | </para> | |
699 | <programlisting><phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Params</phrase> <phrase role="special">></phrase> | |
700 | <phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Params</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">params</phrase><phrase role="special">);</phrase> | |
701 | ||
702 | <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAlloc</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Params</phrase> <phrase role="special">></phrase> | |
703 | <phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">StackAlloc</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Params</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">params</phrase><phrase role="special">);</phrase> | |
704 | ||
705 | <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAlloc</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Params</phrase> <phrase role="special">></phrase> | |
706 | <phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">preallocated</phrase> <phrase role="identifier">palloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">StackAlloc</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Params</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">params</phrase><phrase role="special">);</phrase> | |
707 | </programlisting> | |
708 | <variablelist> | |
709 | <title></title> | |
710 | <varlistentry> | |
711 | <term>Effects:</term> | |
712 | <listitem> | |
713 | <para> | |
714 | Creates a new execution context and prepares the context to execute | |
715 | <code><phrase role="identifier">fn</phrase></code>. <code><phrase role="identifier">fixedsize_stack</phrase></code> | |
716 | is used as default stack allocator (stack size == fixedsize_stack::traits::default_size()). | |
717 | The constructor with argument type <code><phrase role="identifier">preallocated</phrase></code>, | |
718 | is used to create a user defined data <link linkend="ecv2_prealloc">(for | |
719 | instance additional control structures)</link> on top of the stack. | |
720 | </para> | |
721 | </listitem> | |
722 | </varlistentry> | |
723 | </variablelist> | |
724 | <para> | |
725 | <bridgehead renderas="sect4" id="ecv2_destructor destructor_bridgehead"> | |
726 | <phrase id="ecv2_destructor destructor"/> | |
727 | <link linkend="ecv2_destructor | |
728 | destructor">Destructor</link> | |
729 | </bridgehead> | |
730 | </para> | |
731 | <programlisting><phrase role="special">~</phrase><phrase role="identifier">execution_context</phrase><phrase role="special">();</phrase> | |
732 | </programlisting> | |
733 | <variablelist> | |
734 | <title></title> | |
735 | <varlistentry> | |
736 | <term>Effects:</term> | |
737 | <listitem> | |
738 | <para> | |
739 | Destructs the associated stack if <code><phrase role="special">*</phrase><phrase | |
740 | role="keyword">this</phrase></code> is a valid context, e.g. <emphasis>execution_context::operator | |
741 | bool()</emphasis> returns <code><phrase role="keyword">true</phrase></code>. | |
742 | </para> | |
743 | </listitem> | |
744 | </varlistentry> | |
745 | <varlistentry> | |
746 | <term>Throws:</term> | |
747 | <listitem> | |
748 | <para> | |
749 | Nothing. | |
750 | </para> | |
751 | </listitem> | |
752 | </varlistentry> | |
753 | </variablelist> | |
754 | <para> | |
755 | <bridgehead renderas="sect4" id="ecv2_move constructor_bridgehead"> | |
756 | <phrase id="ecv2_move constructor"/> | |
757 | <link linkend="ecv2_move constructor">Move | |
758 | constructor</link> | |
759 | </bridgehead> | |
760 | </para> | |
761 | <programlisting><phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
762 | </programlisting> | |
763 | <variablelist> | |
764 | <title></title> | |
765 | <varlistentry> | |
766 | <term>Effects:</term> | |
767 | <listitem> | |
768 | <para> | |
769 | Moves underlying capture record to <code><phrase role="special">*</phrase><phrase | |
770 | role="keyword">this</phrase></code>. | |
771 | </para> | |
772 | </listitem> | |
773 | </varlistentry> | |
774 | <varlistentry> | |
775 | <term>Throws:</term> | |
776 | <listitem> | |
777 | <para> | |
778 | Nothing. | |
779 | </para> | |
780 | </listitem> | |
781 | </varlistentry> | |
782 | </variablelist> | |
783 | <para> | |
784 | <bridgehead renderas="sect4" id="ecv2_move assignment_bridgehead"> | |
785 | <phrase id="ecv2_move assignment"/> | |
786 | <link linkend="ecv2_move assignment">Move | |
787 | assignment operator</link> | |
788 | </bridgehead> | |
789 | </para> | |
790 | <programlisting><phrase role="identifier">execution_context</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
791 | </programlisting> | |
792 | <variablelist> | |
793 | <title></title> | |
794 | <varlistentry> | |
795 | <term>Effects:</term> | |
796 | <listitem> | |
797 | <para> | |
798 | Moves the state of <code><phrase role="identifier">other</phrase></code> | |
799 | to <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code> | |
800 | using move semantics. | |
801 | </para> | |
802 | </listitem> | |
803 | </varlistentry> | |
804 | <varlistentry> | |
805 | <term>Throws:</term> | |
806 | <listitem> | |
807 | <para> | |
808 | Nothing. | |
809 | </para> | |
810 | </listitem> | |
811 | </varlistentry> | |
812 | </variablelist> | |
813 | <para> | |
814 | <bridgehead renderas="sect4" id="ecv2_operator_bool_bridgehead"> | |
815 | <phrase id="ecv2_operator_bool"/> | |
816 | <link linkend="ecv2_operator_bool">Member function | |
817 | <code>operator bool</code>()</link> | |
818 | </bridgehead> | |
819 | </para> | |
820 | <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> | |
821 | </programlisting> | |
822 | <variablelist> | |
823 | <title></title> | |
824 | <varlistentry> | |
825 | <term>Returns:</term> | |
826 | <listitem> | |
827 | <para> | |
828 | <code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase | |
829 | role="keyword">this</phrase></code> points to a capture record. | |
830 | </para> | |
831 | </listitem> | |
832 | </varlistentry> | |
833 | <varlistentry> | |
834 | <term>Throws:</term> | |
835 | <listitem> | |
836 | <para> | |
837 | Nothing. | |
838 | </para> | |
839 | </listitem> | |
840 | </varlistentry> | |
841 | </variablelist> | |
842 | <para> | |
843 | <bridgehead renderas="sect4" id="ecv2_operator_not_bridgehead"> | |
844 | <phrase id="ecv2_operator_not"/> | |
845 | <link linkend="ecv2_operator_not">Member function | |
846 | <code>operator!</code>()</link> | |
847 | </bridgehead> | |
848 | </para> | |
849 | <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> | |
850 | </programlisting> | |
851 | <variablelist> | |
852 | <title></title> | |
853 | <varlistentry> | |
854 | <term>Returns:</term> | |
855 | <listitem> | |
856 | <para> | |
857 | <code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase | |
858 | role="keyword">this</phrase></code> does not point to a capture record. | |
859 | </para> | |
860 | </listitem> | |
861 | </varlistentry> | |
862 | <varlistentry> | |
863 | <term>Throws:</term> | |
864 | <listitem> | |
865 | <para> | |
866 | Nothing. | |
867 | </para> | |
868 | </listitem> | |
869 | </varlistentry> | |
870 | </variablelist> | |
871 | <para> | |
872 | <bridgehead renderas="sect4" id="ecv2_operator_call_bridgehead"> | |
873 | <phrase id="ecv2_operator_call"/> | |
874 | <link linkend="ecv2_operator_call">Member function | |
875 | <code>operator()</code>()</link> | |
876 | </bridgehead> | |
877 | </para> | |
878 | <programlisting><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tuple</phrase><phrase role="special"><</phrase> <phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">...</phrase> <phrase role="special">>,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">...</phrase> <phrase role="special">></phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase> <phrase role="comment">// member of generic execution_context template</phrase> | |
879 | ||
880 | <phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase> <phrase role="keyword">void</phrase> <phrase role="special">></phrase> <phrase role="keyword">operator</phrase><phrase role="special">()();</phrase> <phrase role="comment">// member of execution_context< void ></phrase> | |
881 | </programlisting> | |
882 | <variablelist> | |
883 | <title></title> | |
884 | <varlistentry> | |
885 | <term>Effects:</term> | |
886 | <listitem> | |
887 | <para> | |
888 | Stores internally the current context data (stack pointer, instruction | |
889 | pointer, and CPU registers) of the current active context and restores | |
890 | the context data from <code><phrase role="special">*</phrase><phrase | |
891 | role="keyword">this</phrase></code>, which implies jumping to <code><phrase | |
892 | role="special">*</phrase><phrase role="keyword">this</phrase></code>'s | |
893 | context. The arguments, <code><phrase role="special">...</phrase> <phrase | |
894 | role="identifier">args</phrase></code>, are passed to the current context | |
895 | to be returned by the most recent call to <code><phrase role="identifier">execution_context</phrase><phrase | |
896 | role="special">::</phrase><phrase role="keyword">operator</phrase><phrase | |
897 | role="special">()</phrase></code> in the same thread. | |
898 | </para> | |
899 | </listitem> | |
900 | </varlistentry> | |
901 | <varlistentry> | |
902 | <term>Returns:</term> | |
903 | <listitem> | |
904 | <para> | |
905 | The tuple of execution_context and returned arguments passed to the most | |
906 | recent call to <code><phrase role="identifier">execution_context</phrase><phrase | |
907 | role="special">::</phrase><phrase role="keyword">operator</phrase><phrase | |
908 | role="special">()</phrase></code>, if any and a execution_context representing | |
909 | the context that has been suspended. | |
910 | </para> | |
911 | </listitem> | |
912 | </varlistentry> | |
913 | <varlistentry> | |
914 | <term>Note:</term> | |
915 | <listitem> | |
916 | <para> | |
917 | The returned execution_context indicates if the suspended context has | |
918 | terminated (return from context-function) via <code><phrase role="keyword">bool</phrase> | |
919 | <phrase role="keyword">operator</phrase><phrase role="special">()</phrase></code>. | |
920 | If the returned execution_context has terminated no data are transferred | |
921 | in the returned tuple. | |
922 | </para> | |
923 | </listitem> | |
924 | </varlistentry> | |
925 | </variablelist> | |
926 | <para> | |
927 | <bridgehead renderas="sect4" id="ecv2_operator_call_ontop_bridgehead"> | |
928 | <phrase id="ecv2_operator_call_ontop"/> | |
929 | <link linkend="ecv2_operator_call_ontop">Member | |
930 | function <code>operator()</code>()</link> | |
931 | </bridgehead> | |
932 | </para> | |
933 | <programlisting><phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">></phrase> | |
934 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">tuple</phrase><phrase role="special"><</phrase> <phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">...</phrase> <phrase role="special">>,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">...</phrase> <phrase role="special">></phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="identifier">exec_ontop_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase> <phrase role="comment">// member of generic execution_context</phrase> | |
935 | ||
936 | <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">></phrase> | |
937 | <phrase role="identifier">execution_context</phrase><phrase role="special"><</phrase> <phrase role="keyword">void</phrase> <phrase role="special">></phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="identifier">exec_ontop_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">);</phrase> <phrase role="comment">// member of execution_context< void ></phrase> | |
938 | </programlisting> | |
939 | <variablelist> | |
940 | <title></title> | |
941 | <varlistentry> | |
942 | <term>Effects:</term> | |
943 | <listitem> | |
944 | <para> | |
945 | Same as <emphasis>execution_context::operator()</emphasis>. Additionally, | |
946 | function <code><phrase role="identifier">fn</phrase></code> is executed | |
947 | in the context of <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code> | |
948 | (e.g. the stack frame of <code><phrase role="identifier">fn</phrase></code> | |
949 | is allocated on stack of <code><phrase role="special">*</phrase><phrase | |
950 | role="keyword">this</phrase></code>). | |
951 | </para> | |
952 | </listitem> | |
953 | </varlistentry> | |
954 | <varlistentry> | |
955 | <term>Returns:</term> | |
956 | <listitem> | |
957 | <para> | |
958 | The tuple of execution_context and returned arguments passed to the most | |
959 | recent call to <code><phrase role="identifier">execution_context</phrase><phrase | |
960 | role="special">::</phrase><phrase role="keyword">operator</phrase><phrase | |
961 | role="special">()</phrase></code>, if any and a execution_context representing | |
962 | the context that has been suspended . | |
963 | </para> | |
964 | </listitem> | |
965 | </varlistentry> | |
966 | <varlistentry> | |
967 | <term>Note:</term> | |
968 | <listitem> | |
969 | <para> | |
970 | The tuple of execution_context and returned arguments from <code><phrase | |
971 | role="identifier">fn</phrase></code> are passed as arguments to the context-function | |
972 | of resumed context (if the context is entered the first time) or those | |
973 | arguments are returned from <code><phrase role="identifier">execution_context</phrase><phrase | |
974 | role="special">::</phrase><phrase role="keyword">operator</phrase><phrase | |
975 | role="special">()</phrase></code> within the resumed context. | |
976 | </para> | |
977 | </listitem> | |
978 | </varlistentry> | |
979 | <varlistentry> | |
980 | <term>Note:</term> | |
981 | <listitem> | |
982 | <para> | |
983 | Function <code><phrase role="identifier">fn</phrase></code> needs to | |
984 | return a tuple of execution_context and arguments (<link linkend="ecv2_ontop">see | |
985 | description</link>). | |
986 | </para> | |
987 | </listitem> | |
988 | </varlistentry> | |
989 | <varlistentry> | |
990 | <term>Note:</term> | |
991 | <listitem> | |
992 | <para> | |
993 | The context calling this function must not be destroyed before the arguments, | |
994 | that will be returned from <code><phrase role="identifier">fn</phrase></code>, | |
995 | are preserved at least in the stack frame of the resumed context. | |
996 | </para> | |
997 | </listitem> | |
998 | </varlistentry> | |
999 | <varlistentry> | |
1000 | <term>Note:</term> | |
1001 | <listitem> | |
1002 | <para> | |
1003 | The returned execution_context indicates if the suspended context has | |
1004 | terminated (return from context-function) via <code><phrase role="keyword">bool</phrase> | |
1005 | <phrase role="keyword">operator</phrase><phrase role="special">()</phrase></code>. | |
1006 | If the returned execution_context has terminated no data are transferred | |
1007 | in the returned tuple. | |
1008 | </para> | |
1009 | </listitem> | |
1010 | </varlistentry> | |
1011 | </variablelist> | |
1012 | <para> | |
1013 | <bridgehead renderas="sect4" id="ecv2_operator_equal_bridgehead"> | |
1014 | <phrase id="ecv2_operator_equal"/> | |
1015 | <link linkend="ecv2_operator_equal">Member | |
1016 | function <code>operator==</code>()</link> | |
1017 | </bridgehead> | |
1018 | </para> | |
1019 | <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">==(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
1020 | </programlisting> | |
1021 | <variablelist> | |
1022 | <title></title> | |
1023 | <varlistentry> | |
1024 | <term>Returns:</term> | |
1025 | <listitem> | |
1026 | <para> | |
1027 | <code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase | |
1028 | role="keyword">this</phrase></code> and <code><phrase role="identifier">other</phrase></code> | |
1029 | represent the same execution context, <code><phrase role="keyword">false</phrase></code> | |
1030 | otherwise. | |
1031 | </para> | |
1032 | </listitem> | |
1033 | </varlistentry> | |
1034 | <varlistentry> | |
1035 | <term>Throws:</term> | |
1036 | <listitem> | |
1037 | <para> | |
1038 | Nothing. | |
1039 | </para> | |
1040 | </listitem> | |
1041 | </varlistentry> | |
1042 | </variablelist> | |
1043 | <para> | |
1044 | <bridgehead renderas="sect4" id="ecv2_operator_notequal_bridgehead"> | |
1045 | <phrase id="ecv2_operator_notequal"/> | |
1046 | <link linkend="ecv2_operator_notequal">Member | |
1047 | function <code>operator!=</code>()</link> | |
1048 | </bridgehead> | |
1049 | </para> | |
1050 | <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
1051 | </programlisting> | |
1052 | <variablelist> | |
1053 | <title></title> | |
1054 | <varlistentry> | |
1055 | <term>Returns:</term> | |
1056 | <listitem> | |
1057 | <para> | |
1058 | <code>! (other == * this)</code> | |
1059 | </para> | |
1060 | </listitem> | |
1061 | </varlistentry> | |
1062 | <varlistentry> | |
1063 | <term>Throws:</term> | |
1064 | <listitem> | |
1065 | <para> | |
1066 | Nothing. | |
1067 | </para> | |
1068 | </listitem> | |
1069 | </varlistentry> | |
1070 | </variablelist> | |
1071 | <para> | |
1072 | <bridgehead renderas="sect4" id="ecv2_operator_less_bridgehead"> | |
1073 | <phrase id="ecv2_operator_less"/> | |
1074 | <link linkend="ecv2_operator_less">Member function | |
1075 | <code>operator<</code>()</link> | |
1076 | </bridgehead> | |
1077 | </para> | |
1078 | <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
1079 | </programlisting> | |
1080 | <variablelist> | |
1081 | <title></title> | |
1082 | <varlistentry> | |
1083 | <term>Returns:</term> | |
1084 | <listitem> | |
1085 | <para> | |
1086 | <code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase | |
1087 | role="keyword">this</phrase> <phrase role="special">!=</phrase> <phrase | |
1088 | role="identifier">other</phrase></code> is true and the implementation-defined | |
1089 | total order of <code><phrase role="identifier">execution_context</phrase></code> | |
1090 | values places <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code> | |
1091 | before <code><phrase role="identifier">other</phrase></code>, false otherwise. | |
1092 | </para> | |
1093 | </listitem> | |
1094 | </varlistentry> | |
1095 | <varlistentry> | |
1096 | <term>Throws:</term> | |
1097 | <listitem> | |
1098 | <para> | |
1099 | Nothing. | |
1100 | </para> | |
1101 | </listitem> | |
1102 | </varlistentry> | |
1103 | </variablelist> | |
1104 | <para> | |
1105 | <bridgehead renderas="sect4" id="ecv2_operator_greater_bridgehead"> | |
1106 | <phrase id="ecv2_operator_greater"/> | |
1107 | <link linkend="ecv2_operator_greater">Member | |
1108 | function <code>operator></code>()</link> | |
1109 | </bridgehead> | |
1110 | </para> | |
1111 | <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
1112 | </programlisting> | |
1113 | <variablelist> | |
1114 | <title></title> | |
1115 | <varlistentry> | |
1116 | <term>Returns:</term> | |
1117 | <listitem> | |
1118 | <para> | |
1119 | <code><phrase role="identifier">other</phrase> <phrase role="special"><</phrase> | |
1120 | <phrase role="special">*</phrase> <phrase role="keyword">this</phrase></code> | |
1121 | </para> | |
1122 | </listitem> | |
1123 | </varlistentry> | |
1124 | <varlistentry> | |
1125 | <term>Throws:</term> | |
1126 | <listitem> | |
1127 | <para> | |
1128 | Nothing. | |
1129 | </para> | |
1130 | </listitem> | |
1131 | </varlistentry> | |
1132 | </variablelist> | |
1133 | <para> | |
1134 | <bridgehead renderas="sect4" id="ecv2_operator_lesseq_bridgehead"> | |
1135 | <phrase id="ecv2_operator_lesseq"/> | |
1136 | <link linkend="ecv2_operator_lesseq">Member | |
1137 | function <code>operator<=</code>()</link> | |
1138 | </bridgehead> | |
1139 | </para> | |
1140 | <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
1141 | </programlisting> | |
1142 | <variablelist> | |
1143 | <title></title> | |
1144 | <varlistentry> | |
1145 | <term>Returns:</term> | |
1146 | <listitem> | |
1147 | <para> | |
1148 | <code><phrase role="special">!</phrase> <phrase role="special">(</phrase><phrase | |
1149 | role="identifier">other</phrase> <phrase role="special"><</phrase> | |
1150 | <phrase role="special">*</phrase> <phrase role="keyword">this</phrase><phrase | |
1151 | role="special">)</phrase></code> | |
1152 | </para> | |
1153 | </listitem> | |
1154 | </varlistentry> | |
1155 | <varlistentry> | |
1156 | <term>Throws:</term> | |
1157 | <listitem> | |
1158 | <para> | |
1159 | Nothing. | |
1160 | </para> | |
1161 | </listitem> | |
1162 | </varlistentry> | |
1163 | </variablelist> | |
1164 | <para> | |
1165 | <bridgehead renderas="sect4" id="ecv2_operator_greatereq_bridgehead"> | |
1166 | <phrase id="ecv2_operator_greatereq"/> | |
1167 | <link linkend="ecv2_operator_greatereq">Member | |
1168 | function <code>operator>=</code>()</link> | |
1169 | </bridgehead> | |
1170 | </para> | |
1171 | <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
1172 | </programlisting> | |
1173 | <variablelist> | |
1174 | <title></title> | |
1175 | <varlistentry> | |
1176 | <term>Returns:</term> | |
1177 | <listitem> | |
1178 | <para> | |
1179 | <code><phrase role="special">!</phrase> <phrase role="special">(*</phrase> | |
1180 | <phrase role="keyword">this</phrase> <phrase role="special"><</phrase> | |
1181 | <phrase role="identifier">other</phrase><phrase role="special">)</phrase></code> | |
1182 | </para> | |
1183 | </listitem> | |
1184 | </varlistentry> | |
1185 | <varlistentry> | |
1186 | <term>Throws:</term> | |
1187 | <listitem> | |
1188 | <para> | |
1189 | Nothing. | |
1190 | </para> | |
1191 | </listitem> | |
1192 | </varlistentry> | |
1193 | </variablelist> | |
1194 | <para> | |
1195 | <bridgehead renderas="sect4" id="ecv2__bridgehead"> | |
1196 | <phrase id="ecv2_"/> | |
1197 | <link linkend="ecv2_">Non-member function <code>operator<<()</code></link> | |
1198 | </bridgehead> | |
1199 | </para> | |
1200 | <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> | |
1201 | <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> | |
1202 | <phrase role="keyword">operator</phrase><phrase role="special"><<(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase> <phrase role="special">&</phrase> <phrase role="identifier">os</phrase><phrase role="special">,</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">);</phrase> | |
1203 | </programlisting> | |
1204 | <variablelist> | |
1205 | <title></title> | |
1206 | <varlistentry> | |
1207 | <term>Efects:</term> | |
1208 | <listitem> | |
1209 | <para> | |
1210 | Writes the representation of <code><phrase role="identifier">other</phrase></code> | |
1211 | to stream <code><phrase role="identifier">os</phrase></code>. | |
1212 | </para> | |
1213 | </listitem> | |
1214 | </varlistentry> | |
1215 | <varlistentry> | |
1216 | <term>Returns:</term> | |
1217 | <listitem> | |
1218 | <para> | |
1219 | <code><phrase role="identifier">os</phrase></code> | |
1220 | </para> | |
1221 | </listitem> | |
1222 | </varlistentry> | |
1223 | </variablelist> | |
1224 | </section> | |
1225 | <section id="context.ecv1"> | |
1226 | <title><anchor id="ecv1"/><link linkend="context.ecv1">Class execution_context | |
1227 | (version 1)</link></title> | |
1228 | <note> | |
1229 | <para> | |
1230 | This class is only enabled if property <emphasis>segmented-stacks=on</emphasis> | |
1231 | (enables segmented stacks) or compiler flag <emphasis>BOOST_EXECUTION_CONTEXT=1</emphasis> | |
1232 | is specified at b2-commandline. | |
1233 | </para> | |
1234 | </note> | |
1235 | <para> | |
1236 | Class <emphasis>execution_context</emphasis> encapsulates context switching | |
1237 | and manages the associated context' stack (allocation/deallocation). | |
1238 | </para> | |
1239 | <para> | |
1240 | <emphasis>execution_context</emphasis> allocates the context stack (using its | |
1241 | <link linkend="stack"><emphasis>StackAllocator</emphasis></link> argument) | |
1242 | and creates a control structure on top of it. This structure is responsible | |
1243 | for managing context' stack. Instances of <emphasis>execution_context</emphasis>, | |
1244 | associated with a specific context, share the ownership of the control structure. | |
1245 | If the last reference goes out of scope, the control structure is destroyed | |
1246 | and the stack gets deallocated via the <emphasis>StackAllocator</emphasis>. | |
1247 | </para> | |
1248 | <para> | |
1249 | <emphasis>execution_context</emphasis> is copy-constructible, move-constructible, | |
1250 | copy-assignable and move-assignable. | |
1251 | </para> | |
1252 | <para> | |
1253 | <emphasis>execution_context</emphasis> maintains a static (thread-local) pointer, | |
1254 | accessed by <emphasis>execution_context::current()</emphasis>, pointing to | |
1255 | the active context. On each context switch the pointer is updated. The usage | |
1256 | of this global pointer makes the context switch a little bit slower (due access | |
1257 | of thread local storage) but has some advantages. It allows to access the control | |
1258 | structure of the current active context from arbitrary code paths required | |
1259 | in order to support segmented stacks, which require to call certain maintenance | |
1260 | functions (like __splitstack_getcontext() etc.) before each context switch | |
1261 | (each context switch exchanges the stack). | |
1262 | </para> | |
1263 | <para> | |
1264 | <emphasis>execution_context</emphasis> expects a function/functor with signature | |
1265 | <code><phrase role="keyword">void</phrase><phrase role="special">(</phrase><phrase | |
1266 | role="keyword">void</phrase><phrase role="special">*</phrase> <phrase role="identifier">vp</phrase><phrase | |
1267 | role="special">)</phrase></code> (<code><phrase role="identifier">vp</phrase></code> | |
1268 | is the data passed at the first invocation of <link linkend="ecv1_operator_call"> <code>ecv1::operator()()</code></link>). | |
1269 | </para> | |
1270 | <bridgehead renderas="sect3" id="context.ecv1.h0"> | |
1271 | <phrase id="context.ecv1.usage_of__emphasis_execution_context__emphasis_"/><link | |
1272 | linkend="context.ecv1.usage_of__emphasis_execution_context__emphasis_">usage | |
1273 | of <emphasis>execution_context</emphasis></link> | |
1274 | </bridgehead> | |
1275 | <programlisting><phrase role="keyword">int</phrase> <phrase role="identifier">n</phrase><phrase role="special">=</phrase><phrase role="number">35</phrase><phrase role="special">;</phrase> | |
1276 | <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase> <phrase role="identifier">sink</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special">::</phrase><phrase role="identifier">current</phrase><phrase role="special">());</phrase> | |
1277 | <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase> <phrase role="identifier">source</phrase><phrase role="special">(</phrase> | |
1278 | <phrase role="special">[</phrase><phrase role="identifier">n</phrase><phrase role="special">,&</phrase><phrase role="identifier">sink</phrase><phrase role="special">](</phrase><phrase role="keyword">void</phrase><phrase role="special">*)</phrase><phrase role="keyword">mutable</phrase><phrase role="special">{</phrase> | |
1279 | <phrase role="keyword">int</phrase> <phrase role="identifier">a</phrase><phrase role="special">=</phrase><phrase role="number">0</phrase><phrase role="special">;</phrase> | |
1280 | <phrase role="keyword">int</phrase> <phrase role="identifier">b</phrase><phrase role="special">=</phrase><phrase role="number">1</phrase><phrase role="special">;</phrase> | |
1281 | <phrase role="keyword">while</phrase><phrase role="special">(</phrase><phrase role="identifier">n</phrase><phrase role="special">--></phrase><phrase role="number">0</phrase><phrase role="special">){</phrase> | |
1282 | <phrase role="identifier">sink</phrase><phrase role="special">(&</phrase><phrase role="identifier">a</phrase><phrase role="special">);</phrase> | |
1283 | <phrase role="keyword">auto</phrase> <phrase role="identifier">next</phrase><phrase role="special">=</phrase><phrase role="identifier">a</phrase><phrase role="special">+</phrase><phrase role="identifier">b</phrase><phrase role="special">;</phrase> | |
1284 | <phrase role="identifier">a</phrase><phrase role="special">=</phrase><phrase role="identifier">b</phrase><phrase role="special">;</phrase> | |
1285 | <phrase role="identifier">b</phrase><phrase role="special">=</phrase><phrase role="identifier">next</phrase><phrase role="special">;</phrase> | |
1286 | <phrase role="special">}</phrase> | |
1287 | <phrase role="special">});</phrase> | |
1288 | <phrase role="keyword">for</phrase><phrase role="special">(</phrase><phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase><phrase role="special">=</phrase><phrase role="number">0</phrase><phrase role="special">;</phrase><phrase role="identifier">i</phrase><phrase role="special"><</phrase><phrase role="number">10</phrase><phrase role="special">;++</phrase><phrase role="identifier">i</phrase><phrase role="special">){</phrase> | |
1289 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase><phrase role="special"><<*(</phrase><phrase role="keyword">int</phrase><phrase role="special">*)</phrase><phrase role="identifier">source</phrase><phrase role="special">()<<</phrase><phrase role="string">" "</phrase><phrase role="special">;</phrase> | |
1290 | <phrase role="special">}</phrase> | |
1291 | ||
1292 | <phrase role="identifier">output</phrase><phrase role="special">:</phrase> | |
1293 | <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> | |
1294 | </programlisting> | |
1295 | <para> | |
1296 | This simple example demonstrates the basic usage of <emphasis>execution_context</emphasis>. | |
1297 | The context <code><phrase role="identifier">sink</phrase></code>, returned | |
1298 | by <emphasis>execution_context::current()</emphasis>, represents the <emphasis>main</emphasis>-context | |
1299 | (function <emphasis>main()</emphasis> running) and is one of the captured parameters | |
1300 | in the lambda expression. The lambda that calculates the Fibonacci numbers | |
1301 | is executed inside the context represented by <code><phrase role="identifier">source</phrase></code>. | |
1302 | Calculated Fibonacci numbers are transferred between the two context' via expression | |
1303 | <emphasis>sink(&a)</emphasis> (and returned by <emphasis>source()</emphasis>). | |
1304 | </para> | |
1305 | <para> | |
1306 | The locale variables <code><phrase role="identifier">a</phrase></code>, <code><phrase | |
1307 | role="identifier">b</phrase></code> and <code> <phrase role="identifier">next</phrase></code> | |
1308 | remain their values during each context switch (<emphasis>yield(a)</emphasis>). | |
1309 | This is possible because <code><phrase role="identifier">ctx</phrase></code> | |
1310 | owns a stack (exchanged by context switch). | |
1311 | </para> | |
1312 | <bridgehead renderas="sect3" id="context.ecv1.h1"> | |
1313 | <phrase id="context.ecv1.inverting_the_control_flow"/><link linkend="context.ecv1.inverting_the_control_flow">inverting | |
1314 | the control flow</link> | |
1315 | </bridgehead> | |
1316 | <programlisting><phrase role="comment">/* | |
1317 | * grammar: | |
1318 | * P ---> E '\0' | |
1319 | * E ---> T {('+'|'-') T} | |
1320 | * T ---> S {('*'|'/') S} | |
1321 | * S ---> digit | '(' E ')' | |
1322 | */</phrase> | |
1323 | <phrase role="keyword">class</phrase> <phrase role="identifier">Parser</phrase><phrase role="special">{</phrase> | |
1324 | <phrase role="comment">// implementation omitted; see examples directory</phrase> | |
1325 | <phrase role="special">};</phrase> | |
1326 | ||
1327 | <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> | |
1328 | <phrase role="keyword">bool</phrase> <phrase role="identifier">done</phrase><phrase role="special">=</phrase><phrase role="keyword">false</phrase><phrase role="special">;</phrase> | |
1329 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">exception_ptr</phrase> <phrase role="identifier">except</phrase><phrase role="special">;</phrase> | |
1330 | ||
1331 | <phrase role="comment">// create handle to main execution context</phrase> | |
1332 | <phrase role="keyword">auto</phrase> <phrase role="identifier">main_ctx</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special">::</phrase><phrase role="identifier">current</phrase><phrase role="special">());</phrase> | |
1333 | <phrase role="comment">// execute parser in new execution context</phrase> | |
1334 | <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase> <phrase role="identifier">source</phrase><phrase role="special">(</phrase> | |
1335 | <phrase role="special">[&</phrase><phrase role="identifier">sink</phrase><phrase role="special">,&</phrase><phrase role="identifier">is</phrase><phrase role="special">,&</phrase><phrase role="identifier">done</phrase><phrase role="special">,&</phrase><phrase role="identifier">except</phrase><phrase role="special">](</phrase><phrase role="keyword">void</phrase><phrase role="special">*){</phrase> | |
1336 | <phrase role="comment">// create parser with callback function</phrase> | |
1337 | <phrase role="identifier">Parser</phrase> <phrase role="identifier">p</phrase><phrase role="special">(</phrase><phrase role="identifier">is</phrase><phrase role="special">,</phrase> | |
1338 | <phrase role="special">[&</phrase><phrase role="identifier">sink</phrase><phrase role="special">](</phrase><phrase role="keyword">char</phrase> <phrase role="identifier">ch</phrase><phrase role="special">){</phrase> | |
1339 | <phrase role="comment">// resume main execution context</phrase> | |
1340 | <phrase role="identifier">sink</phrase><phrase role="special">(&</phrase><phrase role="identifier">ch</phrase><phrase role="special">);</phrase> | |
1341 | <phrase role="special">});</phrase> | |
1342 | <phrase role="keyword">try</phrase> <phrase role="special">{</phrase> | |
1343 | <phrase role="comment">// start recursive parsing</phrase> | |
1344 | <phrase role="identifier">p</phrase><phrase role="special">.</phrase><phrase role="identifier">run</phrase><phrase role="special">();</phrase> | |
1345 | <phrase role="special">}</phrase> <phrase role="keyword">catch</phrase> <phrase role="special">(...)</phrase> <phrase role="special">{</phrase> | |
1346 | <phrase role="comment">// store other exceptions in exception-pointer</phrase> | |
1347 | <phrase role="identifier">except</phrase> <phrase role="special">=</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">current_exception</phrase><phrase role="special">();</phrase> | |
1348 | <phrase role="special">}</phrase> | |
1349 | <phrase role="comment">// set termination flag</phrase> | |
1350 | <phrase role="identifier">done</phrase><phrase role="special">=</phrase><phrase role="keyword">true</phrase><phrase role="special">;</phrase> | |
1351 | <phrase role="comment">// resume main execution context</phrase> | |
1352 | <phrase role="identifier">sink</phrase><phrase role="special">();</phrase> | |
1353 | <phrase role="special">});</phrase> | |
1354 | ||
1355 | <phrase role="comment">// user-code pulls parsed data from parser</phrase> | |
1356 | <phrase role="comment">// invert control flow</phrase> | |
1357 | <phrase role="keyword">void</phrase><phrase role="special">*</phrase> <phrase role="identifier">vp</phrase> <phrase role="special">=</phrase> <phrase role="identifier">source</phrase><phrase role="special">();</phrase> | |
1358 | <phrase role="keyword">if</phrase> <phrase role="special">(</phrase><phrase role="identifier">except</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase> | |
1359 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">rethrow_exception</phrase><phrase role="special">(</phrase><phrase role="identifier">except</phrase><phrase role="special">);</phrase> | |
1360 | <phrase role="special">}</phrase> | |
1361 | <phrase role="keyword">while</phrase><phrase role="special">(</phrase> <phrase role="special">!</phrase> <phrase role="identifier">done</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase> | |
1362 | <phrase role="identifier">printf</phrase><phrase role="special">(</phrase><phrase role="string">"Parsed: %c\n"</phrase><phrase role="special">,*</phrase> <phrase role="keyword">static_cast</phrase><phrase role="special"><</phrase><phrase role="keyword">char</phrase><phrase role="special">*>(</phrase><phrase role="identifier">vp</phrase><phrase role="special">));</phrase> | |
1363 | <phrase role="identifier">vp</phrase> <phrase role="special">=</phrase> <phrase role="identifier">source</phrase><phrase role="special">();</phrase> | |
1364 | <phrase role="keyword">if</phrase> <phrase role="special">(</phrase><phrase role="identifier">except</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase> | |
1365 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">rethrow_exception</phrase><phrase role="special">(</phrase><phrase role="identifier">except</phrase><phrase role="special">);</phrase> | |
1366 | <phrase role="special">}</phrase> | |
1367 | <phrase role="special">}</phrase> | |
1368 | ||
1369 | <phrase role="identifier">output</phrase><phrase role="special">:</phrase> | |
1370 | <phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase> | |
1371 | <phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="special">+</phrase> | |
1372 | <phrase role="identifier">Parsed</phrase><phrase role="special">:</phrase> <phrase role="number">1</phrase> | |
1373 | </programlisting> | |
1374 | <para> | |
1375 | In this example a recursive descent parser uses a callback to emit a newly | |
1376 | passed symbol. Using <emphasis>execution_context</emphasis> the control flow | |
1377 | can be inverted, e.g. the user-code pulls parsed symbols from the parser - | |
1378 | instead to get pushed from the parser (via callback). | |
1379 | </para> | |
1380 | <para> | |
1381 | The data (character) is transferred between the two <emphasis>execution_context</emphasis>. | |
1382 | </para> | |
1383 | <para> | |
1384 | If the code executed by <emphasis>execution_context</emphasis> emits an exception, | |
1385 | the application is terminated. <emphasis>std::exception_ptr</emphasis> can | |
1386 | be used to transfer exceptions between different execution contexts. | |
1387 | </para> | |
1388 | <para> | |
1389 | Sometimes it is necessary to unwind the stack of an unfinished context to destroy | |
1390 | local stack variables so they can release allocated resources (RAII pattern). | |
1391 | The user is responsible for this task. | |
1392 | </para> | |
1393 | <anchor id="ecv1_prealloc"/> | |
1394 | <bridgehead renderas="sect3" id="context.ecv1.h2"> | |
1395 | <phrase id="context.ecv1.allocating_control_structures_on_top_of_stack"/><link | |
1396 | linkend="context.ecv1.allocating_control_structures_on_top_of_stack">allocating | |
1397 | control structures on top of stack</link> | |
1398 | </bridgehead> | |
1399 | <para> | |
1400 | Allocating control structures on top of the stack requires to allocated the | |
1401 | <emphasis>stack_context</emphasis> and create the control structure with placement | |
1402 | new before <emphasis>execution_context</emphasis> is created. | |
1403 | </para> | |
1404 | <note> | |
1405 | <para> | |
1406 | The user is responsible for destructing the control structure at the top | |
1407 | of the stack. | |
1408 | </para> | |
1409 | </note> | |
1410 | <programlisting><phrase role="comment">// stack-allocator used for (de-)allocating stack</phrase> | |
1411 | <phrase role="identifier">fixedsize_stack</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">(</phrase> <phrase role="number">4048</phrase><phrase role="special">);</phrase> | |
1412 | <phrase role="comment">// allocate stack space</phrase> | |
1413 | <phrase role="identifier">stack_context</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">(</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">.</phrase><phrase role="identifier">allocate</phrase><phrase role="special">()</phrase> <phrase role="special">);</phrase> | |
1414 | <phrase role="comment">// reserve space for control structure on top of the stack</phrase> | |
1415 | <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase> <phrase role="special">=</phrase> <phrase role="keyword">static_cast</phrase><phrase role="special"><</phrase> <phrase role="keyword">char</phrase> <phrase role="special">*</phrase> <phrase role="special">>(</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase role="identifier">sp</phrase><phrase role="special">)</phrase> <phrase role="special">-</phrase> <phrase role="keyword">sizeof</phrase><phrase role="special">(</phrase> <phrase role="identifier">my_control_structure</phrase><phrase role="special">);</phrase> | |
1416 | <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> | |
1417 | <phrase role="comment">// placement new creates control structure on reserved space</phrase> | |
1418 | <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> | |
1419 | <phrase role="special">...</phrase> | |
1420 | <phrase role="comment">// destructing the control structure</phrase> | |
1421 | <phrase role="identifier">cs</phrase><phrase role="special">->~</phrase><phrase role="identifier">my_control_structure</phrase><phrase role="special">();</phrase> | |
1422 | <phrase role="special">...</phrase> | |
1423 | <phrase role="keyword">struct</phrase> <phrase role="identifier">my_control_structure</phrase> <phrase role="special">{</phrase> | |
1424 | <phrase role="comment">// execution context</phrase> | |
1425 | <phrase role="identifier">execution_context</phrase> <phrase role="identifier">ectx</phrase><phrase role="special">;</phrase> | |
1426 | ||
1427 | <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase> <phrase role="special">></phrase> | |
1428 | <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> | |
1429 | <phrase role="comment">// create execution context</phrase> | |
1430 | <phrase role="identifier">ectx</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg</phrase><phrase role="special">,</phrase> <phrase role="identifier">preallocated</phrase><phrase role="special">(</phrase> <phrase role="identifier">sp</phrase><phrase role="special">,</phrase> <phrase role="identifier">size</phrase><phrase role="special">,</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">),</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">entry_func</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase> | |
1431 | <phrase role="special">}</phrase> | |
1432 | <phrase role="special">...</phrase> | |
1433 | <phrase role="special">};</phrase> | |
1434 | </programlisting> | |
1435 | <bridgehead renderas="sect3" id="context.ecv1.h3"> | |
1436 | <phrase id="context.ecv1.exception_handling"/><link linkend="context.ecv1.exception_handling">exception | |
1437 | handling</link> | |
1438 | </bridgehead> | |
1439 | <para> | |
1440 | If the function executed inside a <emphasis>execution_context</emphasis> emits | |
1441 | ans exception, the application is terminated by calling <emphasis>std::terminate()</emphasis>. | |
1442 | <emphasis>std::exception_ptr</emphasis> can be used to transfer exceptions | |
1443 | between different execution contexts. | |
1444 | </para> | |
1445 | <important> | |
1446 | <para> | |
1447 | Do not jump from inside a catch block and then re-throw the exception in | |
1448 | another execution context. | |
1449 | </para> | |
1450 | </important> | |
1451 | <bridgehead renderas="sect3" id="context.ecv1.h4"> | |
1452 | <phrase id="context.ecv1.parameter_passing"/><link linkend="context.ecv1.parameter_passing">parameter | |
1453 | passing</link> | |
1454 | </bridgehead> | |
1455 | <para> | |
1456 | The void pointer argument passed to <emphasis>execution_context::operator()</emphasis>, | |
1457 | in one context, is passed as the last argument of the <emphasis>context-function</emphasis> | |
1458 | if the context is started for the first time. In all following invocations | |
1459 | of <emphasis>execution_context::operator()</emphasis> the void pointer passed | |
1460 | to <emphasis>execution_context::operator()</emphasis>, in one context, is returned | |
1461 | by <emphasis>execution_context::operator()</emphasis> in the other context. | |
1462 | </para> | |
1463 | <programlisting><phrase role="keyword">class</phrase> <phrase role="identifier">X</phrase> <phrase role="special">{</phrase> | |
1464 | <phrase role="keyword">private</phrase><phrase role="special">:</phrase> | |
1465 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">exception_ptr</phrase> <phrase role="identifier">excptr_</phrase><phrase role="special">;</phrase> | |
1466 | <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase> <phrase role="identifier">caller_</phrase><phrase role="special">;</phrase> | |
1467 | <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase> <phrase role="identifier">callee_</phrase><phrase role="special">;</phrase> | |
1468 | ||
1469 | <phrase role="keyword">public</phrase><phrase role="special">:</phrase> | |
1470 | <phrase role="identifier">X</phrase><phrase role="special">()</phrase> <phrase role="special">:</phrase> | |
1471 | <phrase role="identifier">excptr_</phrase><phrase role="special">(),</phrase> | |
1472 | <phrase role="identifier">caller_</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">context</phrase><phrase role="special">::</phrase><phrase role="identifier">execution_context</phrase><phrase role="special">::</phrase><phrase role="identifier">current</phrase><phrase role="special">()</phrase> <phrase role="special">),</phrase> | |
1473 | <phrase role="identifier">callee_</phrase><phrase role="special">(</phrase> <phrase role="special">[=]</phrase> <phrase role="special">(</phrase><phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">vp</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase> | |
1474 | <phrase role="keyword">try</phrase> <phrase role="special">{</phrase> | |
1475 | <phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase> <phrase role="special">=</phrase> <phrase role="special">*</phrase> <phrase role="keyword">static_cast</phrase><phrase role="special"><</phrase> <phrase role="keyword">int</phrase> <phrase role="special">*</phrase> <phrase role="special">>(</phrase> <phrase role="identifier">vp</phrase><phrase role="special">);</phrase> | |
1476 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="identifier">str</phrase> <phrase role="special">=</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">lexical_cast</phrase><phrase role="special"><</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">>(</phrase><phrase role="identifier">i</phrase><phrase role="special">);</phrase> | |
1477 | <phrase role="identifier">caller_</phrase><phrase role="special">(</phrase> <phrase role="special">&</phrase> <phrase role="identifier">str</phrase><phrase role="special">);</phrase> | |
1478 | <phrase role="special">}</phrase> <phrase role="keyword">catch</phrase> <phrase role="special">(</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">bad_cast</phrase> <phrase role="keyword">const</phrase><phrase role="special">&)</phrase> <phrase role="special">{</phrase> | |
1479 | <phrase role="identifier">excptr_</phrase><phrase role="special">=</phrase><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">current_exception</phrase><phrase role="special">();</phrase> | |
1480 | <phrase role="special">}</phrase> | |
1481 | <phrase role="special">})</phrase> | |
1482 | <phrase role="special">{}</phrase> | |
1483 | ||
1484 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase><phrase role="special">)</phrase> <phrase role="special">{</phrase> | |
1485 | <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">ret</phrase> <phrase role="special">=</phrase> <phrase role="identifier">callee_</phrase><phrase role="special">(</phrase> <phrase role="special">&</phrase> <phrase role="identifier">i</phrase><phrase role="special">);</phrase> | |
1486 | <phrase role="keyword">if</phrase><phrase role="special">(</phrase><phrase role="identifier">excptr_</phrase><phrase role="special">){</phrase> | |
1487 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">rethrow_exception</phrase><phrase role="special">(</phrase><phrase role="identifier">excptr_</phrase><phrase role="special">);</phrase> | |
1488 | <phrase role="special">}</phrase> | |
1489 | <phrase role="keyword">return</phrase> <phrase role="special">*</phrase> <phrase role="keyword">static_cast</phrase><phrase role="special"><</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="special">*</phrase> <phrase role="special">>(</phrase> <phrase role="identifier">ret</phrase><phrase role="special">);</phrase> | |
1490 | <phrase role="special">}</phrase> | |
1491 | <phrase role="special">};</phrase> | |
1492 | ||
1493 | <phrase role="identifier">X</phrase> <phrase role="identifier">x</phrase><phrase role="special">;</phrase> | |
1494 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">x</phrase><phrase role="special">(</phrase> <phrase role="number">7</phrase><phrase role="special">)</phrase> <phrase role="special"><<</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase> | |
1495 | ||
1496 | <phrase role="identifier">output</phrase><phrase role="special">:</phrase> | |
1497 | <phrase role="number">7</phrase> | |
1498 | </programlisting> | |
1499 | <bridgehead renderas="sect3" id="context.ecv1.h5"> | |
1500 | <phrase id="context.ecv1.class__code__phrase_role__identifier__execution_context__phrase___code_"/><link | |
1501 | linkend="context.ecv1.class__code__phrase_role__identifier__execution_context__phrase___code_">Class | |
1502 | <code><phrase role="identifier">execution_context</phrase></code></link> | |
1503 | </bridgehead> | |
1504 | <programlisting><phrase role="keyword">class</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="special">{</phrase> | |
1505 | <phrase role="keyword">public</phrase><phrase role="special">:</phrase> | |
1506 | <phrase role="keyword">static</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="identifier">current</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
1507 | ||
1508 | <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></phrase> | |
1509 | <phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase> | |
1510 | ||
1511 | <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAlloc</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></phrase> | |
1512 | <phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">StackAlloc</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase> | |
1513 | ||
1514 | <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAlloc</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></phrase> | |
1515 | <phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">preallocated</phrase> <phrase role="identifier">palloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">StackAlloc</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase> | |
1516 | ||
1517 | <phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
1518 | <phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
1519 | ||
1520 | <phrase role="identifier">execution_context</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
1521 | <phrase role="identifier">execution_context</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
1522 | ||
1523 | <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> | |
1524 | <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> | |
1525 | ||
1526 | <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">vp</phrase> <phrase role="special">=</phrase> <phrase role="keyword">nullptr</phrase><phrase role="special">);</phrase> | |
1527 | ||
1528 | <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">></phrase> | |
1529 | <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="identifier">exec_ontop_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">vp</phrase> <phrase role="special">=</phrase> <phrase role="keyword">nullptr</phrase><phrase role="special">);</phrase> | |
1530 | ||
1531 | <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">==(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
1532 | ||
1533 | <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
1534 | ||
1535 | <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
1536 | ||
1537 | <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
1538 | ||
1539 | <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
1540 | ||
1541 | <phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
1542 | ||
1543 | <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> | |
1544 | <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> | |
1545 | <phrase role="keyword">operator</phrase><phrase role="special"><<(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase> <phrase role="special">&</phrase> <phrase role="identifier">os</phrase><phrase role="special">,</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">);</phrase> | |
1546 | <phrase role="special">};</phrase> | |
1547 | </programlisting> | |
1548 | <para> | |
1549 | <bridgehead renderas="sect4" id="ecv1_current_bridgehead"> | |
1550 | <phrase id="ecv1_current"/> | |
1551 | <link linkend="ecv1_current">Static member function <code>current</code>()</link> | |
1552 | </bridgehead> | |
1553 | </para> | |
1554 | <programlisting><phrase role="keyword">static</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="identifier">current</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
1555 | </programlisting> | |
1556 | <variablelist> | |
1557 | <title></title> | |
1558 | <varlistentry> | |
1559 | <term>Returns:</term> | |
1560 | <listitem> | |
1561 | <para> | |
1562 | Returns an instance of excution_context pointing to the active execution | |
1563 | context. | |
1564 | </para> | |
1565 | </listitem> | |
1566 | </varlistentry> | |
1567 | <varlistentry> | |
1568 | <term>Throws:</term> | |
1569 | <listitem> | |
1570 | <para> | |
1571 | Nothing. | |
1572 | </para> | |
1573 | </listitem> | |
1574 | </varlistentry> | |
1575 | </variablelist> | |
1576 | <para> | |
1577 | <bridgehead renderas="sect4" id="ecv1_constructor_bridgehead"> | |
1578 | <phrase id="ecv1_constructor"/> | |
1579 | <link linkend="ecv1_constructor">Constructor</link> | |
1580 | </bridgehead> | |
1581 | </para> | |
1582 | <programlisting><phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></phrase> | |
1583 | <phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase> | |
1584 | ||
1585 | <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAlloc</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></phrase> | |
1586 | <phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">StackAlloc</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase> | |
1587 | ||
1588 | <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAlloc</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">></phrase> | |
1589 | <phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">preallocated</phrase> <phrase role="identifier">palloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">StackAlloc</phrase> <phrase role="identifier">salloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&&</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase> | |
1590 | </programlisting> | |
1591 | <variablelist> | |
1592 | <title></title> | |
1593 | <varlistentry> | |
1594 | <term>Effects:</term> | |
1595 | <listitem> | |
1596 | <para> | |
1597 | Creates a new execution context and prepares the context to execute | |
1598 | <code><phrase role="identifier">fn</phrase></code>. <code><phrase role="identifier">fixedsize_stack</phrase></code> | |
1599 | is used as default stack allocator (stack size == fixedsize_stack::traits::default_size()). | |
1600 | The constructor with argument type <code><phrase role="identifier">preallocated</phrase></code>, | |
1601 | is used to create a user defined data <link linkend="ecv1_prealloc">(for | |
1602 | instance additional control structures)</link> on top of the stack. | |
1603 | </para> | |
1604 | </listitem> | |
1605 | </varlistentry> | |
1606 | </variablelist> | |
1607 | <para> | |
1608 | <bridgehead renderas="sect4" id="ecv1_copy constructor_bridgehead"> | |
1609 | <phrase id="ecv1_copy constructor"/> | |
1610 | <link linkend="ecv1_copy constructor">Copy | |
1611 | constructor</link> | |
1612 | </bridgehead> | |
1613 | </para> | |
1614 | <programlisting><phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
1615 | </programlisting> | |
1616 | <variablelist> | |
1617 | <title></title> | |
1618 | <varlistentry> | |
1619 | <term>Effects:</term> | |
1620 | <listitem> | |
1621 | <para> | |
1622 | Copies <code><phrase role="identifier">other</phrase></code>, e.g. underlying | |
1623 | control structure is shared with <code><phrase role="special">*</phrase><phrase | |
1624 | role="keyword">this</phrase></code>. | |
1625 | </para> | |
1626 | </listitem> | |
1627 | </varlistentry> | |
1628 | <varlistentry> | |
1629 | <term>Throws:</term> | |
1630 | <listitem> | |
1631 | <para> | |
1632 | Nothing. | |
1633 | </para> | |
1634 | </listitem> | |
1635 | </varlistentry> | |
1636 | </variablelist> | |
1637 | <para> | |
1638 | <bridgehead renderas="sect4" id="ecv1_move constructor_bridgehead"> | |
1639 | <phrase id="ecv1_move constructor"/> | |
1640 | <link linkend="ecv1_move constructor">Move | |
1641 | constructor</link> | |
1642 | </bridgehead> | |
1643 | </para> | |
1644 | <programlisting><phrase role="identifier">execution_context</phrase><phrase role="special">(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
1645 | </programlisting> | |
1646 | <variablelist> | |
1647 | <title></title> | |
1648 | <varlistentry> | |
1649 | <term>Effects:</term> | |
1650 | <listitem> | |
1651 | <para> | |
1652 | Moves underlying control structure to <code><phrase role="special">*</phrase><phrase | |
1653 | role="keyword">this</phrase></code>. | |
1654 | </para> | |
1655 | </listitem> | |
1656 | </varlistentry> | |
1657 | <varlistentry> | |
1658 | <term>Throws:</term> | |
1659 | <listitem> | |
1660 | <para> | |
1661 | Nothing. | |
1662 | </para> | |
1663 | </listitem> | |
1664 | </varlistentry> | |
1665 | </variablelist> | |
1666 | <para> | |
1667 | <bridgehead renderas="sect4" id="ecv1_copy assignment_bridgehead"> | |
1668 | <phrase id="ecv1_copy assignment"/> | |
1669 | <link linkend="ecv1_copy assignment">Copy | |
1670 | assignment operator</link> | |
1671 | </bridgehead> | |
1672 | </para> | |
1673 | <programlisting><phrase role="identifier">execution_context</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
1674 | </programlisting> | |
1675 | <variablelist> | |
1676 | <title></title> | |
1677 | <varlistentry> | |
1678 | <term>Effects:</term> | |
1679 | <listitem> | |
1680 | <para> | |
1681 | Copies the state of <code><phrase role="identifier">other</phrase></code> | |
1682 | to <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>, | |
1683 | control structure is shared. | |
1684 | </para> | |
1685 | </listitem> | |
1686 | </varlistentry> | |
1687 | <varlistentry> | |
1688 | <term>Throws:</term> | |
1689 | <listitem> | |
1690 | <para> | |
1691 | Nothing. | |
1692 | </para> | |
1693 | </listitem> | |
1694 | </varlistentry> | |
1695 | </variablelist> | |
1696 | <para> | |
1697 | <bridgehead renderas="sect4" id="ecv1_move assignment_bridgehead"> | |
1698 | <phrase id="ecv1_move assignment"/> | |
1699 | <link linkend="ecv1_move assignment">Move | |
1700 | assignment operator</link> | |
1701 | </bridgehead> | |
1702 | </para> | |
1703 | <programlisting><phrase role="identifier">execution_context</phrase> <phrase role="special">&</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
1704 | </programlisting> | |
1705 | <variablelist> | |
1706 | <title></title> | |
1707 | <varlistentry> | |
1708 | <term>Effects:</term> | |
1709 | <listitem> | |
1710 | <para> | |
1711 | Moves the control structure of <code><phrase role="identifier">other</phrase></code> | |
1712 | to <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code> | |
1713 | using move semantics. | |
1714 | </para> | |
1715 | </listitem> | |
1716 | </varlistentry> | |
1717 | <varlistentry> | |
1718 | <term>Throws:</term> | |
1719 | <listitem> | |
1720 | <para> | |
1721 | Nothing. | |
1722 | </para> | |
1723 | </listitem> | |
1724 | </varlistentry> | |
1725 | </variablelist> | |
1726 | <para> | |
1727 | <bridgehead renderas="sect4" id="ecv1_operator_bool_bridgehead"> | |
1728 | <phrase id="ecv1_operator_bool"/> | |
1729 | <link linkend="ecv1_operator_bool">Member function | |
1730 | <code>operator bool</code>()</link> | |
1731 | </bridgehead> | |
1732 | </para> | |
1733 | <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> | |
1734 | </programlisting> | |
1735 | <variablelist> | |
1736 | <title></title> | |
1737 | <varlistentry> | |
1738 | <term>Returns:</term> | |
1739 | <listitem> | |
1740 | <para> | |
1741 | <code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase | |
1742 | role="keyword">this</phrase></code> points to a control structure. | |
1743 | </para> | |
1744 | </listitem> | |
1745 | </varlistentry> | |
1746 | <varlistentry> | |
1747 | <term>Throws:</term> | |
1748 | <listitem> | |
1749 | <para> | |
1750 | Nothing. | |
1751 | </para> | |
1752 | </listitem> | |
1753 | </varlistentry> | |
1754 | </variablelist> | |
1755 | <para> | |
1756 | <bridgehead renderas="sect4" id="ecv1_operator_not_bridgehead"> | |
1757 | <phrase id="ecv1_operator_not"/> | |
1758 | <link linkend="ecv1_operator_not">Member function | |
1759 | <code>operator!</code>()</link> | |
1760 | </bridgehead> | |
1761 | </para> | |
1762 | <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> | |
1763 | </programlisting> | |
1764 | <variablelist> | |
1765 | <title></title> | |
1766 | <varlistentry> | |
1767 | <term>Returns:</term> | |
1768 | <listitem> | |
1769 | <para> | |
1770 | <code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase | |
1771 | role="keyword">this</phrase></code> does not point to a control structure. | |
1772 | </para> | |
1773 | </listitem> | |
1774 | </varlistentry> | |
1775 | <varlistentry> | |
1776 | <term>Throws:</term> | |
1777 | <listitem> | |
1778 | <para> | |
1779 | Nothing. | |
1780 | </para> | |
1781 | </listitem> | |
1782 | </varlistentry> | |
1783 | </variablelist> | |
1784 | <para> | |
1785 | <bridgehead renderas="sect4" id="ecv1_operator_call_bridgehead"> | |
1786 | <phrase id="ecv1_operator_call"/> | |
1787 | <link linkend="ecv1_operator_call">Member function | |
1788 | <code>operator()</code>()</link> | |
1789 | </bridgehead> | |
1790 | </para> | |
1791 | <programlisting><phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">vp</phrase> <phrase role="special">=</phrase> <phrase role="keyword">nullptr</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
1792 | </programlisting> | |
1793 | <variablelist> | |
1794 | <title></title> | |
1795 | <varlistentry> | |
1796 | <term>Effects:</term> | |
1797 | <listitem> | |
1798 | <para> | |
1799 | Stores internally the current context data (stack pointer, instruction | |
1800 | pointer, and CPU registers) of the current active context and restores | |
1801 | the context data from <code><phrase role="special">*</phrase><phrase | |
1802 | role="keyword">this</phrase></code>, which implies jumping to <code><phrase | |
1803 | role="special">*</phrase><phrase role="keyword">this</phrase></code>'s | |
1804 | context. The void pointer argument, <code><phrase role="identifier">vp</phrase></code>, | |
1805 | is passed to the current context to be returned by the most recent call | |
1806 | to <code><phrase role="identifier">execution_context</phrase><phrase | |
1807 | role="special">::</phrase><phrase role="keyword">operator</phrase><phrase | |
1808 | role="special">()</phrase></code> in the same thread. <code><phrase role="identifier">fn</phrase></code> | |
1809 | is executed with arguments <code><phrase role="identifier">args</phrase></code> | |
1810 | on top of the stack of <code><phrase role="keyword">this</phrase></code>. | |
1811 | </para> | |
1812 | </listitem> | |
1813 | </varlistentry> | |
1814 | <varlistentry> | |
1815 | <term>Note:</term> | |
1816 | <listitem> | |
1817 | <para> | |
1818 | The behaviour is undefined if <code><phrase role="keyword">operator</phrase><phrase | |
1819 | role="special">()()</phrase></code> is called while <emphasis>execution_context::current()</emphasis> | |
1820 | returns <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code> | |
1821 | (e.g. resuming an already running context). If the top-level context | |
1822 | function returns, <code><phrase role="identifier">std</phrase><phrase | |
1823 | role="special">::</phrase><phrase role="identifier">exit</phrase><phrase | |
1824 | role="special">()</phrase></code> is called. | |
1825 | </para> | |
1826 | </listitem> | |
1827 | </varlistentry> | |
1828 | <varlistentry> | |
1829 | <term>Returns:</term> | |
1830 | <listitem> | |
1831 | <para> | |
1832 | The void pointer argument passed to the most recent call to <emphasis>execution_context::operator()</emphasis>, | |
1833 | if any. | |
1834 | </para> | |
1835 | </listitem> | |
1836 | </varlistentry> | |
1837 | </variablelist> | |
1838 | <para> | |
1839 | <bridgehead renderas="sect4" id="ecv1_operator_call_ontop_bridgehead"> | |
1840 | <phrase id="ecv1_operator_call_ontop"/> | |
1841 | <link linkend="ecv1_operator_call_ontop">Member | |
1842 | function <code>operator(exec_ontop_arg_t)</code>()</link> | |
1843 | </bridgehead> | |
1844 | </para> | |
1845 | <programlisting><phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">></phrase> | |
1846 | <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()(</phrase> <phrase role="identifier">exec_ontop_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&&</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">vp</phrase> <phrase role="special">=</phrase> <phrase role="keyword">nullptr</phrase><phrase role="special">);</phrase> | |
1847 | </programlisting> | |
1848 | <variablelist> | |
1849 | <title></title> | |
1850 | <varlistentry> | |
1851 | <term>Effects:</term> | |
1852 | <listitem> | |
1853 | <para> | |
1854 | Same as <emphasis>execution_context::operator()</emphasis>. Additionally, | |
1855 | function <code><phrase role="identifier">fn</phrase></code> is executed | |
1856 | with arguments <code><phrase role="identifier">vp</phrase></code> in | |
1857 | the context of <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code> | |
1858 | (e.g. the stack frame of <code><phrase role="identifier">fn</phrase></code> | |
1859 | is allocated on stack of <code><phrase role="special">*</phrase><phrase | |
1860 | role="keyword">this</phrase></code>). | |
1861 | </para> | |
1862 | </listitem> | |
1863 | </varlistentry> | |
1864 | <varlistentry> | |
1865 | <term>Returns:</term> | |
1866 | <listitem> | |
1867 | <para> | |
1868 | The void pointer argument passed to the most recent call to <emphasis>execution_context::operator()</emphasis>, | |
1869 | if any. | |
1870 | </para> | |
1871 | </listitem> | |
1872 | </varlistentry> | |
1873 | </variablelist> | |
1874 | <para> | |
1875 | <bridgehead renderas="sect4" id="ecv1_operator_equal_bridgehead"> | |
1876 | <phrase id="ecv1_operator_equal"/> | |
1877 | <link linkend="ecv1_operator_equal">Member | |
1878 | function <code>operator==</code>()</link> | |
1879 | </bridgehead> | |
1880 | </para> | |
1881 | <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">==(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
1882 | </programlisting> | |
1883 | <variablelist> | |
1884 | <title></title> | |
1885 | <varlistentry> | |
1886 | <term>Returns:</term> | |
1887 | <listitem> | |
1888 | <para> | |
1889 | <code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase | |
1890 | role="keyword">this</phrase></code> and <code><phrase role="identifier">other</phrase></code> | |
1891 | represent the same execution context, <code><phrase role="keyword">false</phrase></code> | |
1892 | otherwise. | |
1893 | </para> | |
1894 | </listitem> | |
1895 | </varlistentry> | |
1896 | <varlistentry> | |
1897 | <term>Throws:</term> | |
1898 | <listitem> | |
1899 | <para> | |
1900 | Nothing. | |
1901 | </para> | |
1902 | </listitem> | |
1903 | </varlistentry> | |
1904 | </variablelist> | |
1905 | <para> | |
1906 | <bridgehead renderas="sect4" id="ecv1_operator_notequal_bridgehead"> | |
1907 | <phrase id="ecv1_operator_notequal"/> | |
1908 | <link linkend="ecv1_operator_notequal">Member | |
1909 | function <code>operator!=</code>()</link> | |
1910 | </bridgehead> | |
1911 | </para> | |
1912 | <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
1913 | </programlisting> | |
1914 | <variablelist> | |
1915 | <title></title> | |
1916 | <varlistentry> | |
1917 | <term>Returns:</term> | |
1918 | <listitem> | |
1919 | <para> | |
1920 | <code>! (other == * this)</code> | |
1921 | </para> | |
1922 | </listitem> | |
1923 | </varlistentry> | |
1924 | <varlistentry> | |
1925 | <term>Throws:</term> | |
1926 | <listitem> | |
1927 | <para> | |
1928 | Nothing. | |
1929 | </para> | |
1930 | </listitem> | |
1931 | </varlistentry> | |
1932 | </variablelist> | |
1933 | <para> | |
1934 | <bridgehead renderas="sect4" id="ecv1_operator_less_bridgehead"> | |
1935 | <phrase id="ecv1_operator_less"/> | |
1936 | <link linkend="ecv1_operator_less">Member function | |
1937 | <code>operator<</code>()</link> | |
1938 | </bridgehead> | |
1939 | </para> | |
1940 | <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
1941 | </programlisting> | |
1942 | <variablelist> | |
1943 | <title></title> | |
1944 | <varlistentry> | |
1945 | <term>Returns:</term> | |
1946 | <listitem> | |
1947 | <para> | |
1948 | <code><phrase role="keyword">true</phrase></code> if <code><phrase role="special">*</phrase><phrase | |
1949 | role="keyword">this</phrase> <phrase role="special">!=</phrase> <phrase | |
1950 | role="identifier">other</phrase></code> is true and the implementation-defined | |
1951 | total order of <code><phrase role="identifier">execution_context</phrase></code> | |
1952 | values places <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code> | |
1953 | before <code><phrase role="identifier">other</phrase></code>, false otherwise. | |
1954 | </para> | |
1955 | </listitem> | |
1956 | </varlistentry> | |
1957 | <varlistentry> | |
1958 | <term>Throws:</term> | |
1959 | <listitem> | |
1960 | <para> | |
1961 | Nothing. | |
1962 | </para> | |
1963 | </listitem> | |
1964 | </varlistentry> | |
1965 | </variablelist> | |
1966 | <para> | |
1967 | <bridgehead renderas="sect4" id="ecv1_operator_greater_bridgehead"> | |
1968 | <phrase id="ecv1_operator_greater"/> | |
1969 | <link linkend="ecv1_operator_greater">Member | |
1970 | function <code>operator></code>()</link> | |
1971 | </bridgehead> | |
1972 | </para> | |
1973 | <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
1974 | </programlisting> | |
1975 | <variablelist> | |
1976 | <title></title> | |
1977 | <varlistentry> | |
1978 | <term>Returns:</term> | |
1979 | <listitem> | |
1980 | <para> | |
1981 | <code><phrase role="identifier">other</phrase> <phrase role="special"><</phrase> | |
1982 | <phrase role="special">*</phrase> <phrase role="keyword">this</phrase></code> | |
1983 | </para> | |
1984 | </listitem> | |
1985 | </varlistentry> | |
1986 | <varlistentry> | |
1987 | <term>Throws:</term> | |
1988 | <listitem> | |
1989 | <para> | |
1990 | Nothing. | |
1991 | </para> | |
1992 | </listitem> | |
1993 | </varlistentry> | |
1994 | </variablelist> | |
1995 | <para> | |
1996 | <bridgehead renderas="sect4" id="ecv1_operator_lesseq_bridgehead"> | |
1997 | <phrase id="ecv1_operator_lesseq"/> | |
1998 | <link linkend="ecv1_operator_lesseq">Member | |
1999 | function <code>operator<=</code>()</link> | |
2000 | </bridgehead> | |
2001 | </para> | |
2002 | <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special"><=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
2003 | </programlisting> | |
2004 | <variablelist> | |
2005 | <title></title> | |
2006 | <varlistentry> | |
2007 | <term>Returns:</term> | |
2008 | <listitem> | |
2009 | <para> | |
2010 | <code><phrase role="special">!</phrase> <phrase role="special">(</phrase><phrase | |
2011 | role="identifier">other</phrase> <phrase role="special"><</phrase> | |
2012 | <phrase role="special">*</phrase> <phrase role="keyword">this</phrase><phrase | |
2013 | role="special">)</phrase></code> | |
2014 | </para> | |
2015 | </listitem> | |
2016 | </varlistentry> | |
2017 | <varlistentry> | |
2018 | <term>Throws:</term> | |
2019 | <listitem> | |
2020 | <para> | |
2021 | Nothing. | |
2022 | </para> | |
2023 | </listitem> | |
2024 | </varlistentry> | |
2025 | </variablelist> | |
2026 | <para> | |
2027 | <bridgehead renderas="sect4" id="ecv1_operator_greatereq_bridgehead"> | |
2028 | <phrase id="ecv1_operator_greatereq"/> | |
2029 | <link linkend="ecv1_operator_greatereq">Member | |
2030 | function <code>operator>=</code>()</link> | |
2031 | </bridgehead> | |
2032 | </para> | |
2033 | <programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">>=(</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase> | |
2034 | </programlisting> | |
2035 | <variablelist> | |
2036 | <title></title> | |
2037 | <varlistentry> | |
2038 | <term>Returns:</term> | |
2039 | <listitem> | |
2040 | <para> | |
2041 | <code><phrase role="special">!</phrase> <phrase role="special">(*</phrase> | |
2042 | <phrase role="keyword">this</phrase> <phrase role="special"><</phrase> | |
2043 | <phrase role="identifier">other</phrase><phrase role="special">)</phrase></code> | |
2044 | </para> | |
2045 | </listitem> | |
2046 | </varlistentry> | |
2047 | <varlistentry> | |
2048 | <term>Throws:</term> | |
2049 | <listitem> | |
2050 | <para> | |
2051 | Nothing. | |
2052 | </para> | |
2053 | </listitem> | |
2054 | </varlistentry> | |
2055 | </variablelist> | |
2056 | <para> | |
2057 | <bridgehead renderas="sect4" id="ecv1__bridgehead"> | |
2058 | <phrase id="ecv1_"/> | |
2059 | <link linkend="ecv1_">Non-member function <code>operator<<()</code></link> | |
2060 | </bridgehead> | |
2061 | </para> | |
2062 | <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> | |
2063 | <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> | |
2064 | <phrase role="keyword">operator</phrase><phrase role="special"><<(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special"><</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase> <phrase role="special">&</phrase> <phrase role="identifier">os</phrase><phrase role="special">,</phrase> <phrase role="identifier">execution_context</phrase> <phrase role="keyword">const</phrase><phrase role="special">&</phrase> <phrase role="identifier">other</phrase><phrase role="special">);</phrase> | |
2065 | </programlisting> | |
2066 | <variablelist> | |
2067 | <title></title> | |
2068 | <varlistentry> | |
2069 | <term>Efects:</term> | |
2070 | <listitem> | |
2071 | <para> | |
2072 | Writes the representation of <code><phrase role="identifier">other</phrase></code> | |
2073 | to stream <code><phrase role="identifier">os</phrase></code>. | |
2074 | </para> | |
2075 | </listitem> | |
2076 | </varlistentry> | |
2077 | <varlistentry> | |
2078 | <term>Returns:</term> | |
2079 | <listitem> | |
2080 | <para> | |
2081 | <code><phrase role="identifier">os</phrase></code> | |
2082 | </para> | |
2083 | </listitem> | |
2084 | </varlistentry> | |
2085 | </variablelist> | |
2086 | </section> | |
2087 | <section id="context.stack"> | |
2088 | <title><anchor id="stack"/><link linkend="context.stack">Stack allocation</link></title> | |
2089 | <para> | |
2090 | The memory used by the stack is allocated/deallocated via a <emphasis>StackAllocator</emphasis> | |
2091 | which is required to model a <emphasis>stack-allocator concept</emphasis>. | |
2092 | </para> | |
2093 | <bridgehead renderas="sect3" id="context.stack.h0"> | |
2094 | <phrase id="context.stack._emphasis_stack_allocator_concept__emphasis_"/><link | |
2095 | linkend="context.stack._emphasis_stack_allocator_concept__emphasis_"><emphasis>stack-allocator | |
2096 | concept</emphasis></link> | |
2097 | </bridgehead> | |
2098 | <para> | |
2099 | A <emphasis>StackAllocator</emphasis> must satisfy the <emphasis>stack-allocator | |
2100 | concept</emphasis> requirements shown in the following table, in which <code><phrase | |
2101 | role="identifier">a</phrase></code> is an object of a <emphasis>StackAllocator</emphasis> | |
2102 | type, <code><phrase role="identifier">sctx</phrase></code> is a <code><phrase | |
2103 | role="identifier">stack_context</phrase></code>, and <code><phrase role="identifier">size</phrase></code> | |
2104 | is a <code><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase | |
2105 | role="identifier">size_t</phrase></code>: | |
2106 | </para> | |
2107 | <informaltable frame="all"> | |
2108 | <tgroup cols="3"> | |
2109 | <thead> | |
2110 | <row> | |
2111 | <entry> | |
2112 | <para> | |
2113 | expression | |
2114 | </para> | |
2115 | </entry> | |
2116 | <entry> | |
2117 | <para> | |
2118 | return type | |
2119 | </para> | |
2120 | </entry> | |
2121 | <entry> | |
2122 | <para> | |
2123 | notes | |
2124 | </para> | |
2125 | </entry> | |
2126 | </row> | |
2127 | </thead> | |
2128 | <tbody> | |
2129 | <row> | |
2130 | <entry> | |
2131 | <para> | |
2132 | <code><phrase role="identifier">a</phrase><phrase role="special">(</phrase><phrase | |
2133 | role="identifier">size</phrase><phrase role="special">)</phrase></code> | |
2134 | </para> | |
2135 | </entry> | |
2136 | <entry> | |
2137 | </entry> | |
2138 | <entry> | |
2139 | <para> | |
2140 | creates a stack allocator | |
2141 | </para> | |
2142 | </entry> | |
2143 | </row> | |
2144 | <row> | |
2145 | <entry> | |
2146 | <para> | |
2147 | <code><phrase role="identifier">a</phrase><phrase role="special">.</phrase><phrase | |
2148 | role="identifier">allocate</phrase><phrase role="special">()</phrase></code> | |
2149 | </para> | |
2150 | </entry> | |
2151 | <entry> | |
2152 | <para> | |
2153 | <code><phrase role="identifier">stack_context</phrase></code> | |
2154 | </para> | |
2155 | </entry> | |
2156 | <entry> | |
2157 | <para> | |
2158 | creates a stack | |
2159 | </para> | |
2160 | </entry> | |
2161 | </row> | |
2162 | <row> | |
2163 | <entry> | |
2164 | <para> | |
2165 | <code><phrase role="identifier">a</phrase><phrase role="special">.</phrase><phrase | |
2166 | role="identifier">deallocate</phrase><phrase role="special">(</phrase> | |
2167 | <phrase role="identifier">sctx</phrase><phrase role="special">)</phrase></code> | |
2168 | </para> | |
2169 | </entry> | |
2170 | <entry> | |
2171 | <para> | |
2172 | <code><phrase role="keyword">void</phrase></code> | |
2173 | </para> | |
2174 | </entry> | |
2175 | <entry> | |
2176 | <para> | |
2177 | deallocates the stack created by <code><phrase role="identifier">a</phrase><phrase | |
2178 | role="special">.</phrase><phrase role="identifier">allocate</phrase><phrase | |
2179 | role="special">()</phrase></code> | |
2180 | </para> | |
2181 | </entry> | |
2182 | </row> | |
2183 | </tbody> | |
2184 | </tgroup> | |
2185 | </informaltable> | |
2186 | <important> | |
2187 | <para> | |
2188 | The implementation of <code><phrase role="identifier">allocate</phrase><phrase | |
2189 | role="special">()</phrase></code> might include logic to protect against | |
2190 | exceeding the context's available stack size rather than leaving it as undefined | |
2191 | behaviour. | |
2192 | </para> | |
2193 | </important> | |
2194 | <important> | |
2195 | <para> | |
2196 | Calling <code><phrase role="identifier">deallocate</phrase><phrase role="special">()</phrase></code> | |
2197 | with a <code><phrase role="identifier">stack_context</phrase></code> not | |
2198 | set by <code><phrase role="identifier">allocate</phrase><phrase role="special">()</phrase></code> | |
2199 | results in undefined behaviour. | |
2200 | </para> | |
2201 | </important> | |
2202 | <note> | |
2203 | <para> | |
2204 | The stack is not required to be aligned; alignment takes place inside <emphasis>execution_context</emphasis>. | |
2205 | </para> | |
2206 | </note> | |
2207 | <note> | |
2208 | <para> | |
2209 | Depending on the architecture <code><phrase role="identifier">allocate</phrase><phrase | |
2210 | role="special">()</phrase></code> stores an address from the top of the stack | |
2211 | (growing downwards) or the bottom of the stack (growing upwards). | |
2212 | </para> | |
2213 | </note> | |
2214 | <section id="context.stack.protected_fixedsize"> | |
2215 | <title><link linkend="context.stack.protected_fixedsize">Class <emphasis>protected_fixedsize</emphasis></link></title> | |
2216 | <para> | |
2217 | <emphasis role="bold">Boost.Context</emphasis> provides the class <emphasis>protected_fixedsize_stack</emphasis> | |
2218 | which models the <emphasis>stack-allocator concept</emphasis>. It appends | |
2219 | a guard page at the end of each stack to protect against exceeding the stack. | |
2220 | If the guard page is accessed (read or write operation) a segmentation fault/access | |
2221 | violation is generated by the operating system. | |
2222 | </para> | |
2223 | <important> | |
2224 | <para> | |
2225 | Using <emphasis>protected_fixedsize_stack</emphasis> is expensive. That | |
2226 | is, launching a new coroutine with a new stack is expensive; the allocated | |
2227 | stack is just as efficient to use as any other stack. | |
2228 | </para> | |
2229 | </important> | |
2230 | <note> | |
2231 | <para> | |
2232 | The appended <code><phrase role="identifier">guard</phrase> <phrase role="identifier">page</phrase></code> | |
2233 | is <emphasis role="bold">not</emphasis> mapped to physical memory, only | |
2234 | virtual addresses are used. | |
2235 | </para> | |
2236 | </note> | |
2237 | <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> | |
2238 | ||
2239 | <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase> | |
2240 | <phrase role="keyword">struct</phrase> <phrase role="identifier">basic_protected_fixedsize</phrase> <phrase role="special">{</phrase> | |
2241 | <phrase role="keyword">typedef</phrase> <phrase role="identifier">traitT</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">;</phrase> | |
2242 | ||
2243 | <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> | |
2244 | ||
2245 | <phrase role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">();</phrase> | |
2246 | ||
2247 | <phrase role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&);</phrase> | |
2248 | <phrase role="special">}</phrase> | |
2249 | ||
2250 | <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> | |
2251 | </programlisting> | |
2252 | <bridgehead renderas="sect4" id="context.stack.protected_fixedsize.h0"> | |
2253 | <phrase id="context.stack.protected_fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"/><link | |
2254 | linkend="context.stack.protected_fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"><code><phrase | |
2255 | role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase | |
2256 | role="special">()</phrase></code></link> | |
2257 | </bridgehead> | |
2258 | <variablelist> | |
2259 | <title></title> | |
2260 | <varlistentry> | |
2261 | <term>Preconditions:</term> | |
2262 | <listitem> | |
2263 | <para> | |
2264 | <code><phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase | |
2265 | role="identifier">minimum</phrase><phrase role="special">:</phrase><phrase | |
2266 | role="identifier">size</phrase><phrase role="special">()</phrase> | |
2267 | <phrase role="special"><=</phrase> <phrase role="identifier">size</phrase></code> | |
2268 | and <code><phrase role="special">!</phrase> <phrase role="identifier">traits_type</phrase><phrase | |
2269 | role="special">::</phrase><phrase role="identifier">is_unbounded</phrase><phrase | |
2270 | role="special">()</phrase> <phrase role="special">&&</phrase> | |
2271 | <phrase role="special">(</phrase> <phrase role="identifier">traits_type</phrase><phrase | |
2272 | role="special">::</phrase><phrase role="identifier">maximum</phrase><phrase | |
2273 | role="special">:</phrase><phrase role="identifier">size</phrase><phrase | |
2274 | role="special">()</phrase> <phrase role="special">>=</phrase> <phrase | |
2275 | role="identifier">size</phrase><phrase role="special">)</phrase></code>. | |
2276 | </para> | |
2277 | </listitem> | |
2278 | </varlistentry> | |
2279 | <varlistentry> | |
2280 | <term>Effects:</term> | |
2281 | <listitem> | |
2282 | <para> | |
2283 | Allocates memory of at least <code><phrase role="identifier">size</phrase></code> | |
2284 | Bytes and stores a pointer to the stack and its actual size in <code><phrase | |
2285 | role="identifier">sctx</phrase></code>. Depending on the architecture | |
2286 | (the stack grows downwards/upwards) the stored address is the highest/lowest | |
2287 | address of the stack. | |
2288 | </para> | |
2289 | </listitem> | |
2290 | </varlistentry> | |
2291 | </variablelist> | |
2292 | <bridgehead renderas="sect4" id="context.stack.protected_fixedsize.h1"> | |
2293 | <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 | |
2294 | 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 | |
2295 | role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase | |
2296 | role="special">(</phrase> <phrase role="identifier">stack_context</phrase> | |
2297 | <phrase role="special">&</phrase> <phrase role="identifier">sctx</phrase><phrase | |
2298 | role="special">)</phrase></code></link> | |
2299 | </bridgehead> | |
2300 | <variablelist> | |
2301 | <title></title> | |
2302 | <varlistentry> | |
2303 | <term>Preconditions:</term> | |
2304 | <listitem> | |
2305 | <para> | |
2306 | <code><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase | |
2307 | role="identifier">sp</phrase></code> is valid, <code><phrase role="identifier">traits_type</phrase><phrase | |
2308 | role="special">::</phrase><phrase role="identifier">minimum</phrase><phrase | |
2309 | role="special">:</phrase><phrase role="identifier">size</phrase><phrase | |
2310 | role="special">()</phrase> <phrase role="special"><=</phrase> <phrase | |
2311 | role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase | |
2312 | role="identifier">size</phrase></code> and <code><phrase role="special">!</phrase> | |
2313 | <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase | |
2314 | role="identifier">is_unbounded</phrase><phrase role="special">()</phrase> | |
2315 | <phrase role="special">&&</phrase> <phrase role="special">(</phrase> | |
2316 | <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase | |
2317 | role="identifier">maximum</phrase><phrase role="special">:</phrase><phrase | |
2318 | role="identifier">size</phrase><phrase role="special">()</phrase> | |
2319 | <phrase role="special">>=</phrase> <phrase role="identifier">sctx</phrase><phrase | |
2320 | role="special">.</phrase><phrase role="identifier">size</phrase><phrase | |
2321 | role="special">)</phrase></code>. | |
2322 | </para> | |
2323 | </listitem> | |
2324 | </varlistentry> | |
2325 | <varlistentry> | |
2326 | <term>Effects:</term> | |
2327 | <listitem> | |
2328 | <para> | |
2329 | Deallocates the stack space. | |
2330 | </para> | |
2331 | </listitem> | |
2332 | </varlistentry> | |
2333 | </variablelist> | |
2334 | </section> | |
2335 | <section id="context.stack.pooled_fixedsize"> | |
2336 | <title><link linkend="context.stack.pooled_fixedsize">Class <emphasis>pooled_fixedsize_stack</emphasis></link></title> | |
2337 | <para> | |
2338 | <emphasis role="bold">Boost.Context</emphasis> provides the class <emphasis>pooled_fixedsize_stack</emphasis> | |
2339 | which models the <emphasis>stack-allocator concept</emphasis>. In contrast | |
2340 | to <emphasis>protected_fixedsize_stack</emphasis> it does not append a guard | |
2341 | page at the end of each stack. The memory is managed internally by <ulink | |
2342 | url="http://www.boost.org/doc/libs/release/libs/pool/doc/html/boost/pool.html"><code><phrase | |
2343 | role="identifier">boost</phrase><phrase role="special">::</phrase><phrase | |
2344 | role="identifier">pool</phrase><phrase role="special"><></phrase></code></ulink>. | |
2345 | </para> | |
2346 | <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> | |
2347 | ||
2348 | <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase> | |
2349 | <phrase role="keyword">struct</phrase> <phrase role="identifier">basic_pooled_fixedsize_stack</phrase> <phrase role="special">{</phrase> | |
2350 | <phrase role="keyword">typedef</phrase> <phrase role="identifier">traitT</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">;</phrase> | |
2351 | ||
2352 | <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> | |
2353 | ||
2354 | <phrase role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">();</phrase> | |
2355 | ||
2356 | <phrase role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&);</phrase> | |
2357 | <phrase role="special">}</phrase> | |
2358 | ||
2359 | <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> | |
2360 | </programlisting> | |
2361 | <bridgehead renderas="sect4" id="context.stack.pooled_fixedsize.h0"> | |
2362 | <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 | |
2363 | 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 | |
2364 | role="identifier">basic_pooled_fixedsize_stack</phrase><phrase role="special">(</phrase><phrase | |
2365 | role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> | |
2366 | <phrase role="identifier">stack_size</phrase><phrase role="special">,</phrase> | |
2367 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase | |
2368 | role="identifier">size_t</phrase> <phrase role="identifier">next_size</phrase><phrase | |
2369 | role="special">,</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase | |
2370 | role="identifier">size_t</phrase> <phrase role="identifier">max_size</phrase><phrase | |
2371 | role="special">)</phrase></code></link> | |
2372 | </bridgehead> | |
2373 | <variablelist> | |
2374 | <title></title> | |
2375 | <varlistentry> | |
2376 | <term>Preconditions:</term> | |
2377 | <listitem> | |
2378 | <para> | |
2379 | <code><phrase role="special">!</phrase> <phrase role="identifier">traits_type</phrase><phrase | |
2380 | role="special">::</phrase><phrase role="identifier">is_unbounded</phrase><phrase | |
2381 | role="special">()</phrase> <phrase role="special">&&</phrase> | |
2382 | <phrase role="special">(</phrase> <phrase role="identifier">traits_type</phrase><phrase | |
2383 | role="special">::</phrase><phrase role="identifier">maximum</phrase><phrase | |
2384 | role="special">:</phrase><phrase role="identifier">size</phrase><phrase | |
2385 | role="special">()</phrase> <phrase role="special">>=</phrase> <phrase | |
2386 | role="identifier">stack_size</phrase><phrase role="special">)</phrase></code> | |
2387 | and <code><phrase role="number">0</phrase> <phrase role="special"><</phrase> | |
2388 | <phrase role="identifier">nest_size</phrase></code>. | |
2389 | </para> | |
2390 | </listitem> | |
2391 | </varlistentry> | |
2392 | <varlistentry> | |
2393 | <term>Effects:</term> | |
2394 | <listitem> | |
2395 | <para> | |
2396 | Allocates memory of at least <code><phrase role="identifier">stack_size</phrase></code> | |
2397 | Bytes and stores a pointer to the stack and its actual size in <code><phrase | |
2398 | role="identifier">sctx</phrase></code>. Depending on the architecture | |
2399 | (the stack grows downwards/upwards) the stored address is the highest/lowest | |
2400 | address of the stack. Argument <code><phrase role="identifier">next_size</phrase></code> | |
2401 | determines the number of stacks to request from the system the first | |
2402 | time that <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code> | |
2403 | needs to allocate system memory. The third argument <code><phrase role="identifier">max_size</phrase></code> | |
2404 | controls how many memory might be allocated for stacks - a value of | |
2405 | zero means no uper limit. | |
2406 | </para> | |
2407 | </listitem> | |
2408 | </varlistentry> | |
2409 | </variablelist> | |
2410 | <bridgehead renderas="sect4" id="context.stack.pooled_fixedsize.h1"> | |
2411 | <phrase id="context.stack.pooled_fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"/><link | |
2412 | linkend="context.stack.pooled_fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"><code><phrase | |
2413 | role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase | |
2414 | role="special">()</phrase></code></link> | |
2415 | </bridgehead> | |
2416 | <variablelist> | |
2417 | <title></title> | |
2418 | <varlistentry> | |
2419 | <term>Preconditions:</term> | |
2420 | <listitem> | |
2421 | <para> | |
2422 | <code><phrase role="special">!</phrase> <phrase role="identifier">traits_type</phrase><phrase | |
2423 | role="special">::</phrase><phrase role="identifier">is_unbounded</phrase><phrase | |
2424 | role="special">()</phrase> <phrase role="special">&&</phrase> | |
2425 | <phrase role="special">(</phrase> <phrase role="identifier">traits_type</phrase><phrase | |
2426 | role="special">::</phrase><phrase role="identifier">maximum</phrase><phrase | |
2427 | role="special">:</phrase><phrase role="identifier">size</phrase><phrase | |
2428 | role="special">()</phrase> <phrase role="special">>=</phrase> <phrase | |
2429 | role="identifier">stack_size</phrase><phrase role="special">)</phrase></code>. | |
2430 | </para> | |
2431 | </listitem> | |
2432 | </varlistentry> | |
2433 | <varlistentry> | |
2434 | <term>Effects:</term> | |
2435 | <listitem> | |
2436 | <para> | |
2437 | Allocates memory of at least <code><phrase role="identifier">stack_size</phrase></code> | |
2438 | Bytes and stores a pointer to the stack and its actual size in <code><phrase | |
2439 | role="identifier">sctx</phrase></code>. Depending on the architecture | |
2440 | (the stack grows downwards/upwards) the stored address is the highest/lowest | |
2441 | address of the stack. | |
2442 | </para> | |
2443 | </listitem> | |
2444 | </varlistentry> | |
2445 | </variablelist> | |
2446 | <bridgehead renderas="sect4" id="context.stack.pooled_fixedsize.h2"> | |
2447 | <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 | |
2448 | 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 | |
2449 | role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase | |
2450 | role="special">(</phrase> <phrase role="identifier">stack_context</phrase> | |
2451 | <phrase role="special">&</phrase> <phrase role="identifier">sctx</phrase><phrase | |
2452 | role="special">)</phrase></code></link> | |
2453 | </bridgehead> | |
2454 | <variablelist> | |
2455 | <title></title> | |
2456 | <varlistentry> | |
2457 | <term>Preconditions:</term> | |
2458 | <listitem> | |
2459 | <para> | |
2460 | <code><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase | |
2461 | role="identifier">sp</phrase></code> is valid, <code><phrase role="special">!</phrase> | |
2462 | <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase | |
2463 | role="identifier">is_unbounded</phrase><phrase role="special">()</phrase> | |
2464 | <phrase role="special">&&</phrase> <phrase role="special">(</phrase> | |
2465 | <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase | |
2466 | role="identifier">maximum</phrase><phrase role="special">:</phrase><phrase | |
2467 | role="identifier">size</phrase><phrase role="special">()</phrase> | |
2468 | <phrase role="special">>=</phrase> <phrase role="identifier">sctx</phrase><phrase | |
2469 | role="special">.</phrase><phrase role="identifier">size</phrase><phrase | |
2470 | role="special">)</phrase></code>. | |
2471 | </para> | |
2472 | </listitem> | |
2473 | </varlistentry> | |
2474 | <varlistentry> | |
2475 | <term>Effects:</term> | |
2476 | <listitem> | |
2477 | <para> | |
2478 | Deallocates the stack space. | |
2479 | </para> | |
2480 | </listitem> | |
2481 | </varlistentry> | |
2482 | </variablelist> | |
2483 | </section> | |
2484 | <section id="context.stack.fixedsize"> | |
2485 | <title><link linkend="context.stack.fixedsize">Class <emphasis>fixedsize_stack</emphasis></link></title> | |
2486 | <para> | |
2487 | <emphasis role="bold">Boost.Context</emphasis> provides the class <emphasis>fixedsize_stack</emphasis> | |
2488 | which models the <emphasis>stack-allocator concept</emphasis>. In contrast | |
2489 | to <emphasis>protected_fixedsize_stack</emphasis> it does not append a guard | |
2490 | page at the end of each stack. The memory is simply managed by <code><phrase | |
2491 | role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">malloc</phrase><phrase | |
2492 | role="special">()</phrase></code> and <code><phrase role="identifier">std</phrase><phrase | |
2493 | role="special">::</phrase><phrase role="identifier">free</phrase><phrase | |
2494 | role="special">()</phrase></code>. | |
2495 | </para> | |
2496 | <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> | |
2497 | ||
2498 | <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase> | |
2499 | <phrase role="keyword">struct</phrase> <phrase role="identifier">basic_fixedsize_stack</phrase> <phrase role="special">{</phrase> | |
2500 | <phrase role="keyword">typedef</phrase> <phrase role="identifier">traitT</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">;</phrase> | |
2501 | ||
2502 | <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> | |
2503 | ||
2504 | <phrase role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">();</phrase> | |
2505 | ||
2506 | <phrase role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&);</phrase> | |
2507 | <phrase role="special">}</phrase> | |
2508 | ||
2509 | <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> | |
2510 | </programlisting> | |
2511 | <bridgehead renderas="sect4" id="context.stack.fixedsize.h0"> | |
2512 | <phrase id="context.stack.fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"/><link | |
2513 | linkend="context.stack.fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"><code><phrase | |
2514 | role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase | |
2515 | role="special">()</phrase></code></link> | |
2516 | </bridgehead> | |
2517 | <variablelist> | |
2518 | <title></title> | |
2519 | <varlistentry> | |
2520 | <term>Preconditions:</term> | |
2521 | <listitem> | |
2522 | <para> | |
2523 | <code><phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase | |
2524 | role="identifier">minimum</phrase><phrase role="special">:</phrase><phrase | |
2525 | role="identifier">size</phrase><phrase role="special">()</phrase> | |
2526 | <phrase role="special"><=</phrase> <phrase role="identifier">size</phrase></code> | |
2527 | and <code><phrase role="special">!</phrase> <phrase role="identifier">traits_type</phrase><phrase | |
2528 | role="special">::</phrase><phrase role="identifier">is_unbounded</phrase><phrase | |
2529 | role="special">()</phrase> <phrase role="special">&&</phrase> | |
2530 | <phrase role="special">(</phrase> <phrase role="identifier">traits_type</phrase><phrase | |
2531 | role="special">::</phrase><phrase role="identifier">maximum</phrase><phrase | |
2532 | role="special">:</phrase><phrase role="identifier">size</phrase><phrase | |
2533 | role="special">()</phrase> <phrase role="special">>=</phrase> <phrase | |
2534 | role="identifier">size</phrase><phrase role="special">)</phrase></code>. | |
2535 | </para> | |
2536 | </listitem> | |
2537 | </varlistentry> | |
2538 | <varlistentry> | |
2539 | <term>Effects:</term> | |
2540 | <listitem> | |
2541 | <para> | |
2542 | Allocates memory of at least <code><phrase role="identifier">size</phrase></code> | |
2543 | Bytes and stores a pointer to the stack and its actual size in <code><phrase | |
2544 | role="identifier">sctx</phrase></code>. Depending on the architecture | |
2545 | (the stack grows downwards/upwards) the stored address is the highest/lowest | |
2546 | address of the stack. | |
2547 | </para> | |
2548 | </listitem> | |
2549 | </varlistentry> | |
2550 | </variablelist> | |
2551 | <bridgehead renderas="sect4" id="context.stack.fixedsize.h1"> | |
2552 | <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 | |
2553 | 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 | |
2554 | role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase | |
2555 | role="special">(</phrase> <phrase role="identifier">stack_context</phrase> | |
2556 | <phrase role="special">&</phrase> <phrase role="identifier">sctx</phrase><phrase | |
2557 | role="special">)</phrase></code></link> | |
2558 | </bridgehead> | |
2559 | <variablelist> | |
2560 | <title></title> | |
2561 | <varlistentry> | |
2562 | <term>Preconditions:</term> | |
2563 | <listitem> | |
2564 | <para> | |
2565 | <code><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase | |
2566 | role="identifier">sp</phrase></code> is valid, <code><phrase role="identifier">traits_type</phrase><phrase | |
2567 | role="special">::</phrase><phrase role="identifier">minimum</phrase><phrase | |
2568 | role="special">:</phrase><phrase role="identifier">size</phrase><phrase | |
2569 | role="special">()</phrase> <phrase role="special"><=</phrase> <phrase | |
2570 | role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase | |
2571 | role="identifier">size</phrase></code> and <code><phrase role="special">!</phrase> | |
2572 | <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase | |
2573 | role="identifier">is_unbounded</phrase><phrase role="special">()</phrase> | |
2574 | <phrase role="special">&&</phrase> <phrase role="special">(</phrase> | |
2575 | <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase | |
2576 | role="identifier">maximum</phrase><phrase role="special">:</phrase><phrase | |
2577 | role="identifier">size</phrase><phrase role="special">()</phrase> | |
2578 | <phrase role="special">>=</phrase> <phrase role="identifier">sctx</phrase><phrase | |
2579 | role="special">.</phrase><phrase role="identifier">size</phrase><phrase | |
2580 | role="special">)</phrase></code>. | |
2581 | </para> | |
2582 | </listitem> | |
2583 | </varlistentry> | |
2584 | <varlistentry> | |
2585 | <term>Effects:</term> | |
2586 | <listitem> | |
2587 | <para> | |
2588 | Deallocates the stack space. | |
2589 | </para> | |
2590 | </listitem> | |
2591 | </varlistentry> | |
2592 | </variablelist> | |
2593 | </section> | |
2594 | <section id="context.stack.segmented"> | |
2595 | <title><link linkend="context.stack.segmented">Class <emphasis>segmented_stack</emphasis></link></title> | |
2596 | <para> | |
2597 | <emphasis role="bold">Boost.Context</emphasis> supports usage of a <emphasis>segmented_stack</emphasis>, | |
2598 | e. g. the size of the stack grows on demand. The coroutine is created with | |
2599 | a minimal stack size and will be increased as required. Class <emphasis>segmented_stack</emphasis> | |
2600 | models the <emphasis>stack-allocator concept</emphasis>. In contrast to | |
2601 | <emphasis>protected_fixedsize_stack</emphasis> and <emphasis>fixedsize_stack</emphasis> | |
2602 | it creates a stack which grows on demand. | |
2603 | </para> | |
2604 | <note> | |
2605 | <para> | |
2606 | Segmented stacks are currently only supported by <emphasis role="bold">gcc</emphasis> | |
2607 | from version <emphasis role="bold">4.7</emphasis> <emphasis role="bold">clang</emphasis> | |
2608 | from version <emphasis role="bold">3.4</emphasis> onwards. In order to | |
2609 | use a __segmented_stack__ <emphasis role="bold">Boost.Context</emphasis> | |
2610 | must be built with property <code><phrase role="identifier">segmented</phrase><phrase | |
2611 | role="special">-</phrase><phrase role="identifier">stacks</phrase></code>, | |
2612 | e.g. <emphasis role="bold">toolset=gcc segmented-stacks=on</emphasis> at | |
2613 | b2/bjam command line. | |
2614 | </para> | |
2615 | </note> | |
2616 | <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> | |
2617 | ||
2618 | <phrase role="keyword">template</phrase><phrase role="special"><</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">></phrase> | |
2619 | <phrase role="keyword">struct</phrase> <phrase role="identifier">basic_segmented_stack</phrase> <phrase role="special">{</phrase> | |
2620 | <phrase role="keyword">typedef</phrase> <phrase role="identifier">traitT</phrase> <phrase role="identifier">traits_type</phrase><phrase role="special">;</phrase> | |
2621 | ||
2622 | <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> | |
2623 | ||
2624 | <phrase role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">();</phrase> | |
2625 | ||
2626 | <phrase role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&);</phrase> | |
2627 | <phrase role="special">}</phrase> | |
2628 | ||
2629 | <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> | |
2630 | </programlisting> | |
2631 | <bridgehead renderas="sect4" id="context.stack.segmented.h0"> | |
2632 | <phrase id="context.stack.segmented._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"/><link | |
2633 | linkend="context.stack.segmented._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"><code><phrase | |
2634 | role="identifier">stack_context</phrase> <phrase role="identifier">allocate</phrase><phrase | |
2635 | role="special">()</phrase></code></link> | |
2636 | </bridgehead> | |
2637 | <variablelist> | |
2638 | <title></title> | |
2639 | <varlistentry> | |
2640 | <term>Preconditions:</term> | |
2641 | <listitem> | |
2642 | <para> | |
2643 | <code><phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase | |
2644 | role="identifier">minimum</phrase><phrase role="special">:</phrase><phrase | |
2645 | role="identifier">size</phrase><phrase role="special">()</phrase> | |
2646 | <phrase role="special"><=</phrase> <phrase role="identifier">size</phrase></code> | |
2647 | and <code><phrase role="special">!</phrase> <phrase role="identifier">traits_type</phrase><phrase | |
2648 | role="special">::</phrase><phrase role="identifier">is_unbounded</phrase><phrase | |
2649 | role="special">()</phrase> <phrase role="special">&&</phrase> | |
2650 | <phrase role="special">(</phrase> <phrase role="identifier">traits_type</phrase><phrase | |
2651 | role="special">::</phrase><phrase role="identifier">maximum</phrase><phrase | |
2652 | role="special">:</phrase><phrase role="identifier">size</phrase><phrase | |
2653 | role="special">()</phrase> <phrase role="special">>=</phrase> <phrase | |
2654 | role="identifier">size</phrase><phrase role="special">)</phrase></code>. | |
2655 | </para> | |
2656 | </listitem> | |
2657 | </varlistentry> | |
2658 | <varlistentry> | |
2659 | <term>Effects:</term> | |
2660 | <listitem> | |
2661 | <para> | |
2662 | Allocates memory of at least <code><phrase role="identifier">size</phrase></code> | |
2663 | Bytes and stores a pointer to the stack and its actual size in <code><phrase | |
2664 | role="identifier">sctx</phrase></code>. Depending on the architecture | |
2665 | (the stack grows downwards/upwards) the stored address is the highest/lowest | |
2666 | address of the stack. | |
2667 | </para> | |
2668 | </listitem> | |
2669 | </varlistentry> | |
2670 | </variablelist> | |
2671 | <bridgehead renderas="sect4" id="context.stack.segmented.h1"> | |
2672 | <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 | |
2673 | 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 | |
2674 | role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase | |
2675 | role="special">(</phrase> <phrase role="identifier">stack_context</phrase> | |
2676 | <phrase role="special">&</phrase> <phrase role="identifier">sctx</phrase><phrase | |
2677 | role="special">)</phrase></code></link> | |
2678 | </bridgehead> | |
2679 | <variablelist> | |
2680 | <title></title> | |
2681 | <varlistentry> | |
2682 | <term>Preconditions:</term> | |
2683 | <listitem> | |
2684 | <para> | |
2685 | <code><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase | |
2686 | role="identifier">sp</phrase></code> is valid, <code><phrase role="identifier">traits_type</phrase><phrase | |
2687 | role="special">::</phrase><phrase role="identifier">minimum</phrase><phrase | |
2688 | role="special">:</phrase><phrase role="identifier">size</phrase><phrase | |
2689 | role="special">()</phrase> <phrase role="special"><=</phrase> <phrase | |
2690 | role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase | |
2691 | role="identifier">size</phrase></code> and <code><phrase role="special">!</phrase> | |
2692 | <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase | |
2693 | role="identifier">is_unbounded</phrase><phrase role="special">()</phrase> | |
2694 | <phrase role="special">&&</phrase> <phrase role="special">(</phrase> | |
2695 | <phrase role="identifier">traits_type</phrase><phrase role="special">::</phrase><phrase | |
2696 | role="identifier">maximum</phrase><phrase role="special">:</phrase><phrase | |
2697 | role="identifier">size</phrase><phrase role="special">()</phrase> | |
2698 | <phrase role="special">>=</phrase> <phrase role="identifier">sctx</phrase><phrase | |
2699 | role="special">.</phrase><phrase role="identifier">size</phrase><phrase | |
2700 | role="special">)</phrase></code>. | |
2701 | </para> | |
2702 | </listitem> | |
2703 | </varlistentry> | |
2704 | <varlistentry> | |
2705 | <term>Effects:</term> | |
2706 | <listitem> | |
2707 | <para> | |
2708 | Deallocates the stack space. | |
2709 | </para> | |
2710 | </listitem> | |
2711 | </varlistentry> | |
2712 | </variablelist> | |
2713 | <note> | |
2714 | <para> | |
2715 | If the library is compiled for segmented stacks, __segmented_stack__ is | |
2716 | the only available stack allocator. | |
2717 | </para> | |
2718 | </note> | |
2719 | </section> | |
2720 | <section id="context.stack.stack_traits"> | |
2721 | <title><link linkend="context.stack.stack_traits">Class <emphasis>stack_traits</emphasis></link></title> | |
2722 | <para> | |
2723 | <emphasis>stack_traits</emphasis> models a <emphasis>stack-traits</emphasis> | |
2724 | providing a way to access certain properites defined by the enironment. Stack | |
2725 | allocators use <emphasis>stack-traits</emphasis> to allocate stacks. | |
2726 | </para> | |
2727 | <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> | |
2728 | ||
2729 | <phrase role="keyword">struct</phrase> <phrase role="identifier">stack_traits</phrase> <phrase role="special">{</phrase> | |
2730 | <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> | |
2731 | ||
2732 | <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> | |
2733 | ||
2734 | <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> | |
2735 | ||
2736 | <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> | |
2737 | ||
2738 | <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> | |
2739 | <phrase role="special">}</phrase> | |
2740 | </programlisting> | |
2741 | <bridgehead renderas="sect4" id="context.stack.stack_traits.h0"> | |
2742 | <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 | |
2743 | 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 | |
2744 | role="keyword">static</phrase> <phrase role="keyword">bool</phrase> <phrase | |
2745 | role="identifier">is_unbounded</phrase><phrase role="special">()</phrase></code></link> | |
2746 | </bridgehead> | |
2747 | <variablelist> | |
2748 | <title></title> | |
2749 | <varlistentry> | |
2750 | <term>Returns:</term> | |
2751 | <listitem> | |
2752 | <para> | |
2753 | Returns <code><phrase role="keyword">true</phrase></code> if the environment | |
2754 | defines no limit for the size of a stack. | |
2755 | </para> | |
2756 | </listitem> | |
2757 | </varlistentry> | |
2758 | <varlistentry> | |
2759 | <term>Throws:</term> | |
2760 | <listitem> | |
2761 | <para> | |
2762 | Nothing. | |
2763 | </para> | |
2764 | </listitem> | |
2765 | </varlistentry> | |
2766 | </variablelist> | |
2767 | <bridgehead renderas="sect4" id="context.stack.stack_traits.h1"> | |
2768 | <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 | |
2769 | 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 | |
2770 | role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase | |
2771 | role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase | |
2772 | role="identifier">page_size</phrase><phrase role="special">()</phrase></code></link> | |
2773 | </bridgehead> | |
2774 | <variablelist> | |
2775 | <title></title> | |
2776 | <varlistentry> | |
2777 | <term>Returns:</term> | |
2778 | <listitem> | |
2779 | <para> | |
2780 | Returns the page size in bytes. | |
2781 | </para> | |
2782 | </listitem> | |
2783 | </varlistentry> | |
2784 | <varlistentry> | |
2785 | <term>Throws:</term> | |
2786 | <listitem> | |
2787 | <para> | |
2788 | Nothing. | |
2789 | </para> | |
2790 | </listitem> | |
2791 | </varlistentry> | |
2792 | </variablelist> | |
2793 | <bridgehead renderas="sect4" id="context.stack.stack_traits.h2"> | |
2794 | <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 | |
2795 | 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 | |
2796 | role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase | |
2797 | role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase | |
2798 | role="identifier">default_size</phrase><phrase role="special">()</phrase></code></link> | |
2799 | </bridgehead> | |
2800 | <variablelist> | |
2801 | <title></title> | |
2802 | <varlistentry> | |
2803 | <term>Returns:</term> | |
2804 | <listitem> | |
2805 | <para> | |
2806 | Returns a default stack size, which may be platform specific. If the | |
2807 | stack is unbounded then the present implementation returns the maximum | |
2808 | of <code><phrase role="number">64</phrase> <phrase role="identifier">kB</phrase></code> | |
2809 | and <code><phrase role="identifier">minimum_size</phrase><phrase role="special">()</phrase></code>. | |
2810 | </para> | |
2811 | </listitem> | |
2812 | </varlistentry> | |
2813 | <varlistentry> | |
2814 | <term>Throws:</term> | |
2815 | <listitem> | |
2816 | <para> | |
2817 | Nothing. | |
2818 | </para> | |
2819 | </listitem> | |
2820 | </varlistentry> | |
2821 | </variablelist> | |
2822 | <bridgehead renderas="sect4" id="context.stack.stack_traits.h3"> | |
2823 | <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 | |
2824 | 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 | |
2825 | role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase | |
2826 | role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase | |
2827 | role="identifier">minimum_size</phrase><phrase role="special">()</phrase></code></link> | |
2828 | </bridgehead> | |
2829 | <variablelist> | |
2830 | <title></title> | |
2831 | <varlistentry> | |
2832 | <term>Returns:</term> | |
2833 | <listitem> | |
2834 | <para> | |
2835 | Returns the minimum size in bytes of stack defined by the environment | |
2836 | (Win32 4kB/Win64 8kB, defined by rlimit on POSIX). | |
2837 | </para> | |
2838 | </listitem> | |
2839 | </varlistentry> | |
2840 | <varlistentry> | |
2841 | <term>Throws:</term> | |
2842 | <listitem> | |
2843 | <para> | |
2844 | Nothing. | |
2845 | </para> | |
2846 | </listitem> | |
2847 | </varlistentry> | |
2848 | </variablelist> | |
2849 | <bridgehead renderas="sect4" id="context.stack.stack_traits.h4"> | |
2850 | <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 | |
2851 | 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 | |
2852 | role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase | |
2853 | role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase | |
2854 | role="identifier">maximum_size</phrase><phrase role="special">()</phrase></code></link> | |
2855 | </bridgehead> | |
2856 | <variablelist> | |
2857 | <title></title> | |
2858 | <varlistentry> | |
2859 | <term>Preconditions:</term> | |
2860 | <listitem> | |
2861 | <para> | |
2862 | <code><phrase role="identifier">is_unbounded</phrase><phrase role="special">()</phrase></code> | |
2863 | returns <code><phrase role="keyword">false</phrase></code>. | |
2864 | </para> | |
2865 | </listitem> | |
2866 | </varlistentry> | |
2867 | <varlistentry> | |
2868 | <term>Returns:</term> | |
2869 | <listitem> | |
2870 | <para> | |
2871 | Returns the maximum size in bytes of stack defined by the environment. | |
2872 | </para> | |
2873 | </listitem> | |
2874 | </varlistentry> | |
2875 | <varlistentry> | |
2876 | <term>Throws:</term> | |
2877 | <listitem> | |
2878 | <para> | |
2879 | Nothing. | |
2880 | </para> | |
2881 | </listitem> | |
2882 | </varlistentry> | |
2883 | </variablelist> | |
2884 | </section> | |
2885 | <section id="context.stack.stack_context"> | |
2886 | <title><link linkend="context.stack.stack_context">Class <emphasis>stack_context</emphasis></link></title> | |
2887 | <para> | |
2888 | <emphasis role="bold">Boost.Context</emphasis> provides the class <emphasis>stack_context</emphasis> | |
2889 | which will contain the stack pointer and the size of the stack. In case of | |
2890 | a <emphasis>segmented_stack</emphasis>, <emphasis>stack_context</emphasis> | |
2891 | contains some extra control structures. | |
2892 | </para> | |
2893 | <programlisting><phrase role="keyword">struct</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">{</phrase> | |
2894 | <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">;</phrase> | |
2895 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">;</phrase> | |
2896 | ||
2897 | <phrase role="comment">// might contain additional control structures</phrase> | |
2898 | <phrase role="comment">// for segmented stacks</phrase> | |
2899 | <phrase role="special">}</phrase> | |
2900 | </programlisting> | |
2901 | <bridgehead renderas="sect4" id="context.stack.stack_context.h0"> | |
2902 | <phrase id="context.stack.stack_context._code__phrase_role__keyword__void__phrase___phrase_role__special_____phrase___phrase_role__identifier__sp__phrase___code_"/><link | |
2903 | linkend="context.stack.stack_context._code__phrase_role__keyword__void__phrase___phrase_role__special_____phrase___phrase_role__identifier__sp__phrase___code_"><code><phrase | |
2904 | role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase></code></link> | |
2905 | </bridgehead> | |
2906 | <variablelist> | |
2907 | <title></title> | |
2908 | <varlistentry> | |
2909 | <term>Value:</term> | |
2910 | <listitem> | |
2911 | <para> | |
2912 | Pointer to the beginning of the stack. | |
2913 | </para> | |
2914 | </listitem> | |
2915 | </varlistentry> | |
2916 | </variablelist> | |
2917 | <bridgehead renderas="sect4" id="context.stack.stack_context.h1"> | |
2918 | <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 | |
2919 | 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 | |
2920 | role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> | |
2921 | <phrase role="identifier">size</phrase></code></link> | |
2922 | </bridgehead> | |
2923 | <variablelist> | |
2924 | <title></title> | |
2925 | <varlistentry> | |
2926 | <term>Value:</term> | |
2927 | <listitem> | |
2928 | <para> | |
2929 | Actual size of the stack. | |
2930 | </para> | |
2931 | </listitem> | |
2932 | </varlistentry> | |
2933 | </variablelist> | |
2934 | </section> | |
2935 | <section id="context.stack.valgrind"> | |
2936 | <title><link linkend="context.stack.valgrind">Support for valgrind</link></title> | |
2937 | <para> | |
2938 | Running programs that switch stacks under valgrind causes problems. Property | |
2939 | (b2 command-line) <code><phrase role="identifier">valgrind</phrase><phrase | |
2940 | role="special">=</phrase><phrase role="identifier">on</phrase></code> let | |
2941 | valgrind treat the memory regions as stack space which suppresses the errors. | |
2942 | </para> | |
2943 | </section> | |
2944 | </section> | |
2945 | <section id="context.struct__preallocated_"> | |
2946 | <title><link linkend="context.struct__preallocated_">Struct <code><phrase role="identifier">preallocated</phrase></code></link></title> | |
2947 | <programlisting><phrase role="keyword">struct</phrase> <phrase role="identifier">preallocated</phrase> <phrase role="special">{</phrase> | |
2948 | <phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">;</phrase> | |
2949 | <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">;</phrase> | |
2950 | <phrase role="identifier">stack_context</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">;</phrase> | |
2951 | ||
2952 | <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> | |
2953 | <phrase role="special">};</phrase> | |
2954 | </programlisting> | |
2955 | <bridgehead renderas="sect3" id="context.struct__preallocated_.h0"> | |
2956 | <phrase id="context.struct__preallocated_.constructor"/><link linkend="context.struct__preallocated_.constructor">Constructor</link> | |
2957 | </bridgehead> | |
2958 | <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> | |
2959 | </programlisting> | |
2960 | <variablelist> | |
2961 | <title></title> | |
2962 | <varlistentry> | |
2963 | <term>Effects:</term> | |
2964 | <listitem> | |
2965 | <para> | |
2966 | Creates an object of preallocated. | |
2967 | </para> | |
2968 | </listitem> | |
2969 | </varlistentry> | |
2970 | </variablelist> | |
2971 | </section> | |
2972 | <section id="context.performance"> | |
2973 | <title><link linkend="context.performance">Performance</link></title> | |
2974 | <para> | |
2975 | Performance of <emphasis role="bold">Boost.Context</emphasis> was measured | |
2976 | on the platforms shown in the following table. Performance measurements were | |
2977 | taken using <code><phrase role="identifier">rdtsc</phrase></code> and <code><phrase | |
2978 | role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">chrono</phrase><phrase | |
2979 | role="special">::</phrase><phrase role="identifier">high_resolution_clock</phrase></code>, | |
2980 | with overhead corrections, on x86 platforms. In each case, cache warm-up was | |
2981 | accounted for, and the one running thread was pinned to a single CPU. The code | |
2982 | was compiled using the build options, 'variant = release cxxflags = -DBOOST_DISABLE_ASSERTS'. | |
2983 | </para> | |
2984 | <table frame="all" id="context.performance.performance_of_context_switch"> | |
2985 | <title>Performance of context switch</title> | |
2986 | <tgroup cols="4"> | |
2987 | <thead> | |
2988 | <row> | |
2989 | <entry> | |
2990 | <para> | |
2991 | Platform | |
2992 | </para> | |
2993 | </entry> | |
2994 | <entry> | |
2995 | <para> | |
2996 | ucontext_t | |
2997 | </para> | |
2998 | </entry> | |
2999 | <entry> | |
3000 | <para> | |
3001 | execution_context (v1) | |
3002 | </para> | |
3003 | </entry> | |
3004 | <entry> | |
3005 | <para> | |
3006 | execution_context (v2) | |
3007 | </para> | |
3008 | </entry> | |
3009 | </row> | |
3010 | </thead> | |
3011 | <tbody> | |
3012 | <row> | |
3013 | <entry> | |
3014 | <para> | |
3015 | x86_64 <footnote id="context.performance.f0"> | |
3016 | <para> | |
3017 | Intel Core2 Q6700 | |
3018 | </para> | |
3019 | </footnote> | |
3020 | </para> | |
3021 | </entry> | |
3022 | <entry> | |
3023 | <para> | |
3024 | 547 ns / 1433 cycles | |
3025 | </para> | |
3026 | </entry> | |
3027 | <entry> | |
3028 | <para> | |
3029 | 51 ns / 141 cycles | |
3030 | </para> | |
3031 | </entry> | |
3032 | <entry> | |
3033 | <para> | |
3034 | 7 ns / 18 cycles | |
3035 | </para> | |
3036 | </entry> | |
3037 | </row> | |
3038 | </tbody> | |
3039 | </tgroup> | |
3040 | </table> | |
3041 | </section> | |
3042 | <section id="context.architectures"> | |
3043 | <title><link linkend="context.architectures">Architectures</link></title> | |
3044 | <para> | |
3045 | <emphasis role="bold">Boost.Context</emphasis> supports following architectures: | |
3046 | </para> | |
3047 | <table frame="all" id="context.architectures.supported_architectures___abi_binary_format__"> | |
3048 | <title>Supported architectures (<ABI|binary format>)</title> | |
3049 | <tgroup cols="5"> | |
3050 | <thead> | |
3051 | <row> | |
3052 | <entry> | |
3053 | <para> | |
3054 | Architecture | |
3055 | </para> | |
3056 | </entry> | |
3057 | <entry> | |
3058 | <para> | |
3059 | LINUX (UNIX) | |
3060 | </para> | |
3061 | </entry> | |
3062 | <entry> | |
3063 | <para> | |
3064 | Windows | |
3065 | </para> | |
3066 | </entry> | |
3067 | <entry> | |
3068 | <para> | |
3069 | MacOS X | |
3070 | </para> | |
3071 | </entry> | |
3072 | <entry> | |
3073 | <para> | |
3074 | iOS | |
3075 | </para> | |
3076 | </entry> | |
3077 | </row> | |
3078 | </thead> | |
3079 | <tbody> | |
3080 | <row> | |
3081 | <entry> | |
3082 | <para> | |
3083 | arm (aarch32) | |
3084 | </para> | |
3085 | </entry> | |
3086 | <entry> | |
3087 | <para> | |
3088 | AAPCS|ELF | |
3089 | </para> | |
3090 | </entry> | |
3091 | <entry> | |
3092 | <para> | |
3093 | AAPCS|PE | |
3094 | </para> | |
3095 | </entry> | |
3096 | <entry> | |
3097 | <para> | |
3098 | - | |
3099 | </para> | |
3100 | </entry> | |
3101 | <entry> | |
3102 | <para> | |
3103 | AAPCS|MACH-O | |
3104 | </para> | |
3105 | </entry> | |
3106 | </row> | |
3107 | <row> | |
3108 | <entry> | |
3109 | <para> | |
3110 | arm (aarch64) | |
3111 | </para> | |
3112 | </entry> | |
3113 | <entry> | |
3114 | <para> | |
3115 | AAPCS|ELF | |
3116 | </para> | |
3117 | </entry> | |
3118 | <entry> | |
3119 | <para> | |
3120 | - | |
3121 | </para> | |
3122 | </entry> | |
3123 | <entry> | |
3124 | <para> | |
3125 | - | |
3126 | </para> | |
3127 | </entry> | |
3128 | <entry> | |
3129 | <para> | |
3130 | AAPCS|MACH-O | |
3131 | </para> | |
3132 | </entry> | |
3133 | </row> | |
3134 | <row> | |
3135 | <entry> | |
3136 | <para> | |
3137 | i386 | |
3138 | </para> | |
3139 | </entry> | |
3140 | <entry> | |
3141 | <para> | |
3142 | SYSV|ELF | |
3143 | </para> | |
3144 | </entry> | |
3145 | <entry> | |
3146 | <para> | |
3147 | MS|PE | |
3148 | </para> | |
3149 | </entry> | |
3150 | <entry> | |
3151 | <para> | |
3152 | SYSV|MACH-O | |
3153 | </para> | |
3154 | </entry> | |
3155 | <entry> | |
3156 | <para> | |
3157 | - | |
3158 | </para> | |
3159 | </entry> | |
3160 | </row> | |
3161 | <row> | |
3162 | <entry> | |
3163 | <para> | |
3164 | mips1 | |
3165 | </para> | |
3166 | </entry> | |
3167 | <entry> | |
3168 | <para> | |
3169 | O32|ELF | |
3170 | </para> | |
3171 | </entry> | |
3172 | <entry> | |
3173 | <para> | |
3174 | - | |
3175 | </para> | |
3176 | </entry> | |
3177 | <entry> | |
3178 | <para> | |
3179 | - | |
3180 | </para> | |
3181 | </entry> | |
3182 | <entry> | |
3183 | <para> | |
3184 | - | |
3185 | </para> | |
3186 | </entry> | |
3187 | </row> | |
3188 | <row> | |
3189 | <entry> | |
3190 | <para> | |
3191 | ppc32 | |
3192 | </para> | |
3193 | </entry> | |
3194 | <entry> | |
3195 | <para> | |
3196 | SYSV|ELF,XCOFF | |
3197 | </para> | |
3198 | </entry> | |
3199 | <entry> | |
3200 | <para> | |
3201 | - | |
3202 | </para> | |
3203 | </entry> | |
3204 | <entry> | |
3205 | <para> | |
3206 | SYSV|MACH-O | |
3207 | </para> | |
3208 | </entry> | |
3209 | <entry> | |
3210 | <para> | |
3211 | - | |
3212 | </para> | |
3213 | </entry> | |
3214 | </row> | |
3215 | <row> | |
3216 | <entry> | |
3217 | <para> | |
3218 | ppc64 | |
3219 | </para> | |
3220 | </entry> | |
3221 | <entry> | |
3222 | <para> | |
3223 | SYSV|ELF,XCOFF | |
3224 | </para> | |
3225 | </entry> | |
3226 | <entry> | |
3227 | <para> | |
3228 | - | |
3229 | </para> | |
3230 | </entry> | |
3231 | <entry> | |
3232 | <para> | |
3233 | SYSV|MACH-O | |
3234 | </para> | |
3235 | </entry> | |
3236 | <entry> | |
3237 | <para> | |
3238 | - | |
3239 | </para> | |
3240 | </entry> | |
3241 | </row> | |
3242 | <row> | |
3243 | <entry> | |
3244 | <para> | |
3245 | sparc | |
3246 | </para> | |
3247 | </entry> | |
3248 | <entry> | |
3249 | <para> | |
3250 | - | |
3251 | </para> | |
3252 | </entry> | |
3253 | <entry> | |
3254 | <para> | |
3255 | - | |
3256 | </para> | |
3257 | </entry> | |
3258 | <entry> | |
3259 | <para> | |
3260 | - | |
3261 | </para> | |
3262 | </entry> | |
3263 | <entry> | |
3264 | <para> | |
3265 | - | |
3266 | </para> | |
3267 | </entry> | |
3268 | </row> | |
3269 | <row> | |
3270 | <entry> | |
3271 | <para> | |
3272 | x86_64 | |
3273 | </para> | |
3274 | </entry> | |
3275 | <entry> | |
3276 | <para> | |
3277 | SYSV,X32|ELF | |
3278 | </para> | |
3279 | </entry> | |
3280 | <entry> | |
3281 | <para> | |
3282 | MS|PE | |
3283 | </para> | |
3284 | </entry> | |
3285 | <entry> | |
3286 | <para> | |
3287 | SYSV|MACH-O | |
3288 | </para> | |
3289 | </entry> | |
3290 | <entry> | |
3291 | <para> | |
3292 | - | |
3293 | </para> | |
3294 | </entry> | |
3295 | </row> | |
3296 | </tbody> | |
3297 | </tgroup> | |
3298 | </table> | |
3299 | <section id="context.architectures.crosscompiling"> | |
3300 | <title><link linkend="context.architectures.crosscompiling">Cross compiling</link></title> | |
3301 | <para> | |
3302 | Cross compiling the library requires to specify the build properties <architecture>, | |
3303 | <address-model>, <binary-format> and <abi> at b2 command | |
3304 | line. | |
3305 | </para> | |
3306 | </section> | |
3307 | </section> | |
3308 | <section id="context.rationale"> | |
3309 | <title><link linkend="context.rationale">Rationale</link></title> | |
3310 | <bridgehead renderas="sect3" id="context.rationale.h0"> | |
3311 | <phrase id="context.rationale.no_inline_assembler"/><link linkend="context.rationale.no_inline_assembler">No | |
3312 | inline-assembler</link> | |
3313 | </bridgehead> | |
3314 | <para> | |
3315 | Some newer compiler (for instance MSVC 10 for x86_64 and itanium) do not support | |
3316 | inline assembler. <footnote id="context.rationale.f0"> | |
3317 | <para> | |
3318 | <ulink url="http://msdn.microsoft.com/en-us/library/4ks26t93.aspx">MSDN article | |
3319 | 'Inline Assembler'</ulink> | |
3320 | </para> | |
3321 | </footnote>. Inlined assembler generates code bloating which is not welcome | |
3322 | on embedded systems. | |
3323 | </para> | |
3324 | <bridgehead renderas="sect3" id="context.rationale.h1"> | |
3325 | <phrase id="context.rationale.fcontext_t"/><link linkend="context.rationale.fcontext_t">fcontext_t</link> | |
3326 | </bridgehead> | |
3327 | <para> | |
3328 | <emphasis role="bold">Boost.Context</emphasis> provides the low level API fcontext_t | |
3329 | which is implemented in assembler to provide context swapping operations. fcontext_t | |
3330 | is the part to port to new platforms. | |
3331 | </para> | |
3332 | <note> | |
3333 | <para> | |
3334 | Context switches do not preserve the signal mask on UNIX systems. | |
3335 | </para> | |
3336 | </note> | |
3337 | <para> | |
3338 | <emphasis>fcontext_t</emphasis> is an opaque pointer. | |
3339 | </para> | |
3340 | <section id="context.rationale.other_apis_"> | |
3341 | <title><link linkend="context.rationale.other_apis_">Other APIs </link></title> | |
3342 | <bridgehead renderas="sect4" id="context.rationale.other_apis_.h0"> | |
3343 | <phrase id="context.rationale.other_apis_.setjmp___longjmp__"/><link linkend="context.rationale.other_apis_.setjmp___longjmp__">setjmp()/longjmp()</link> | |
3344 | </bridgehead> | |
3345 | <para> | |
3346 | C99 defines <code><phrase role="identifier">setjmp</phrase><phrase role="special">()</phrase></code>/<code><phrase | |
3347 | role="identifier">longjmp</phrase><phrase role="special">()</phrase></code> | |
3348 | to provide non-local jumps but it does not require that <emphasis>longjmp()</emphasis> | |
3349 | preserves the current stack frame. Therefore, jumping into a function which | |
3350 | was exited via a call to <emphasis>longjmp()</emphasis> is undefined <footnote | |
3351 | id="context.rationale.other_apis_.f0"> | |
3352 | <para> | |
3353 | ISO/IEC 9899:1999, 2005, 7.13.2.1:2 | |
3354 | </para> | |
3355 | </footnote>. | |
3356 | </para> | |
3357 | <bridgehead renderas="sect4" id="context.rationale.other_apis_.h1"> | |
3358 | <phrase id="context.rationale.other_apis_.ucontext_t"/><link linkend="context.rationale.other_apis_.ucontext_t">ucontext_t</link> | |
3359 | </bridgehead> | |
3360 | <para> | |
3361 | Since POSIX.1-2003 <code><phrase role="identifier">ucontext_t</phrase></code> | |
3362 | is deprecated and was removed in POSIX.1-2008! The function signature of | |
3363 | <code><phrase role="identifier">makecontext</phrase><phrase role="special">()</phrase></code> | |
3364 | is: | |
3365 | </para> | |
3366 | <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> | |
3367 | </programlisting> | |
3368 | <para> | |
3369 | The third argument of <code><phrase role="identifier">makecontext</phrase><phrase | |
3370 | role="special">()</phrase></code> specifies the number of integer arguments | |
3371 | that follow which will require function pointer cast if <code><phrase role="identifier">func</phrase></code> | |
3372 | will accept those arguments which is undefined in C99 <footnote id="context.rationale.other_apis_.f1"> | |
3373 | <para> | |
3374 | ISO/IEC 9899:1999, 2005, J.2 | |
3375 | </para> | |
3376 | </footnote>. | |
3377 | </para> | |
3378 | <para> | |
3379 | The arguments in the var-arg list are required to be integers, passing pointers | |
3380 | in var-arg list is not guaranteed to work, especially it will fail for architectures | |
3381 | where pointers are larger than integers. | |
3382 | </para> | |
3383 | <para> | |
3384 | <code><phrase role="identifier">ucontext_t</phrase></code> preserves signal | |
3385 | mask between context switches which involves system calls consuming a lot | |
3386 | of CPU cycles (ucontext_t is slower by perfomance_link[factor 13x] relative | |
3387 | to <code><phrase role="identifier">fcontext_t</phrase></code>). | |
3388 | </para> | |
3389 | <bridgehead renderas="sect4" id="context.rationale.other_apis_.h2"> | |
3390 | <phrase id="context.rationale.other_apis_.windows_fibers"/><link linkend="context.rationale.other_apis_.windows_fibers">Windows | |
3391 | fibers</link> | |
3392 | </bridgehead> | |
3393 | <para> | |
3394 | A drawback of Windows Fiber API is that <code><phrase role="identifier">CreateFiber</phrase><phrase | |
3395 | role="special">()</phrase></code> does not accept a pointer to user allocated | |
3396 | stack space preventing the reuse of stacks for other context instances. Because | |
3397 | the Windows Fiber API requires to call <code><phrase role="identifier">ConvertThreadToFiber</phrase><phrase | |
3398 | role="special">()</phrase></code> if <code><phrase role="identifier">SwitchFiber</phrase><phrase | |
3399 | role="special">()</phrase></code> is called for a thread which has not been | |
3400 | converted to a fiber. For the same reason <code><phrase role="identifier">ConvertFiberToThread</phrase><phrase | |
3401 | role="special">()</phrase></code> must be called after return from <code><phrase | |
3402 | role="identifier">SwitchFiber</phrase><phrase role="special">()</phrase></code> | |
3403 | if the thread was forced to be converted to a fiber before (which is inefficient). | |
3404 | </para> | |
3405 | <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> | |
3406 | <phrase role="special">{</phrase> | |
3407 | <phrase role="identifier">ConvertThreadToFiber</phrase><phrase role="special">(</phrase> <phrase role="number">0</phrase><phrase role="special">);</phrase> | |
3408 | <phrase role="identifier">SwitchToFiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">);</phrase> | |
3409 | <phrase role="identifier">ConvertFiberToThread</phrase><phrase role="special">();</phrase> | |
3410 | <phrase role="special">}</phrase> | |
3411 | </programlisting> | |
3412 | <para> | |
3413 | If the condition <code><phrase role="identifier">_WIN32_WINNT</phrase> <phrase | |
3414 | role="special">>=</phrase> <phrase role="identifier">_WIN32_WINNT_VISTA</phrase></code> | |
3415 | is met function <code><phrase role="identifier">IsThreadAFiber</phrase><phrase | |
3416 | role="special">()</phrase></code> is provided in order to detect if the current | |
3417 | thread was already converted. Unfortunately Windows XP + SP 2/3 defines | |
3418 | <code><phrase role="identifier">_WIN32_WINNT</phrase> <phrase role="special">>=</phrase> | |
3419 | <phrase role="identifier">_WIN32_WINNT_VISTA</phrase></code> without providing | |
3420 | <code><phrase role="identifier">IsThreadAFiber</phrase><phrase role="special">()</phrase></code>. | |
3421 | </para> | |
3422 | </section> | |
3423 | <section id="context.rationale.x86_and_floating_point_env"> | |
3424 | <title><link linkend="context.rationale.x86_and_floating_point_env">x86 and | |
3425 | floating-point env</link></title> | |
3426 | <bridgehead renderas="sect4" id="context.rationale.x86_and_floating_point_env.h0"> | |
3427 | <phrase id="context.rationale.x86_and_floating_point_env.i386"/><link linkend="context.rationale.x86_and_floating_point_env.i386">i386</link> | |
3428 | </bridgehead> | |
3429 | <para> | |
3430 | "The FpCsr and the MxCsr register must be saved and restored before | |
3431 | any call or return by any procedure that needs to modify them ..." | |
3432 | <footnote id="context.rationale.x86_and_floating_point_env.f0"> | |
3433 | <para> | |
3434 | 'Calling Conventions', Agner Fog | |
3435 | </para> | |
3436 | </footnote>. | |
3437 | </para> | |
3438 | <bridgehead renderas="sect4" id="context.rationale.x86_and_floating_point_env.h1"> | |
3439 | <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> | |
3440 | </bridgehead> | |
3441 | <bridgehead renderas="sect4" id="context.rationale.x86_and_floating_point_env.h2"> | |
3442 | <phrase id="context.rationale.x86_and_floating_point_env.windows"/><link | |
3443 | linkend="context.rationale.x86_and_floating_point_env.windows">Windows</link> | |
3444 | </bridgehead> | |
3445 | <para> | |
3446 | MxCsr - "A callee that modifies any of the non-volatile fields within | |
3447 | MxCsr must restore them before returning to its caller. Furthermore, a caller | |
3448 | that has modified any of these fields must restore them to their standard | |
3449 | values before invoking a callee ..." <footnote id="context.rationale.x86_and_floating_point_env.f1"> | |
3450 | <para> | |
3451 | <ulink url="http://http://msdn.microsoft.com/en-us/library/yxty7t75.aspx">MSDN | |
3452 | article 'MxCsr'</ulink> | |
3453 | </para> | |
3454 | </footnote>. | |
3455 | </para> | |
3456 | <para> | |
3457 | FpCsr - "A callee that modifies any of the fields within FpCsr must | |
3458 | restore them before returning to its caller. Furthermore, a caller that has | |
3459 | modified any of these fields must restore them to their standard values before | |
3460 | invoking a callee ..." <footnote id="context.rationale.x86_and_floating_point_env.f2"> | |
3461 | <para> | |
3462 | <ulink url="http://http://msdn.microsoft.com/en-us/library/ms235300.aspx">MSDN | |
3463 | article 'FpCsr'</ulink> | |
3464 | </para> | |
3465 | </footnote>. | |
3466 | </para> | |
3467 | <para> | |
3468 | "The MMX and floating-point stack registers (MM0-MM7/ST0-ST7) are preserved | |
3469 | across context switches. There is no explicit calling convention for these | |
3470 | registers." <footnote id="context.rationale.x86_and_floating_point_env.f3"> | |
3471 | <para> | |
3472 | <ulink url="http://msdn.microsoft.com/en-us/library/a32tsf7t%28VS.80%29.aspx">MSDN | |
3473 | article 'Legacy Floating-Point Support'</ulink> | |
3474 | </para> | |
3475 | </footnote>. | |
3476 | </para> | |
3477 | <para> | |
3478 | "The 64-bit Microsoft compiler does not use ST(0)-ST(7)/MM0-MM7". | |
3479 | <footnote id="context.rationale.x86_and_floating_point_env.f4"> | |
3480 | <para> | |
3481 | 'Calling Conventions', Agner Fog | |
3482 | </para> | |
3483 | </footnote>. | |
3484 | </para> | |
3485 | <para> | |
3486 | "XMM6-XMM15 must be preserved" <footnote id="context.rationale.x86_and_floating_point_env.f5"> | |
3487 | <para> | |
3488 | <ulink url="http://msdn.microsoft.com/en-us/library/9z1stfyw%28v=vs.100%29.aspx">MSDN | |
3489 | article 'Register Usage'</ulink> | |
3490 | </para> | |
3491 | </footnote> | |
3492 | </para> | |
3493 | <bridgehead renderas="sect4" id="context.rationale.x86_and_floating_point_env.h3"> | |
3494 | <phrase id="context.rationale.x86_and_floating_point_env.sysv"/><link linkend="context.rationale.x86_and_floating_point_env.sysv">SysV</link> | |
3495 | </bridgehead> | |
3496 | <para> | |
3497 | "The control bits of the MxCsr register are callee-saved (preserved | |
3498 | across calls), while the status bits are caller-saved (not preserved). The | |
3499 | x87 status word register is caller-saved, whereas the x87 control word (FpCsr) | |
3500 | is callee-saved." <footnote id="context.rationale.x86_and_floating_point_env.f6"> | |
3501 | <para> | |
3502 | SysV ABI AMD64 Architecture Processor Supplement Draft Version 0.99.4, | |
3503 | 3.2.1 | |
3504 | </para> | |
3505 | </footnote>. | |
3506 | </para> | |
3507 | </section> | |
3508 | </section> | |
3509 | <section id="context.reference"> | |
3510 | <title><link linkend="context.reference">Reference</link></title> | |
3511 | <bridgehead renderas="sect3" id="context.reference.h0"> | |
3512 | <phrase id="context.reference.arm"/><link linkend="context.reference.arm">ARM</link> | |
3513 | </bridgehead> | |
3514 | <itemizedlist> | |
3515 | <listitem> | |
3516 | <simpara> | |
3517 | AAPCS ABI: Procedure Call Standard for the ARM Architecture | |
3518 | </simpara> | |
3519 | </listitem> | |
3520 | <listitem> | |
3521 | <simpara> | |
3522 | AAPCS/LINUX: ARM GNU/Linux Application Binary Interface Supplement | |
3523 | </simpara> | |
3524 | </listitem> | |
3525 | </itemizedlist> | |
3526 | <bridgehead renderas="sect3" id="context.reference.h1"> | |
3527 | <phrase id="context.reference.mips"/><link linkend="context.reference.mips">MIPS</link> | |
3528 | </bridgehead> | |
3529 | <itemizedlist> | |
3530 | <listitem> | |
3531 | <simpara> | |
3532 | O32 ABI: SYSTEM V APPLICATION BINARY INTERFACE, MIPS RISC Processor Supplement | |
3533 | </simpara> | |
3534 | </listitem> | |
3535 | </itemizedlist> | |
3536 | <bridgehead renderas="sect3" id="context.reference.h2"> | |
3537 | <phrase id="context.reference.powerpc32"/><link linkend="context.reference.powerpc32">PowerPC32</link> | |
3538 | </bridgehead> | |
3539 | <itemizedlist> | |
3540 | <listitem> | |
3541 | <simpara> | |
3542 | SYSV ABI: SYSTEM V APPLICATION BINARY INTERFACE PowerPC Processor Supplement | |
3543 | </simpara> | |
3544 | </listitem> | |
3545 | </itemizedlist> | |
3546 | <bridgehead renderas="sect3" id="context.reference.h3"> | |
3547 | <phrase id="context.reference.powerpc64"/><link linkend="context.reference.powerpc64">PowerPC64</link> | |
3548 | </bridgehead> | |
3549 | <itemizedlist> | |
3550 | <listitem> | |
3551 | <simpara> | |
3552 | SYSV ABI: PowerPC User Instruction Set Architecture, Book I | |
3553 | </simpara> | |
3554 | </listitem> | |
3555 | </itemizedlist> | |
3556 | <bridgehead renderas="sect3" id="context.reference.h4"> | |
3557 | <phrase id="context.reference.x86_32"/><link linkend="context.reference.x86_32">X86-32</link> | |
3558 | </bridgehead> | |
3559 | <itemizedlist> | |
3560 | <listitem> | |
3561 | <simpara> | |
3562 | SYSV ABI: SYSTEM V APPLICATION BINARY INTERFACE, Intel386TM Architecture | |
3563 | Processor Supplement | |
3564 | </simpara> | |
3565 | </listitem> | |
3566 | <listitem> | |
3567 | <simpara> | |
3568 | MS PE: <ulink url="http://msdn.microsoft.com/en-us/library/k2b2ssfy.aspx">Calling | |
3569 | Conventions</ulink> | |
3570 | </simpara> | |
3571 | </listitem> | |
3572 | </itemizedlist> | |
3573 | <bridgehead renderas="sect3" id="context.reference.h5"> | |
3574 | <phrase id="context.reference.x86_64"/><link linkend="context.reference.x86_64">X86-64</link> | |
3575 | </bridgehead> | |
3576 | <itemizedlist> | |
3577 | <listitem> | |
3578 | <simpara> | |
3579 | SYSV ABI: System V Application Binary Interface, AMD64 Architecture Processor | |
3580 | Supplement | |
3581 | </simpara> | |
3582 | </listitem> | |
3583 | <listitem> | |
3584 | <simpara> | |
3585 | MS PE: <ulink url="http://msdn.microsoft.com/en-us/library/7kcdt6fy%28VS.80%29.aspx">x64 | |
3586 | Software Conventions</ulink> | |
3587 | </simpara> | |
3588 | </listitem> | |
3589 | </itemizedlist> | |
3590 | </section> | |
3591 | <section id="context.acknowledgements"> | |
3592 | <title><link linkend="context.acknowledgements">Acknowledgments</link></title> | |
3593 | <para> | |
3594 | I'd like to thank Adreas Fett, Artyom Beilis, Daniel Larimer, David Deakins, | |
3595 | Evgeny Shapovalov, Fernando Pelliccioni, Giovanni Piero Deretta, Gordon Woodhull, | |
3596 | Helge Bahmann, Holger Grund, Jeffrey Lee Hellrung (Jr.), Keith Jeffery, Martin | |
3597 | Husemann, Phil Endecott, Robert Stewart, Sergey Cheban, Steven Watanabe, Vicente | |
3598 | J. Botet Escriba, Wayne Piekarski. | |
3599 | </para> | |
3600 | </section> | |
3601 | </library> |