Merge branch 'develop'

This commit is contained in:
Oliver Kowalke 2015-06-02 09:49:01 +02:00
commit 47219de46b
6 changed files with 61 additions and 123 deletions

View File

@ -49,5 +49,7 @@ int main(int argc,char* argv[]){
std::copy(begin(words),end(words),begin(writer)); std::copy(begin(words),end(words),begin(writer));
std::cout << "\nDone" << std::endl;
return 0; return 0;
} }

View File

@ -27,7 +27,6 @@ struct pull_coroutine< T >::control_block {
boost::context::execution_context callee; boost::context::execution_context callee;
bool preserve_fpu; bool preserve_fpu;
int state; int state;
std::exception_ptr except;
template< typename StackAllocator, typename Fn > template< typename StackAllocator, typename Fn >
control_block( context::preallocated, StackAllocator, Fn &&, bool); control_block( context::preallocated, StackAllocator, Fn &&, bool);
@ -51,7 +50,6 @@ struct pull_coroutine< T & >::control_block {
boost::context::execution_context callee; boost::context::execution_context callee;
bool preserve_fpu; bool preserve_fpu;
int state; int state;
std::exception_ptr except;
template< typename StackAllocator, typename Fn > template< typename StackAllocator, typename Fn >
control_block( context::preallocated, StackAllocator, Fn &&, bool); control_block( context::preallocated, StackAllocator, Fn &&, bool);
@ -74,7 +72,6 @@ struct pull_coroutine< void >::control_block {
boost::context::execution_context callee; boost::context::execution_context callee;
bool preserve_fpu; bool preserve_fpu;
int state; int state;
std::exception_ptr except;
template< typename StackAllocator, typename Fn > template< typename StackAllocator, typename Fn >
control_block( context::preallocated, StackAllocator, Fn &&, bool); control_block( context::preallocated, StackAllocator, Fn &&, bool);

View File

@ -36,29 +36,25 @@ pull_coroutine< T >::control_block::control_block( context::preallocated palloc,
caller( boost::context::execution_context::current() ), caller( boost::context::execution_context::current() ),
callee( palloc, salloc, callee( palloc, salloc,
[=,fn=std::forward< Fn >( fn_)] () mutable { [=,fn=std::forward< Fn >( fn_)] () mutable {
try {
// create synthesized push_coroutine< T > // create synthesized push_coroutine< T >
typename push_coroutine< T >::control_block synthesized_cb( this); typename push_coroutine< T >::control_block synthesized_cb( this);
push_coroutine< T > synthesized( & synthesized_cb); push_coroutine< T > synthesized( & synthesized_cb);
other = & synthesized_cb; other = & synthesized_cb;
try {
// call coroutine-fn with synthesized push_coroutine as argument // call coroutine-fn with synthesized push_coroutine as argument
fn( synthesized); fn( synthesized);
} catch ( forced_unwind const&) { } catch ( forced_unwind const&) {
// do nothing for unwinding exception // do nothing for unwinding exception
} catch (...) {
// store other exceptions in exception-pointer
except = std::current_exception();
} }
// set termination flags // set termination flags
state |= static_cast< int >( state_t::complete); state |= static_cast< int >( state_t::complete);
// jump back to caller // jump back to caller
caller.resume( preserve_fpu); caller( preserve_fpu);
BOOST_ASSERT_MSG( false, "pull_coroutine is complete"); BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
}), }),
preserve_fpu( preserve_fpu_), preserve_fpu( preserve_fpu_),
state( static_cast< int >( state_t::unwind) ), state( static_cast< int >( state_t::unwind) ) {
except() { callee( preserve_fpu);
callee.resume( preserve_fpu);
} }
template< typename T > template< typename T >
@ -67,8 +63,7 @@ pull_coroutine< T >::control_block::control_block( typename push_coroutine< T >:
caller( other->callee), caller( other->callee),
callee( other->caller), callee( other->caller),
preserve_fpu( other->preserve_fpu), preserve_fpu( other->preserve_fpu),
state( 0), state( 0) {
except() {
} }
template< typename T > template< typename T >
@ -77,17 +72,14 @@ pull_coroutine< T >::control_block::~control_block() {
0 != ( state & static_cast< int >( state_t::unwind) ) ) { 0 != ( state & static_cast< int >( state_t::unwind) ) ) {
// set early-exit flag // set early-exit flag
state |= static_cast< int >( state_t::early_exit); state |= static_cast< int >( state_t::early_exit);
callee.resume( preserve_fpu); callee( preserve_fpu);
} }
} }
template< typename T > template< typename T >
void void
pull_coroutine< T >::control_block::resume() { pull_coroutine< T >::control_block::resume() {
callee.resume( preserve_fpu); callee( preserve_fpu);
if ( except) {
std::rethrow_exception( except);
}
// test early-exit-flag // test early-exit-flag
if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) { if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) {
throw forced_unwind(); throw forced_unwind();
@ -111,29 +103,25 @@ pull_coroutine< T & >::control_block::control_block( context::preallocated pallo
caller( boost::context::execution_context::current() ), caller( boost::context::execution_context::current() ),
callee( palloc, salloc, callee( palloc, salloc,
[=,fn=std::forward< Fn >( fn_)] () mutable { [=,fn=std::forward< Fn >( fn_)] () mutable {
try {
// create synthesized push_coroutine< T > // create synthesized push_coroutine< T >
typename push_coroutine< T & >::control_block synthesized_cb( this); typename push_coroutine< T & >::control_block synthesized_cb( this);
push_coroutine< T & > synthesized( & synthesized_cb); push_coroutine< T & > synthesized( & synthesized_cb);
other = & synthesized_cb; other = & synthesized_cb;
try {
// call coroutine-fn with synthesized push_coroutine as argument // call coroutine-fn with synthesized push_coroutine as argument
fn( synthesized); fn( synthesized);
} catch ( forced_unwind const&) { } catch ( forced_unwind const&) {
// do nothing for unwinding exception // do nothing for unwinding exception
} catch (...) {
// store other exceptions in exception-pointer
except = std::current_exception();
} }
// set termination flags // set termination flags
state |= static_cast< int >( state_t::complete); state |= static_cast< int >( state_t::complete);
// jump back to caller // jump back to caller
caller.resume( preserve_fpu); caller( preserve_fpu);
BOOST_ASSERT_MSG( false, "pull_coroutine is complete"); BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
}), }),
preserve_fpu( preserve_fpu_), preserve_fpu( preserve_fpu_),
state( static_cast< int >( state_t::unwind) ), state( static_cast< int >( state_t::unwind) ) {
except() { callee( preserve_fpu);
callee.resume( preserve_fpu);
} }
template< typename T > template< typename T >
@ -142,8 +130,7 @@ pull_coroutine< T & >::control_block::control_block( typename push_coroutine< T
caller( other->callee), caller( other->callee),
callee( other->caller), callee( other->caller),
preserve_fpu( other->preserve_fpu), preserve_fpu( other->preserve_fpu),
state( 0), state( 0) {
except() {
} }
template< typename T > template< typename T >
@ -152,17 +139,14 @@ pull_coroutine< T & >::control_block::~control_block() {
0 != ( state & static_cast< int >( state_t::unwind) ) ) { 0 != ( state & static_cast< int >( state_t::unwind) ) ) {
// set early-exit flag // set early-exit flag
state |= static_cast< int >( state_t::early_exit); state |= static_cast< int >( state_t::early_exit);
callee.resume( preserve_fpu); callee( preserve_fpu);
} }
} }
template< typename T > template< typename T >
void void
pull_coroutine< T & >::control_block::resume() { pull_coroutine< T & >::control_block::resume() {
callee.resume( preserve_fpu); callee( preserve_fpu);
if ( except) {
std::rethrow_exception( except);
}
// test early-exit-flag // test early-exit-flag
if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) { if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) {
throw forced_unwind(); throw forced_unwind();
@ -185,29 +169,25 @@ pull_coroutine< void >::control_block::control_block( context::preallocated pall
caller( boost::context::execution_context::current() ), caller( boost::context::execution_context::current() ),
callee( palloc, salloc, callee( palloc, salloc,
[=,fn=std::forward< Fn >( fn_)] () mutable { [=,fn=std::forward< Fn >( fn_)] () mutable {
try {
// create synthesized push_coroutine< T > // create synthesized push_coroutine< T >
typename push_coroutine< void >::control_block synthesized_cb( this); typename push_coroutine< void >::control_block synthesized_cb( this);
push_coroutine< void > synthesized( & synthesized_cb); push_coroutine< void > synthesized( & synthesized_cb);
other = & synthesized_cb; other = & synthesized_cb;
try {
// call coroutine-fn with synthesized push_coroutine as argument // call coroutine-fn with synthesized push_coroutine as argument
fn( synthesized); fn( synthesized);
} catch ( forced_unwind const&) { } catch ( forced_unwind const&) {
// do nothing for unwinding exception // do nothing for unwinding exception
} catch (...) {
// store other exceptions in exception-pointer
except = std::current_exception();
} }
// set termination flags // set termination flags
state |= static_cast< int >( state_t::complete); state |= static_cast< int >( state_t::complete);
// jump back to caller // jump back to caller
caller.resume( preserve_fpu); caller( preserve_fpu);
BOOST_ASSERT_MSG( false, "pull_coroutine is complete"); BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
}), }),
preserve_fpu( preserve_fpu_), preserve_fpu( preserve_fpu_),
state( static_cast< int >( state_t::unwind) ), state( static_cast< int >( state_t::unwind) ) {
except() { callee( preserve_fpu);
callee.resume( preserve_fpu);
} }
inline inline
@ -216,8 +196,7 @@ pull_coroutine< void >::control_block::control_block( push_coroutine< void >::co
caller( other->callee), caller( other->callee),
callee( other->caller), callee( other->caller),
preserve_fpu( other->preserve_fpu), preserve_fpu( other->preserve_fpu),
state( 0), state( 0) {
except() {
} }
inline inline
@ -226,17 +205,14 @@ pull_coroutine< void >::control_block::~control_block() {
0 != ( state & static_cast< int >( state_t::unwind) ) ) { 0 != ( state & static_cast< int >( state_t::unwind) ) ) {
// set early-exit flag // set early-exit flag
state |= static_cast< int >( state_t::early_exit); state |= static_cast< int >( state_t::early_exit);
callee.resume( preserve_fpu); callee( preserve_fpu);
} }
} }
inline inline
void void
pull_coroutine< void >::control_block::resume() { pull_coroutine< void >::control_block::resume() {
callee.resume( preserve_fpu); callee( preserve_fpu);
if ( except) {
std::rethrow_exception( except);
}
// test early-exit-flag // test early-exit-flag
if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) { if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) {
throw forced_unwind(); throw forced_unwind();

View File

@ -27,7 +27,6 @@ struct push_coroutine< T >::control_block {
boost::context::execution_context callee; boost::context::execution_context callee;
bool preserve_fpu; bool preserve_fpu;
int state; int state;
std::exception_ptr except;
T * t; T * t;
template< typename StackAllocator, typename Fn > template< typename StackAllocator, typename Fn >
@ -54,7 +53,6 @@ struct push_coroutine< T & >::control_block {
boost::context::execution_context callee; boost::context::execution_context callee;
bool preserve_fpu; bool preserve_fpu;
int state; int state;
std::exception_ptr except;
T * t; T * t;
template< typename StackAllocator, typename Fn > template< typename StackAllocator, typename Fn >
@ -78,7 +76,6 @@ struct push_coroutine< void >::control_block {
boost::context::execution_context callee; boost::context::execution_context callee;
bool preserve_fpu; bool preserve_fpu;
int state; int state;
std::exception_ptr except;
template< typename StackAllocator, typename Fn > template< typename StackAllocator, typename Fn >
control_block( context::preallocated, StackAllocator, Fn &&, bool); control_block( context::preallocated, StackAllocator, Fn &&, bool);

View File

@ -37,28 +37,23 @@ push_coroutine< T >::control_block::control_block( context::preallocated palloc,
caller( boost::context::execution_context::current() ), caller( boost::context::execution_context::current() ),
callee( palloc, salloc, callee( palloc, salloc,
[=,fn=std::forward< Fn >( fn_)] () mutable { [=,fn=std::forward< Fn >( fn_)] () mutable {
try {
// create synthesized pull_coroutine< T > // create synthesized pull_coroutine< T >
typename pull_coroutine< T >::control_block synthesized_cb( this); typename pull_coroutine< T >::control_block synthesized_cb( this);
pull_coroutine< T > synthesized( & synthesized_cb); pull_coroutine< T > synthesized( & synthesized_cb);
other = & synthesized_cb; other = & synthesized_cb;
try {
// call coroutine-fn with synthesized pull_coroutine as argument // call coroutine-fn with synthesized pull_coroutine as argument
fn( synthesized); fn( synthesized);
} catch ( forced_unwind const&) { } catch ( forced_unwind const&) {
// do nothing for unwinding exception // do nothing for unwinding exception
} catch (...) {
// store other exceptions in exception-pointer
except = std::current_exception();
} }
// set termination flags // set termination flags
state |= static_cast< int >( state_t::complete); state |= static_cast< int >( state_t::complete);
// jump back to caller caller( preserve_fpu);
caller.resume( preserve_fpu_);
BOOST_ASSERT_MSG( false, "push_coroutine is complete"); BOOST_ASSERT_MSG( false, "push_coroutine is complete");
}), }),
preserve_fpu( preserve_fpu_), preserve_fpu( preserve_fpu_),
state( static_cast< int >( state_t::unwind) ), state( static_cast< int >( state_t::unwind) ),
except(),
t( nullptr) { t( nullptr) {
} }
@ -69,7 +64,6 @@ push_coroutine< T >::control_block::control_block( typename pull_coroutine< T >:
callee( other->caller), callee( other->caller),
preserve_fpu( other->preserve_fpu), preserve_fpu( other->preserve_fpu),
state( 0), state( 0),
except(),
t( nullptr) { t( nullptr) {
} }
@ -79,7 +73,7 @@ push_coroutine< T >::control_block::~control_block() {
0 != ( state & static_cast< int >( state_t::unwind) ) ) { 0 != ( state & static_cast< int >( state_t::unwind) ) ) {
// set early-exit flag // set early-exit flag
state |= static_cast< int >( state_t::early_exit); state |= static_cast< int >( state_t::early_exit);
callee.resume( preserve_fpu); callee( preserve_fpu);
} }
} }
@ -90,11 +84,8 @@ push_coroutine< T >::control_block::resume( T const& t_) {
// pass an pointer (address of tmp) to other context // pass an pointer (address of tmp) to other context
T tmp( t_); T tmp( t_);
t = & tmp; t = & tmp;
callee.resume( preserve_fpu); callee( preserve_fpu);
t = nullptr; t = nullptr;
if ( except) {
std::rethrow_exception( except);
}
// test early-exit-flag // test early-exit-flag
if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) { if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) {
throw forced_unwind(); throw forced_unwind();
@ -108,11 +99,8 @@ push_coroutine< T >::control_block::resume( T && t_) {
// pass an pointer (address of tmp) to other context // pass an pointer (address of tmp) to other context
T tmp( std::move( t_) ); T tmp( std::move( t_) );
t = & tmp; t = & tmp;
callee.resume( preserve_fpu); callee( preserve_fpu);
t = nullptr; t = nullptr;
if ( except) {
std::rethrow_exception( except);
}
// test early-exit-flag // test early-exit-flag
if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) { if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) {
throw forced_unwind(); throw forced_unwind();
@ -136,28 +124,23 @@ push_coroutine< T & >::control_block::control_block( context::preallocated pallo
caller( boost::context::execution_context::current() ), caller( boost::context::execution_context::current() ),
callee( palloc, salloc, callee( palloc, salloc,
[=,fn=std::forward< Fn >( fn_)] () mutable { [=,fn=std::forward< Fn >( fn_)] () mutable {
try {
// create synthesized pull_coroutine< T > // create synthesized pull_coroutine< T >
typename pull_coroutine< T & >::control_block synthesized_cb( this); typename pull_coroutine< T & >::control_block synthesized_cb( this);
pull_coroutine< T & > synthesized( & synthesized_cb); pull_coroutine< T & > synthesized( & synthesized_cb);
other = & synthesized_cb; other = & synthesized_cb;
try {
// call coroutine-fn with synthesized pull_coroutine as argument // call coroutine-fn with synthesized pull_coroutine as argument
fn( synthesized); fn( synthesized);
} catch ( forced_unwind const&) { } catch ( forced_unwind const&) {
// do nothing for unwinding exception // do nothing for unwinding exception
} catch (...) {
// store other exceptions in exception-pointer
except = std::current_exception();
} }
// set termination flags // set termination flags
state |= static_cast< int >( state_t::complete); state |= static_cast< int >( state_t::complete);
// jump back to caller caller( preserve_fpu);
caller.resume( preserve_fpu_);
BOOST_ASSERT_MSG( false, "push_coroutine is complete"); BOOST_ASSERT_MSG( false, "push_coroutine is complete");
}), }),
preserve_fpu( preserve_fpu_), preserve_fpu( preserve_fpu_),
state( static_cast< int >( state_t::unwind) ), state( static_cast< int >( state_t::unwind) ),
except(),
t( nullptr) { t( nullptr) {
} }
@ -168,7 +151,6 @@ push_coroutine< T & >::control_block::control_block( typename pull_coroutine< T
callee( other->caller), callee( other->caller),
preserve_fpu( other->preserve_fpu), preserve_fpu( other->preserve_fpu),
state( 0), state( 0),
except(),
t( nullptr) { t( nullptr) {
} }
@ -178,7 +160,7 @@ push_coroutine< T & >::control_block::~control_block() {
0 != ( state & static_cast< int >( state_t::unwind) ) ) { 0 != ( state & static_cast< int >( state_t::unwind) ) ) {
// set early-exit flag // set early-exit flag
state |= static_cast< int >( state_t::early_exit); state |= static_cast< int >( state_t::early_exit);
callee.resume( preserve_fpu); callee( preserve_fpu);
} }
} }
@ -186,11 +168,8 @@ template< typename T >
void void
push_coroutine< T & >::control_block::resume( T & t_) { push_coroutine< T & >::control_block::resume( T & t_) {
t = & t_; t = & t_;
callee.resume( preserve_fpu); callee( preserve_fpu);
t = nullptr; t = nullptr;
if ( except) {
std::rethrow_exception( except);
}
// test early-exit-flag // test early-exit-flag
if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) { if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) {
throw forced_unwind(); throw forced_unwind();
@ -212,28 +191,23 @@ push_coroutine< void >::control_block::control_block( context::preallocated pall
caller( boost::context::execution_context::current() ), caller( boost::context::execution_context::current() ),
callee( palloc, salloc, callee( palloc, salloc,
[=,fn=std::forward< Fn >( fn_)] () mutable { [=,fn=std::forward< Fn >( fn_)] () mutable {
try {
// create synthesized pull_coroutine< T > // create synthesized pull_coroutine< T >
typename pull_coroutine< void >::control_block synthesized_cb( this); typename pull_coroutine< void >::control_block synthesized_cb( this);
pull_coroutine< void > synthesized( & synthesized_cb); pull_coroutine< void > synthesized( & synthesized_cb);
other = & synthesized_cb; other = & synthesized_cb;
try {
// call coroutine-fn with synthesized pull_coroutine as argument // call coroutine-fn with synthesized pull_coroutine as argument
fn( synthesized); fn( synthesized);
} catch ( forced_unwind const&) { } catch ( forced_unwind const&) {
// do nothing for unwinding exception // do nothing for unwinding exception
} catch (...) {
// store other exceptions in exception-pointer
except = std::current_exception();
} }
// set termination flags // set termination flags
state |= static_cast< int >( state_t::complete); state |= static_cast< int >( state_t::complete);
// jump back to caller caller( preserve_fpu);
caller.resume( preserve_fpu_);
BOOST_ASSERT_MSG( false, "push_coroutine is complete"); BOOST_ASSERT_MSG( false, "push_coroutine is complete");
}), }),
preserve_fpu( preserve_fpu_), preserve_fpu( preserve_fpu_),
state( static_cast< int >( state_t::unwind) ), state( static_cast< int >( state_t::unwind) ) {
except() {
} }
inline inline
@ -242,8 +216,7 @@ push_coroutine< void >::control_block::control_block( pull_coroutine< void >::co
caller( other->callee), caller( other->callee),
callee( other->caller), callee( other->caller),
preserve_fpu( other->preserve_fpu), preserve_fpu( other->preserve_fpu),
state( 0), state( 0) {
except() {
} }
inline inline
@ -252,17 +225,14 @@ push_coroutine< void >::control_block::~control_block() {
0 != ( state & static_cast< int >( state_t::unwind) ) ) { 0 != ( state & static_cast< int >( state_t::unwind) ) ) {
// set early-exit flag // set early-exit flag
state |= static_cast< int >( state_t::early_exit); state |= static_cast< int >( state_t::early_exit);
callee.resume( preserve_fpu); callee( preserve_fpu);
} }
} }
inline inline
void void
push_coroutine< void >::control_block::resume() { push_coroutine< void >::control_block::resume() {
callee.resume( preserve_fpu); callee( preserve_fpu);
if ( except) {
std::rethrow_exception( except);
}
// test early-exit-flag // test early-exit-flag
if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) { if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) {
throw forced_unwind(); throw forced_unwind();

View File

@ -461,8 +461,8 @@ void test_unwind()
void test_exceptions() void test_exceptions()
{ {
bool thrown = false; std::string msg("abc"), value;
std::runtime_error ex("abc"); std::runtime_error ex( msg);
try try
{ {
coro::coroutine< void >::push_type coro( coro::coroutine< void >::push_type coro(
@ -472,13 +472,9 @@ void test_exceptions()
BOOST_CHECK( ! coro); BOOST_CHECK( ! coro);
BOOST_CHECK( false); BOOST_CHECK( false);
} }
catch ( std::runtime_error const&) catch ( std::runtime_error const& ex)
{ thrown = true; } { value = ex.what(); }
catch ( std::exception const&) BOOST_CHECK_EQUAL( value, msg);
{}
catch (...)
{}
BOOST_CHECK( thrown);
} }
void test_input_iterator() void test_input_iterator()