2
0
mirror of https://github.com/boostorg/context.git synced 2026-02-02 20:52:18 +00:00
Files
context/doc/execution_context.qbk
Oliver Kowalke f285d64a3f docu update
2014-11-24 18:07:24 +01:00

141 lines
4.5 KiB
Plaintext

[/
Copyright Oliver Kowalke 2014.
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt
]
[section:econtext Class execution_context]
[important __econtext__ is supported only by C++11.]
Class __econtext__ encapsulates __fcontext__ and related functions (
__jump_fcontext__ and __make_fcontext__) as well as stack management.
__econtext__ permits access to the current, active context via
`execution_context::current()`.
/*
* grammar:
* P ---> E '\0'
* E ---> T {('+'|'-') T}
* T ---> S {('*'|'/') S}
* S ---> digit | '(' E ')'
*/
class Parser{
// implementation omitted; see examples directory
};
int main() {
std::istringstream is("1+1");
bool done=false;
char c;
// create handle to main execution context
boost::context::execution_context main_ctx(
boost::context::execution_context::current() );
// executes parser in new execution context
boost::context::execution_context parser_ctx(
boost::context::fixedsize(),
[&is,&main_ctx,&done,&c](){
// create parser with callback function
// jumping back to main context
Parser p(is,
[&main_ctx,&c](char ch){
c=ch;
// resume main execution context
main_ctx.jump_to();
});
// start recursive parsing
p.run();
done=true;
});
// user-code pulls parsed data from parser
// inverted control flow
while(!done){
// resume parser execution context
parser_ctx.jump_to();
printf("Parsed: %c\n",c);
}
}
output:
Parsed: 1
Parsed: +
Parsed: 1
In this example a recursive descent parser uses a callback to emit a newly passed
symbol. Using __econtext__ the control flow can be inverted, e.g. the user-code
pulls parsed symbols from the parser - instead to get pushed from the parser
(via callback).
The interface of __econtext__ does not transfer data. This is not required
because usually sharing data's address (pointer/reference) sufficient.
If the code executed by __econtext__ emits an exception, `std::terminate()` will
be called.
[important Do not jump from inside a catch block and than re-throw exceptions in
another execution context.]
Sometimes it is necessary to unwind the stack of an unfinished context to
destroy local stack variables so they can release allocated resources (RAII
pattern). The user is responsible for this task.
[heading Class `execution_context`]
class execution_context {
public:
static execution_context current() noexcept;
template< typename StackAlloc, typename Fn >
execution_context( StackAlloc salloc, Fn && fn);
void jump_to() noexcept;
explicit operator bool() const noexcept;
bool operator!() const noexcept;
};
[heading `static execution_context current()`]
[variablelist
[[Returns:] [Returns an instance of excution_context pointing to the active
execution context.]]
[[Throws:] [Nothing.]]
]
[heading `template< typename StackAlloc, typname Fn > execution_context( StackAlloc salloc, Fn && fn)`]
[variablelist
[[Effects:] [Creates a new execution context and prepares the context to execute
`fn`.]]
]
[heading `void jump_to()`]
[variablelist
[[Effects:] [Stores internally the current context data (stack pointer,
instruction pointer, and CPU registers) to the current active context and
restores the context data from `*this`, which implies jumping to `*this`'s
execution context.]]
[[Throws:] [Nothing.]]
]
[heading `explicit operator bool() const`]
[variablelist
[[Returns:] [If `*this` refers to an invalid context or the context-function
has returned (completed), the function returns `false`. Otherwise `true`.]]
[[Throws:] [Nothing.]]
]
[heading `bool operator!() const`]
[variablelist
[[Returns:] [If `*this` refers to an invalid context or the context-function
has returned (completed), the function returns `true`. Otherwise `false`.]]
[[Throws:] [Nothing.]]
]
[endsect]