From e5120a4b710608173a066bfe5bf848be059489ef Mon Sep 17 00:00:00 2001 From: Oliver Kowalke Date: Wed, 30 Oct 2013 08:23:09 +0000 Subject: [PATCH] coroutine: remove deprecated interface [SVN r86521] --- example/cpp03/Jamfile.v2 | 4 + example/cpp03/echo.cpp | 37 - example/cpp03/exception.cpp | 52 + example/cpp03/fibonacci.cpp | 33 - example/cpp03/parallel.cpp | 42 - example/cpp03/power.cpp | 39 - example/cpp03/segmented_stack.cpp | 18 - example/cpp03/tree.h | 30 - example/cpp03/unwind.cpp | 37 - example/cpp11/await_emu.cpp | 6 +- example/cpp11/fibonacci.cpp | 26 - include/boost/coroutine/all.hpp | 1 + include/boost/coroutine/checkpoint.hpp | 34 - include/boost/coroutine/coroutine.hpp | 2991 +++++++++++++++- include/boost/coroutine/detail/config.hpp | 16 - .../{v2 => }/detail/pull_coroutine_base.hpp | 6 +- .../{v2 => }/detail/pull_coroutine_caller.hpp | 8 +- .../{v2 => }/detail/pull_coroutine_object.hpp | 8 +- .../{v2 => }/detail/push_coroutine_base.hpp | 6 +- .../{v2 => }/detail/push_coroutine_caller.hpp | 8 +- .../{v2 => }/detail/push_coroutine_object.hpp | 8 +- include/boost/coroutine/v1/coroutine.hpp | 1430 -------- include/boost/coroutine/v1/detail/arg.hpp | 62 - .../coroutine/v1/detail/coroutine_base.hpp | 125 - .../v1/detail/coroutine_base_resume.hpp | 237 -- .../coroutine/v1/detail/coroutine_caller.hpp | 57 - .../coroutine/v1/detail/coroutine_get.hpp | 54 - .../coroutine/v1/detail/coroutine_object.hpp | 74 - .../v1/detail/coroutine_object_result_0.ipp | 363 -- .../v1/detail/coroutine_object_result_1.ipp | 557 --- .../detail/coroutine_object_result_arity.ipp | 559 --- .../v1/detail/coroutine_object_void_0.ipp | 357 -- .../v1/detail/coroutine_object_void_1.ipp | 550 --- .../v1/detail/coroutine_object_void_arity.ipp | 551 --- .../coroutine/v1/detail/coroutine_op.hpp | 326 -- include/boost/coroutine/v2/coroutine.hpp | 3001 ----------------- performance/performance.cpp | 59 - test/test_coroutine.cpp | 516 --- 38 files changed, 3068 insertions(+), 9220 deletions(-) create mode 100644 example/cpp03/exception.cpp delete mode 100644 include/boost/coroutine/checkpoint.hpp rename include/boost/coroutine/{v2 => }/detail/pull_coroutine_base.hpp (97%) rename include/boost/coroutine/{v2 => }/detail/pull_coroutine_caller.hpp (91%) rename include/boost/coroutine/{v2 => }/detail/pull_coroutine_object.hpp (99%) rename include/boost/coroutine/{v2 => }/detail/push_coroutine_base.hpp (98%) rename include/boost/coroutine/{v2 => }/detail/push_coroutine_caller.hpp (83%) rename include/boost/coroutine/{v2 => }/detail/push_coroutine_object.hpp (99%) delete mode 100644 include/boost/coroutine/v1/coroutine.hpp delete mode 100644 include/boost/coroutine/v1/detail/arg.hpp delete mode 100644 include/boost/coroutine/v1/detail/coroutine_base.hpp delete mode 100644 include/boost/coroutine/v1/detail/coroutine_base_resume.hpp delete mode 100644 include/boost/coroutine/v1/detail/coroutine_caller.hpp delete mode 100644 include/boost/coroutine/v1/detail/coroutine_get.hpp delete mode 100644 include/boost/coroutine/v1/detail/coroutine_object.hpp delete mode 100644 include/boost/coroutine/v1/detail/coroutine_object_result_0.ipp delete mode 100644 include/boost/coroutine/v1/detail/coroutine_object_result_1.ipp delete mode 100644 include/boost/coroutine/v1/detail/coroutine_object_result_arity.ipp delete mode 100644 include/boost/coroutine/v1/detail/coroutine_object_void_0.ipp delete mode 100644 include/boost/coroutine/v1/detail/coroutine_object_void_1.ipp delete mode 100644 include/boost/coroutine/v1/detail/coroutine_object_void_arity.ipp delete mode 100644 include/boost/coroutine/v1/detail/coroutine_op.hpp delete mode 100644 include/boost/coroutine/v2/coroutine.hpp diff --git a/example/cpp03/Jamfile.v2 b/example/cpp03/Jamfile.v2 index 391f57d..519306b 100644 --- a/example/cpp03/Jamfile.v2 +++ b/example/cpp03/Jamfile.v2 @@ -75,3 +75,7 @@ exe layout exe chaining : chaining.cpp ; + +exe exception + : exception.cpp + ; diff --git a/example/cpp03/echo.cpp b/example/cpp03/echo.cpp index 1219707..dbdb48e 100644 --- a/example/cpp03/echo.cpp +++ b/example/cpp03/echo.cpp @@ -10,7 +10,6 @@ #include #include -#ifdef BOOST_COROUTINES_UNIDIRECT typedef boost::coroutines::coroutine< void >::pull_type pull_coro_t; typedef boost::coroutines::coroutine< void >::push_type push_coro_t; @@ -46,39 +45,3 @@ int main( int argc, char * argv[]) return EXIT_SUCCESS; } -#else -typedef boost::coroutines::coroutine< void() > coro_t; - -void echo( coro_t & ca, int i) -{ - std::cout << i; - ca(); -} - -void runit( coro_t & ca) -{ - std::cout << "started! "; - for ( int i = 0; i < 10; ++i) - { - coro_t c( boost::bind( echo, _1, i) ); - while ( c) - c(); - ca(); - } -} - -int main( int argc, char * argv[]) -{ - { - coro_t c( runit); - while ( c) { - std::cout << "-"; - c(); - } - } - - std::cout << "\nDone" << std::endl; - - return EXIT_SUCCESS; -} -#endif diff --git a/example/cpp03/exception.cpp b/example/cpp03/exception.cpp new file mode 100644 index 0000000..8782dee --- /dev/null +++ b/example/cpp03/exception.cpp @@ -0,0 +1,52 @@ + +// Copyright Oliver Kowalke 2009. +// 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) + +#include +#include +#include +#include + +#include +#include +#include + +typedef boost::coroutines::coroutine< int >::pull_type pull_coro_t; +typedef boost::coroutines::coroutine< int >::push_type push_coro_t; + +struct my_exception : public std::runtime_error +{ + my_exception( std::string const& str) : + std::runtime_error( str) + {} +}; + +void echo( push_coro_t & sink, int j) +{ + for ( int i = 0; i < j; ++i) + { + if ( i == 5) boost::throw_exception( my_exception("abc") ); + sink( i); + } +} + +int main( int argc, char * argv[]) +{ + pull_coro_t source( boost::bind( echo, _1, 10) ); + try + { + while ( source) + { + std::cout << source.get() << std::endl; + source(); + } + } + catch ( my_exception const& ex) + { std::cout << "exception: " << ex.what() << std::endl; } + + std::cout << "\nDone" << std::endl; + + return EXIT_SUCCESS; +} diff --git a/example/cpp03/fibonacci.cpp b/example/cpp03/fibonacci.cpp index 5f6dd4f..b497021 100644 --- a/example/cpp03/fibonacci.cpp +++ b/example/cpp03/fibonacci.cpp @@ -10,7 +10,6 @@ #include #include -#ifdef BOOST_COROUTINES_UNIDIRECT void fibonacci( boost::coroutines::coroutine< int >::push_type & sink) { int first = 1, second = 1; @@ -41,35 +40,3 @@ int main() return EXIT_SUCCESS; } -#else -void fibonacci( boost::coroutines::coroutine< void( int) > & c) -{ - int first = 1, second = 1; - c( first); - c( second); - while ( true) - { - int third = first + second; - first = second; - second = third; - c( third); - } -} - -int main() -{ - boost::coroutines::coroutine< int() > c( fibonacci); - boost::range_iterator< - boost::coroutines::coroutine< int() > - >::type it( boost::begin( c) ); - for ( int i = 0; i < 10; ++i) - { - std::cout << * it << " "; - ++it; - } - - std::cout << "\nDone" << std::endl; - - return EXIT_SUCCESS; -} -#endif diff --git a/example/cpp03/parallel.cpp b/example/cpp03/parallel.cpp index 29098e2..294cfeb 100644 --- a/example/cpp03/parallel.cpp +++ b/example/cpp03/parallel.cpp @@ -10,7 +10,6 @@ #include #include -#ifdef BOOST_COROUTINES_UNIDIRECT void first( boost::coroutines::coroutine< void >::push_type & sink) { std::cout << "started first! "; @@ -48,44 +47,3 @@ int main( int argc, char * argv[]) return EXIT_SUCCESS; } -#else -typedef boost::coroutines::coroutine< void() > coroutine_t; - -void first( coroutine_t::caller_type & self) -{ - std::cout << "started first! "; - for ( int i = 0; i < 10; ++i) - { - self(); - std::cout << "a" << i; - } -} - -void second( coroutine_t::caller_type & self) -{ - std::cout << "started second! "; - for ( int i = 0; i < 10; ++i) - { - self(); - std::cout << "b" << i; - } -} - -int main( int argc, char * argv[]) -{ - { - coroutine_t c1( boost::bind( first, _1) ); - coroutine_t c2( boost::bind( second, _1) ); - while ( c1 && c2) { - c1(); - std::cout << " "; - c2(); - std::cout << " "; - } - } - - std::cout << "\nDone" << std::endl; - - return EXIT_SUCCESS; -} -#endif diff --git a/example/cpp03/power.cpp b/example/cpp03/power.cpp index 3a43b6a..5a77b9a 100644 --- a/example/cpp03/power.cpp +++ b/example/cpp03/power.cpp @@ -12,7 +12,6 @@ #include #include -#ifdef BOOST_COROUTINES_UNIDIRECT void power( boost::coroutines::coroutine< int >::push_type & sink, int number, int exponent) { int counter = 0; @@ -46,41 +45,3 @@ int main() return EXIT_SUCCESS; } -#else -typedef boost::coroutines::coroutine< int() > coro1_t; -typedef boost::coroutines::coroutine< void( int) > coro2_t; -typedef boost::range_iterator< coro1_t >::type iterator_t; - -void power( coro2_t & c, int number, int exponent) -{ - int counter = 0; - int result = 1; - while ( counter++ < exponent) - { - result = result * number; - c( result); - } -} - -int main() -{ - { - std::cout << "using range functions" << std::endl; - coro1_t c( boost::bind( power, _1, 2, 8) ); - iterator_t e( boost::end( c) ); - for ( iterator_t i( boost::begin( c) ); i != e; ++i) - std::cout << * i << " "; - } - - { - std::cout << "\nusing BOOST_FOREACH" << std::endl; - coro1_t c( boost::bind( power, _1, 2, 8) ); - BOOST_FOREACH( int i, c) - { std::cout << i << " "; } - } - - std::cout << "\nDone" << std::endl; - - return EXIT_SUCCESS; -} -#endif diff --git a/example/cpp03/segmented_stack.cpp b/example/cpp03/segmented_stack.cpp index 96b6625..ba4a8bd 100644 --- a/example/cpp03/segmented_stack.cpp +++ b/example/cpp03/segmented_stack.cpp @@ -35,7 +35,6 @@ void bar( int i) } } -#ifdef BOOST_COROUTINES_UNIDIRECT void foo( boost::coroutines::coroutine< void >::pull_type & source) { bar( count); @@ -49,23 +48,6 @@ void thread_fn() sink(); } } -#else -typedef boost::coroutines::coroutine< void() > coro_t; - -void foo( coro_t & c) -{ - bar( count); - c(); -} - -void thread_fn() -{ - { - coro_t c( foo); - c(); - } -} -#endif int main( int argc, char * argv[]) { diff --git a/example/cpp03/tree.h b/example/cpp03/tree.h index 81a3348..23615eb 100644 --- a/example/cpp03/tree.h +++ b/example/cpp03/tree.h @@ -91,7 +91,6 @@ inline bool operator!=( leaf const& l, leaf const& r) { return l.value != r.value; } -#ifdef BOOST_COROUTINES_UNIDIRECT class tree_visitor : public visitor { private: @@ -117,35 +116,6 @@ void enumerate_leafs( boost::coroutines::coroutine< leaf & >::push_type & c, nod tree_visitor v( c); root->accept( v); } -#else -typedef boost::coroutines::coroutine< leaf&() > coro_t; - -class tree_visitor : public visitor -{ -private: - coro_t::caller_type & c_; - -public: - tree_visitor( coro_t::caller_type & c) : - c_( c) - {} - - void visit( branch & b) - { - if ( b.left) b.left->accept( * this); - if ( b.right) b.right->accept( * this); - } - - void visit( leaf & l) - { c_( l); } -}; - -void enumerate_leafs( coro_t::caller_type & c, node::ptr_t root) -{ - tree_visitor v( c); - root->accept( v); -} -#endif # if defined(BOOST_MSVC) # pragma warning(pop) diff --git a/example/cpp03/unwind.cpp b/example/cpp03/unwind.cpp index bda050d..46f04c8 100644 --- a/example/cpp03/unwind.cpp +++ b/example/cpp03/unwind.cpp @@ -10,7 +10,6 @@ #include #include -#ifdef BOOST_COROUTINES_UNIDIRECT struct X : private boost::noncopyable { X() { std::cout << "X()" << std::endl; } @@ -43,39 +42,3 @@ int main( int argc, char * argv[]) return EXIT_SUCCESS; } -#else -typedef boost::coroutines::coroutine< void() > coro_t; - -struct X : private boost::noncopyable -{ - X() { std::cout << "X()" << std::endl; } - ~X() { std::cout << "~X()" << std::endl; } -}; - -void fn( coro_t & ca) -{ - X x; - int i = 0; - while ( true) - { - std::cout << "fn() : " << ++i << std::endl; - ca(); - } -} - -int main( int argc, char * argv[]) -{ - { - coro_t c( fn); - for ( int k = 0; k < 3; ++k) - { - c(); - } - std::cout << "destroying coroutine and unwinding stack" << std::endl; - } - - std::cout << "\nDone" << std::endl; - - return EXIT_SUCCESS; -} -#endif diff --git a/example/cpp11/await_emu.cpp b/example/cpp11/await_emu.cpp index 3f06af5..db6e135 100644 --- a/example/cpp11/await_emu.cpp +++ b/example/cpp11/await_emu.cpp @@ -70,13 +70,9 @@ void reschedule() // ___________________________________________________________ // -#ifdef BOOST_COROUTINES_UNIDIRECT typedef coroutines::coroutine::pull_type coro_pull; typedef coroutines::coroutine::push_type coro_push; -#else -typedef coroutines::coroutine coro_pull; -typedef coroutines::coroutine::caller_type coro_push; -#endif + struct CurrentCoro { std::shared_ptr coro; diff --git a/example/cpp11/fibonacci.cpp b/example/cpp11/fibonacci.cpp index fc1f1b9..4222011 100644 --- a/example/cpp11/fibonacci.cpp +++ b/example/cpp11/fibonacci.cpp @@ -9,7 +9,6 @@ #include -#ifdef BOOST_COROUTINES_UNIDIRECT int main() { boost::coroutines::coroutine< int >::pull_type source( @@ -33,28 +32,3 @@ int main() return EXIT_SUCCESS; } -#else -int main() -{ - boost::coroutines::coroutine< int() > c( - [&]( boost::coroutines::coroutine< void( int) > & c) { - int first = 1, second = 1; - c( first); - c( second); - for ( int i = 0; i < 8; ++i) - { - int third = first + second; - first = second; - second = third; - c( third); - } - }); - - for ( auto i : c) - std::cout << i << " "; - - std::cout << "\nDone" << std::endl; - - return EXIT_SUCCESS; -} -#endif diff --git a/include/boost/coroutine/all.hpp b/include/boost/coroutine/all.hpp index e32a420..96327d6 100644 --- a/include/boost/coroutine/all.hpp +++ b/include/boost/coroutine/all.hpp @@ -12,5 +12,6 @@ #include #include #include +#include #endif // BOOST_COROUTINES_ALL_H diff --git a/include/boost/coroutine/checkpoint.hpp b/include/boost/coroutine/checkpoint.hpp deleted file mode 100644 index e713414..0000000 --- a/include/boost/coroutine/checkpoint.hpp +++ /dev/null @@ -1,34 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// 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) - -#ifndef BOOST_COROUTINES_CHECKPOINT_H -#define BOOST_COROUTINES_CHECKPOINT_H - -#include -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace boost { -namespace coroutines { - -class checkpoint -{ -public: -private: - context::fcontext_t ctx_; - void * sp_; -}; - -}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_COROUTINES_CHECKPOINT_H diff --git a/include/boost/coroutine/coroutine.hpp b/include/boost/coroutine/coroutine.hpp index 647faf9..e8d93c6 100644 --- a/include/boost/coroutine/coroutine.hpp +++ b/include/boost/coroutine/coroutine.hpp @@ -7,10 +7,2995 @@ #ifndef BOOST_COROUTINES_COROUTINE_H #define BOOST_COROUTINES_COROUTINE_H -#ifdef BOOST_COROUTINES_UNIDIRECT -#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_HAS_ABI_HEADERS +# include BOOST_ABI_PREFIX +#endif + +namespace boost { +namespace coroutines { + +template< typename Arg > +class pull_coroutine; + +template< typename Arg > +class push_coroutine +{ +private: + template< + typename X, typename Y, typename Z, typename V, typename W + > + friend class detail::pull_coroutine_object; + + typedef detail::push_coroutine_base< Arg > base_t; + typedef typename base_t::ptr_t ptr_t; + + struct dummy + { void nonnull() {} }; + + typedef void ( dummy::*safe_bool)(); + + ptr_t impl_; + + BOOST_MOVABLE_BUT_NOT_COPYABLE( push_coroutine) + + template< typename Allocator > + push_coroutine( detail::coroutine_context const& callee, + bool unwind, bool preserve_fpu, + Allocator const& alloc) : + impl_() + { + typedef detail::push_coroutine_caller< + Arg, Allocator + > caller_t; + typename caller_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) caller_t( + callee, unwind, preserve_fpu, a) ); + } + +public: + push_coroutine() BOOST_NOEXCEPT : + impl_() + {} + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +#ifdef BOOST_MSVC + typedef void ( * coroutine_fn) ( pull_coroutine< Arg > &); + + explicit push_coroutine( coroutine_fn fn, attributes const& attr = attributes(), + stack_allocator const& stack_alloc = + stack_allocator(), + std::allocator< push_coroutine > const& alloc = + std::allocator< push_coroutine >(), + typename disable_if< + is_same< typename decay< coroutine_fn >::type, push_coroutine >, + dummy * + >::type = 0); + + template< typename StackAllocator > + explicit push_coroutine( coroutine_fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc = + std::allocator< push_coroutine >(), + typename disable_if< + is_same< typename decay< coroutine_fn >::type, push_coroutine >, + dummy * + >::type = 0); + + template< typename StackAllocator, typename Allocator > + explicit push_coroutine(coroutine_fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_same< typename decay< coroutine_fn >::type, push_coroutine >, + dummy * + >::type = 0); +#endif + template< typename Fn > + explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), + stack_allocator const& stack_alloc = + stack_allocator(), + std::allocator< push_coroutine > const& alloc = + std::allocator< push_coroutine >(), + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type = 0); + + template< typename Fn, typename StackAllocator > + explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc = + std::allocator< push_coroutine >(), + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type = 0); + + template< typename Fn, typename StackAllocator, typename Allocator > + explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type = 0); #else -#include + template< typename Fn > + explicit push_coroutine( Fn fn, attributes const& attr = attributes(), + stack_allocator const& stack_alloc = + stack_allocator(), + std::allocator< push_coroutine > const& alloc = + std::allocator< push_coroutine >(), + typename disable_if< + is_convertible< Fn &, BOOST_RV_REF( Fn) >, + dummy * + >::type = 0); + + template< typename Fn, typename StackAllocator > + explicit push_coroutine( Fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc = + std::allocator< push_coroutine >(), + typename disable_if< + is_convertible< Fn &, BOOST_RV_REF( Fn) >, + dummy * + >::type = 0); + + template< typename Fn, typename StackAllocator, typename Allocator > + explicit push_coroutine( Fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_convertible< Fn &, BOOST_RV_REF( Fn) >, + dummy * + >::type = 0); + + template< typename Fn > + explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), + stack_allocator const& stack_alloc = + stack_allocator(), + std::allocator< push_coroutine > const& alloc = + std::allocator< push_coroutine >(), + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type = 0); + + template< typename Fn, typename StackAllocator > + explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc = + std::allocator< push_coroutine >(), + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type = 0); + + template< typename Fn, typename StackAllocator, typename Allocator > + explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type = 0); +#endif + + push_coroutine( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT : + impl_() + { swap( other); } + + push_coroutine & operator=( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT + { + push_coroutine tmp( boost::move( other) ); + swap( tmp); + return * this; + } + + bool empty() const BOOST_NOEXCEPT + { return ! impl_; } + + operator safe_bool() const BOOST_NOEXCEPT + { return ( empty() || impl_->is_complete() ) ? 0 : & dummy::nonnull; } + + bool operator!() const BOOST_NOEXCEPT + { return empty() || impl_->is_complete(); } + + void swap( push_coroutine & other) BOOST_NOEXCEPT + { impl_.swap( other.impl_); } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + push_coroutine & operator()( Arg const& arg) + { + BOOST_ASSERT( * this); + + impl_->push( arg); + return * this; + } + + push_coroutine & operator()( Arg && arg) { + BOOST_ASSERT( * this); + + impl_->push( arg); + return * this; + } +#else + push_coroutine & operator()( Arg const& arg) + { + BOOST_ASSERT( * this); + + impl_->push( forward< Arg >( arg) ); + return * this; + } + + push_coroutine & operator()( BOOST_RV_REF( Arg) arg) + { + BOOST_ASSERT( * this); + + impl_->push( forward< Arg >( arg) ); + return * this; + } +#endif + + class iterator : public std::iterator< std::output_iterator_tag, void, void, void, void > + { + private: + push_coroutine< Arg > * c_; + + public: + iterator() : + c_( 0) + {} + + explicit iterator( push_coroutine< Arg > * c) : + c_( c) + {} + + iterator & operator=( Arg a) + { + BOOST_ASSERT( c_); + if ( ! ( * c_)( a) ) c_ = 0; + return * this; + } + + bool operator==( iterator const& other) + { return other.c_ == c_; } + + bool operator!=( iterator const& other) + { return other.c_ != c_; } + + iterator & operator*() + { return * this; } + + iterator & operator++() + { return * this; } + }; + + struct const_iterator; +}; + +template< typename Arg > +class push_coroutine< Arg & > +{ +private: + template< + typename X, typename Y, typename Z, typename V, typename W + > + friend class detail::pull_coroutine_object; + + typedef detail::push_coroutine_base< Arg & > base_t; + typedef typename base_t::ptr_t ptr_t; + + struct dummy + { void nonnull() {} }; + + typedef void ( dummy::*safe_bool)(); + + ptr_t impl_; + + BOOST_MOVABLE_BUT_NOT_COPYABLE( push_coroutine) + + template< typename Allocator > + push_coroutine( detail::coroutine_context const& callee, + bool unwind, bool preserve_fpu, + Allocator const& alloc) : + impl_() + { + typedef detail::push_coroutine_caller< + Arg &, Allocator + > caller_t; + typename caller_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) caller_t( + callee, unwind, preserve_fpu, a) ); + } + +public: + push_coroutine() BOOST_NOEXCEPT : + impl_() + {} + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +#ifdef BOOST_MSVC + typedef void ( * coroutine_fn) ( pull_coroutine< Arg & > &); + + explicit push_coroutine( coroutine_fn fn, attributes const& attr = attributes(), + stack_allocator const& stack_alloc = + stack_allocator(), + std::allocator< push_coroutine > const& alloc = + std::allocator< push_coroutine >(), + typename disable_if< + is_same< typename decay< coroutine_fn >::type, push_coroutine >, + dummy * + >::type = 0); + + template< typename StackAllocator > + explicit push_coroutine( coroutine_fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc = + std::allocator< push_coroutine >(), + typename disable_if< + is_same< typename decay< coroutine_fn >::type, push_coroutine >, + dummy * + >::type = 0); + + template< typename StackAllocator, typename Allocator > + explicit push_coroutine( coroutine_fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_same< typename decay< coroutine_fn >::type, push_coroutine >, + dummy * + >::type = 0); +#endif + template< typename Fn > + explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), + stack_allocator const& stack_alloc = + stack_allocator(), + std::allocator< push_coroutine > const& alloc = + std::allocator< push_coroutine >(), + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type = 0); + + template< typename Fn, typename StackAllocator > + explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc = + std::allocator< push_coroutine >(), + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type = 0); + + template< typename Fn, typename StackAllocator, typename Allocator > + explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type = 0); +#else + template< typename Fn > + explicit push_coroutine( Fn fn, attributes const& attr = attributes(), + stack_allocator const& stack_alloc = + stack_allocator(), + std::allocator< push_coroutine > const& alloc = + std::allocator< push_coroutine >(), + typename disable_if< + is_convertible< Fn &, BOOST_RV_REF( Fn) >, + dummy * + >::type = 0); + + template< typename Fn, typename StackAllocator > + explicit push_coroutine( Fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc = + std::allocator< push_coroutine >(), + typename disable_if< + is_convertible< Fn &, BOOST_RV_REF( Fn) >, + dummy * + >::type = 0); + + template< typename Fn, typename StackAllocator, typename Allocator > + explicit push_coroutine( Fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_convertible< Fn &, BOOST_RV_REF( Fn) >, + dummy * + >::type = 0); + + template< typename Fn > + explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), + stack_allocator const& stack_alloc = + stack_allocator(), + std::allocator< push_coroutine > const& alloc = + std::allocator< push_coroutine >(), + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type = 0); + + template< typename Fn, typename StackAllocator > + explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc = + std::allocator< push_coroutine >(), + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type = 0); + + template< typename Fn, typename StackAllocator, typename Allocator > + explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type = 0); +#endif + + push_coroutine( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT : + impl_() + { swap( other); } + + push_coroutine & operator=( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT + { + push_coroutine tmp( boost::move( other) ); + swap( tmp); + return * this; + } + + bool empty() const BOOST_NOEXCEPT + { return ! impl_; } + + operator safe_bool() const BOOST_NOEXCEPT + { return ( empty() || impl_->is_complete() ) ? 0 : & dummy::nonnull; } + + bool operator!() const BOOST_NOEXCEPT + { return empty() || impl_->is_complete(); } + + void swap( push_coroutine & other) BOOST_NOEXCEPT + { impl_.swap( other.impl_); } + + push_coroutine & operator()( Arg & arg) + { + BOOST_ASSERT( * this); + + impl_->push( arg); + return * this; + } + + class iterator : public std::iterator< std::output_iterator_tag, void, void, void, void > + { + private: + push_coroutine< Arg & > * c_; + + public: + iterator() : + c_( 0) + {} + + explicit iterator( push_coroutine< Arg & > * c) : + c_( c) + {} + + iterator & operator=( Arg & a) + { + BOOST_ASSERT( c_); + if ( ! ( * c_)( a) ) c_ = 0; + return * this; + } + + bool operator==( iterator const& other) + { return other.c_ == c_; } + + bool operator!=( iterator const& other) + { return other.c_ != c_; } + + iterator & operator*() + { return * this; } + + iterator & operator++() + { return * this; } + }; + + struct const_iterator; +}; + +template<> +class push_coroutine< void > +{ +private: + template< + typename X, typename Y, typename Z, typename V, typename W + > + friend class detail::pull_coroutine_object; + + typedef detail::push_coroutine_base< void > base_t; + typedef base_t::ptr_t ptr_t; + + struct dummy + { void nonnull() {} }; + + typedef void ( dummy::*safe_bool)(); + + ptr_t impl_; + + BOOST_MOVABLE_BUT_NOT_COPYABLE( push_coroutine) + + template< typename Allocator > + push_coroutine( detail::coroutine_context const& callee, + bool unwind, bool preserve_fpu, + Allocator const& alloc) : + impl_() + { + typedef detail::push_coroutine_caller< + void, Allocator + > caller_t; + typename caller_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) caller_t( + callee, unwind, preserve_fpu, a) ); + } + +public: + push_coroutine() BOOST_NOEXCEPT : + impl_() + {} + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +#ifdef BOOST_MSVC + typedef void ( * coroutine_fn) ( pull_coroutine< void > &); + + explicit push_coroutine( coroutine_fn fn, attributes const& attr = attributes(), + stack_allocator const& stack_alloc = + stack_allocator(), + std::allocator< push_coroutine > const& alloc = + std::allocator< push_coroutine >(), + disable_if< + is_same< typename decay< coroutine_fn >::type, push_coroutine >, + dummy * + >::type = 0); + + template< typename StackAllocator > + explicit push_coroutine( coroutine_fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc = + std::allocator< push_coroutine >(), + disable_if< + is_same< typename decay< coroutine_fn >::type, push_coroutine >, + dummy * + >::type = 0); + + template< typename StackAllocator, typename Allocator > + explicit push_coroutine( coroutine_fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + disable_if< + is_same< typename decay< coroutine_fn >::type, push_coroutine >, + dummy * + >::type = 0); +#endif + template< typename Fn > + explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), + stack_allocator const& stack_alloc = + stack_allocator(), + std::allocator< push_coroutine > const& alloc = + std::allocator< push_coroutine >(), + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type = 0); + + template< typename Fn, typename StackAllocator > + explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc = + std::allocator< push_coroutine >(), + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type = 0); + + template< typename Fn, typename StackAllocator, typename Allocator > + explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type = 0); +#else + template< typename Fn > + explicit push_coroutine( Fn fn, attributes const& attr = attributes(), + stack_allocator const& stack_alloc = + stack_allocator(), + std::allocator< push_coroutine > const& alloc = + std::allocator< push_coroutine >(), + typename disable_if< + is_convertible< Fn &, BOOST_RV_REF( Fn) >, + dummy * + >::type = 0); + + template< typename Fn, typename StackAllocator > + explicit push_coroutine( Fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc = + std::allocator< push_coroutine >(), + typename disable_if< + is_convertible< Fn &, BOOST_RV_REF( Fn) >, + dummy * + >::type = 0); + + template< typename Fn, typename StackAllocator, typename Allocator > + explicit push_coroutine( Fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_convertible< Fn &, BOOST_RV_REF( Fn) >, + dummy * + >::type = 0); + + template< typename Fn > + explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), + stack_allocator const& stack_alloc = + stack_allocator(), + std::allocator< push_coroutine > const& alloc = + std::allocator< push_coroutine >(), + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type = 0); + + template< typename Fn, typename StackAllocator > + explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc = + std::allocator< push_coroutine >(), + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type = 0); + + template< typename Fn, typename StackAllocator, typename Allocator > + explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type = 0); +#endif + + push_coroutine( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT : + impl_() + { swap( other); } + + push_coroutine & operator=( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT + { + push_coroutine tmp( boost::move( other) ); + swap( tmp); + return * this; + } + + bool empty() const BOOST_NOEXCEPT + { return ! impl_; } + + operator safe_bool() const BOOST_NOEXCEPT + { return ( empty() || impl_->is_complete() ) ? 0 : & dummy::nonnull; } + + bool operator!() const BOOST_NOEXCEPT + { return empty() || impl_->is_complete(); } + + void swap( push_coroutine & other) BOOST_NOEXCEPT + { impl_.swap( other.impl_); } + + push_coroutine & operator()() + { + BOOST_ASSERT( * this); + + impl_->push(); + return * this; + } + + struct iterator; + struct const_iterator; +}; + + + +template< typename R > +class pull_coroutine +{ +private: + template< + typename X, typename Y, typename Z, typename V, typename W + > + friend class detail::push_coroutine_object; + + typedef detail::pull_coroutine_base< R > base_t; + typedef typename base_t::ptr_t ptr_t; + + struct dummy + { void nonnull() {} }; + + typedef void ( dummy::*safe_bool)(); + + ptr_t impl_; + + BOOST_MOVABLE_BUT_NOT_COPYABLE( pull_coroutine) + + template< typename Allocator > + pull_coroutine( detail::coroutine_context const& callee, + bool unwind, bool preserve_fpu, + Allocator const& alloc, + optional< R > const& result) : + impl_() + { + typedef detail::pull_coroutine_caller< + R, Allocator + > caller_t; + typename caller_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) caller_t( + callee, unwind, preserve_fpu, a, result) ); + } + +public: + pull_coroutine() BOOST_NOEXCEPT : + impl_() + {} + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +#ifdef BOOST_MSVC + typedef void ( * coroutine_fn) ( push_coroutine< R > &); + + explicit pull_coroutine( coroutine_fn fn, attributes const& attr = attributes(), + stack_allocator const& stack_alloc = + stack_allocator(), + std::allocator< pull_coroutine > const& alloc = + std::allocator< pull_coroutine >(), + typename disable_if< + is_same< typename decay< coroutine_fn >::type, pull_coroutine >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + R, coroutine_fn, stack_allocator, std::allocator< pull_coroutine >, + push_coroutine< R > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); + } + + template< typename StackAllocator > + explicit pull_coroutine( coroutine_fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< pull_coroutine > const& alloc = + std::allocator< pull_coroutine >(), + typename disable_if< + is_same< typename decay< coroutine_fn >::type, pull_coroutine >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + R, coroutine_fn, StackAllocator, std::allocator< pull_coroutine >, + push_coroutine< R > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); + } + + template< typename StackAllocator, typename Allocator > + explicit pull_coroutine( coroutine_fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_same< typename decay< coroutine_fn >::type, pull_coroutine >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + R, coroutine_fn, StackAllocator, Allocator, + push_coroutine< R > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); + } +#endif + template< typename Fn > + explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), + stack_allocator const& stack_alloc = + stack_allocator(), + std::allocator< pull_coroutine > const& alloc = + std::allocator< pull_coroutine >(), + typename disable_if< + is_same< typename decay< Fn >::type, pull_coroutine >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + R, Fn, stack_allocator, std::allocator< pull_coroutine >, + push_coroutine< R > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); + } + + template< typename Fn, typename StackAllocator > + explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< pull_coroutine > const& alloc = + std::allocator< pull_coroutine >(), + typename disable_if< + is_same< typename decay< Fn >::type, pull_coroutine >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + R, Fn, StackAllocator, std::allocator< pull_coroutine >, + push_coroutine< R > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); + } + + template< typename Fn, typename StackAllocator, typename Allocator > + explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, pull_coroutine >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + R, Fn, StackAllocator, Allocator, + push_coroutine< R > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); + } +#else + template< typename Fn > + explicit pull_coroutine( Fn fn, attributes const& attr = attributes(), + stack_allocator const& stack_alloc = + stack_allocator(), + std::allocator< pull_coroutine > const& alloc = + std::allocator< pull_coroutine >(), + typename disable_if< + is_convertible< Fn &, BOOST_RV_REF( Fn) >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + R, Fn, stack_allocator, std::allocator< pull_coroutine >, + push_coroutine< R > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); + } + + template< typename Fn, typename StackAllocator > + explicit pull_coroutine( Fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< pull_coroutine > const& alloc = + std::allocator< pull_coroutine >(), + typename disable_if< + is_convertible< Fn &, BOOST_RV_REF( Fn) >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + R, Fn, StackAllocator, std::allocator< pull_coroutine >, + push_coroutine< R > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); + } + + template< typename Fn, typename StackAllocator, typename Allocator > + explicit pull_coroutine( Fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_convertible< Fn &, BOOST_RV_REF( Fn) >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + R, Fn, StackAllocator, Allocator, + push_coroutine< R > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); + } + + template< typename Fn > + explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), + stack_allocator const& stack_alloc = + stack_allocator(), + std::allocator< pull_coroutine > const& alloc = + std::allocator< pull_coroutine >(), + typename disable_if< + is_same< typename decay< Fn >::type, pull_coroutine >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + R, Fn, stack_allocator, std::allocator< pull_coroutine >, + push_coroutine< R > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); + } + + template< typename Fn, typename StackAllocator > + explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< pull_coroutine > const& alloc = + std::allocator< pull_coroutine >(), + typename disable_if< + is_same< typename decay< Fn >::type, pull_coroutine >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + R, Fn, StackAllocator, std::allocator< pull_coroutine >, + push_coroutine< R > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); + } + + template< typename Fn, typename StackAllocator, typename Allocator > + explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, pull_coroutine >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + R, Fn, StackAllocator, Allocator, + push_coroutine< R > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); + } +#endif + + pull_coroutine( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT : + impl_() + { swap( other); } + + pull_coroutine & operator=( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT + { + pull_coroutine tmp( boost::move( other) ); + swap( tmp); + return * this; + } + + bool empty() const BOOST_NOEXCEPT + { return ! impl_; } + + operator safe_bool() const BOOST_NOEXCEPT + { return ( empty() || impl_->is_complete() ) ? 0 : & dummy::nonnull; } + + bool operator!() const BOOST_NOEXCEPT + { return empty() || impl_->is_complete(); } + + void swap( pull_coroutine & other) BOOST_NOEXCEPT + { impl_.swap( other.impl_); } + + pull_coroutine & operator()() + { + BOOST_ASSERT( * this); + + impl_->pull(); + return * this; + } + + bool has_result() const + { + BOOST_ASSERT( ! empty() ); + + return impl_->has_result(); + } + + R get() const + { + BOOST_ASSERT( ! empty() ); + + return impl_->get(); + } + + class iterator : public std::iterator< std::input_iterator_tag, typename remove_reference< R >::type > + { + private: + pull_coroutine< R > * c_; + optional< R > val_; + + void fetch_() + { + BOOST_ASSERT( c_); + + if ( ! c_->has_result() ) + { + c_ = 0; + val_ = none; + return; + } + val_ = c_->get(); + } + + void increment_() + { + BOOST_ASSERT( c_); + BOOST_ASSERT( * c_); + + ( * c_)(); + fetch_(); + } + + public: + typedef typename iterator::pointer pointer_t; + typedef typename iterator::reference reference_t; + + iterator() : + c_( 0), val_() + {} + + explicit iterator( pull_coroutine< R > * c) : + c_( c), val_() + { fetch_(); } + + iterator( iterator const& other) : + c_( other.c_), val_( other.val_) + {} + + iterator & operator=( iterator const& other) + { + if ( this == & other) return * this; + c_ = other.c_; + val_ = other.val_; + return * this; + } + + bool operator==( iterator const& other) + { return other.c_ == c_ && other.val_ == val_; } + + bool operator!=( iterator const& other) + { return other.c_ != c_ || other.val_ != val_; } + + iterator & operator++() + { + increment_(); + return * this; + } + + iterator operator++( int) + { + iterator tmp( * this); + ++*this; + return tmp; + } + + reference_t operator*() const + { + if ( ! val_) + boost::throw_exception( + invalid_result() ); + return const_cast< optional< R > & >( val_).get(); + } + + pointer_t operator->() const + { + if ( ! val_) + boost::throw_exception( + invalid_result() ); + return const_cast< optional< R > & >( val_).get_ptr(); + } + }; + + class const_iterator : public std::iterator< std::input_iterator_tag, const typename remove_reference< R >::type > + { + private: + pull_coroutine< R > * c_; + optional< R > val_; + + void fetch_() + { + BOOST_ASSERT( c_); + + if ( ! c_->has_result() ) + { + c_ = 0; + val_ = none; + return; + } + val_ = c_->get(); + } + + void increment_() + { + BOOST_ASSERT( c_); + BOOST_ASSERT( * c_); + + ( * c_)(); + fetch_(); + } + + public: + typedef typename const_iterator::pointer pointer_t; + typedef typename const_iterator::reference reference_t; + + const_iterator() : + c_( 0), val_() + {} + + explicit const_iterator( pull_coroutine< R > const* c) : + c_( const_cast< pull_coroutine< R > * >( c) ), val_() + { fetch_(); } + + const_iterator( const_iterator const& other) : + c_( other.c_), val_( other.val_) + {} + + const_iterator & operator=( const_iterator const& other) + { + if ( this == & other) return * this; + c_ = other.c_; + val_ = other.val_; + return * this; + } + + bool operator==( const_iterator const& other) + { return other.c_ == c_ && other.val_ == val_; } + + bool operator!=( const_iterator const& other) + { return other.c_ != c_ || other.val_ != val_; } + + const_iterator & operator++() + { + increment_(); + return * this; + } + + const_iterator operator++( int) + { + const_iterator tmp( * this); + ++*this; + return tmp; + } + + reference_t operator*() const + { + if ( ! val_) + boost::throw_exception( + invalid_result() ); + return val_.get(); + } + + pointer_t operator->() const + { + if ( ! val_) + boost::throw_exception( + invalid_result() ); + return val_.get_ptr(); + } + }; +}; + +template< typename R > +class pull_coroutine< R & > +{ +private: + template< + typename X, typename Y, typename Z, typename V, typename W + > + friend class detail::push_coroutine_object; + + typedef detail::pull_coroutine_base< R & > base_t; + typedef typename base_t::ptr_t ptr_t; + + struct dummy + { void nonnull() {} }; + + typedef void ( dummy::*safe_bool)(); + + ptr_t impl_; + + BOOST_MOVABLE_BUT_NOT_COPYABLE( pull_coroutine) + + template< typename Allocator > + pull_coroutine( detail::coroutine_context const& callee, + bool unwind, bool preserve_fpu, + Allocator const& alloc, + optional< R * > const& result) : + impl_() + { + typedef detail::pull_coroutine_caller< + R &, Allocator + > caller_t; + typename caller_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) caller_t( + callee, unwind, preserve_fpu, a, result) ); + } + +public: + pull_coroutine() BOOST_NOEXCEPT : + impl_() + {} + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +#ifdef BOOST_MSVC + typedef void ( * coroutine_fn) ( push_coroutine< R & > &); + + explicit pull_coroutine( coroutine_fn fn, attributes const& attr = attributes(), + stack_allocator const& stack_alloc = + stack_allocator(), + std::allocator< pull_coroutine > const& alloc = + std::allocator< pull_coroutine >(), + typename disable_if< + is_same< typename decay< coroutine_fn >::type, pull_coroutine >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + R &, coroutine_fn, stack_allocator, std::allocator< pull_coroutine >, + push_coroutine< R & > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); + } + + template< typename StackAllocator > + explicit pull_coroutine( coroutine_fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< pull_coroutine > const& alloc = + std::allocator< pull_coroutine >(), + typename disable_if< + is_same< typename decay< coroutine_fn >::type, pull_coroutine >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + R &, coroutine_fn, StackAllocator, std::allocator< pull_coroutine >, + push_coroutine< R & > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); + } + + template< typename StackAllocator, typename Allocator > + explicit pull_coroutine( coroutine_fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_same< typename decay< coroutine_fn >::type, pull_coroutine >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + R &, coroutine_fn, StackAllocator, Allocator, + push_coroutine< R & > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); + } +#endif + template< typename Fn > + explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), + stack_allocator const& stack_alloc = + stack_allocator(), + std::allocator< pull_coroutine > const& alloc = + std::allocator< pull_coroutine >(), + typename disable_if< + is_same< typename decay< Fn >::type, pull_coroutine >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + R &, Fn, stack_allocator, std::allocator< pull_coroutine >, + push_coroutine< R & > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); + } + + template< typename Fn, typename StackAllocator > + explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< pull_coroutine > const& alloc = + std::allocator< pull_coroutine >(), + typename disable_if< + is_same< typename decay< Fn >::type, pull_coroutine >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + R &, Fn, StackAllocator, std::allocator< pull_coroutine >, + push_coroutine< R & > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); + } + + template< typename Fn, typename StackAllocator, typename Allocator > + explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, pull_coroutine >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + R &, Fn, StackAllocator, Allocator, + push_coroutine< R & > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); + } +#else + template< typename Fn > + explicit pull_coroutine( Fn fn, attributes const& attr = attributes(), + stack_allocator const& stack_alloc = + stack_allocator(), + std::allocator< pull_coroutine > const& alloc = + std::allocator< pull_coroutine >(), + typename disable_if< + is_convertible< Fn &, BOOST_RV_REF( Fn) >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + R &, Fn, stack_allocator, std::allocator< pull_coroutine >, + push_coroutine< R & > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); + } + + template< typename Fn, typename StackAllocator > + explicit pull_coroutine( Fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< pull_coroutine > const& alloc = + std::allocator< pull_coroutine >(), + typename disable_if< + is_convertible< Fn &, BOOST_RV_REF( Fn) >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + R &, Fn, StackAllocator, std::allocator< pull_coroutine >, + push_coroutine< R & > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); + } + + template< typename Fn, typename StackAllocator, typename Allocator > + explicit pull_coroutine( Fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_convertible< Fn &, BOOST_RV_REF( Fn) >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + R &, Fn, StackAllocator, Allocator, + push_coroutine< R & > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); + } + + template< typename Fn > + explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), + stack_allocator const& stack_alloc = + stack_allocator(), + std::allocator< pull_coroutine > const& alloc = + std::allocator< pull_coroutine >(), + typename disable_if< + is_same< typename decay< Fn >::type, pull_coroutine >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + R &, Fn, stack_allocator, std::allocator< pull_coroutine >, + push_coroutine< R & > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); + } + + template< typename Fn, typename StackAllocator > + explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< pull_coroutine > const& alloc = + std::allocator< pull_coroutine >(), + typename disable_if< + is_same< typename decay< Fn >::type, pull_coroutine >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + R &, Fn, StackAllocator, std::allocator< pull_coroutine >, + push_coroutine< R & > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); + } + + template< typename Fn, typename StackAllocator, typename Allocator > + explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, pull_coroutine >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + R &, Fn, StackAllocator, Allocator, + push_coroutine< R & > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); + } +#endif + + pull_coroutine( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT : + impl_() + { swap( other); } + + pull_coroutine & operator=( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT + { + pull_coroutine tmp( boost::move( other) ); + swap( tmp); + return * this; + } + + bool empty() const BOOST_NOEXCEPT + { return ! impl_; } + + operator safe_bool() const BOOST_NOEXCEPT + { return ( empty() || impl_->is_complete() ) ? 0 : & dummy::nonnull; } + + bool operator!() const BOOST_NOEXCEPT + { return empty() || impl_->is_complete(); } + + void swap( pull_coroutine & other) BOOST_NOEXCEPT + { impl_.swap( other.impl_); } + + pull_coroutine & operator()() + { + BOOST_ASSERT( * this); + + impl_->pull(); + return * this; + } + + bool has_result() const + { + BOOST_ASSERT( ! empty() ); + + return impl_->has_result(); + } + + R & get() const + { return impl_->get(); } + + class iterator : public std::iterator< std::input_iterator_tag, R > + { + private: + pull_coroutine< R & > * c_; + optional< R & > val_; + + void fetch_() + { + BOOST_ASSERT( c_); + + if ( ! c_->has_result() ) + { + c_ = 0; + val_ = none; + return; + } + val_ = c_->get(); + } + + void increment_() + { + BOOST_ASSERT( c_); + BOOST_ASSERT( * c_); + + ( * c_)(); + fetch_(); + } + + public: + typedef typename iterator::pointer pointer_t; + typedef typename iterator::reference reference_t; + + iterator() : + c_( 0), val_() + {} + + explicit iterator( pull_coroutine< R & > * c) : + c_( c), val_() + { fetch_(); } + + iterator( iterator const& other) : + c_( other.c_), val_( other.val_) + {} + + iterator & operator=( iterator const& other) + { + if ( this == & other) return * this; + c_ = other.c_; + val_ = other.val_; + return * this; + } + + bool operator==( iterator const& other) + { return other.c_ == c_ && other.val_ == val_; } + + bool operator!=( iterator const& other) + { return other.c_ != c_ || other.val_ != val_; } + + iterator & operator++() + { + increment_(); + return * this; + } + + iterator operator++( int) + { + iterator tmp( * this); + ++*this; + return tmp; + } + + reference_t operator*() const + { + if ( ! val_) + boost::throw_exception( + invalid_result() ); + return const_cast< optional< R & > & >( val_).get(); + } + + pointer_t operator->() const + { + if ( ! val_) + boost::throw_exception( + invalid_result() ); + return const_cast< optional< R & > & >( val_).get_ptr(); + } + }; + + class const_iterator : public std::iterator< std::input_iterator_tag, R > + { + private: + pull_coroutine< R & > * c_; + optional< R & > val_; + + void fetch_() + { + BOOST_ASSERT( c_); + + if ( ! c_->has_result() ) + { + c_ = 0; + val_ = none; + return; + } + val_ = c_->get(); + } + + void increment_() + { + BOOST_ASSERT( c_); + BOOST_ASSERT( * c_); + + ( * c_)(); + fetch_(); + } + + public: + typedef typename const_iterator::pointer pointer_t; + typedef typename const_iterator::reference reference_t; + + const_iterator() : + c_( 0), val_() + {} + + explicit const_iterator( pull_coroutine< R & > const* c) : + c_( const_cast< pull_coroutine< R & > * >( c) ), val_() + { fetch_(); } + + const_iterator( const_iterator const& other) : + c_( other.c_), val_( other.val_) + {} + + const_iterator & operator=( const_iterator const& other) + { + if ( this == & other) return * this; + c_ = other.c_; + val_ = other.val_; + return * this; + } + + bool operator==( const_iterator const& other) + { return other.c_ == c_ && other.val_ == val_; } + + bool operator!=( const_iterator const& other) + { return other.c_ != c_ || other.val_ != val_; } + + const_iterator & operator++() + { + increment_(); + return * this; + } + + const_iterator operator++( int) + { + const_iterator tmp( * this); + ++*this; + return tmp; + } + + reference_t operator*() const + { + if ( ! val_) + boost::throw_exception( + invalid_result() ); + return val_.get(); + } + + pointer_t operator->() const + { + if ( ! val_) + boost::throw_exception( + invalid_result() ); + return val_.get_ptr(); + } + }; +}; + +template<> +class pull_coroutine< void > +{ +private: + template< + typename X, typename Y, typename Z, typename V, typename W + > + friend class detail::push_coroutine_object; + + typedef detail::pull_coroutine_base< void > base_t; + typedef base_t::ptr_t ptr_t; + + struct dummy + { void nonnull() {} }; + + typedef void ( dummy::*safe_bool)(); + + ptr_t impl_; + + BOOST_MOVABLE_BUT_NOT_COPYABLE( pull_coroutine) + + template< typename Allocator > + pull_coroutine( detail::coroutine_context const& callee, + bool unwind, bool preserve_fpu, + Allocator const& alloc) : + impl_() + { + typedef detail::pull_coroutine_caller< + void, Allocator + > caller_t; + typename caller_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) caller_t( + callee, unwind, preserve_fpu, a) ); + } + +public: + pull_coroutine() BOOST_NOEXCEPT : + impl_() + {} + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +#ifdef BOOST_MSVC + typedef void ( * coroutine_fn) ( push_coroutine< void > &); + + explicit pull_coroutine( coroutine_fn fn, attributes const& attr = attributes(), + stack_allocator const& stack_alloc = + stack_allocator(), + std::allocator< pull_coroutine > const& alloc = + std::allocator< pull_coroutine >(), + disable_if< + is_same< typename decay< coroutine_fn >::type, pull_coroutine >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + void, coroutine_fn, stack_allocator, std::allocator< pull_coroutine >, + push_coroutine< void > + > object_t; + object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); + } + + template< typename StackAllocator > + explicit pull_coroutine( coroutine_fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< pull_coroutine > const& alloc = + std::allocator< pull_coroutine >(), + disable_if< + is_same< typename decay< coroutine_fn >::type, pull_coroutine >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + void, coroutine_fn, StackAllocator, std::allocator< pull_coroutine >, + push_coroutine< void > + > object_t; + object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); + } + + template< typename StackAllocator, typename Allocator > + explicit pull_coroutine( coroutine_fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + disable_if< + is_same< typename decay< coroutine_fn >::type, pull_coroutine >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + void, coroutine_fn, StackAllocator, Allocator, + push_coroutine< void > + > object_t; + object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); + } +#endif + template< typename Fn > + explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), + stack_allocator const& stack_alloc = + stack_allocator(), + std::allocator< pull_coroutine > const& alloc = + std::allocator< pull_coroutine >(), + typename disable_if< + is_same< typename decay< Fn >::type, pull_coroutine >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + void, Fn, stack_allocator, std::allocator< pull_coroutine >, + push_coroutine< void > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); + } + + template< typename Fn, typename StackAllocator > + explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< pull_coroutine > const& alloc = + std::allocator< pull_coroutine >(), + typename disable_if< + is_same< typename decay< Fn >::type, pull_coroutine >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + void, Fn, StackAllocator, std::allocator< pull_coroutine >, + push_coroutine< void > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); + } + + template< typename Fn, typename StackAllocator, typename Allocator > + explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, pull_coroutine >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + void, Fn, StackAllocator, Allocator, + push_coroutine< void > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); + } +#else + template< typename Fn > + explicit pull_coroutine( Fn fn, attributes const& attr = attributes(), + stack_allocator const& stack_alloc = + stack_allocator(), + std::allocator< pull_coroutine > const& alloc = + std::allocator< pull_coroutine >(), + typename disable_if< + is_convertible< Fn &, BOOST_RV_REF( Fn) >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + void, Fn, stack_allocator, std::allocator< pull_coroutine >, + push_coroutine< void > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); + } + + template< typename Fn, typename StackAllocator > + explicit pull_coroutine( Fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< pull_coroutine > const& alloc = + std::allocator< pull_coroutine >(), + typename disable_if< + is_convertible< Fn &, BOOST_RV_REF( Fn) >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + void, Fn, StackAllocator, std::allocator< pull_coroutine >, + push_coroutine< void > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); + } + + template< typename Fn, typename StackAllocator, typename Allocator > + explicit pull_coroutine( Fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_convertible< Fn &, BOOST_RV_REF( Fn) >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + void, Fn, StackAllocator, Allocator, + push_coroutine< void > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); + } + + template< typename Fn > + explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), + stack_allocator const& stack_alloc = + stack_allocator(), + std::allocator< pull_coroutine > const& alloc = + std::allocator< pull_coroutine >(), + typename disable_if< + is_same< typename decay< Fn >::type, pull_coroutine >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + void, Fn, stack_allocator, std::allocator< pull_coroutine >, + push_coroutine< void > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); + } + + template< typename Fn, typename StackAllocator > + explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< pull_coroutine > const& alloc = + std::allocator< pull_coroutine >(), + typename disable_if< + is_same< typename decay< Fn >::type, pull_coroutine >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + void, Fn, StackAllocator, std::allocator< pull_coroutine >, + push_coroutine< void > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); + } + + template< typename Fn, typename StackAllocator, typename Allocator > + explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, pull_coroutine >, + dummy * + >::type = 0) : + impl_() + { + typedef detail::pull_coroutine_object< + void, Fn, StackAllocator, Allocator, + push_coroutine< void > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); + } +#endif + + pull_coroutine( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT : + impl_() + { swap( other); } + + pull_coroutine & operator=( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT + { + pull_coroutine tmp( boost::move( other) ); + swap( tmp); + return * this; + } + + bool empty() const BOOST_NOEXCEPT + { return ! impl_; } + + operator safe_bool() const BOOST_NOEXCEPT + { return ( empty() || impl_->is_complete() ) ? 0 : & dummy::nonnull; } + + bool operator!() const BOOST_NOEXCEPT + { return empty() || impl_->is_complete(); } + + void swap( pull_coroutine & other) BOOST_NOEXCEPT + { impl_.swap( other.impl_); } + + pull_coroutine & operator()() + { + BOOST_ASSERT( * this); + + impl_->pull(); + return * this; + } + + struct iterator; + struct const_iterator; +}; + + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +#ifdef BOOST_MSVC +template< typename Arg > +push_coroutine< Arg >::push_coroutine( coroutine_fn fn, attributes const& attr, + stack_allocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc, + typename disable_if< + is_same< typename decay< coroutine_fn >::type, push_coroutine >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + Arg, coroutine_fn, stack_allocator, std::allocator< push_coroutine >, + pull_coroutine< Arg > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); +} + +template< typename Arg > +template< typename StackAllocator > +push_coroutine< Arg >::push_coroutine( coroutine_fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc, + typename disable_if< + is_same< typename decay< coroutine_fn >::type, push_coroutine >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + Arg, coroutine_fn, StackAllocator, std::allocator< push_coroutine >, + pull_coroutine< Arg > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); +} + +template< typename Arg > +template< typename StackAllocator, typename Allocator > +push_coroutine< Arg >::push_coroutine( coroutine_fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_same< typename decay< coroutine_fn >::type, push_coroutine >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + Arg, coroutine_fn, StackAllocator, Allocator, + pull_coroutine< Arg > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); +} + +template< typename Arg > +push_coroutine< Arg & >::push_coroutine( coroutine_fn fn, attributes const& attr, + stack_allocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc, + typename disable_if< + is_same< typename decay< coroutine_fn >::type, push_coroutine >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + Arg &, coroutine_fn, stack_allocator, std::allocator< push_coroutine >, + pull_coroutine< Arg & > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); +} + +template< typename Arg > +template< typename StackAllocator > +push_coroutine< Arg & >::push_coroutine( coroutine_fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc, + typename disable_if< + is_same< typename decay< coroutine_fn >::type, push_coroutine >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + Arg &, coroutine_fn, StackAllocator, std::allocator< push_coroutine >, + pull_coroutine< Arg & > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); +} + +template< typename Arg > +template< typename StackAllocator, typename Allocator > +push_coroutine< Arg & >::push_coroutine( coroutine_fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_same< typename decay< coroutine_fn >::type, push_coroutine >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + Arg &, coroutine_fn, StackAllocator, Allocator, + pull_coroutine< Arg & > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); +} + +inline +push_coroutine< void >::push_coroutine( coroutine_fn fn, attributes const& attr, + stack_allocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc, + disable_if< + is_same< typename decay< coroutine_fn >::type, push_coroutine >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + void, coroutine_fn, stack_allocator, std::allocator< push_coroutine >, + pull_coroutine< void > + > object_t; + object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); +} + +template< typename StackAllocator > +push_coroutine< void >::push_coroutine( coroutine_fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc, + disable_if< + is_same< typename decay< coroutine_fn >::type, push_coroutine >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + void, coroutine_fn, StackAllocator, std::allocator< push_coroutine >, + pull_coroutine< void > + > object_t; + object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); +} + +template< typename StackAllocator, typename Allocator > +push_coroutine< void >::push_coroutine( coroutine_fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + disable_if< + is_same< typename decay< coroutine_fn >::type, push_coroutine >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + void, coroutine_fn, StackAllocator, Allocator, + pull_coroutine< void > + > object_t; + object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); +} +#endif +template< typename Arg > +template< typename Fn > +push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + stack_allocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + Arg, Fn, stack_allocator, std::allocator< push_coroutine >, + pull_coroutine< Arg > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); +} + +template< typename Arg > +template< typename Fn, typename StackAllocator > +push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + Arg, Fn, StackAllocator, std::allocator< push_coroutine >, + pull_coroutine< Arg > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); +} + +template< typename Arg > +template< typename Fn, typename StackAllocator, typename Allocator > +push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + Arg, Fn, StackAllocator, Allocator, + pull_coroutine< Arg > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); +} + +template< typename Arg > +template< typename Fn > +push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + stack_allocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + Arg &, Fn, stack_allocator, std::allocator< push_coroutine >, + pull_coroutine< Arg & > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); +} + +template< typename Arg > +template< typename Fn, typename StackAllocator > +push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + Arg &, Fn, StackAllocator, std::allocator< push_coroutine >, + pull_coroutine< Arg & > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); +} + +template< typename Arg > +template< typename Fn, typename StackAllocator, typename Allocator > +push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + Arg &, Fn, StackAllocator, Allocator, + pull_coroutine< Arg & > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); +} + +template< typename Fn > +push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + stack_allocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + void, Fn, stack_allocator, std::allocator< push_coroutine >, + pull_coroutine< void > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); +} + +template< typename Fn, typename StackAllocator > +push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + void, Fn, StackAllocator, std::allocator< push_coroutine >, + pull_coroutine< void > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); +} + +template< typename Fn, typename StackAllocator, typename Allocator > +push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + void, Fn, StackAllocator, Allocator, + pull_coroutine< void > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); +} +#else +template< typename Arg > +template< typename Fn > +push_coroutine< Arg >::push_coroutine( Fn fn, attributes const& attr, + stack_allocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc, + typename disable_if< + is_convertible< Fn &, BOOST_RV_REF( Fn) >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + Arg, Fn, stack_allocator, std::allocator< push_coroutine >, + pull_coroutine< Arg > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); +} + +template< typename Arg > +template< typename Fn, typename StackAllocator > +push_coroutine< Arg >::push_coroutine( Fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc, + typename disable_if< + is_convertible< Fn &, BOOST_RV_REF( Fn) >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + Arg, Fn, StackAllocator, std::allocator< push_coroutine >, + pull_coroutine< Arg > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); +} + +template< typename Arg > +template< typename Fn, typename StackAllocator, typename Allocator > +push_coroutine< Arg >::push_coroutine( Fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_convertible< Fn &, BOOST_RV_REF( Fn) >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + Arg, Fn, StackAllocator, Allocator, + pull_coroutine< Arg > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); +} + +template< typename Arg > +template< typename Fn > +push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + stack_allocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + Arg, Fn, stack_allocator, std::allocator< push_coroutine >, + pull_coroutine< Arg > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); +} + +template< typename Arg > +template< typename Fn, typename StackAllocator > +push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + Arg, Fn, StackAllocator, std::allocator< push_coroutine >, + pull_coroutine< Arg > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); +} + +template< typename Arg > +template< typename Fn, typename StackAllocator, typename Allocator > +push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + Arg, Fn, StackAllocator, Allocator, + pull_coroutine< Arg > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); +} + +template< typename Arg > +template< typename Fn > +push_coroutine< Arg & >::push_coroutine( Fn fn, attributes const& attr, + stack_allocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc, + typename disable_if< + is_convertible< Fn &, BOOST_RV_REF( Fn) >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + Arg &, Fn, stack_allocator, std::allocator< push_coroutine >, + pull_coroutine< Arg & > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); +} + +template< typename Arg > +template< typename Fn, typename StackAllocator > +push_coroutine< Arg & >::push_coroutine( Fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc, + typename disable_if< + is_convertible< Fn &, BOOST_RV_REF( Fn) >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + Arg &, Fn, StackAllocator, std::allocator< push_coroutine >, + pull_coroutine< Arg & > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); +} + +template< typename Arg > +template< typename Fn, typename StackAllocator, typename Allocator > +push_coroutine< Arg & >::push_coroutine( Fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_convertible< Fn &, BOOST_RV_REF( Fn) >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + Arg &, Fn, StackAllocator, Allocator, + pull_coroutine< Arg & > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); +} + +template< typename Arg > +template< typename Fn > +push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + stack_allocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + Arg &, Fn, stack_allocator, std::allocator< push_coroutine >, + pull_coroutine< Arg & > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); +} + +template< typename Arg > +template< typename Fn, typename StackAllocator > +push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + Arg &, Fn, StackAllocator, std::allocator< push_coroutine >, + pull_coroutine< Arg & > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); +} + +template< typename Arg > +template< typename Fn, typename StackAllocator, typename Allocator > +push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + Arg &, Fn, StackAllocator, Allocator, + pull_coroutine< Arg & > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); +} + +template< typename Fn > +push_coroutine< void >::push_coroutine( Fn fn, attributes const& attr, + stack_allocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc, + typename disable_if< + is_convertible< Fn &, BOOST_RV_REF( Fn) >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + void, Fn, stack_allocator, std::allocator< push_coroutine >, + pull_coroutine< void > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); +} + +template< typename Fn, typename StackAllocator > +push_coroutine< void >::push_coroutine( Fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc, + typename disable_if< + is_convertible< Fn &, BOOST_RV_REF( Fn) >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + void, Fn, StackAllocator, std::allocator< push_coroutine >, + pull_coroutine< void > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); +} + +template< typename Fn, typename StackAllocator, typename Allocator > +push_coroutine< void >::push_coroutine( Fn fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_convertible< Fn &, BOOST_RV_REF( Fn) >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + void, Fn, StackAllocator, Allocator, + pull_coroutine< void > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); +} + +template< typename Fn > +push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + stack_allocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + void, Fn, stack_allocator, std::allocator< push_coroutine >, + pull_coroutine< void > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); +} + +template< typename Fn, typename StackAllocator > +push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + std::allocator< push_coroutine > const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + void, Fn, StackAllocator, std::allocator< push_coroutine >, + pull_coroutine< void > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); +} + +template< typename Fn, typename StackAllocator, typename Allocator > +push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, + StackAllocator const& stack_alloc, + Allocator const& alloc, + typename disable_if< + is_same< typename decay< Fn >::type, push_coroutine >, + dummy * + >::type) : + impl_() +{ + typedef detail::push_coroutine_object< + void, Fn, StackAllocator, Allocator, + pull_coroutine< void > + > object_t; + typename object_t::allocator_t a( alloc); + impl_ = ptr_t( + // placement new + ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); +} +#endif + +template< typename R > +void swap( pull_coroutine< R > & l, pull_coroutine< R > & r) BOOST_NOEXCEPT +{ l.swap( r); } + +template< typename Arg > +void swap( push_coroutine< Arg > & l, push_coroutine< Arg > & r) BOOST_NOEXCEPT +{ l.swap( r); } + +template< typename R > +inline +typename pull_coroutine< R >::iterator +range_begin( pull_coroutine< R > & c) +{ return typename pull_coroutine< R >::iterator( & c); } + +template< typename R > +inline +typename pull_coroutine< R >::const_iterator +range_begin( pull_coroutine< R > const& c) +{ return typename pull_coroutine< R >::const_iterator( & c); } + +template< typename R > +inline +typename pull_coroutine< R >::iterator +range_end( pull_coroutine< R > &) +{ return typename pull_coroutine< R >::iterator(); } + +template< typename R > +inline +typename pull_coroutine< R >::const_iterator +range_end( pull_coroutine< R > const&) +{ return typename pull_coroutine< R >::const_iterator(); } + +template< typename Arg > +inline +typename push_coroutine< Arg >::iterator +range_begin( push_coroutine< Arg > & c) +{ return typename push_coroutine< Arg >::iterator( & c); } + +template< typename Arg > +inline +typename push_coroutine< Arg >::const_iterator +range_begin( push_coroutine< Arg > const& c) +{ return typename push_coroutine< Arg >::const_iterator( & c); } + +template< typename Arg > +inline +typename push_coroutine< Arg >::iterator +range_end( push_coroutine< Arg > &) +{ return typename push_coroutine< Arg >::iterator(); } + +template< typename Arg > +inline +typename push_coroutine< Arg >::const_iterator +range_end( push_coroutine< Arg > const&) +{ return typename push_coroutine< Arg >::const_iterator(); } + +template< typename T > +struct coroutine +{ + typedef push_coroutine< T > push_type; + typedef pull_coroutine< T > pull_type; +}; + +} + +template< typename Arg > +struct range_mutable_iterator< coroutines::push_coroutine< Arg > > +{ typedef typename coroutines::push_coroutine< Arg >::iterator type; }; + +template< typename Arg > +struct range_const_iterator< coroutines::push_coroutine< Arg > > +{ typedef typename coroutines::push_coroutine< Arg >::const_iterator type; }; + +template< typename R > +struct range_mutable_iterator< coroutines::pull_coroutine< R > > +{ typedef typename coroutines::pull_coroutine< R >::iterator type; }; + +template< typename R > +struct range_const_iterator< coroutines::pull_coroutine< R > > +{ typedef typename coroutines::pull_coroutine< R >::const_iterator type; }; + +} + +namespace std { + +template< typename R > +inline +typename boost::coroutines::pull_coroutine< R >::iterator +begin( boost::coroutines::pull_coroutine< R > & c) +{ return boost::begin( c); } + +template< typename R > +inline +typename boost::coroutines::pull_coroutine< R >::iterator +end( boost::coroutines::pull_coroutine< R > & c) +{ return boost::end( c); } + +template< typename R > +inline +typename boost::coroutines::pull_coroutine< R >::const_iterator +begin( boost::coroutines::pull_coroutine< R > const& c) +{ return boost::const_begin( c); } + +template< typename R > +inline +typename boost::coroutines::pull_coroutine< R >::const_iterator +end( boost::coroutines::pull_coroutine< R > const& c) +{ return boost::const_end( c); } + +template< typename R > +inline +typename boost::coroutines::push_coroutine< R >::iterator +begin( boost::coroutines::push_coroutine< R > & c) +{ return boost::begin( c); } + +template< typename R > +inline +typename boost::coroutines::push_coroutine< R >::iterator +end( boost::coroutines::push_coroutine< R > & c) +{ return boost::end( c); } + +template< typename R > +inline +typename boost::coroutines::push_coroutine< R >::const_iterator +begin( boost::coroutines::push_coroutine< R > const& c) +{ return boost::const_begin( c); } + +template< typename R > +inline +typename boost::coroutines::push_coroutine< R >::const_iterator +end( boost::coroutines::push_coroutine< R > const& c) +{ return boost::const_end( c); } + +} + +#ifdef BOOST_HAS_ABI_HEADERS +# include BOOST_ABI_SUFFIX #endif #endif // BOOST_COROUTINES_COROUTINE_H diff --git a/include/boost/coroutine/detail/config.hpp b/include/boost/coroutine/detail/config.hpp index 618235c..e647f1e 100644 --- a/include/boost/coroutine/detail/config.hpp +++ b/include/boost/coroutine/detail/config.hpp @@ -42,20 +42,4 @@ # define BOOST_COROUTINES_SEGMENTS 10 #endif -#if defined(BOOST_COROUTINES_V2) -# define BOOST_COROUTINES_UNIDIRECT -#endif - -#if defined(BOOST_COROUTINES_V1) -# define BOOST_COROUTINES_OLD -#endif - -#if defined(BOOST_COROUTINES_BIDIRECT) -# define BOOST_COROUTINES_OLD -#endif - -#if ! defined(BOOST_COROUTINES_OLD) -# define BOOST_COROUTINES_UNIDIRECT -#endif - #endif // BOOST_COROUTINES_DETAIL_CONFIG_H diff --git a/include/boost/coroutine/v2/detail/pull_coroutine_base.hpp b/include/boost/coroutine/detail/pull_coroutine_base.hpp similarity index 97% rename from include/boost/coroutine/v2/detail/pull_coroutine_base.hpp rename to include/boost/coroutine/detail/pull_coroutine_base.hpp index 74cdc4d..f2fd9b5 100644 --- a/include/boost/coroutine/v2/detail/pull_coroutine_base.hpp +++ b/include/boost/coroutine/detail/pull_coroutine_base.hpp @@ -4,8 +4,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#ifndef BOOST_COROUTINES_UNIDIRECT_DETAIL_PULL_COROUTINE_BASE_H -#define BOOST_COROUTINES_UNIDIRECT_DETAIL_PULL_COROUTINE_BASE_H +#ifndef BOOST_COROUTINES_DETAIL_PULL_COROUTINE_BASE_H +#define BOOST_COROUTINES_DETAIL_PULL_COROUTINE_BASE_H #include #include @@ -334,4 +334,4 @@ public: # include BOOST_ABI_SUFFIX #endif -#endif // BOOST_COROUTINES_UNIDIRECT_DETAIL_PULL_COROUTINE_BASE_H +#endif // BOOST_COROUTINES_DETAIL_PULL_COROUTINE_BASE_H diff --git a/include/boost/coroutine/v2/detail/pull_coroutine_caller.hpp b/include/boost/coroutine/detail/pull_coroutine_caller.hpp similarity index 91% rename from include/boost/coroutine/v2/detail/pull_coroutine_caller.hpp rename to include/boost/coroutine/detail/pull_coroutine_caller.hpp index 0e9cf44..8c66215 100644 --- a/include/boost/coroutine/v2/detail/pull_coroutine_caller.hpp +++ b/include/boost/coroutine/detail/pull_coroutine_caller.hpp @@ -3,15 +3,15 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#ifndef BOOST_COROUTINES_UNIDIRECT_DETAIL_PULL_COROUTINE_CALLER_H -#define BOOST_COROUTINES_UNIDIRECT_DETAIL_PULL_COROUTINE_CALLER_H +#ifndef BOOST_COROUTINES_DETAIL_PULL_COROUTINE_CALLER_H +#define BOOST_COROUTINES_DETAIL_PULL_COROUTINE_CALLER_H #include #include #include #include -#include +#include #ifdef BOOST_HAS_ABI_HEADERS # include BOOST_ABI_PREFIX @@ -108,4 +108,4 @@ private: # include BOOST_ABI_SUFFIX #endif -#endif // BOOST_COROUTINES_UNIDIRECT_DETAIL_PULL_COROUTINE_CALLER_H +#endif // BOOST_COROUTINES_DETAIL_PULL_COROUTINE_CALLER_H diff --git a/include/boost/coroutine/v2/detail/pull_coroutine_object.hpp b/include/boost/coroutine/detail/pull_coroutine_object.hpp similarity index 99% rename from include/boost/coroutine/v2/detail/pull_coroutine_object.hpp rename to include/boost/coroutine/detail/pull_coroutine_object.hpp index 30affdc..f432f1c 100644 --- a/include/boost/coroutine/v2/detail/pull_coroutine_object.hpp +++ b/include/boost/coroutine/detail/pull_coroutine_object.hpp @@ -4,8 +4,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#ifndef BOOST_COROUTINES_UNIDIRECT_DETAIL_PULL_COROUTINE_OBJECT_H -#define BOOST_COROUTINES_UNIDIRECT_DETAIL_PULL_COROUTINE_OBJECT_H +#ifndef BOOST_COROUTINES_DETAIL_PULL_COROUTINE_OBJECT_H +#define BOOST_COROUTINES_DETAIL_PULL_COROUTINE_OBJECT_H #include @@ -29,7 +29,7 @@ #include #include #include -#include +#include #ifdef BOOST_MSVC #pragma warning (push) @@ -1121,4 +1121,4 @@ public: #pragma warning (pop) #endif -#endif // BOOST_COROUTINES_UNIDIRECT_DETAIL_PULL_COROUTINE_OBJECT_H +#endif // BOOST_COROUTINES_DETAIL_PULL_COROUTINE_OBJECT_H diff --git a/include/boost/coroutine/v2/detail/push_coroutine_base.hpp b/include/boost/coroutine/detail/push_coroutine_base.hpp similarity index 98% rename from include/boost/coroutine/v2/detail/push_coroutine_base.hpp rename to include/boost/coroutine/detail/push_coroutine_base.hpp index 511da61..c74f358 100644 --- a/include/boost/coroutine/v2/detail/push_coroutine_base.hpp +++ b/include/boost/coroutine/detail/push_coroutine_base.hpp @@ -4,8 +4,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#ifndef BOOST_COROUTINES_UNIDIRECT_DETAIL_PUSH_COROUTINE_BASE_H -#define BOOST_COROUTINES_UNIDIRECT_DETAIL_PUSH_COROUTINE_BASE_H +#ifndef BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_BASE_H +#define BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_BASE_H #include #include @@ -351,4 +351,4 @@ public: # include BOOST_ABI_SUFFIX #endif -#endif // BOOST_COROUTINES_UNIDIRECT_DETAIL_PUSH_COROUTINE_BASE_H +#endif // BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_BASE_H diff --git a/include/boost/coroutine/v2/detail/push_coroutine_caller.hpp b/include/boost/coroutine/detail/push_coroutine_caller.hpp similarity index 83% rename from include/boost/coroutine/v2/detail/push_coroutine_caller.hpp rename to include/boost/coroutine/detail/push_coroutine_caller.hpp index 3c627f7..a8d7a84 100644 --- a/include/boost/coroutine/v2/detail/push_coroutine_caller.hpp +++ b/include/boost/coroutine/detail/push_coroutine_caller.hpp @@ -3,14 +3,14 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#ifndef BOOST_COROUTINES_UNIDIRECT_DETAIL_PUSH_COROUTINE_CALLER_H -#define BOOST_COROUTINES_UNIDIRECT_DETAIL_PUSH_COROUTINE_CALLER_H +#ifndef BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_CALLER_H +#define BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_CALLER_H #include #include #include -#include +#include #ifdef BOOST_HAS_ABI_HEADERS # include BOOST_ABI_PREFIX @@ -53,4 +53,4 @@ private: # include BOOST_ABI_SUFFIX #endif -#endif // BOOST_COROUTINES_UNIDIRECT_DETAIL_PUSH_COROUTINE_CALLER_H +#endif // BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_CALLER_H diff --git a/include/boost/coroutine/v2/detail/push_coroutine_object.hpp b/include/boost/coroutine/detail/push_coroutine_object.hpp similarity index 99% rename from include/boost/coroutine/v2/detail/push_coroutine_object.hpp rename to include/boost/coroutine/detail/push_coroutine_object.hpp index 0f840f2..bce670b 100644 --- a/include/boost/coroutine/v2/detail/push_coroutine_object.hpp +++ b/include/boost/coroutine/detail/push_coroutine_object.hpp @@ -4,8 +4,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#ifndef BOOST_COROUTINES_UNIDIRECT_DETAIL_PUSH_COROUTINE_OBJECT_H -#define BOOST_COROUTINES_UNIDIRECT_DETAIL_PUSH_COROUTINE_OBJECT_H +#ifndef BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_OBJECT_H +#define BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_OBJECT_H #include @@ -29,7 +29,7 @@ #include #include #include -#include +#include #ifdef BOOST_MSVC #pragma warning (push) @@ -1205,4 +1205,4 @@ public: #pragma warning (pop) #endif -#endif // BOOST_COROUTINES_UNIDIRECT_DETAIL_PUSH_COROUTINE_OBJECT_H +#endif // BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_OBJECT_H diff --git a/include/boost/coroutine/v1/coroutine.hpp b/include/boost/coroutine/v1/coroutine.hpp deleted file mode 100644 index ae1374e..0000000 --- a/include/boost/coroutine/v1/coroutine.hpp +++ /dev/null @@ -1,1430 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// 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) - -#ifndef BOOST_COROUTINES_OLD_COROUTINE_H -#define BOOST_COROUTINES_OLD_COROUTINE_H - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace boost { -namespace coroutines { -namespace detail { - -template< - typename Signature, - template< class, int > class C, - typename Result = typename function_traits< Signature >::result_type, - int arity = function_traits< Signature >::arity -> -struct caller; - -template< - typename Signature, - template< class, int > class C -> -struct caller< Signature, C, void, 0 > -{ typedef C< void(), 0 > type; }; - -template< - typename Signature, - template< class, int > class C, - typename Result -> -struct caller< Signature, C, Result, 0 > -{ typedef C< void( Result), 1 > type; }; - -template< - typename Signature, - template< class, int > class C, - int arity -> -struct caller< Signature, C, void, arity > -{ typedef C< typename detail::arg< Signature >::type(), 0 > type; }; - -template< - typename Signature, - template< class, int > class C, - typename Result, int arity -> -struct caller -{ typedef C< typename detail::arg< Signature >::type( Result), 1 > type; }; - -} - -template< typename Signature, int arity = function_traits< Signature >::arity > -class coroutine; - -template< typename Signature > -class coroutine< Signature, 0 > : public detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >, - public detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > -{ -private: - typedef detail::coroutine_base< Signature > base_t; - typedef typename base_t::ptr_t ptr_t; - - template< typename X, typename Y, int > - friend struct detail::coroutine_get; - template< typename X, typename Y, typename Z, int > - friend struct detail::coroutine_op; - template< typename X, typename Y, typename Z, typename A, typename B, typename C, int > - friend class detail::coroutine_object; - - struct dummy - { void nonnull() {} }; - - typedef void ( dummy::*safe_bool)(); - - ptr_t impl_; - - BOOST_MOVABLE_BUT_NOT_COPYABLE( coroutine) - - template< typename Allocator > - coroutine( detail::coroutine_context const& callee, - bool unwind, bool preserve_fpu, - Allocator const& alloc) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - - >(), - impl_() - { - typedef detail::coroutine_caller< - Signature, Allocator - > caller_t; - typename caller_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) caller_t( - callee, unwind, preserve_fpu, a) ); - } - -public: - typedef typename detail::caller< - Signature, - boost::coroutines::coroutine - >::type caller_type; - - coroutine() BOOST_NOEXCEPT : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - {} - -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES -#ifdef BOOST_MSVC - typedef void ( * coroutine_fn) ( caller_type &); - - explicit coroutine( coroutine_fn fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< coroutine > const& alloc = - std::allocator< coroutine >() ) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { - typedef detail::coroutine_object< - Signature, - coroutine_fn, stack_allocator, std::allocator< coroutine >, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); - } - - template< typename StackAllocator > - explicit coroutine( coroutine_fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< coroutine > const& alloc = - std::allocator< coroutine >() ) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { - typedef detail::coroutine_object< - Signature, - coroutine_fn, StackAllocator, std::allocator< coroutine >, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); - } - - template< typename StackAllocator, typename Allocator > - explicit coroutine( coroutine_fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { - typedef detail::coroutine_object< - Signature, - coroutine_fn, StackAllocator, Allocator, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); - } -#endif - template< typename Fn > - explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< coroutine > const& alloc = - std::allocator< coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, coroutine >, - dummy * - >::type = 0) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { -// BOOST_STATIC_ASSERT(( -// is_same< void, typename result_of< Fn() >::type >::value)); - typedef detail::coroutine_object< - Signature, - Fn, stack_allocator, std::allocator< coroutine >, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator > - explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< coroutine > const& alloc = - std::allocator< coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, coroutine >, - dummy * - >::type = 0) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { -// BOOST_STATIC_ASSERT(( -// is_same< void, typename result_of< Fn() >::type >::value)); - typedef detail::coroutine_object< - Signature, - Fn, StackAllocator, std::allocator< coroutine >, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator, typename Allocator > - explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, coroutine >, - dummy * - >::type = 0) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { -// BOOST_STATIC_ASSERT(( -// is_same< void, typename result_of< Fn() >::type >::value)); - typedef detail::coroutine_object< - Signature, - Fn, StackAllocator, Allocator, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); - } -#else - template< typename Fn > - explicit coroutine( Fn fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< coroutine > const& alloc = - std::allocator< coroutine >(), - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type = 0) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { -// BOOST_STATIC_ASSERT(( -// is_same< void, typename result_of< Fn() >::type >::value)); - typedef detail::coroutine_object< - Signature, - Fn, stack_allocator, std::allocator< coroutine >, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator > - explicit coroutine( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< coroutine > const& alloc = - std::allocator< coroutine >(), - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type = 0) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { -// BOOST_STATIC_ASSERT(( -// is_same< void, typename result_of< Fn() >::type >::value)); - typedef detail::coroutine_object< - Signature, - Fn, StackAllocator, std::allocator< coroutine >, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator, typename Allocator > - explicit coroutine( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type = 0) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { -// BOOST_STATIC_ASSERT(( -// is_same< void, typename result_of< Fn() >::type >::value)); - typedef detail::coroutine_object< - Signature, - Fn, StackAllocator, Allocator, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } - - template< typename Fn > - explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< coroutine > const& alloc = - std::allocator< coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, coroutine >, - dummy * - >::type = 0) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { -// BOOST_STATIC_ASSERT(( -// is_same< void, typename result_of< Fn() >::type >::value)); - typedef detail::coroutine_object< - Signature, - Fn, stack_allocator, std::allocator< coroutine >, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator > - explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< coroutine > const& alloc = - std::allocator< coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, coroutine >, - dummy * - >::type = 0) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { -// BOOST_STATIC_ASSERT(( -// is_same< void, typename result_of< Fn() >::type >::value)); - typedef detail::coroutine_object< - Signature, - Fn, StackAllocator, std::allocator< coroutine >, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator, typename Allocator > - explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, coroutine >, - dummy * - >::type = 0) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { -// BOOST_STATIC_ASSERT(( -// is_same< void, typename result_of< Fn() >::type >::value)); - typedef detail::coroutine_object< - Signature, - Fn, StackAllocator, Allocator, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } -#endif - - coroutine( BOOST_RV_REF( coroutine) other) BOOST_NOEXCEPT : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { swap( other); } - - coroutine & operator=( BOOST_RV_REF( coroutine) other) BOOST_NOEXCEPT - { - coroutine tmp( boost::move( other) ); - swap( tmp); - return * this; - } - - bool empty() const BOOST_NOEXCEPT - { return ! impl_; } - - operator safe_bool() const BOOST_NOEXCEPT - { return ( empty() || impl_->is_complete() ) ? 0 : & dummy::nonnull; } - - bool operator!() const BOOST_NOEXCEPT - { return empty() || impl_->is_complete(); } - - void swap( coroutine & other) BOOST_NOEXCEPT - { impl_.swap( other.impl_); } -}; - -template< typename Signature, int arity > -class coroutine : public detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >, - public detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > -{ -private: - typedef detail::coroutine_base< Signature > base_t; - typedef typename base_t::ptr_t ptr_t; - - template< typename X, typename Y, int > - friend struct detail::coroutine_get; - template< typename X, typename Y, typename Z, int > - friend struct detail::coroutine_op; - template< typename X, typename Y, typename Z, typename A, typename B, typename C, int > - friend class detail::coroutine_object; - - struct dummy - { void nonnull() {} }; - - typedef void ( dummy::*safe_bool)(); - - ptr_t impl_; - - BOOST_MOVABLE_BUT_NOT_COPYABLE( coroutine) - - template< typename Allocator > - coroutine( detail::coroutine_context const& callee, - bool unwind, bool preserve_fpu, - Allocator const& alloc) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { - typedef detail::coroutine_caller< - Signature, Allocator - > caller_t; - typename caller_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) caller_t( - callee, unwind, preserve_fpu, a) ); - } - -public: - typedef typename detail::caller< - Signature, - boost::coroutines::coroutine - >::type caller_type; - typedef typename detail::arg< Signature >::type arguments; - - coroutine() BOOST_NOEXCEPT : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - {} - -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES -#ifdef BOOST_MSVC - typedef void ( * coroutine_fn) ( caller_type &); - - explicit coroutine( coroutine_fn fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< coroutine > const& alloc = - std::allocator< coroutine >() ) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { - typedef detail::coroutine_object< - Signature, - coroutine_fn, stack_allocator, std::allocator< coroutine >, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); - } - - explicit coroutine( coroutine_fn fn, arguments arg, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< coroutine > const& alloc = - std::allocator< coroutine >() ) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { - typedef detail::coroutine_object< - Signature, - coroutine_fn, stack_allocator, std::allocator< coroutine >, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), arg, attr, stack_alloc, a) ); - } - - template< typename StackAllocator > - explicit coroutine( coroutine_fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< coroutine > const& alloc = - std::allocator< coroutine >() ) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { - typedef detail::coroutine_object< - Signature, - coroutine_fn, StackAllocator, std::allocator< coroutine >, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); - } - - template< typename StackAllocator, typename Allocator > - explicit coroutine( coroutine_fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { - typedef detail::coroutine_object< - Signature, - coroutine_fn, StackAllocator, Allocator, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); - } -#endif - template< typename Fn > - explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< coroutine > const& alloc = - std::allocator< coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, coroutine >, - dummy * - >::type = 0) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { -// BOOST_STATIC_ASSERT(( -// is_same< void, typename result_of< Fn() >::type >::value)); - typedef detail::coroutine_object< - Signature, - Fn, stack_allocator, std::allocator< coroutine >, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); - } - - template< typename Fn > - explicit coroutine( BOOST_RV_REF( Fn) fn, arguments arg, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< coroutine > const& alloc = - std::allocator< coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, coroutine >, - dummy * - >::type = 0) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { -// BOOST_STATIC_ASSERT(( -// is_same< void, typename result_of< Fn() >::type >::value)); - typedef detail::coroutine_object< - Signature, - Fn, stack_allocator, std::allocator< coroutine >, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), arg, attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator > - explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< coroutine > const& alloc = - std::allocator< coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, coroutine >, - dummy * - >::type = 0) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { -// BOOST_STATIC_ASSERT(( -// is_same< void, typename result_of< Fn() >::type >::value)); - typedef detail::coroutine_object< - Signature, - Fn, StackAllocator, std::allocator< coroutine >, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator > - explicit coroutine( BOOST_RV_REF( Fn) fn, arguments arg, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< coroutine > const& alloc = - std::allocator< coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, coroutine >, - dummy * - >::type = 0) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { -// BOOST_STATIC_ASSERT(( -// is_same< void, typename result_of< Fn() >::type >::value)); - typedef detail::coroutine_object< - Signature, - Fn, StackAllocator, std::allocator< coroutine >, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), arg, attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator, typename Allocator > - explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, coroutine >, - dummy * - >::type = 0) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { -// BOOST_STATIC_ASSERT(( -// is_same< void, typename result_of< Fn() >::type >::value)); - typedef detail::coroutine_object< - Signature, - Fn, StackAllocator, Allocator, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator, typename Allocator > - explicit coroutine( BOOST_RV_REF( Fn) fn, arguments arg, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, coroutine >, - dummy * - >::type = 0) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { -// BOOST_STATIC_ASSERT(( -// is_same< void, typename result_of< Fn() >::type >::value)); - typedef detail::coroutine_object< - Signature, - Fn, StackAllocator, Allocator, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), arg, attr, stack_alloc, a) ); - } -#else - template< typename Fn > - explicit coroutine( Fn fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< coroutine > const& alloc = - std::allocator< coroutine >(), - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type = 0) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { -// BOOST_STATIC_ASSERT(( -// is_same< void, typename result_of< Fn() >::type >::value)); - typedef detail::coroutine_object< - Signature, - Fn, stack_allocator, std::allocator< coroutine >, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } - - template< typename Fn > - explicit coroutine( Fn fn, arguments arg, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< coroutine > const& alloc = - std::allocator< coroutine >(), - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type = 0) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { -// BOOST_STATIC_ASSERT(( -// is_same< void, typename result_of< Fn() >::type >::value)); - typedef detail::coroutine_object< - Signature, - Fn, stack_allocator, std::allocator< coroutine >, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, arg, attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator > - explicit coroutine( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< coroutine > const& alloc = - std::allocator< coroutine >(), - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type = 0) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { -// BOOST_STATIC_ASSERT(( -// is_same< void, typename result_of< Fn() >::type >::value)); - typedef detail::coroutine_object< - Signature, - Fn, StackAllocator, std::allocator< coroutine >, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator, typename Allocator > - explicit coroutine( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type = 0) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { -// BOOST_STATIC_ASSERT(( -// is_same< void, typename result_of< Fn() >::type >::value)); - typedef detail::coroutine_object< - Signature, - Fn, StackAllocator, Allocator, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } - - template< typename Fn > - explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< coroutine > const& alloc = - std::allocator< coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, coroutine >, - dummy * - >::type = 0) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { -// BOOST_STATIC_ASSERT(( -// is_same< void, typename result_of< Fn() >::type >::value)); - typedef detail::coroutine_object< - Signature, - Fn, stack_allocator, std::allocator< coroutine >, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator > - explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< coroutine > const& alloc = - std::allocator< coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, coroutine >, - dummy * - >::type = 0) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { -// BOOST_STATIC_ASSERT(( -// is_same< void, typename result_of< Fn() >::type >::value)); - typedef detail::coroutine_object< - Signature, - Fn, StackAllocator, std::allocator< coroutine >, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator, typename Allocator > - explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, coroutine >, - dummy * - >::type = 0) : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { -// BOOST_STATIC_ASSERT(( -// is_same< void, typename result_of< Fn() >::type >::value)); - typedef detail::coroutine_object< - Signature, - Fn, StackAllocator, Allocator, - caller_type, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } -#endif - - coroutine( BOOST_RV_REF( coroutine) other) BOOST_NOEXCEPT : - detail::coroutine_op< - Signature, - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - detail::coroutine_get< - coroutine< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - impl_() - { swap( other); } - - coroutine & operator=( BOOST_RV_REF( coroutine) other) BOOST_NOEXCEPT - { - coroutine tmp( boost::move( other) ); - swap( tmp); - return * this; - } - - bool empty() const BOOST_NOEXCEPT - { return ! impl_; } - - operator safe_bool() const BOOST_NOEXCEPT - { return ( empty() || impl_->is_complete() ) ? 0 : & dummy::nonnull; } - - bool operator!() const BOOST_NOEXCEPT - { return empty() || impl_->is_complete(); } - - void swap( coroutine & other) BOOST_NOEXCEPT - { impl_.swap( other.impl_); } -}; - -template< typename Signature > -void swap( coroutine< Signature > & l, coroutine< Signature > & r) BOOST_NOEXCEPT -{ l.swap( r); } - -template< typename Signature > -inline -typename coroutine< Signature >::iterator -range_begin( coroutine< Signature > & c) -{ return typename coroutine< Signature >::iterator( & c); } - -template< typename Signature > -inline -typename coroutine< Signature >::const_iterator -range_begin( coroutine< Signature > const& c) -{ return typename coroutine< Signature >::const_iterator( & c); } - -template< typename Signature > -inline -typename coroutine< Signature >::iterator -range_end( coroutine< Signature > &) -{ return typename coroutine< Signature >::iterator(); } - -template< typename Signature > -inline -typename coroutine< Signature >::const_iterator -range_end( coroutine< Signature > const&) -{ return typename coroutine< Signature >::const_iterator(); } - -template< typename Signature > -inline -typename coroutine< Signature >::iterator -begin( coroutine< Signature > & c) -{ return boost::begin( c); } - -template< typename Signature > -inline -typename coroutine< Signature >::iterator -end( coroutine< Signature > & c) -{ return boost::end( c); } - -template< typename Signature > -inline -typename coroutine< Signature >::const_iterator -begin( coroutine< Signature > const& c) -{ return boost::const_begin( c); } - -template< typename Signature > -inline -typename coroutine< Signature >::const_iterator -end( coroutine< Signature > const& c) -{ return boost::const_end( c); } - -} - -template< typename Signature > -struct range_mutable_iterator< coroutines::coroutine< Signature > > -{ typedef typename coroutines::coroutine< Signature >::iterator type; }; - -template< typename Signature > -struct range_const_iterator< coroutines::coroutine< Signature > > -{ typedef typename coroutines::coroutine< Signature >::const_iterator type; }; - -} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_COROUTINES_OLD_COROUTINE_H diff --git a/include/boost/coroutine/v1/detail/arg.hpp b/include/boost/coroutine/v1/detail/arg.hpp deleted file mode 100644 index cecefd0..0000000 --- a/include/boost/coroutine/v1/detail/arg.hpp +++ /dev/null @@ -1,62 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// 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) - -#ifndef BOOST_COROUTINES_OLD_DETAIL_ARG_H -#define BOOST_COROUTINES_OLD_DETAIL_ARG_H - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace boost { -namespace coroutines { -namespace detail { - -template< - typename Signature, - int arity = function_traits< Signature >::arity > -struct arg; - -template< typename Signature > -struct arg< Signature, 1 > -{ - typedef typename function_traits< Signature >::arg1_type type; -}; - -#define BOOST_CONTEXT_TUPLE_COMMA(n) BOOST_PP_COMMA_IF(BOOST_PP_SUB(n,1)) -#define BOOST_CONTEXT_TUPLE_TYPE(z,n,unused) \ - BOOST_CONTEXT_TUPLE_COMMA(n) typename function_traits< Signature >::BOOST_PP_CAT(BOOST_PP_CAT(arg,n),_type) -#define BOOST_CONTEXT_TUPLE_TYPES(n) BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(n,1),BOOST_CONTEXT_TUPLE_TYPE,~) -#define BOOST_CONTEXT_TUPLE(z,n,unused) \ -template< typename Signature > \ -struct arg< Signature, n > \ -{ \ - typedef tuple< BOOST_CONTEXT_TUPLE_TYPES(n) > type; \ -}; -BOOST_PP_REPEAT_FROM_TO(2,11,BOOST_CONTEXT_TUPLE,~) -#undef BOOST_CONTEXT_TUPLE -#undef BOOST_CONTEXT_TUPLE_TYPES -#undef BOOST_CONTEXT_TUPLE_TYPE -#undef BOOST_CONTEXT_TUPLE_COMMA - -}}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_COROUTINES_OLD_DETAIL_ARG_H diff --git a/include/boost/coroutine/v1/detail/coroutine_base.hpp b/include/boost/coroutine/v1/detail/coroutine_base.hpp deleted file mode 100644 index 07e94f6..0000000 --- a/include/boost/coroutine/v1/detail/coroutine_base.hpp +++ /dev/null @@ -1,125 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// 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) - -#ifndef BOOST_COROUTINES_OLD_DETAIL_COROUTINE_BASE_H -#define BOOST_COROUTINES_OLD_DETAIL_COROUTINE_BASE_H - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace boost { -namespace coroutines { - -struct stack_context; - -namespace detail { - -template< typename Signature > -class coroutine_base : private noncopyable, - public coroutine_base_resume< - Signature, - coroutine_base< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - > -{ -public: - typedef intrusive_ptr< coroutine_base > ptr_t; - -private: - template< typename X, typename Y, typename Z, int > - friend class coroutine_base_resume; - template< typename X, typename Y, typename Z, typename A, typename B, typename C, int > - friend class coroutine_object; - - unsigned int use_count_; - coroutine_context caller_; - coroutine_context callee_; - int flags_; - exception_ptr except_; - -protected: - virtual void deallocate_object() = 0; - -public: - coroutine_base( coroutine_context::ctx_fn fn, stack_context * stack_ctx, - bool unwind, bool preserve_fpu) : - coroutine_base_resume< - Signature, - coroutine_base< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - use_count_( 0), - caller_(), - callee_( fn, stack_ctx), - flags_( 0), - except_() - { - if ( unwind) flags_ |= flag_force_unwind; - if ( preserve_fpu) flags_ |= flag_preserve_fpu; - } - - coroutine_base( coroutine_context const& callee, bool unwind, bool preserve_fpu) : - coroutine_base_resume< - Signature, - coroutine_base< Signature >, - typename function_traits< Signature >::result_type, - function_traits< Signature >::arity - >(), - use_count_( 0), - caller_(), - callee_( callee), - flags_( 0), - except_() - { - if ( unwind) flags_ |= flag_force_unwind; - if ( preserve_fpu) flags_ |= flag_preserve_fpu; - } - - virtual ~coroutine_base() - {} - - bool force_unwind() const BOOST_NOEXCEPT - { return 0 != ( flags_ & flag_force_unwind); } - - bool unwind_requested() const BOOST_NOEXCEPT - { return 0 != ( flags_ & flag_unwind_stack); } - - bool preserve_fpu() const BOOST_NOEXCEPT - { return 0 != ( flags_ & flag_preserve_fpu); } - - bool is_complete() const BOOST_NOEXCEPT - { return 0 != ( flags_ & flag_complete); } - - friend inline void intrusive_ptr_add_ref( coroutine_base * p) BOOST_NOEXCEPT - { ++p->use_count_; } - - friend inline void intrusive_ptr_release( coroutine_base * p) BOOST_NOEXCEPT - { if ( --p->use_count_ == 0) p->deallocate_object(); } -}; - -}}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_COROUTINES_OLD_DETAIL_COROUTINE_BASE_H diff --git a/include/boost/coroutine/v1/detail/coroutine_base_resume.hpp b/include/boost/coroutine/v1/detail/coroutine_base_resume.hpp deleted file mode 100644 index a932edd..0000000 --- a/include/boost/coroutine/v1/detail/coroutine_base_resume.hpp +++ /dev/null @@ -1,237 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// 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) - -#ifndef BOOST_COROUTINES_OLD_DETAIL_COROUTINE_BASE_RESUME_H -#define BOOST_COROUTINES_OLD_DETAIL_COROUTINE_BASE_RESUME_H - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace boost { -namespace coroutines { -namespace detail { - -template< typename Signature, typename D, typename Result, int arity > -class coroutine_base_resume; - -template< typename Signature, typename D > -class coroutine_base_resume< Signature, D, void, 0 > -{ -public: - void resume() - { - holder< void > hldr_to( & static_cast< D * >( this)->caller_); - holder< void > * hldr_from( - reinterpret_cast< holder< void > * >( - hldr_to.ctx->jump( - static_cast< D * >( this)->callee_, - reinterpret_cast< intptr_t >( & hldr_to), - static_cast< D * >( this)->preserve_fpu() ) ) ); - BOOST_ASSERT( hldr_from->ctx); - static_cast< D * >( this)->callee_ = * hldr_from->ctx; - if ( hldr_from->force_unwind) throw forced_unwind(); - if ( static_cast< D * >( this)->except_) - rethrow_exception( static_cast< D * >( this)->except_); - } -}; - -template< typename Signature, typename D, typename Result > -class coroutine_base_resume< Signature, D, Result, 0 > -{ -public: - void resume() - { - BOOST_ASSERT( static_cast< D * >( this)); - BOOST_ASSERT( ! static_cast< D * >( this)->is_complete() ); - - holder< void > hldr_to( & static_cast< D * >( this)->caller_); - holder< Result > * hldr_from( - reinterpret_cast< holder< Result > * >( - hldr_to.ctx->jump( - static_cast< D * >( this)->callee_, - reinterpret_cast< intptr_t >( & hldr_to), - static_cast< D * >( this)->preserve_fpu() ) ) ); - BOOST_ASSERT( hldr_from->ctx); - static_cast< D * >( this)->callee_ = * hldr_from->ctx; - result_ = hldr_from->data; - if ( hldr_from->force_unwind) throw forced_unwind(); - if ( static_cast< D * >( this)->except_) - rethrow_exception( static_cast< D * >( this)->except_); - } - -protected: - template< typename X, typename Y, int > - friend struct coroutine_get; - - optional< Result > result_; -}; - -template< typename Signature, typename D > -class coroutine_base_resume< Signature, D, void, 1 > -{ -public: - typedef typename arg< Signature >::type arg_type; - - void resume( arg_type a1) - { - BOOST_ASSERT( static_cast< D * >( this)); - BOOST_ASSERT( ! static_cast< D * >( this)->is_complete() ); - - holder< arg_type > hldr_to( & static_cast< D * >( this)->caller_, a1); - holder< void > * hldr_from( - reinterpret_cast< holder< void > * >( - hldr_to.ctx->jump( - static_cast< D * >( this)->callee_, - reinterpret_cast< intptr_t >( & hldr_to), - static_cast< D * >( this)->preserve_fpu() ) ) ); - BOOST_ASSERT( hldr_from->ctx); - static_cast< D * >( this)->callee_ = * hldr_from->ctx; - if ( hldr_from->force_unwind) throw forced_unwind(); - if ( static_cast< D * >( this)->except_) - rethrow_exception( static_cast< D * >( this)->except_); - } -}; - -template< typename Signature, typename D, typename Result > -class coroutine_base_resume< Signature, D, Result, 1 > -{ -public: - typedef typename arg< Signature >::type arg_type; - - void resume( arg_type a1) - { - BOOST_ASSERT( static_cast< D * >( this)); - BOOST_ASSERT( ! static_cast< D * >( this)->is_complete() ); - - coroutine_context caller; - holder< arg_type > hldr_to( & static_cast< D * >( this)->caller_, a1); - holder< Result > * hldr_from( - reinterpret_cast< holder< Result > * >( - hldr_to.ctx->jump( - static_cast< D * >( this)->callee_, - reinterpret_cast< intptr_t >( & hldr_to), - static_cast< D * >( this)->preserve_fpu() ) ) ); - BOOST_ASSERT( hldr_from->ctx); - static_cast< D * >( this)->callee_ = * hldr_from->ctx; - result_ = hldr_from->data; - if ( hldr_from->force_unwind) throw forced_unwind(); - if ( static_cast< D * >( this)->except_) - rethrow_exception( static_cast< D * >( this)->except_); - } - -protected: - template< typename X, typename Y, int > - friend struct coroutine_get; - - optional< Result > result_; -}; - -#define BOOST_COROUTINE_BASE_RESUME_COMMA(n) BOOST_PP_COMMA_IF(BOOST_PP_SUB(n,1)) -#define BOOST_COROUTINE_BASE_RESUME_VAL(z,n,unused) BOOST_COROUTINE_BASE_RESUME_COMMA(n) BOOST_PP_CAT(a,n) -#define BOOST_COROUTINE_BASE_RESUME_VALS(n) BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(n,1),BOOST_COROUTINE_BASE_RESUME_VAL,~) -#define BOOST_COROUTINE_BASE_RESUME_ARG_TYPE(n) \ - typename function_traits< Signature >::BOOST_PP_CAT(BOOST_PP_CAT(arg,n),_type) -#define BOOST_COROUTINE_BASE_RESUME_ARG(z,n,unused) BOOST_COROUTINE_BASE_RESUME_COMMA(n) BOOST_COROUTINE_BASE_RESUME_ARG_TYPE(n) BOOST_PP_CAT(a,n) -#define BOOST_COROUTINE_BASE_RESUME_ARGS(n) BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(n,1),BOOST_COROUTINE_BASE_RESUME_ARG,~) -#define BOOST_COROUTINE_BASE_RESUME(z,n,unused) \ -template< typename Signature, typename D > \ -class coroutine_base_resume< Signature, D, void, n > \ -{ \ -public: \ - typedef typename arg< Signature >::type arg_type; \ -\ - void resume( BOOST_COROUTINE_BASE_RESUME_ARGS(n)) \ - { \ - BOOST_ASSERT( static_cast< D * >( this)); \ - BOOST_ASSERT( ! static_cast< D * >( this)->is_complete() ); \ -\ - holder< arg_type > hldr_to( \ - & static_cast< D * >( this)->caller_, \ - arg_type(BOOST_COROUTINE_BASE_RESUME_VALS(n) ) ); \ - holder< void > * hldr_from( \ - reinterpret_cast< holder< void > * >( \ - hldr_to.ctx->jump( \ - static_cast< D * >( this)->callee_, \ - reinterpret_cast< intptr_t >( & hldr_to), \ - static_cast< D * >( this)->preserve_fpu() ) ) ); \ - BOOST_ASSERT( hldr_from->ctx); \ - static_cast< D * >( this)->callee_ = * hldr_from->ctx; \ - if ( hldr_from->force_unwind) throw forced_unwind(); \ - if ( static_cast< D * >( this)->except_) \ - rethrow_exception( static_cast< D * >( this)->except_); \ - } \ -}; \ -\ -template< typename Signature, typename D, typename Result > \ -class coroutine_base_resume< Signature, D, Result, n > \ -{ \ -public: \ - typedef typename arg< Signature >::type arg_type; \ -\ - void resume( BOOST_COROUTINE_BASE_RESUME_ARGS(n)) \ - { \ - BOOST_ASSERT( static_cast< D * >( this)); \ - BOOST_ASSERT( ! static_cast< D * >( this)->is_complete() ); \ -\ - holder< arg_type > hldr_to( \ - & static_cast< D * >( this)->caller_, \ - arg_type(BOOST_COROUTINE_BASE_RESUME_VALS(n) ) ); \ - holder< Result > * hldr_from( \ - reinterpret_cast< holder< Result > * >( \ - hldr_to.ctx->jump( \ - static_cast< D * >( this)->callee_, \ - reinterpret_cast< intptr_t >( & hldr_to), \ - static_cast< D * >( this)->preserve_fpu() ) ) ); \ - BOOST_ASSERT( hldr_from->ctx); \ - static_cast< D * >( this)->callee_ = * hldr_from->ctx; \ - result_ = hldr_from->data; \ - if ( hldr_from->force_unwind) throw forced_unwind(); \ - if ( static_cast< D * >( this)->except_) \ - rethrow_exception( static_cast< D * >( this)->except_); \ - } \ -\ -protected: \ - template< typename X, typename Y, int > \ - friend struct coroutine_get; \ -\ - optional< Result > result_; \ -}; -BOOST_PP_REPEAT_FROM_TO(2,11,BOOST_COROUTINE_BASE_RESUME,~) -#undef BOOST_COROUTINE_BASE_RESUME -#undef BOOST_COROUTINE_BASE_RESUME_ARGS -#undef BOOST_COROUTINE_BASE_RESUME_ARG -#undef BOOST_COROUTINE_BASE_RESUME_ARG_TYPE -#undef BOOST_COROUTINE_BASE_RESUME_VALS -#undef BOOST_COROUTINE_BASE_RESUME_VAL -#undef BOOST_COROUTINE_BASE_RESUME_COMMA - -}}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_COROUTINES_OLD_DETAIL_coroutine_base_resume_H diff --git a/include/boost/coroutine/v1/detail/coroutine_caller.hpp b/include/boost/coroutine/v1/detail/coroutine_caller.hpp deleted file mode 100644 index 7e0bb9f..0000000 --- a/include/boost/coroutine/v1/detail/coroutine_caller.hpp +++ /dev/null @@ -1,57 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// 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) - -#ifndef BOOST_COROUTINES_OLD_DETAIL_COROUTINE_CALLER_H -#define BOOST_COROUTINES_OLD_DETAIL_COROUTINE_CALLER_H - -#include -#include - -#include -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace boost { -namespace coroutines { -namespace detail { - -template< typename Signature, typename Allocator > -class coroutine_caller : public coroutine_base< Signature > -{ -public: - typedef typename Allocator::template rebind< - coroutine_caller< Signature, Allocator > - >::other allocator_t; - - coroutine_caller( coroutine_context const& callee, bool unwind, bool preserve_fpu, - allocator_t const& alloc) BOOST_NOEXCEPT : - coroutine_base< Signature >( callee, unwind, preserve_fpu), - alloc_( alloc) - {} - - void deallocate_object() - { destroy_( alloc_, this); } - -private: - allocator_t alloc_; - - static void destroy_( allocator_t & alloc, coroutine_caller * p) - { - alloc.destroy( p); - alloc.deallocate( p, 1); - } -}; - -}}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_COROUTINES_OLD_DETAIL_COROUTINE_CALLER_H diff --git a/include/boost/coroutine/v1/detail/coroutine_get.hpp b/include/boost/coroutine/v1/detail/coroutine_get.hpp deleted file mode 100644 index 26d0406..0000000 --- a/include/boost/coroutine/v1/detail/coroutine_get.hpp +++ /dev/null @@ -1,54 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// 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) - -#ifndef BOOST_COROUTINES_OLD_DETAIL_COROUTINE_GET_H -#define BOOST_COROUTINES_OLD_DETAIL_COROUTINE_GET_H - -#include -#include -#include - -#include -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace boost { -namespace coroutines { -namespace detail { - -template< - typename D, - typename Result, int arity -> -struct coroutine_get; - -template< typename D, int arity > -struct coroutine_get< D, void, arity > -{}; - -template< typename D, typename Result, int arity > -struct coroutine_get -{ - bool has_result() const - { return static_cast< D const* >( this)->impl_->result_; } - - typename param< Result >::type get() const - { - BOOST_ASSERT( static_cast< D const* >( this)->impl_->result_); - return static_cast< D const* >( this)->impl_->result_.get(); - } -}; - -}}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_COROUTINES_OLD_DETAIL_COROUTINE_GET_H diff --git a/include/boost/coroutine/v1/detail/coroutine_object.hpp b/include/boost/coroutine/v1/detail/coroutine_object.hpp deleted file mode 100644 index 2f260a3..0000000 --- a/include/boost/coroutine/v1/detail/coroutine_object.hpp +++ /dev/null @@ -1,74 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// 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) - -#ifndef BOOST_COROUTINES_OLD_DETAIL_COROUTINE_OBJECT_H -#define BOOST_COROUTINES_OLD_DETAIL_COROUTINE_OBJECT_H - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef BOOST_MSVC - #pragma warning (push) - #pragma warning (disable: 4355) // using 'this' in initializer list -#endif - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace boost { -namespace coroutines { -namespace detail { - -template< - typename Signature, - typename Fn, typename StackAllocator, typename Allocator, - typename Caller, - typename Result, int arity -> -class coroutine_object; - -#include -#include -#include -#include -#include -#include - -}}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#ifdef BOOST_MSVC - #pragma warning (pop) -#endif - -#endif // BOOST_COROUTINES_OLD_DETAIL_COROUTINE_OBJECT_H diff --git a/include/boost/coroutine/v1/detail/coroutine_object_result_0.ipp b/include/boost/coroutine/v1/detail/coroutine_object_result_0.ipp deleted file mode 100644 index 96022fc..0000000 --- a/include/boost/coroutine/v1/detail/coroutine_object_result_0.ipp +++ /dev/null @@ -1,363 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// 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) - -template< - typename Signature, - typename Fn, typename StackAllocator, typename Allocator, - typename Caller, - typename Result -> -class coroutine_object< Signature, Fn, StackAllocator, Allocator, Caller, Result, 0 > : - private stack_tuple< StackAllocator >, - public coroutine_base< Signature > -{ -public: - typedef typename Allocator::template rebind< - coroutine_object< - Signature, Fn, StackAllocator, Allocator, Caller, Result, 0 - > - >::other allocator_t; - -private: - typedef stack_tuple< StackAllocator > pbase_type; - typedef coroutine_base< Signature > base_type; - - Fn fn_; - allocator_t alloc_; - - static void destroy_( allocator_t & alloc, coroutine_object * p) - { - alloc.destroy( p); - alloc.deallocate( p, 1); - } - - coroutine_object( coroutine_object const&); - coroutine_object & operator=( coroutine_object const&); - - void enter_() - { - holder< Result > * hldr_from( - reinterpret_cast< holder< Result > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( this), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - this->result_ = hldr_from->data; - if ( this->except_) rethrow_exception( this->except_); - } - - void unwind_stack_() BOOST_NOEXCEPT - { - BOOST_ASSERT( ! this->is_complete() ); - - this->flags_ |= flag_unwind_stack; - holder< void > hldr_to( & this->caller_, true); - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - this->flags_ &= ~flag_unwind_stack; - - BOOST_ASSERT( this->is_complete() ); - } - -public: -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( forward< Fn >( fn) ), - alloc_( alloc) - { enter_(); } -#else - coroutine_object( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_(); } - - coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_(); } -#endif - - ~coroutine_object() - { - if ( ! this->is_complete() && this->force_unwind() ) - unwind_stack_(); - } - - void run() - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< Result > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void deallocate_object() - { destroy_( alloc_, this); } -}; - -template< - typename Signature, - typename Fn, typename StackAllocator, typename Allocator, - typename Caller, - typename Result -> -class coroutine_object< Signature, reference_wrapper< Fn >, StackAllocator, Allocator, Caller, Result, 0 > : - private stack_tuple< StackAllocator >, - public coroutine_base< Signature > -{ -public: - typedef typename Allocator::template rebind< - coroutine_object< - Signature, Fn, StackAllocator, Allocator, Caller, Result, 0 - > - >::other allocator_t; - -private: - typedef stack_tuple< StackAllocator > pbase_type; - typedef coroutine_base< Signature > base_type; - - Fn fn_; - allocator_t alloc_; - - static void destroy_( allocator_t & alloc, coroutine_object * p) - { - alloc.destroy( p); - alloc.deallocate( p, 1); - } - - coroutine_object( coroutine_object const&); - coroutine_object & operator=( coroutine_object const&); - - void enter_() - { - holder< Result > * hldr_from( - reinterpret_cast< holder< Result > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( this), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - this->result_ = hldr_from->data; - if ( this->except_) rethrow_exception( this->except_); - } - - void unwind_stack_() BOOST_NOEXCEPT - { - BOOST_ASSERT( ! this->is_complete() ); - - this->flags_ |= flag_unwind_stack; - holder< void > hldr_to( & this->caller_, true); - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - this->flags_ &= ~flag_unwind_stack; - - BOOST_ASSERT( this->is_complete() ); - } - -public: - coroutine_object( reference_wrapper< Fn > fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_(); } - - ~coroutine_object() - { - if ( ! this->is_complete() && this->force_unwind() ) - unwind_stack_(); - } - - void run() - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< Result > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void deallocate_object() - { destroy_( alloc_, this); } -}; - -template< - typename Signature, - typename Fn, typename StackAllocator, typename Allocator, - typename Caller, - typename Result -> -class coroutine_object< Signature, const reference_wrapper< Fn >, StackAllocator, Allocator, Caller, Result, 0 > : - private stack_tuple< StackAllocator >, - public coroutine_base< Signature > -{ -public: - typedef typename Allocator::template rebind< - coroutine_object< - Signature, Fn, StackAllocator, Allocator, Caller, Result, 0 - > - >::other allocator_t; - -private: - typedef stack_tuple< StackAllocator > pbase_type; - typedef coroutine_base< Signature > base_type; - - Fn fn_; - allocator_t alloc_; - - static void destroy_( allocator_t & alloc, coroutine_object * p) - { - alloc.destroy( p); - alloc.deallocate( p, 1); - } - - coroutine_object( coroutine_object const&); - coroutine_object & operator=( coroutine_object const&); - - void enter_() - { - holder< Result > * hldr_from( - reinterpret_cast< holder< Result > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( this), - this->preserve_fpu() ) ) ); - this->callee_ = hldr_from->ctx; - this->result_ = hldr_from->data; - if ( this->except_) rethrow_exception( this->except_); - } - - void unwind_stack_() BOOST_NOEXCEPT - { - BOOST_ASSERT( ! this->is_complete() ); - - this->flags_ |= flag_unwind_stack; - holder< void > hldr_to( & this->caller_, true); - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - this->flags_ &= ~flag_unwind_stack; - - BOOST_ASSERT( this->is_complete() ); - } - -public: - coroutine_object( const reference_wrapper< Fn > fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_(); } - - ~coroutine_object() - { - if ( ! this->is_complete() && this->force_unwind() ) - unwind_stack_(); - } - - void run() - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( & this->caller_, false, this->preserve_fpu(), alloc_); - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< Result > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void deallocate_object() - { destroy_( alloc_, this); } -}; diff --git a/include/boost/coroutine/v1/detail/coroutine_object_result_1.ipp b/include/boost/coroutine/v1/detail/coroutine_object_result_1.ipp deleted file mode 100644 index b1e5dfe..0000000 --- a/include/boost/coroutine/v1/detail/coroutine_object_result_1.ipp +++ /dev/null @@ -1,557 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// 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) - -template< - typename Signature, - typename Fn, typename StackAllocator, typename Allocator, - typename Caller, - typename Result -> -class coroutine_object< Signature, Fn, StackAllocator, Allocator, Caller, Result, 1 > : - private stack_tuple< StackAllocator >, - public coroutine_base< Signature > -{ -public: - typedef typename Allocator::template rebind< - coroutine_object< - Signature, Fn, StackAllocator, Allocator, Caller, Result, 1 - > - >::other allocator_t; - typedef typename arg< Signature >::type arg_type; - -private: - typedef stack_tuple< StackAllocator > pbase_type; - typedef coroutine_base< Signature > base_type; - - Fn fn_; - allocator_t alloc_; - - static void destroy_( allocator_t & alloc, coroutine_object * p) - { - alloc.destroy( p); - alloc.deallocate( p, 1); - } - - coroutine_object( coroutine_object &); - coroutine_object & operator=( coroutine_object const&); - - void enter_() - { - holder< Result > * hldr_from( - reinterpret_cast< holder< Result > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( this), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - this->result_ = hldr_from->data; - if ( this->except_) rethrow_exception( this->except_); - } - - void enter_( typename detail::param< arg_type >::type arg) - { - tuple< coroutine_object *, - typename detail::param< arg_type >::type - > tpl( this, arg); - holder< Result > * hldr_from( - reinterpret_cast< holder< Result > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & tpl), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - this->result_ = hldr_from->data; - if ( this->except_) rethrow_exception( this->except_); - } - - void unwind_stack_() BOOST_NOEXCEPT - { - BOOST_ASSERT( ! this->is_complete() ); - - this->flags_ |= flag_unwind_stack; - holder< arg_type > hldr_to( & this->caller_, true); - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - this->flags_ &= ~flag_unwind_stack; - - BOOST_ASSERT( this->is_complete() ); - } - -public: -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( forward< Fn >( fn) ), - alloc_( alloc) - { enter_(); } - - coroutine_object( BOOST_RV_REF( Fn) fn, typename detail::param< arg_type >::type arg, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline2< coroutine_object, typename detail::param< arg_type >::type >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( forward< Fn >( fn) ), - alloc_( alloc) - { enter_( arg); } -#else - coroutine_object( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_(); } - - coroutine_object( Fn fn, typename detail::param< arg_type >::type arg, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline2< coroutine_object, typename detail::param< arg_type >::type >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_( arg); } - - coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_(); } - - coroutine_object( BOOST_RV_REF( Fn) fn, typename detail::param< arg_type >::type arg, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline2< coroutine_object, typename detail::param< arg_type >::type >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_( arg); } -#endif - - ~coroutine_object() - { - if ( ! this->is_complete() && this->force_unwind() ) - unwind_stack_(); - } - - void run() - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< Result > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void run( typename detail::param< arg_type >::type arg) - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - c.impl_->result_ = arg; - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< Result > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void deallocate_object() - { destroy_( alloc_, this); } -}; - -template< - typename Signature, - typename Fn, typename StackAllocator, typename Allocator, - typename Caller, - typename Result -> -class coroutine_object< Signature, reference_wrapper< Fn >, StackAllocator, Allocator, Caller, Result, 1 > : - private stack_tuple< StackAllocator >, - public coroutine_base< Signature > -{ -public: - typedef typename Allocator::template rebind< - coroutine_object< - Signature, Fn, StackAllocator, Allocator, Caller, Result, 1 - > - >::other allocator_t; - typedef typename arg< Signature >::type arg_type; - -private: - typedef stack_tuple< StackAllocator > pbase_type; - typedef coroutine_base< Signature > base_type; - - Fn fn_; - allocator_t alloc_; - - static void destroy_( allocator_t & alloc, coroutine_object * p) - { - alloc.destroy( p); - alloc.deallocate( p, 1); - } - - coroutine_object( coroutine_object &); - coroutine_object & operator=( coroutine_object const&); - - void enter_() - { - holder< Result > * hldr_from( - reinterpret_cast< holder< Result > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( this), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - this->result_ = hldr_from->data; - if ( this->except_) rethrow_exception( this->except_); - } - - void enter_( typename detail::param< arg_type >::type arg) - { - tuple< coroutine_object *, - typename detail::param< arg_type >::type - > tpl( this, arg); - holder< Result > * hldr_from( - reinterpret_cast< holder< Result > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & tpl), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - this->result_ = hldr_from->data; - if ( this->except_) rethrow_exception( this->except_); - } - - void unwind_stack_() BOOST_NOEXCEPT - { - BOOST_ASSERT( ! this->is_complete() ); - - this->flags_ |= flag_unwind_stack; - holder< arg_type > hldr_to( & this->caller_, true); - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - this->flags_ &= ~flag_unwind_stack; - - BOOST_ASSERT( this->is_complete() ); - } - -public: - coroutine_object( reference_wrapper< Fn > fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_(); } - - coroutine_object( reference_wrapper< Fn > fn, typename detail::param< arg_type >::type arg, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline2< coroutine_object, typename detail::param< arg_type >::type >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_( arg); } - - ~coroutine_object() - { - if ( ! this->is_complete() && this->force_unwind() ) - unwind_stack_(); - } - - void run() - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< Result > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void run( typename detail::param< arg_type >::type arg) - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - c.impl_->result_ = arg; - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< Result > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void deallocate_object() - { destroy_( alloc_, this); } -}; - -template< - typename Signature, - typename Fn, typename StackAllocator, typename Allocator, - typename Caller, - typename Result -> -class coroutine_object< Signature, const reference_wrapper< Fn >, StackAllocator, Allocator, Caller, Result, 1 > : - private stack_tuple< StackAllocator >, - public coroutine_base< Signature > -{ -public: - typedef typename Allocator::template rebind< - coroutine_object< - Signature, Fn, StackAllocator, Allocator, Caller, Result, 1 - > - >::other allocator_t; - typedef typename arg< Signature >::type arg_type; - -private: - typedef stack_tuple< StackAllocator > pbase_type; - typedef coroutine_base< Signature > base_type; - - Fn fn_; - allocator_t alloc_; - - static void destroy_( allocator_t & alloc, coroutine_object * p) - { - alloc.destroy( p); - alloc.deallocate( p, 1); - } - - coroutine_object( coroutine_object &); - coroutine_object & operator=( coroutine_object const&); - - void enter_() - { - holder< Result > * hldr_from( - reinterpret_cast< holder< Result > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( this), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - this->result_ = hldr_from->data; - if ( this->except_) rethrow_exception( this->except_); - } - - void enter_( typename detail::param< arg_type >::type arg) - { - tuple< coroutine_object *, - typename detail::param< arg_type >::type - > tpl( this, arg); - holder< Result > * hldr_from( - reinterpret_cast< holder< Result > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & tpl), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - this->result_ = hldr_from->data; - if ( this->except_) rethrow_exception( this->except_); - } - - void unwind_stack_() BOOST_NOEXCEPT - { - BOOST_ASSERT( ! this->is_complete() ); - - this->flags_ |= flag_unwind_stack; - holder< arg_type > hldr_to( & this->caller_, true); - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - this->flags_ &= ~flag_unwind_stack; - - BOOST_ASSERT( this->is_complete() ); - } - -public: - coroutine_object( const reference_wrapper< Fn > fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_(); } - - coroutine_object( const reference_wrapper< Fn > fn, typename detail::param< arg_type >::type arg, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline2< coroutine_object, typename detail::param< arg_type >::type >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_( arg); } - - ~coroutine_object() - { - if ( ! this->is_complete() && this->force_unwind() ) - unwind_stack_(); - } - - void run() - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< Result > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void run( typename detail::param< arg_type >::type arg) - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - c.impl_->result_ = arg; - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< Result > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void deallocate_object() - { destroy_( alloc_, this); } -}; diff --git a/include/boost/coroutine/v1/detail/coroutine_object_result_arity.ipp b/include/boost/coroutine/v1/detail/coroutine_object_result_arity.ipp deleted file mode 100644 index c2728cb..0000000 --- a/include/boost/coroutine/v1/detail/coroutine_object_result_arity.ipp +++ /dev/null @@ -1,559 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// 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) - -template< - typename Signature, - typename Fn, typename StackAllocator, typename Allocator, - typename Caller, - typename Result, int arity -> -class coroutine_object : - private stack_tuple< StackAllocator >, - public coroutine_base< Signature > -{ -public: - typedef typename Allocator::template rebind< - coroutine_object< - Signature, Fn, StackAllocator, Allocator, Caller, Result, arity - > - >::other allocator_t; - typedef typename arg< Signature >::type arg_type; - -private: - typedef stack_tuple< StackAllocator > pbase_type; - typedef coroutine_base< Signature > base_type; - - Fn fn_; - allocator_t alloc_; - - static void destroy_( allocator_t & alloc, coroutine_object * p) - { - alloc.destroy( p); - alloc.deallocate( p, 1); - } - - coroutine_object( coroutine_object &); - coroutine_object & operator=( coroutine_object const&); - - void enter_() - { - holder< Result > * hldr_from( - reinterpret_cast< holder< Result > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( this), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - this->result_ = hldr_from->data; - if ( this->except_) rethrow_exception( this->except_); - } - - void enter_( typename detail::param< arg_type >::type arg) - { - tuple< coroutine_object *, - typename detail::param< arg_type >::type - > tpl( this, arg); - holder< Result > * hldr_from( - reinterpret_cast< holder< Result > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & tpl), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - this->result_ = hldr_from->data; - if ( this->except_) rethrow_exception( this->except_); - } - - void unwind_stack_() BOOST_NOEXCEPT - { - BOOST_ASSERT( ! this->is_complete() ); - - this->flags_ |= flag_unwind_stack; - holder< arg_type > hldr_to( & this->caller_, true); - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - this->flags_ &= ~flag_unwind_stack; - - BOOST_ASSERT( this->is_complete() ); - } - -public: -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( forward< Fn >( fn) ), - alloc_( alloc) - { enter_(); } - - coroutine_object( BOOST_RV_REF( Fn) fn, typename detail::param< arg_type >::type arg, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline2< coroutine_object, typename detail::param< arg_type >::type >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( forward< Fn >( fn) ), - alloc_( alloc) - { enter_( arg); } -#else - coroutine_object( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_(); } - - coroutine_object( Fn fn, typename detail::param< arg_type >::type arg, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline2< coroutine_object, typename detail::param< arg_type >::type >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_( arg); } - - coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_(); } - - coroutine_object( BOOST_RV_REF( Fn) fn, typename detail::param< arg_type >::type arg, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline2< coroutine_object, typename detail::param< arg_type >::type >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_( arg); } -#endif - - ~coroutine_object() - { - if ( ! this->is_complete() && this->force_unwind() ) - unwind_stack_(); - } - - void run() - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< Result > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void run( typename detail::param< arg_type >::type arg) - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - c.impl_->result_ = arg; - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< Result > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void deallocate_object() - { destroy_( alloc_, this); } -}; - -template< - typename Signature, - typename Fn, typename StackAllocator, typename Allocator, - typename Caller, - typename Result, int arity -> -class coroutine_object< Signature, reference_wrapper< Fn >, StackAllocator, Allocator, Caller, Result, arity > : - private stack_tuple< StackAllocator >, - public coroutine_base< Signature > -{ -public: - typedef typename Allocator::template rebind< - coroutine_object< - Signature, Fn, StackAllocator, Allocator, Caller, Result, arity - > - >::other allocator_t; - typedef typename arg< Signature >::type arg_type; - -private: - typedef stack_tuple< StackAllocator > pbase_type; - typedef coroutine_base< Signature > base_type; - - Fn fn_; - allocator_t alloc_; - - static void destroy_( allocator_t & alloc, coroutine_object * p) - { - alloc.destroy( p); - alloc.deallocate( p, 1); - } - - coroutine_object( coroutine_object &); - coroutine_object & operator=( coroutine_object const&); - - void enter_() - { - holder< Result > * hldr_from( - reinterpret_cast< holder< Result > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( this), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - this->result_ = hldr_from->data; - if ( this->except_) rethrow_exception( this->except_); - } - - void enter_( typename detail::param< arg_type >::type arg) - { - tuple< coroutine_object *, - typename detail::param< arg_type >::type - > tpl( this, arg); - holder< Result > * hldr_from( - reinterpret_cast< holder< Result > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & tpl), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - this->result_ = hldr_from->data; - if ( this->except_) rethrow_exception( this->except_); - } - - void unwind_stack_() BOOST_NOEXCEPT - { - BOOST_ASSERT( ! this->is_complete() ); - - this->flags_ |= flag_unwind_stack; - holder< arg_type > hldr_to( & this->caller_, true); - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - this->flags_ &= ~flag_unwind_stack; - - BOOST_ASSERT( this->is_complete() ); - } - -public: - coroutine_object( reference_wrapper< Fn > fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_(); } - - coroutine_object( reference_wrapper< Fn > fn, typename detail::param< arg_type >::type arg, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline2< coroutine_object, typename detail::param< arg_type >::type >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_( arg); } - - ~coroutine_object() - { - if ( ! this->is_complete() && this->force_unwind() ) - unwind_stack_(); - } - - void run() - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< Result > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void run( typename detail::param< arg_type >::type arg) - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - c.impl_->result_ = arg; - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< Result > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void deallocate_object() - { destroy_( alloc_, this); } -}; - -template< - typename Signature, - typename Fn, typename StackAllocator, typename Allocator, - typename Caller, - typename Result, int arity -> -class coroutine_object< Signature, const reference_wrapper< Fn >, StackAllocator, Allocator, Caller, Result, arity > : - private stack_tuple< StackAllocator >, - public coroutine_base< Signature > -{ -public: - typedef typename Allocator::template rebind< - coroutine_object< - Signature, Fn, StackAllocator, Allocator, Caller, Result, arity - > - >::other allocator_t; - typedef typename arg< Signature >::type arg_type; - -private: - typedef stack_tuple< StackAllocator > pbase_type; - typedef coroutine_base< Signature > base_type; - - Fn fn_; - allocator_t alloc_; - - static void destroy_( allocator_t & alloc, coroutine_object * p) - { - alloc.destroy( p); - alloc.deallocate( p, 1); - } - - coroutine_object( coroutine_object &); - coroutine_object & operator=( coroutine_object const&); - - void enter_() - { - holder< Result > * hldr_from( - reinterpret_cast< holder< Result > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( this), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - this->result_ = hldr_from->data; - if ( this->except_) rethrow_exception( this->except_); - } - - void enter_( typename detail::param< arg_type >::type arg) - { - tuple< coroutine_object *, - typename detail::param< arg_type >::type - > tpl( this, arg); - holder< Result > * hldr_from( - reinterpret_cast< holder< Result > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & tpl), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - this->result_ = hldr_from->data; - if ( this->except_) rethrow_exception( this->except_); - } - - void unwind_stack_() BOOST_NOEXCEPT - { - BOOST_ASSERT( ! this->is_complete() ); - - this->flags_ |= flag_unwind_stack; - holder< arg_type > hldr_to( & this->caller_, true); - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - this->flags_ &= ~flag_unwind_stack; - - BOOST_ASSERT( this->is_complete() ); - } - -public: - coroutine_object( const reference_wrapper< Fn > fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_(); } - - coroutine_object( const reference_wrapper< Fn > fn, typename detail::param< arg_type >::type arg, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline2< coroutine_object, typename detail::param< arg_type >::type >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_( arg); } - - ~coroutine_object() - { - if ( ! this->is_complete() && this->force_unwind() ) - unwind_stack_(); - } - - void run() - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< Result > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void run( typename detail::param< arg_type >::type arg) - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - c.impl_->result_ = arg; - try - { - fn_( c); - } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< Result > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void deallocate_object() - { destroy_( alloc_, this); } -}; diff --git a/include/boost/coroutine/v1/detail/coroutine_object_void_0.ipp b/include/boost/coroutine/v1/detail/coroutine_object_void_0.ipp deleted file mode 100644 index e20df6f..0000000 --- a/include/boost/coroutine/v1/detail/coroutine_object_void_0.ipp +++ /dev/null @@ -1,357 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// 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) - -template< - typename Signature, - typename Fn, typename StackAllocator, typename Allocator, - typename Caller -> -class coroutine_object< Signature, Fn, StackAllocator, Allocator, Caller, void, 0 > : - private stack_tuple< StackAllocator >, - public coroutine_base< Signature > -{ -public: - typedef typename Allocator::template rebind< - coroutine_object< - Signature, Fn, StackAllocator, Allocator, Caller, void, 0 - > - >::other allocator_t; - -private: - typedef stack_tuple< StackAllocator > pbase_type; - typedef coroutine_base< Signature > base_type; - - Fn fn_; - allocator_t alloc_; - - static void destroy_( allocator_t & alloc, coroutine_object * p) - { - alloc.destroy( p); - alloc.deallocate( p, 1); - } - - coroutine_object( coroutine_object const&); - coroutine_object & operator=( coroutine_object const&); - - void enter_() - { - holder< void > * hldr_from( - reinterpret_cast< holder< void > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( this), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - if ( this->except_) rethrow_exception( this->except_); - } - - void unwind_stack_() BOOST_NOEXCEPT - { - BOOST_ASSERT( ! this->is_complete() ); - - this->flags_ |= flag_unwind_stack; - holder< void > hldr_to( & this->caller_, true); - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - this->flags_ &= ~flag_unwind_stack; - - BOOST_ASSERT( this->is_complete() ); - } - -public: -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( forward< Fn >( fn) ), - alloc_( alloc) - { enter_(); } -#else - coroutine_object( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->pbase_type::stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_(); } - - coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_(); } -#endif - - ~coroutine_object() - { - if ( ! this->is_complete() && this->force_unwind() ) - unwind_stack_(); - } - - void run() - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< void > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void deallocate_object() - { destroy_( alloc_, this); } -}; - -template< - typename Signature, - typename Fn, typename StackAllocator, typename Allocator, - typename Caller -> -class coroutine_object< Signature, reference_wrapper< Fn >, StackAllocator, Allocator, Caller, void, 0 > : - private stack_tuple< StackAllocator >, - public coroutine_base< Signature > -{ -public: - typedef typename Allocator::template rebind< - coroutine_object< - Signature, Fn, StackAllocator, Allocator, Caller, void, 0 - > - >::other allocator_t; - -private: - typedef stack_tuple< StackAllocator > pbase_type; - typedef coroutine_base< Signature > base_type; - - Fn fn_; - allocator_t alloc_; - - static void destroy_( allocator_t & alloc, coroutine_object * p) - { - alloc.destroy( p); - alloc.deallocate( p, 1); - } - - coroutine_object( coroutine_object const&); - coroutine_object & operator=( coroutine_object const&); - - void enter_() - { - holder< void > * hldr_from( - reinterpret_cast< holder< void > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( this), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - if ( this->except_) rethrow_exception( this->except_); - } - - void unwind_stack_() BOOST_NOEXCEPT - { - BOOST_ASSERT( ! this->is_complete() ); - - this->flags_ |= flag_unwind_stack; - holder< void > hldr_to( & this->caller_, true); - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - this->flags_ &= ~flag_unwind_stack; - - BOOST_ASSERT( this->is_complete() ); - } - -public: - coroutine_object( reference_wrapper< Fn > fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_(); } - - ~coroutine_object() - { - if ( ! this->is_complete() && this->force_unwind() ) - unwind_stack_(); - } - - void run() - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< void > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void deallocate_object() - { destroy_( alloc_, this); } -}; - -template< - typename Signature, - typename Fn, typename StackAllocator, typename Allocator, - typename Caller -> -class coroutine_object< Signature, const reference_wrapper< Fn >, StackAllocator, Allocator, Caller, void, 0 > : - private stack_tuple< StackAllocator >, - public coroutine_base< Signature > -{ -public: - typedef typename Allocator::template rebind< - coroutine_object< - Signature, Fn, StackAllocator, Allocator, Caller, void, 0 - > - >::other allocator_t; - -private: - typedef stack_tuple< StackAllocator > pbase_type; - typedef coroutine_base< Signature > base_type; - - Fn fn_; - allocator_t alloc_; - - static void destroy_( allocator_t & alloc, coroutine_object * p) - { - alloc.destroy( p); - alloc.deallocate( p, 1); - } - - coroutine_object( coroutine_object const&); - coroutine_object & operator=( coroutine_object const&); - - void enter_() - { - holder< void > * hldr_from( - reinterpret_cast< holder< void > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( this), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - if ( this->except_) rethrow_exception( this->except_); - } - - void unwind_stack_() BOOST_NOEXCEPT - { - BOOST_ASSERT( ! this->is_complete() ); - - this->flags_ |= flag_unwind_stack; - holder< void > hldr_to( & this->caller_, true); - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - this->flags_ &= ~flag_unwind_stack; - - BOOST_ASSERT( this->is_complete() ); - } - -public: - coroutine_object( const reference_wrapper< Fn > fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_(); } - - ~coroutine_object() - { - if ( ! this->is_complete() && this->force_unwind() ) - unwind_stack_(); - } - - void run() - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< void > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void deallocate_object() - { destroy_( alloc_, this); } -}; diff --git a/include/boost/coroutine/v1/detail/coroutine_object_void_1.ipp b/include/boost/coroutine/v1/detail/coroutine_object_void_1.ipp deleted file mode 100644 index 7fba216..0000000 --- a/include/boost/coroutine/v1/detail/coroutine_object_void_1.ipp +++ /dev/null @@ -1,550 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// 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) - -template< - typename Signature, - typename Fn, typename StackAllocator, typename Allocator, - typename Caller -> -class coroutine_object< Signature, Fn, StackAllocator, Allocator, Caller, void, 1 > : - private stack_tuple< StackAllocator >, - public coroutine_base< Signature > -{ -public: - typedef typename Allocator::template rebind< - coroutine_object< - Signature, Fn, StackAllocator, Allocator, Caller, void, 1 - > - >::other allocator_t; - typedef typename arg< Signature >::type arg_type; - -private: - typedef stack_tuple< StackAllocator > pbase_type; - typedef coroutine_base< Signature > base_type; - - Fn fn_; - allocator_t alloc_; - - static void destroy_( allocator_t & alloc, coroutine_object * p) - { - alloc.destroy( p); - alloc.deallocate( p, 1); - } - - coroutine_object( coroutine_object &); - coroutine_object & operator=( coroutine_object const&); - - void enter_() - { - holder< void > * hldr_from( - reinterpret_cast< holder< void > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( this), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - if ( this->except_) rethrow_exception( this->except_); - } - - void enter_( typename detail::param< arg_type >::type arg) - { - tuple< coroutine_object *, - typename detail::param< arg_type >::type - > tpl( this, arg); - holder< void > * hldr_from( - reinterpret_cast< holder< void > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & tpl), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - if ( this->except_) rethrow_exception( this->except_); - } - - void unwind_stack_() BOOST_NOEXCEPT - { - BOOST_ASSERT( ! this->is_complete() ); - - this->flags_ |= flag_unwind_stack; - holder< arg_type > hldr_to( & this->caller_, true); - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - this->flags_ &= ~flag_unwind_stack; - - BOOST_ASSERT( this->is_complete() ); - } - -public: -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( forward< Fn >( fn) ), - alloc_( alloc) - { enter_(); } - - coroutine_object( BOOST_RV_REF( Fn) fn, typename detail::param< arg_type >::type arg, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline2< coroutine_object, typename detail::param< arg_type >::type >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( forward< Fn >( fn) ), - alloc_( alloc) - { enter_( arg); } -#else - coroutine_object( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_(); } - - coroutine_object( Fn fn, typename detail::param< arg_type >::type arg, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline2< coroutine_object, typename detail::param< arg_type >::type >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_( arg); } - - coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_(); } - - coroutine_object( BOOST_RV_REF( Fn) fn, typename detail::param< arg_type >::type arg, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline2< coroutine_object, typename detail::param< arg_type >::type >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_( arg); } -#endif - - ~coroutine_object() - { - if ( ! this->is_complete() && this->force_unwind() ) - unwind_stack_(); - } - - void run() - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< void > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void run( typename detail::param< arg_type >::type arg) - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - c.impl_->result_ = arg; - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< void > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void deallocate_object() - { destroy_( alloc_, this); } -}; - -template< - typename Signature, - typename Fn, typename StackAllocator, typename Allocator, - typename Caller -> -class coroutine_object< Signature, reference_wrapper< Fn >, StackAllocator, Allocator, Caller, void, 1 > : - private stack_tuple< StackAllocator >, - public coroutine_base< Signature > -{ -public: - typedef typename Allocator::template rebind< - coroutine_object< - Signature, Fn, StackAllocator, Allocator, Caller, void, 1 - > - >::other allocator_t; - typedef typename arg< Signature >::type arg_type; - -private: - typedef stack_tuple< StackAllocator > pbase_type; - typedef coroutine_base< Signature > base_type; - - Fn fn_; - allocator_t alloc_; - - static void destroy_( allocator_t & alloc, coroutine_object * p) - { - alloc.destroy( p); - alloc.deallocate( p, 1); - } - - coroutine_object( coroutine_object &); - coroutine_object & operator=( coroutine_object const&); - - void enter_() - { - holder< void > * hldr_from( - reinterpret_cast< holder< void > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( this), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - if ( this->except_) rethrow_exception( this->except_); - } - - void enter_( typename detail::param< arg_type >::type arg) - { - tuple< coroutine_object *, - typename detail::param< arg_type >::type - > tpl( this, arg); - holder< void > * hldr_from( - reinterpret_cast< holder< void > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & tpl), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - if ( this->except_) rethrow_exception( this->except_); - } - - void unwind_stack_() BOOST_NOEXCEPT - { - BOOST_ASSERT( ! this->is_complete() ); - - this->flags_ |= flag_unwind_stack; - holder< arg_type > hldr_to( & this->caller_, true); - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - this->flags_ &= ~flag_unwind_stack; - - BOOST_ASSERT( this->is_complete() ); - } - -public: - coroutine_object( reference_wrapper< Fn > fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_(); } - - coroutine_object( reference_wrapper< Fn > fn, - typename detail::param< arg_type >::type arg, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline2< coroutine_object, typename detail::param< arg_type >::type >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_( arg); } - - ~coroutine_object() - { - if ( ! this->is_complete() && this->force_unwind() ) - unwind_stack_(); - } - - void run() - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< void > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void run( typename detail::param< arg_type >::type arg) - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - c.impl_->result_ = arg; - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< void > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void deallocate_object() - { destroy_( alloc_, this); } -}; - -template< - typename Signature, - typename Fn, typename StackAllocator, typename Allocator, - typename Caller -> -class coroutine_object< Signature, const reference_wrapper< Fn >, StackAllocator, Allocator, Caller, void, 1 > : - private stack_tuple< StackAllocator >, - public coroutine_base< Signature > -{ -public: - typedef typename Allocator::template rebind< - coroutine_object< - Signature, Fn, StackAllocator, Allocator, Caller, void, 1 - > - >::other allocator_t; - typedef typename arg< Signature >::type arg_type; - -private: - typedef stack_tuple< StackAllocator > pbase_type; - typedef coroutine_base< Signature > base_type; - - Fn fn_; - allocator_t alloc_; - - static void destroy_( allocator_t & alloc, coroutine_object * p) - { - alloc.destroy( p); - alloc.deallocate( p, 1); - } - - coroutine_object( coroutine_object &); - coroutine_object & operator=( coroutine_object const&); - - void enter_() - { - holder< void > * hldr_from( - reinterpret_cast< holder< void > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( this), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - if ( this->except_) rethrow_exception( this->except_); - } - - void enter_( typename detail::param< arg_type >::type arg) - { - tuple< coroutine_object *, - typename detail::param< arg_type >::type - > tpl( this, arg); - holder< void > * hldr_from( - reinterpret_cast< holder< void > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & tpl), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - if ( this->except_) rethrow_exception( this->except_); - } - - void unwind_stack_() BOOST_NOEXCEPT - { - BOOST_ASSERT( ! this->is_complete() ); - - this->flags_ |= flag_unwind_stack; - holder< arg_type > hldr_to( & this->caller_, true); - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - this->flags_ &= ~flag_unwind_stack; - - BOOST_ASSERT( this->is_complete() ); - } - -public: - coroutine_object( const reference_wrapper< Fn > fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_(); } - - coroutine_object( const reference_wrapper< Fn > fn, - typename detail::param< arg_type >::type arg, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline2< coroutine_object, typename detail::param< arg_type >::type >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_( arg); } - - ~coroutine_object() - { - if ( ! this->is_complete() && this->force_unwind() ) - unwind_stack_(); - } - - void run() - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< void > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void run( typename detail::param< arg_type >::type arg) - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - c.impl_->result_ = arg; - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< void > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void deallocate_object() - { destroy_( alloc_, this); } -}; diff --git a/include/boost/coroutine/v1/detail/coroutine_object_void_arity.ipp b/include/boost/coroutine/v1/detail/coroutine_object_void_arity.ipp deleted file mode 100644 index 7da3e77..0000000 --- a/include/boost/coroutine/v1/detail/coroutine_object_void_arity.ipp +++ /dev/null @@ -1,551 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// 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) - -template< - typename Signature, - typename Fn, typename StackAllocator, typename Allocator, - typename Caller, - int arity -> -class coroutine_object< Signature, Fn, StackAllocator, Allocator, Caller, void, arity > : - private stack_tuple< StackAllocator >, - public coroutine_base< Signature > -{ -public: - typedef typename Allocator::template rebind< - coroutine_object< - Signature, Fn, StackAllocator, Allocator, Caller, void, arity - > - >::other allocator_t; - typedef typename arg< Signature >::type arg_type; - -private: - typedef stack_tuple< StackAllocator > pbase_type; - typedef coroutine_base< Signature > base_type; - - Fn fn_; - allocator_t alloc_; - - static void destroy_( allocator_t & alloc, coroutine_object * p) - { - alloc.destroy( p); - alloc.deallocate( p, 1); - } - - coroutine_object( coroutine_object &); - coroutine_object & operator=( coroutine_object const&); - - void enter_() - { - holder< void > * hldr_from( - reinterpret_cast< holder< void > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( this), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - if ( this->except_) rethrow_exception( this->except_); - } - - void enter_( typename detail::param< arg_type >::type arg) - { - tuple< coroutine_object *, - typename detail::param< arg_type >::type - > tpl( this, arg); - holder< void > * hldr_from( - reinterpret_cast< holder< void > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & tpl), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - if ( this->except_) rethrow_exception( this->except_); - } - - void unwind_stack_() BOOST_NOEXCEPT - { - BOOST_ASSERT( ! this->is_complete() ); - - this->flags_ |= flag_unwind_stack; - holder< arg_type > hldr_to( & this->caller_, true); - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - this->flags_ &= ~flag_unwind_stack; - - BOOST_ASSERT( this->is_complete() ); - } - -public: -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( forward< Fn >( fn) ), - alloc_( alloc) - { enter_(); } - - coroutine_object( BOOST_RV_REF( Fn) fn, typename detail::param< arg_type >::type arg, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline2< coroutine_object, typename detail::param< arg_type >::type >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( forward< Fn >( fn) ), - alloc_( alloc) - { enter_( arg); } -#else - coroutine_object( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_(); } - - coroutine_object( Fn fn, typename detail::param< arg_type >::type arg, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline2< coroutine_object, typename detail::param< arg_type >::type >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_( arg); } - - coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_(); } - - coroutine_object( BOOST_RV_REF( Fn) fn, typename detail::param< arg_type >::type arg, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline2< coroutine_object, typename detail::param< arg_type >::type >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_( arg); } -#endif - - ~coroutine_object() - { - if ( ! this->is_complete() && this->force_unwind() ) - unwind_stack_(); - } - - void run() - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< void > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void run( typename detail::param< arg_type >::type arg) - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - c.impl_->result_ = arg; - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< void > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void deallocate_object() - { destroy_( alloc_, this); } -}; - -template< - typename Signature, - typename Fn, typename StackAllocator, typename Allocator, - typename Caller, - int arity -> -class coroutine_object< Signature, reference_wrapper< Fn >, StackAllocator, Allocator, Caller, void, arity > : - private stack_tuple< StackAllocator >, - public coroutine_base< Signature > -{ -public: - typedef typename Allocator::template rebind< - coroutine_object< - Signature, Fn, StackAllocator, Allocator, Caller, void, arity - > - >::other allocator_t; - typedef typename arg< Signature >::type arg_type; - -private: - typedef stack_tuple< StackAllocator > pbase_type; - typedef coroutine_base< Signature > base_type; - - Fn fn_; - allocator_t alloc_; - - static void destroy_( allocator_t & alloc, coroutine_object * p) - { - alloc.destroy( p); - alloc.deallocate( p, 1); - } - - coroutine_object( coroutine_object &); - coroutine_object & operator=( coroutine_object const&); - - void enter_() - { - holder< void > * hldr_from( - reinterpret_cast< holder< void > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( this), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - if ( this->except_) rethrow_exception( this->except_); - } - - void enter_( typename detail::param< arg_type >::type arg) - { - tuple< coroutine_object *, - typename detail::param< arg_type >::type - > tpl( this, arg); - holder< void > * hldr_from( - reinterpret_cast< holder< void > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & tpl), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - if ( this->except_) rethrow_exception( this->except_); - } - - void unwind_stack_() BOOST_NOEXCEPT - { - BOOST_ASSERT( ! this->is_complete() ); - - this->flags_ |= flag_unwind_stack; - holder< arg_type > hldr_to( & this->caller_, true); - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - this->flags_ &= ~flag_unwind_stack; - - BOOST_ASSERT( this->is_complete() ); - } - -public: - coroutine_object( reference_wrapper< Fn > fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_(); } - - coroutine_object( reference_wrapper< Fn > fn, typename detail::param< arg_type >::type arg, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline2< coroutine_object, typename detail::param< arg_type >::type >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_( arg); } - - ~coroutine_object() - { - if ( ! this->is_complete() && this->force_unwind() ) - unwind_stack_(); - } - - void run() - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< void > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void run( typename detail::param< arg_type >::type arg) - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - c.impl_->result_ = arg; - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< void > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void deallocate_object() - { destroy_( alloc_, this); } -}; - -template< - typename Signature, - typename Fn, typename StackAllocator, typename Allocator, - typename Caller, - int arity -> -class coroutine_object< Signature, const reference_wrapper< Fn >, StackAllocator, Allocator, Caller, void, arity > : - private stack_tuple< StackAllocator >, - public coroutine_base< Signature > -{ -public: - typedef typename Allocator::template rebind< - coroutine_object< - Signature, Fn, StackAllocator, Allocator, Caller, void, arity - > - >::other allocator_t; - typedef typename arg< Signature >::type arg_type; - -private: - typedef stack_tuple< StackAllocator > pbase_type; - typedef coroutine_base< Signature > base_type; - - Fn fn_; - allocator_t alloc_; - - static void destroy_( allocator_t & alloc, coroutine_object * p) - { - alloc.destroy( p); - alloc.deallocate( p, 1); - } - - coroutine_object( coroutine_object &); - coroutine_object & operator=( coroutine_object const&); - - void enter_() - { - holder< void > * hldr_from( - reinterpret_cast< holder< void > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( this), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - if ( this->except_) rethrow_exception( this->except_); - } - - void enter_( typename detail::param< arg_type >::type arg) - { - tuple< coroutine_object *, - typename detail::param< arg_type >::type - > tpl( this, arg); - holder< void > * hldr_from( - reinterpret_cast< holder< void > * >( - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & tpl), - this->preserve_fpu() ) ) ); - this->callee_ = * hldr_from->ctx; - if ( this->except_) rethrow_exception( this->except_); - } - - void unwind_stack_() BOOST_NOEXCEPT - { - BOOST_ASSERT( ! this->is_complete() ); - - this->flags_ |= flag_unwind_stack; - holder< arg_type > hldr_to( & this->caller_, true); - this->caller_.jump( - this->callee_, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - this->flags_ &= ~flag_unwind_stack; - - BOOST_ASSERT( this->is_complete() ); - } - -public: - coroutine_object( const reference_wrapper< Fn > fn, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline1< coroutine_object >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_(); } - - coroutine_object( const reference_wrapper< Fn > fn, typename detail::param< arg_type >::type arg, attributes const& attr, - StackAllocator const& stack_alloc, - allocator_t const& alloc) : - pbase_type( stack_alloc, attr.size), - base_type( - trampoline2< coroutine_object, typename detail::param< arg_type >::type >, - & this->stack_ctx, - stack_unwind == attr.do_unwind, - fpu_preserved == attr.preserve_fpu), - fn_( fn), - alloc_( alloc) - { enter_( arg); } - - ~coroutine_object() - { - if ( ! this->is_complete() && this->force_unwind() ) - unwind_stack_(); - } - - void run() - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< void > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void run( typename detail::param< arg_type >::type arg) - { - coroutine_context callee; - coroutine_context caller; - - { - Caller c( this->caller_, false, this->preserve_fpu(), alloc_); - c.impl_->result_ = arg; - try - { fn_( c); } - catch ( forced_unwind const&) - {} - catch (...) - { this->except_ = current_exception(); } - callee = c.impl_->callee_; - } - - this->flags_ |= flag_complete; - holder< void > hldr_to( & caller); - caller.jump( - callee, - reinterpret_cast< intptr_t >( & hldr_to), - this->preserve_fpu() ); - BOOST_ASSERT_MSG( false, "coroutine is complete"); - } - - void deallocate_object() - { destroy_( alloc_, this); } -}; diff --git a/include/boost/coroutine/v1/detail/coroutine_op.hpp b/include/boost/coroutine/v1/detail/coroutine_op.hpp deleted file mode 100644 index b449070..0000000 --- a/include/boost/coroutine/v1/detail/coroutine_op.hpp +++ /dev/null @@ -1,326 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// 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) - -#ifndef BOOST_COROUTINES_OLD_DETAIL_COROUTINE_OP_H -#define BOOST_COROUTINES_OLD_DETAIL_COROUTINE_OP_H - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace boost { -namespace coroutines { -namespace detail { - -template< typename Signature, typename D, typename Result, int arity > -struct coroutine_op; - -template< typename Signature, typename D > -struct coroutine_op< Signature, D, void, 0 > -{ - D & operator()() - { - BOOST_ASSERT( static_cast< D * >( this)->impl_); - BOOST_ASSERT( ! static_cast< D * >( this)->impl_->is_complete() ); - - static_cast< D * >( this)->impl_->resume(); - - return * static_cast< D * >( this); - } -}; - -template< typename Signature, typename D, typename Result > -struct coroutine_op< Signature, D, Result, 0 > -{ - class iterator : public std::iterator< std::input_iterator_tag, typename remove_reference< Result >::type > - { - private: - D * dp_; - optional< Result > val_; - - void fetch_() - { - BOOST_ASSERT( dp_); - - if ( ! dp_->has_result() ) - { - dp_ = 0; - val_ = none; - return; - } - val_ = dp_->get(); - } - - void increment_() - { - BOOST_ASSERT( dp_); - BOOST_ASSERT( * dp_); - - ( * dp_)(); - fetch_(); - } - - public: - typedef typename iterator::pointer pointer_t; - typedef typename iterator::reference reference_t; - - iterator() : - dp_( 0), val_() - {} - - explicit iterator( D * dp) : - dp_( dp), val_() - { fetch_(); } - - iterator( iterator const& other) : - dp_( other.dp_), val_( other.val_) - {} - - iterator & operator=( iterator const& other) - { - if ( this == & other) return * this; - dp_ = other.dp_; - val_ = other.val_; - return * this; - } - - bool operator==( iterator const& other) - { return other.dp_ == dp_ && other.val_ == val_; } - - bool operator!=( iterator const& other) - { return other.dp_ != dp_ || other.val_ != val_; } - - iterator & operator++() - { - increment_(); - return * this; - } - - iterator operator++( int) - { - iterator tmp( * this); - ++*this; - return tmp; - } - - reference_t operator*() const - { return const_cast< optional< Result > & >( val_).get(); } - - pointer_t operator->() const - { return const_cast< optional< Result > & >( val_).get_ptr(); } - }; - - class const_iterator : public std::iterator< std::input_iterator_tag, const typename remove_reference< Result >::type > - { - private: - D * dp_; - optional< Result > val_; - - void fetch_() - { - BOOST_ASSERT( dp_); - - if ( ! dp_->has_result() ) - { - dp_ = 0; - val_ = none; - return; - } - val_ = dp_->get(); - } - - void increment_() - { - BOOST_ASSERT( dp_); - BOOST_ASSERT( * dp_); - - ( * dp_)(); - fetch_(); - } - - public: - typedef typename const_iterator::pointer pointer_t; - typedef typename const_iterator::reference reference_t; - - const_iterator() : - dp_( 0), val_() - {} - - explicit const_iterator( D const* dp) : - dp_( const_cast< D * >( dp) ), val_() - { fetch_(); } - - const_iterator( const_iterator const& other) : - dp_( other.dp_), val_( other.val_) - {} - - const_iterator & operator=( const_iterator const& other) - { - if ( this == & other) return * this; - dp_ = other.dp_; - val_ = other.val_; - return * this; - } - - bool operator==( const_iterator const& other) - { return other.dp_ == dp_ && other.val_ == val_; } - - bool operator!=( const_iterator const& other) - { return other.dp_ != dp_ || other.val_ != val_; } - - const_iterator & operator++() - { - increment_(); - return * this; - } - - const_iterator operator++( int) - { - const_iterator tmp( * this); - ++*this; - return tmp; - } - - reference_t operator*() const - { return val_.get(); } - - pointer_t operator->() const - { return val_.get_ptr(); } - }; - - D & operator()() - { - BOOST_ASSERT( static_cast< D * >( this)->impl_); - BOOST_ASSERT( ! static_cast< D * >( this)->impl_->is_complete() ); - - static_cast< D * >( this)->impl_->resume(); - - return * static_cast< D * >( this); - } -}; - -template< typename Signature, typename D > -struct coroutine_op< Signature, D, void, 1 > -{ - typedef typename arg< Signature >::type arg_type; - - class iterator : public std::iterator< std::output_iterator_tag, void, void, void, void > - { - private: - D * dp_; - - public: - iterator() : - dp_( 0) - {} - - explicit iterator( D * dp) : - dp_( dp) - {} - - iterator & operator=( arg_type a1) - { - BOOST_ASSERT( dp_); - if ( ! ( * dp_)( a1) ) dp_ = 0; - return * this; - } - - bool operator==( iterator const& other) - { return other.dp_ == dp_; } - - bool operator!=( iterator const& other) - { return other.dp_ != dp_; } - - iterator & operator*() - { return * this; } - - iterator & operator++() - { return * this; } - }; - - struct const_iterator; - - D & operator()( arg_type a1) - { - BOOST_ASSERT( static_cast< D * >( this)->impl_); - BOOST_ASSERT( ! static_cast< D * >( this)->impl_->is_complete() ); - - static_cast< D * >( this)->impl_->resume( a1); - - return * static_cast< D * >( this); - } -}; - -template< typename Signature, typename D, typename Result > -struct coroutine_op< Signature, D, Result, 1 > -{ - typedef typename arg< Signature >::type arg_type; - - D & operator()( arg_type a1) - { - BOOST_ASSERT( static_cast< D * >( this)->impl_); - BOOST_ASSERT( ! static_cast< D * >( this)->impl_->is_complete() ); - - static_cast< D * >( this)->impl_->resume( a1); - - return * static_cast< D * >( this); - } -}; - -#define BOOST_COROUTINE_OP_COMMA(n) BOOST_PP_COMMA_IF(BOOST_PP_SUB(n,1)) -#define BOOST_COROUTINE_OP_VAL(z,n,unused) BOOST_COROUTINE_OP_COMMA(n) BOOST_PP_CAT(a,n) -#define BOOST_COROUTINE_OP_VALS(n) BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(n,1),BOOST_COROUTINE_OP_VAL,~) -#define BOOST_COROUTINE_OP_ARG_TYPE(n) \ - typename function_traits< Signature >::BOOST_PP_CAT(BOOST_PP_CAT(arg,n),_type) -#define BOOST_COROUTINE_OP_ARG(z,n,unused) BOOST_COROUTINE_OP_COMMA(n) BOOST_COROUTINE_OP_ARG_TYPE(n) BOOST_PP_CAT(a,n) -#define BOOST_COROUTINE_OP_ARGS(n) BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(n,1),BOOST_COROUTINE_OP_ARG,~) -#define BOOST_COROUTINE_OP(z,n,unused) \ -template< typename Signature, typename D, typename Result > \ -struct coroutine_op< Signature, D, Result, n > \ -{ \ - D & operator()( BOOST_COROUTINE_OP_ARGS(n)) \ - { \ - BOOST_ASSERT( static_cast< D * >( this)->impl_); \ - BOOST_ASSERT( ! static_cast< D * >( this)->impl_->is_complete() ); \ -\ - static_cast< D * >( this)->impl_->resume(BOOST_COROUTINE_OP_VALS(n)); \ -\ - return * static_cast< D * >( this); \ - } \ -}; -BOOST_PP_REPEAT_FROM_TO(2,11,BOOST_COROUTINE_OP,~) -#undef BOOST_COROUTINE_OP -#undef BOOST_COROUTINE_OP_ARGS -#undef BOOST_COROUTINE_OP_ARG -#undef BOOST_COROUTINE_OP_ARG_TYPE -#undef BOOST_COROUTINE_OP_VALS -#undef BOOST_COROUTINE_OP_VAL -#undef BOOST_COROUTINE_OP_COMMA - -}}} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_COROUTINES_OLD_DETAIL_COROUTINE_OP_H diff --git a/include/boost/coroutine/v2/coroutine.hpp b/include/boost/coroutine/v2/coroutine.hpp deleted file mode 100644 index bc116cb..0000000 --- a/include/boost/coroutine/v2/coroutine.hpp +++ /dev/null @@ -1,3001 +0,0 @@ - -// Copyright Oliver Kowalke 2009. -// 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) - -#ifndef BOOST_COROUTINES_UNIDIRECT_COROUTINE_H -#define BOOST_COROUTINES_UNIDIRECT_COROUTINE_H - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_PREFIX -#endif - -namespace boost { -namespace coroutines { - -template< typename Arg > -class pull_coroutine; - -template< typename Arg > -class push_coroutine -{ -private: - template< - typename X, typename Y, typename Z, typename V, typename W - > - friend class detail::pull_coroutine_object; - - typedef detail::push_coroutine_base< Arg > base_t; - typedef typename base_t::ptr_t ptr_t; - - struct dummy - { void nonnull() {} }; - - typedef void ( dummy::*safe_bool)(); - - ptr_t impl_; - - BOOST_MOVABLE_BUT_NOT_COPYABLE( push_coroutine) - - template< typename Allocator > - push_coroutine( detail::coroutine_context const& callee, - bool unwind, bool preserve_fpu, - Allocator const& alloc) : - impl_() - { - typedef detail::push_coroutine_caller< - Arg, Allocator - > caller_t; - typename caller_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) caller_t( - callee, unwind, preserve_fpu, a) ); - } - -public: - push_coroutine() BOOST_NOEXCEPT : - impl_() - {} - -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES -#ifdef BOOST_MSVC - typedef void ( * coroutine_fn) ( pull_coroutine< Arg > &); - - explicit push_coroutine( coroutine_fn fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< push_coroutine > const& alloc = - std::allocator< push_coroutine >(), - typename disable_if< - is_same< typename decay< coroutine_fn >::type, push_coroutine >, - dummy * - >::type = 0); - - template< typename StackAllocator > - explicit push_coroutine( coroutine_fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc = - std::allocator< push_coroutine >(), - typename disable_if< - is_same< typename decay< coroutine_fn >::type, push_coroutine >, - dummy * - >::type = 0); - - template< typename StackAllocator, typename Allocator > - explicit push_coroutine(coroutine_fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< coroutine_fn >::type, push_coroutine >, - dummy * - >::type = 0); -#endif - template< typename Fn > - explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< push_coroutine > const& alloc = - std::allocator< push_coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type = 0); - - template< typename Fn, typename StackAllocator > - explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc = - std::allocator< push_coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type = 0); - - template< typename Fn, typename StackAllocator, typename Allocator > - explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type = 0); -#else - template< typename Fn > - explicit push_coroutine( Fn fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< push_coroutine > const& alloc = - std::allocator< push_coroutine >(), - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type = 0); - - template< typename Fn, typename StackAllocator > - explicit push_coroutine( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc = - std::allocator< push_coroutine >(), - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type = 0); - - template< typename Fn, typename StackAllocator, typename Allocator > - explicit push_coroutine( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type = 0); - - template< typename Fn > - explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< push_coroutine > const& alloc = - std::allocator< push_coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type = 0); - - template< typename Fn, typename StackAllocator > - explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc = - std::allocator< push_coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type = 0); - - template< typename Fn, typename StackAllocator, typename Allocator > - explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type = 0); -#endif - - push_coroutine( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT : - impl_() - { swap( other); } - - push_coroutine & operator=( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT - { - push_coroutine tmp( boost::move( other) ); - swap( tmp); - return * this; - } - - bool empty() const BOOST_NOEXCEPT - { return ! impl_; } - - operator safe_bool() const BOOST_NOEXCEPT - { return ( empty() || impl_->is_complete() ) ? 0 : & dummy::nonnull; } - - bool operator!() const BOOST_NOEXCEPT - { return empty() || impl_->is_complete(); } - - void swap( push_coroutine & other) BOOST_NOEXCEPT - { impl_.swap( other.impl_); } - -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - push_coroutine & operator()( Arg const& arg) - { - BOOST_ASSERT( * this); - - impl_->push( arg); - return * this; - } - - push_coroutine & operator()( Arg && arg) { - BOOST_ASSERT( * this); - - impl_->push( arg); - return * this; - } -#else - push_coroutine & operator()( Arg const& arg) - { - BOOST_ASSERT( * this); - - impl_->push( forward< Arg >( arg) ); - return * this; - } - - push_coroutine & operator()( BOOST_RV_REF( Arg) arg) - { - BOOST_ASSERT( * this); - - impl_->push( forward< Arg >( arg) ); - return * this; - } -#endif - - class iterator : public std::iterator< std::output_iterator_tag, void, void, void, void > - { - private: - push_coroutine< Arg > * c_; - - public: - iterator() : - c_( 0) - {} - - explicit iterator( push_coroutine< Arg > * c) : - c_( c) - {} - - iterator & operator=( Arg a) - { - BOOST_ASSERT( c_); - if ( ! ( * c_)( a) ) c_ = 0; - return * this; - } - - bool operator==( iterator const& other) - { return other.c_ == c_; } - - bool operator!=( iterator const& other) - { return other.c_ != c_; } - - iterator & operator*() - { return * this; } - - iterator & operator++() - { return * this; } - }; - - struct const_iterator; -}; - -template< typename Arg > -class push_coroutine< Arg & > -{ -private: - template< - typename X, typename Y, typename Z, typename V, typename W - > - friend class detail::pull_coroutine_object; - - typedef detail::push_coroutine_base< Arg & > base_t; - typedef typename base_t::ptr_t ptr_t; - - struct dummy - { void nonnull() {} }; - - typedef void ( dummy::*safe_bool)(); - - ptr_t impl_; - - BOOST_MOVABLE_BUT_NOT_COPYABLE( push_coroutine) - - template< typename Allocator > - push_coroutine( detail::coroutine_context const& callee, - bool unwind, bool preserve_fpu, - Allocator const& alloc) : - impl_() - { - typedef detail::push_coroutine_caller< - Arg &, Allocator - > caller_t; - typename caller_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) caller_t( - callee, unwind, preserve_fpu, a) ); - } - -public: - push_coroutine() BOOST_NOEXCEPT : - impl_() - {} - -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES -#ifdef BOOST_MSVC - typedef void ( * coroutine_fn) ( pull_coroutine< Arg & > &); - - explicit push_coroutine( coroutine_fn fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< push_coroutine > const& alloc = - std::allocator< push_coroutine >(), - typename disable_if< - is_same< typename decay< coroutine_fn >::type, push_coroutine >, - dummy * - >::type = 0); - - template< typename StackAllocator > - explicit push_coroutine( coroutine_fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc = - std::allocator< push_coroutine >(), - typename disable_if< - is_same< typename decay< coroutine_fn >::type, push_coroutine >, - dummy * - >::type = 0); - - template< typename StackAllocator, typename Allocator > - explicit push_coroutine( coroutine_fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< coroutine_fn >::type, push_coroutine >, - dummy * - >::type = 0); -#endif - template< typename Fn > - explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< push_coroutine > const& alloc = - std::allocator< push_coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type = 0); - - template< typename Fn, typename StackAllocator > - explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc = - std::allocator< push_coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type = 0); - - template< typename Fn, typename StackAllocator, typename Allocator > - explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type = 0); -#else - template< typename Fn > - explicit push_coroutine( Fn fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< push_coroutine > const& alloc = - std::allocator< push_coroutine >(), - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type = 0); - - template< typename Fn, typename StackAllocator > - explicit push_coroutine( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc = - std::allocator< push_coroutine >(), - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type = 0); - - template< typename Fn, typename StackAllocator, typename Allocator > - explicit push_coroutine( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type = 0); - - template< typename Fn > - explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< push_coroutine > const& alloc = - std::allocator< push_coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type = 0); - - template< typename Fn, typename StackAllocator > - explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc = - std::allocator< push_coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type = 0); - - template< typename Fn, typename StackAllocator, typename Allocator > - explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type = 0); -#endif - - push_coroutine( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT : - impl_() - { swap( other); } - - push_coroutine & operator=( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT - { - push_coroutine tmp( boost::move( other) ); - swap( tmp); - return * this; - } - - bool empty() const BOOST_NOEXCEPT - { return ! impl_; } - - operator safe_bool() const BOOST_NOEXCEPT - { return ( empty() || impl_->is_complete() ) ? 0 : & dummy::nonnull; } - - bool operator!() const BOOST_NOEXCEPT - { return empty() || impl_->is_complete(); } - - void swap( push_coroutine & other) BOOST_NOEXCEPT - { impl_.swap( other.impl_); } - - push_coroutine & operator()( Arg & arg) - { - BOOST_ASSERT( * this); - - impl_->push( arg); - return * this; - } - - class iterator : public std::iterator< std::output_iterator_tag, void, void, void, void > - { - private: - push_coroutine< Arg & > * c_; - - public: - iterator() : - c_( 0) - {} - - explicit iterator( push_coroutine< Arg & > * c) : - c_( c) - {} - - iterator & operator=( Arg & a) - { - BOOST_ASSERT( c_); - if ( ! ( * c_)( a) ) c_ = 0; - return * this; - } - - bool operator==( iterator const& other) - { return other.c_ == c_; } - - bool operator!=( iterator const& other) - { return other.c_ != c_; } - - iterator & operator*() - { return * this; } - - iterator & operator++() - { return * this; } - }; - - struct const_iterator; -}; - -template<> -class push_coroutine< void > -{ -private: - template< - typename X, typename Y, typename Z, typename V, typename W - > - friend class detail::pull_coroutine_object; - - typedef detail::push_coroutine_base< void > base_t; - typedef base_t::ptr_t ptr_t; - - struct dummy - { void nonnull() {} }; - - typedef void ( dummy::*safe_bool)(); - - ptr_t impl_; - - BOOST_MOVABLE_BUT_NOT_COPYABLE( push_coroutine) - - template< typename Allocator > - push_coroutine( detail::coroutine_context const& callee, - bool unwind, bool preserve_fpu, - Allocator const& alloc) : - impl_() - { - typedef detail::push_coroutine_caller< - void, Allocator - > caller_t; - typename caller_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) caller_t( - callee, unwind, preserve_fpu, a) ); - } - -public: - push_coroutine() BOOST_NOEXCEPT : - impl_() - {} - -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES -#ifdef BOOST_MSVC - typedef void ( * coroutine_fn) ( pull_coroutine< void > &); - - explicit push_coroutine( coroutine_fn fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< push_coroutine > const& alloc = - std::allocator< push_coroutine >(), - disable_if< - is_same< typename decay< coroutine_fn >::type, push_coroutine >, - dummy * - >::type = 0); - - template< typename StackAllocator > - explicit push_coroutine( coroutine_fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc = - std::allocator< push_coroutine >(), - disable_if< - is_same< typename decay< coroutine_fn >::type, push_coroutine >, - dummy * - >::type = 0); - - template< typename StackAllocator, typename Allocator > - explicit push_coroutine( coroutine_fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - disable_if< - is_same< typename decay< coroutine_fn >::type, push_coroutine >, - dummy * - >::type = 0); -#endif - template< typename Fn > - explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< push_coroutine > const& alloc = - std::allocator< push_coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type = 0); - - template< typename Fn, typename StackAllocator > - explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc = - std::allocator< push_coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type = 0); - - template< typename Fn, typename StackAllocator, typename Allocator > - explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type = 0); -#else - template< typename Fn > - explicit push_coroutine( Fn fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< push_coroutine > const& alloc = - std::allocator< push_coroutine >(), - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type = 0); - - template< typename Fn, typename StackAllocator > - explicit push_coroutine( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc = - std::allocator< push_coroutine >(), - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type = 0); - - template< typename Fn, typename StackAllocator, typename Allocator > - explicit push_coroutine( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type = 0); - - template< typename Fn > - explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< push_coroutine > const& alloc = - std::allocator< push_coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type = 0); - - template< typename Fn, typename StackAllocator > - explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc = - std::allocator< push_coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type = 0); - - template< typename Fn, typename StackAllocator, typename Allocator > - explicit push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type = 0); -#endif - - push_coroutine( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT : - impl_() - { swap( other); } - - push_coroutine & operator=( BOOST_RV_REF( push_coroutine) other) BOOST_NOEXCEPT - { - push_coroutine tmp( boost::move( other) ); - swap( tmp); - return * this; - } - - bool empty() const BOOST_NOEXCEPT - { return ! impl_; } - - operator safe_bool() const BOOST_NOEXCEPT - { return ( empty() || impl_->is_complete() ) ? 0 : & dummy::nonnull; } - - bool operator!() const BOOST_NOEXCEPT - { return empty() || impl_->is_complete(); } - - void swap( push_coroutine & other) BOOST_NOEXCEPT - { impl_.swap( other.impl_); } - - push_coroutine & operator()() - { - BOOST_ASSERT( * this); - - impl_->push(); - return * this; - } - - struct iterator; - struct const_iterator; -}; - - - -template< typename R > -class pull_coroutine -{ -private: - template< - typename X, typename Y, typename Z, typename V, typename W - > - friend class detail::push_coroutine_object; - - typedef detail::pull_coroutine_base< R > base_t; - typedef typename base_t::ptr_t ptr_t; - - struct dummy - { void nonnull() {} }; - - typedef void ( dummy::*safe_bool)(); - - ptr_t impl_; - - BOOST_MOVABLE_BUT_NOT_COPYABLE( pull_coroutine) - - template< typename Allocator > - pull_coroutine( detail::coroutine_context const& callee, - bool unwind, bool preserve_fpu, - Allocator const& alloc, - optional< R > const& result) : - impl_() - { - typedef detail::pull_coroutine_caller< - R, Allocator - > caller_t; - typename caller_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) caller_t( - callee, unwind, preserve_fpu, a, result) ); - } - -public: - pull_coroutine() BOOST_NOEXCEPT : - impl_() - {} - -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES -#ifdef BOOST_MSVC - typedef void ( * coroutine_fn) ( push_coroutine< R > &); - - explicit pull_coroutine( coroutine_fn fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< pull_coroutine > const& alloc = - std::allocator< pull_coroutine >(), - typename disable_if< - is_same< typename decay< coroutine_fn >::type, pull_coroutine >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - R, coroutine_fn, stack_allocator, std::allocator< pull_coroutine >, - push_coroutine< R > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); - } - - template< typename StackAllocator > - explicit pull_coroutine( coroutine_fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< pull_coroutine > const& alloc = - std::allocator< pull_coroutine >(), - typename disable_if< - is_same< typename decay< coroutine_fn >::type, pull_coroutine >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - R, coroutine_fn, StackAllocator, std::allocator< pull_coroutine >, - push_coroutine< R > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); - } - - template< typename StackAllocator, typename Allocator > - explicit pull_coroutine( coroutine_fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< coroutine_fn >::type, pull_coroutine >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - R, coroutine_fn, StackAllocator, Allocator, - push_coroutine< R > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); - } -#endif - template< typename Fn > - explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< pull_coroutine > const& alloc = - std::allocator< pull_coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, pull_coroutine >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - R, Fn, stack_allocator, std::allocator< pull_coroutine >, - push_coroutine< R > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator > - explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< pull_coroutine > const& alloc = - std::allocator< pull_coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, pull_coroutine >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - R, Fn, StackAllocator, std::allocator< pull_coroutine >, - push_coroutine< R > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator, typename Allocator > - explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, pull_coroutine >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - R, Fn, StackAllocator, Allocator, - push_coroutine< R > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); - } -#else - template< typename Fn > - explicit pull_coroutine( Fn fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< pull_coroutine > const& alloc = - std::allocator< pull_coroutine >(), - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - R, Fn, stack_allocator, std::allocator< pull_coroutine >, - push_coroutine< R > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator > - explicit pull_coroutine( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< pull_coroutine > const& alloc = - std::allocator< pull_coroutine >(), - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - R, Fn, StackAllocator, std::allocator< pull_coroutine >, - push_coroutine< R > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator, typename Allocator > - explicit pull_coroutine( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - R, Fn, StackAllocator, Allocator, - push_coroutine< R > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } - - template< typename Fn > - explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< pull_coroutine > const& alloc = - std::allocator< pull_coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, pull_coroutine >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - R, Fn, stack_allocator, std::allocator< pull_coroutine >, - push_coroutine< R > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator > - explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< pull_coroutine > const& alloc = - std::allocator< pull_coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, pull_coroutine >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - R, Fn, StackAllocator, std::allocator< pull_coroutine >, - push_coroutine< R > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator, typename Allocator > - explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, pull_coroutine >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - R, Fn, StackAllocator, Allocator, - push_coroutine< R > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } -#endif - - pull_coroutine( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT : - impl_() - { swap( other); } - - pull_coroutine & operator=( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT - { - pull_coroutine tmp( boost::move( other) ); - swap( tmp); - return * this; - } - - bool empty() const BOOST_NOEXCEPT - { return ! impl_; } - - operator safe_bool() const BOOST_NOEXCEPT - { return ( empty() || impl_->is_complete() ) ? 0 : & dummy::nonnull; } - - bool operator!() const BOOST_NOEXCEPT - { return empty() || impl_->is_complete(); } - - void swap( pull_coroutine & other) BOOST_NOEXCEPT - { impl_.swap( other.impl_); } - - pull_coroutine & operator()() - { - BOOST_ASSERT( * this); - - impl_->pull(); - return * this; - } - - bool has_result() const - { - BOOST_ASSERT( ! empty() ); - - return impl_->has_result(); - } - - R get() const - { - BOOST_ASSERT( ! empty() ); - - return impl_->get(); - } - - class iterator : public std::iterator< std::input_iterator_tag, typename remove_reference< R >::type > - { - private: - pull_coroutine< R > * c_; - optional< R > val_; - - void fetch_() - { - BOOST_ASSERT( c_); - - if ( ! c_->has_result() ) - { - c_ = 0; - val_ = none; - return; - } - val_ = c_->get(); - } - - void increment_() - { - BOOST_ASSERT( c_); - BOOST_ASSERT( * c_); - - ( * c_)(); - fetch_(); - } - - public: - typedef typename iterator::pointer pointer_t; - typedef typename iterator::reference reference_t; - - iterator() : - c_( 0), val_() - {} - - explicit iterator( pull_coroutine< R > * c) : - c_( c), val_() - { fetch_(); } - - iterator( iterator const& other) : - c_( other.c_), val_( other.val_) - {} - - iterator & operator=( iterator const& other) - { - if ( this == & other) return * this; - c_ = other.c_; - val_ = other.val_; - return * this; - } - - bool operator==( iterator const& other) - { return other.c_ == c_ && other.val_ == val_; } - - bool operator!=( iterator const& other) - { return other.c_ != c_ || other.val_ != val_; } - - iterator & operator++() - { - increment_(); - return * this; - } - - iterator operator++( int) - { - iterator tmp( * this); - ++*this; - return tmp; - } - - reference_t operator*() const - { - if ( ! val_) - boost::throw_exception( - invalid_result() ); - return const_cast< optional< R > & >( val_).get(); - } - - pointer_t operator->() const - { - if ( ! val_) - boost::throw_exception( - invalid_result() ); - return const_cast< optional< R > & >( val_).get_ptr(); - } - }; - - class const_iterator : public std::iterator< std::input_iterator_tag, const typename remove_reference< R >::type > - { - private: - pull_coroutine< R > * c_; - optional< R > val_; - - void fetch_() - { - BOOST_ASSERT( c_); - - if ( ! c_->has_result() ) - { - c_ = 0; - val_ = none; - return; - } - val_ = c_->get(); - } - - void increment_() - { - BOOST_ASSERT( c_); - BOOST_ASSERT( * c_); - - ( * c_)(); - fetch_(); - } - - public: - typedef typename const_iterator::pointer pointer_t; - typedef typename const_iterator::reference reference_t; - - const_iterator() : - c_( 0), val_() - {} - - explicit const_iterator( pull_coroutine< R > const* c) : - c_( const_cast< pull_coroutine< R > * >( c) ), val_() - { fetch_(); } - - const_iterator( const_iterator const& other) : - c_( other.c_), val_( other.val_) - {} - - const_iterator & operator=( const_iterator const& other) - { - if ( this == & other) return * this; - c_ = other.c_; - val_ = other.val_; - return * this; - } - - bool operator==( const_iterator const& other) - { return other.c_ == c_ && other.val_ == val_; } - - bool operator!=( const_iterator const& other) - { return other.c_ != c_ || other.val_ != val_; } - - const_iterator & operator++() - { - increment_(); - return * this; - } - - const_iterator operator++( int) - { - const_iterator tmp( * this); - ++*this; - return tmp; - } - - reference_t operator*() const - { - if ( ! val_) - boost::throw_exception( - invalid_result() ); - return val_.get(); - } - - pointer_t operator->() const - { - if ( ! val_) - boost::throw_exception( - invalid_result() ); - return val_.get_ptr(); - } - }; -}; - -template< typename R > -class pull_coroutine< R & > -{ -private: - template< - typename X, typename Y, typename Z, typename V, typename W - > - friend class detail::push_coroutine_object; - - typedef detail::pull_coroutine_base< R & > base_t; - typedef typename base_t::ptr_t ptr_t; - - struct dummy - { void nonnull() {} }; - - typedef void ( dummy::*safe_bool)(); - - ptr_t impl_; - - BOOST_MOVABLE_BUT_NOT_COPYABLE( pull_coroutine) - - template< typename Allocator > - pull_coroutine( detail::coroutine_context const& callee, - bool unwind, bool preserve_fpu, - Allocator const& alloc, - optional< R * > const& result) : - impl_() - { - typedef detail::pull_coroutine_caller< - R &, Allocator - > caller_t; - typename caller_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) caller_t( - callee, unwind, preserve_fpu, a, result) ); - } - -public: - pull_coroutine() BOOST_NOEXCEPT : - impl_() - {} - -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES -#ifdef BOOST_MSVC - typedef void ( * coroutine_fn) ( push_coroutine< R & > &); - - explicit pull_coroutine( coroutine_fn fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< pull_coroutine > const& alloc = - std::allocator< pull_coroutine >(), - typename disable_if< - is_same< typename decay< coroutine_fn >::type, pull_coroutine >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - R &, coroutine_fn, stack_allocator, std::allocator< pull_coroutine >, - push_coroutine< R & > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); - } - - template< typename StackAllocator > - explicit pull_coroutine( coroutine_fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< pull_coroutine > const& alloc = - std::allocator< pull_coroutine >(), - typename disable_if< - is_same< typename decay< coroutine_fn >::type, pull_coroutine >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - R &, coroutine_fn, StackAllocator, std::allocator< pull_coroutine >, - push_coroutine< R & > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); - } - - template< typename StackAllocator, typename Allocator > - explicit pull_coroutine( coroutine_fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< coroutine_fn >::type, pull_coroutine >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - R &, coroutine_fn, StackAllocator, Allocator, - push_coroutine< R & > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); - } -#endif - template< typename Fn > - explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< pull_coroutine > const& alloc = - std::allocator< pull_coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, pull_coroutine >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - R &, Fn, stack_allocator, std::allocator< pull_coroutine >, - push_coroutine< R & > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator > - explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< pull_coroutine > const& alloc = - std::allocator< pull_coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, pull_coroutine >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - R &, Fn, StackAllocator, std::allocator< pull_coroutine >, - push_coroutine< R & > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator, typename Allocator > - explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, pull_coroutine >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - R &, Fn, StackAllocator, Allocator, - push_coroutine< R & > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); - } -#else - template< typename Fn > - explicit pull_coroutine( Fn fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< pull_coroutine > const& alloc = - std::allocator< pull_coroutine >(), - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - R &, Fn, stack_allocator, std::allocator< pull_coroutine >, - push_coroutine< R & > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator > - explicit pull_coroutine( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< pull_coroutine > const& alloc = - std::allocator< pull_coroutine >(), - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - R &, Fn, StackAllocator, std::allocator< pull_coroutine >, - push_coroutine< R & > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator, typename Allocator > - explicit pull_coroutine( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - R &, Fn, StackAllocator, Allocator, - push_coroutine< R & > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } - - template< typename Fn > - explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< pull_coroutine > const& alloc = - std::allocator< pull_coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, pull_coroutine >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - R &, Fn, stack_allocator, std::allocator< pull_coroutine >, - push_coroutine< R & > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator > - explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< pull_coroutine > const& alloc = - std::allocator< pull_coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, pull_coroutine >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - R &, Fn, StackAllocator, std::allocator< pull_coroutine >, - push_coroutine< R & > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator, typename Allocator > - explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, pull_coroutine >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - R &, Fn, StackAllocator, Allocator, - push_coroutine< R & > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } -#endif - - pull_coroutine( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT : - impl_() - { swap( other); } - - pull_coroutine & operator=( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT - { - pull_coroutine tmp( boost::move( other) ); - swap( tmp); - return * this; - } - - bool empty() const BOOST_NOEXCEPT - { return ! impl_; } - - operator safe_bool() const BOOST_NOEXCEPT - { return ( empty() || impl_->is_complete() ) ? 0 : & dummy::nonnull; } - - bool operator!() const BOOST_NOEXCEPT - { return empty() || impl_->is_complete(); } - - void swap( pull_coroutine & other) BOOST_NOEXCEPT - { impl_.swap( other.impl_); } - - pull_coroutine & operator()() - { - BOOST_ASSERT( * this); - - impl_->pull(); - return * this; - } - - bool has_result() const - { - BOOST_ASSERT( ! empty() ); - - return impl_->has_result(); - } - - R & get() const - { return impl_->get(); } - - class iterator : public std::iterator< std::input_iterator_tag, R > - { - private: - pull_coroutine< R & > * c_; - optional< R & > val_; - - void fetch_() - { - BOOST_ASSERT( c_); - - if ( ! c_->has_result() ) - { - c_ = 0; - val_ = none; - return; - } - val_ = c_->get(); - } - - void increment_() - { - BOOST_ASSERT( c_); - BOOST_ASSERT( * c_); - - ( * c_)(); - fetch_(); - } - - public: - typedef typename iterator::pointer pointer_t; - typedef typename iterator::reference reference_t; - - iterator() : - c_( 0), val_() - {} - - explicit iterator( pull_coroutine< R & > * c) : - c_( c), val_() - { fetch_(); } - - iterator( iterator const& other) : - c_( other.c_), val_( other.val_) - {} - - iterator & operator=( iterator const& other) - { - if ( this == & other) return * this; - c_ = other.c_; - val_ = other.val_; - return * this; - } - - bool operator==( iterator const& other) - { return other.c_ == c_ && other.val_ == val_; } - - bool operator!=( iterator const& other) - { return other.c_ != c_ || other.val_ != val_; } - - iterator & operator++() - { - increment_(); - return * this; - } - - iterator operator++( int) - { - iterator tmp( * this); - ++*this; - return tmp; - } - - reference_t operator*() const - { - if ( ! val_) - boost::throw_exception( - invalid_result() ); - return const_cast< optional< R & > & >( val_).get(); - } - - pointer_t operator->() const - { - if ( ! val_) - boost::throw_exception( - invalid_result() ); - return const_cast< optional< R & > & >( val_).get_ptr(); - } - }; - - class const_iterator : public std::iterator< std::input_iterator_tag, R > - { - private: - pull_coroutine< R & > * c_; - optional< R & > val_; - - void fetch_() - { - BOOST_ASSERT( c_); - - if ( ! c_->has_result() ) - { - c_ = 0; - val_ = none; - return; - } - val_ = c_->get(); - } - - void increment_() - { - BOOST_ASSERT( c_); - BOOST_ASSERT( * c_); - - ( * c_)(); - fetch_(); - } - - public: - typedef typename const_iterator::pointer pointer_t; - typedef typename const_iterator::reference reference_t; - - const_iterator() : - c_( 0), val_() - {} - - explicit const_iterator( pull_coroutine< R & > const* c) : - c_( const_cast< pull_coroutine< R & > * >( c) ), val_() - { fetch_(); } - - const_iterator( const_iterator const& other) : - c_( other.c_), val_( other.val_) - {} - - const_iterator & operator=( const_iterator const& other) - { - if ( this == & other) return * this; - c_ = other.c_; - val_ = other.val_; - return * this; - } - - bool operator==( const_iterator const& other) - { return other.c_ == c_ && other.val_ == val_; } - - bool operator!=( const_iterator const& other) - { return other.c_ != c_ || other.val_ != val_; } - - const_iterator & operator++() - { - increment_(); - return * this; - } - - const_iterator operator++( int) - { - const_iterator tmp( * this); - ++*this; - return tmp; - } - - reference_t operator*() const - { - if ( ! val_) - boost::throw_exception( - invalid_result() ); - return val_.get(); - } - - pointer_t operator->() const - { - if ( ! val_) - boost::throw_exception( - invalid_result() ); - return val_.get_ptr(); - } - }; -}; - -template<> -class pull_coroutine< void > -{ -private: - template< - typename X, typename Y, typename Z, typename V, typename W - > - friend class detail::push_coroutine_object; - - typedef detail::pull_coroutine_base< void > base_t; - typedef base_t::ptr_t ptr_t; - - struct dummy - { void nonnull() {} }; - - typedef void ( dummy::*safe_bool)(); - - ptr_t impl_; - - BOOST_MOVABLE_BUT_NOT_COPYABLE( pull_coroutine) - - template< typename Allocator > - pull_coroutine( detail::coroutine_context const& callee, - bool unwind, bool preserve_fpu, - Allocator const& alloc) : - impl_() - { - typedef detail::pull_coroutine_caller< - void, Allocator - > caller_t; - typename caller_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) caller_t( - callee, unwind, preserve_fpu, a) ); - } - -public: - pull_coroutine() BOOST_NOEXCEPT : - impl_() - {} - -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES -#ifdef BOOST_MSVC - typedef void ( * coroutine_fn) ( push_coroutine< void > &); - - explicit pull_coroutine( coroutine_fn fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< pull_coroutine > const& alloc = - std::allocator< pull_coroutine >(), - disable_if< - is_same< typename decay< coroutine_fn >::type, pull_coroutine >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - void, coroutine_fn, stack_allocator, std::allocator< pull_coroutine >, - push_coroutine< void > - > object_t; - object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); - } - - template< typename StackAllocator > - explicit pull_coroutine( coroutine_fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< pull_coroutine > const& alloc = - std::allocator< pull_coroutine >(), - disable_if< - is_same< typename decay< coroutine_fn >::type, pull_coroutine >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - void, coroutine_fn, StackAllocator, std::allocator< pull_coroutine >, - push_coroutine< void > - > object_t; - object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); - } - - template< typename StackAllocator, typename Allocator > - explicit pull_coroutine( coroutine_fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - disable_if< - is_same< typename decay< coroutine_fn >::type, pull_coroutine >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - void, coroutine_fn, StackAllocator, Allocator, - push_coroutine< void > - > object_t; - object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); - } -#endif - template< typename Fn > - explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< pull_coroutine > const& alloc = - std::allocator< pull_coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, pull_coroutine >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - void, Fn, stack_allocator, std::allocator< pull_coroutine >, - push_coroutine< void > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator > - explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< pull_coroutine > const& alloc = - std::allocator< pull_coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, pull_coroutine >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - void, Fn, StackAllocator, std::allocator< pull_coroutine >, - push_coroutine< void > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator, typename Allocator > - explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, pull_coroutine >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - void, Fn, StackAllocator, Allocator, - push_coroutine< void > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); - } -#else - template< typename Fn > - explicit pull_coroutine( Fn fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< pull_coroutine > const& alloc = - std::allocator< pull_coroutine >(), - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - void, Fn, stack_allocator, std::allocator< pull_coroutine >, - push_coroutine< void > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator > - explicit pull_coroutine( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< pull_coroutine > const& alloc = - std::allocator< pull_coroutine >(), - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - void, Fn, StackAllocator, std::allocator< pull_coroutine >, - push_coroutine< void > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator, typename Allocator > - explicit pull_coroutine( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - void, Fn, StackAllocator, Allocator, - push_coroutine< void > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } - - template< typename Fn > - explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(), - stack_allocator const& stack_alloc = - stack_allocator(), - std::allocator< pull_coroutine > const& alloc = - std::allocator< pull_coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, pull_coroutine >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - void, Fn, stack_allocator, std::allocator< pull_coroutine >, - push_coroutine< void > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator > - explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< pull_coroutine > const& alloc = - std::allocator< pull_coroutine >(), - typename disable_if< - is_same< typename decay< Fn >::type, pull_coroutine >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - void, Fn, StackAllocator, std::allocator< pull_coroutine >, - push_coroutine< void > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } - - template< typename Fn, typename StackAllocator, typename Allocator > - explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, pull_coroutine >, - dummy * - >::type = 0) : - impl_() - { - typedef detail::pull_coroutine_object< - void, Fn, StackAllocator, Allocator, - push_coroutine< void > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); - } -#endif - - pull_coroutine( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT : - impl_() - { swap( other); } - - pull_coroutine & operator=( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT - { - pull_coroutine tmp( boost::move( other) ); - swap( tmp); - return * this; - } - - bool empty() const BOOST_NOEXCEPT - { return ! impl_; } - - operator safe_bool() const BOOST_NOEXCEPT - { return ( empty() || impl_->is_complete() ) ? 0 : & dummy::nonnull; } - - bool operator!() const BOOST_NOEXCEPT - { return empty() || impl_->is_complete(); } - - void swap( pull_coroutine & other) BOOST_NOEXCEPT - { impl_.swap( other.impl_); } - - pull_coroutine & operator()() - { - BOOST_ASSERT( * this); - - impl_->pull(); - return * this; - } - - struct iterator; - struct const_iterator; -}; - - -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES -#ifdef BOOST_MSVC -template< typename Arg > -push_coroutine< Arg >::push_coroutine( coroutine_fn fn, attributes const& attr, - stack_allocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc, - typename disable_if< - is_same< typename decay< coroutine_fn >::type, push_coroutine >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - Arg, coroutine_fn, stack_allocator, std::allocator< push_coroutine >, - pull_coroutine< Arg > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); -} - -template< typename Arg > -template< typename StackAllocator > -push_coroutine< Arg >::push_coroutine( coroutine_fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc, - typename disable_if< - is_same< typename decay< coroutine_fn >::type, push_coroutine >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - Arg, coroutine_fn, StackAllocator, std::allocator< push_coroutine >, - pull_coroutine< Arg > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); -} - -template< typename Arg > -template< typename StackAllocator, typename Allocator > -push_coroutine< Arg >::push_coroutine( coroutine_fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< coroutine_fn >::type, push_coroutine >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - Arg, coroutine_fn, StackAllocator, Allocator, - pull_coroutine< Arg > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); -} - -template< typename Arg > -push_coroutine< Arg & >::push_coroutine( coroutine_fn fn, attributes const& attr, - stack_allocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc, - typename disable_if< - is_same< typename decay< coroutine_fn >::type, push_coroutine >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - Arg &, coroutine_fn, stack_allocator, std::allocator< push_coroutine >, - pull_coroutine< Arg & > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); -} - -template< typename Arg > -template< typename StackAllocator > -push_coroutine< Arg & >::push_coroutine( coroutine_fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc, - typename disable_if< - is_same< typename decay< coroutine_fn >::type, push_coroutine >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - Arg &, coroutine_fn, StackAllocator, std::allocator< push_coroutine >, - pull_coroutine< Arg & > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); -} - -template< typename Arg > -template< typename StackAllocator, typename Allocator > -push_coroutine< Arg & >::push_coroutine( coroutine_fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< coroutine_fn >::type, push_coroutine >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - Arg &, coroutine_fn, StackAllocator, Allocator, - pull_coroutine< Arg & > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); -} - -inline -push_coroutine< void >::push_coroutine( coroutine_fn fn, attributes const& attr, - stack_allocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc, - disable_if< - is_same< typename decay< coroutine_fn >::type, push_coroutine >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - void, coroutine_fn, stack_allocator, std::allocator< push_coroutine >, - pull_coroutine< void > - > object_t; - object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); -} - -template< typename StackAllocator > -push_coroutine< void >::push_coroutine( coroutine_fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc, - disable_if< - is_same< typename decay< coroutine_fn >::type, push_coroutine >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - void, coroutine_fn, StackAllocator, std::allocator< push_coroutine >, - pull_coroutine< void > - > object_t; - object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); -} - -template< typename StackAllocator, typename Allocator > -push_coroutine< void >::push_coroutine( coroutine_fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - disable_if< - is_same< typename decay< coroutine_fn >::type, push_coroutine >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - void, coroutine_fn, StackAllocator, Allocator, - pull_coroutine< void > - > object_t; - object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) ); -} -#endif -template< typename Arg > -template< typename Fn > -push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - stack_allocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - Arg, Fn, stack_allocator, std::allocator< push_coroutine >, - pull_coroutine< Arg > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); -} - -template< typename Arg > -template< typename Fn, typename StackAllocator > -push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - Arg, Fn, StackAllocator, std::allocator< push_coroutine >, - pull_coroutine< Arg > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); -} - -template< typename Arg > -template< typename Fn, typename StackAllocator, typename Allocator > -push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - Arg, Fn, StackAllocator, Allocator, - pull_coroutine< Arg > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); -} - -template< typename Arg > -template< typename Fn > -push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - stack_allocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - Arg &, Fn, stack_allocator, std::allocator< push_coroutine >, - pull_coroutine< Arg & > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); -} - -template< typename Arg > -template< typename Fn, typename StackAllocator > -push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - Arg &, Fn, StackAllocator, std::allocator< push_coroutine >, - pull_coroutine< Arg & > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); -} - -template< typename Arg > -template< typename Fn, typename StackAllocator, typename Allocator > -push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - Arg &, Fn, StackAllocator, Allocator, - pull_coroutine< Arg & > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); -} - -template< typename Fn > -push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - stack_allocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - void, Fn, stack_allocator, std::allocator< push_coroutine >, - pull_coroutine< void > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); -} - -template< typename Fn, typename StackAllocator > -push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - void, Fn, StackAllocator, std::allocator< push_coroutine >, - pull_coroutine< void > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); -} - -template< typename Fn, typename StackAllocator, typename Allocator > -push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - void, Fn, StackAllocator, Allocator, - pull_coroutine< void > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) ); -} -#else -template< typename Arg > -template< typename Fn > -push_coroutine< Arg >::push_coroutine( Fn fn, attributes const& attr, - stack_allocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc, - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - Arg, Fn, stack_allocator, std::allocator< push_coroutine >, - pull_coroutine< Arg > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); -} - -template< typename Arg > -template< typename Fn, typename StackAllocator > -push_coroutine< Arg >::push_coroutine( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc, - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - Arg, Fn, StackAllocator, std::allocator< push_coroutine >, - pull_coroutine< Arg > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); -} - -template< typename Arg > -template< typename Fn, typename StackAllocator, typename Allocator > -push_coroutine< Arg >::push_coroutine( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - Arg, Fn, StackAllocator, Allocator, - pull_coroutine< Arg > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); -} - -template< typename Arg > -template< typename Fn > -push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - stack_allocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - Arg, Fn, stack_allocator, std::allocator< push_coroutine >, - pull_coroutine< Arg > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); -} - -template< typename Arg > -template< typename Fn, typename StackAllocator > -push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - Arg, Fn, StackAllocator, std::allocator< push_coroutine >, - pull_coroutine< Arg > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); -} - -template< typename Arg > -template< typename Fn, typename StackAllocator, typename Allocator > -push_coroutine< Arg >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - Arg, Fn, StackAllocator, Allocator, - pull_coroutine< Arg > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); -} - -template< typename Arg > -template< typename Fn > -push_coroutine< Arg & >::push_coroutine( Fn fn, attributes const& attr, - stack_allocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc, - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - Arg &, Fn, stack_allocator, std::allocator< push_coroutine >, - pull_coroutine< Arg & > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); -} - -template< typename Arg > -template< typename Fn, typename StackAllocator > -push_coroutine< Arg & >::push_coroutine( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc, - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - Arg &, Fn, StackAllocator, std::allocator< push_coroutine >, - pull_coroutine< Arg & > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); -} - -template< typename Arg > -template< typename Fn, typename StackAllocator, typename Allocator > -push_coroutine< Arg & >::push_coroutine( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - Arg &, Fn, StackAllocator, Allocator, - pull_coroutine< Arg & > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); -} - -template< typename Arg > -template< typename Fn > -push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - stack_allocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - Arg &, Fn, stack_allocator, std::allocator< push_coroutine >, - pull_coroutine< Arg & > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); -} - -template< typename Arg > -template< typename Fn, typename StackAllocator > -push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - Arg &, Fn, StackAllocator, std::allocator< push_coroutine >, - pull_coroutine< Arg & > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); -} - -template< typename Arg > -template< typename Fn, typename StackAllocator, typename Allocator > -push_coroutine< Arg & >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - Arg &, Fn, StackAllocator, Allocator, - pull_coroutine< Arg & > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); -} - -template< typename Fn > -push_coroutine< void >::push_coroutine( Fn fn, attributes const& attr, - stack_allocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc, - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - void, Fn, stack_allocator, std::allocator< push_coroutine >, - pull_coroutine< void > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); -} - -template< typename Fn, typename StackAllocator > -push_coroutine< void >::push_coroutine( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc, - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - void, Fn, StackAllocator, std::allocator< push_coroutine >, - pull_coroutine< void > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); -} - -template< typename Fn, typename StackAllocator, typename Allocator > -push_coroutine< void >::push_coroutine( Fn fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_convertible< Fn &, BOOST_RV_REF( Fn) >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - void, Fn, StackAllocator, Allocator, - pull_coroutine< void > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); -} - -template< typename Fn > -push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - stack_allocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - void, Fn, stack_allocator, std::allocator< push_coroutine >, - pull_coroutine< void > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); -} - -template< typename Fn, typename StackAllocator > -push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - std::allocator< push_coroutine > const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - void, Fn, StackAllocator, std::allocator< push_coroutine >, - pull_coroutine< void > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); -} - -template< typename Fn, typename StackAllocator, typename Allocator > -push_coroutine< void >::push_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr, - StackAllocator const& stack_alloc, - Allocator const& alloc, - typename disable_if< - is_same< typename decay< Fn >::type, push_coroutine >, - dummy * - >::type) : - impl_() -{ - typedef detail::push_coroutine_object< - void, Fn, StackAllocator, Allocator, - pull_coroutine< void > - > object_t; - typename object_t::allocator_t a( alloc); - impl_ = ptr_t( - // placement new - ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) ); -} -#endif - -template< typename R > -void swap( pull_coroutine< R > & l, pull_coroutine< R > & r) BOOST_NOEXCEPT -{ l.swap( r); } - -template< typename Arg > -void swap( push_coroutine< Arg > & l, push_coroutine< Arg > & r) BOOST_NOEXCEPT -{ l.swap( r); } - -template< typename R > -inline -typename pull_coroutine< R >::iterator -range_begin( pull_coroutine< R > & c) -{ return typename pull_coroutine< R >::iterator( & c); } - -template< typename R > -inline -typename pull_coroutine< R >::const_iterator -range_begin( pull_coroutine< R > const& c) -{ return typename pull_coroutine< R >::const_iterator( & c); } - -template< typename R > -inline -typename pull_coroutine< R >::iterator -range_end( pull_coroutine< R > &) -{ return typename pull_coroutine< R >::iterator(); } - -template< typename R > -inline -typename pull_coroutine< R >::const_iterator -range_end( pull_coroutine< R > const&) -{ return typename pull_coroutine< R >::const_iterator(); } - -template< typename Arg > -inline -typename push_coroutine< Arg >::iterator -range_begin( push_coroutine< Arg > & c) -{ return typename push_coroutine< Arg >::iterator( & c); } - -template< typename Arg > -inline -typename push_coroutine< Arg >::const_iterator -range_begin( push_coroutine< Arg > const& c) -{ return typename push_coroutine< Arg >::const_iterator( & c); } - -template< typename Arg > -inline -typename push_coroutine< Arg >::iterator -range_end( push_coroutine< Arg > &) -{ return typename push_coroutine< Arg >::iterator(); } - -template< typename Arg > -inline -typename push_coroutine< Arg >::const_iterator -range_end( push_coroutine< Arg > const&) -{ return typename push_coroutine< Arg >::const_iterator(); } - -template< typename T > -struct coroutine -{ - typedef push_coroutine< T > push_type; - typedef pull_coroutine< T > pull_type; -}; - -} - -template< typename Arg > -struct range_mutable_iterator< coroutines::push_coroutine< Arg > > -{ typedef typename coroutines::push_coroutine< Arg >::iterator type; }; - -template< typename Arg > -struct range_const_iterator< coroutines::push_coroutine< Arg > > -{ typedef typename coroutines::push_coroutine< Arg >::const_iterator type; }; - -template< typename R > -struct range_mutable_iterator< coroutines::pull_coroutine< R > > -{ typedef typename coroutines::pull_coroutine< R >::iterator type; }; - -template< typename R > -struct range_const_iterator< coroutines::pull_coroutine< R > > -{ typedef typename coroutines::pull_coroutine< R >::const_iterator type; }; - -} - -namespace std { - -template< typename R > -inline -typename boost::coroutines::pull_coroutine< R >::iterator -begin( boost::coroutines::pull_coroutine< R > & c) -{ return boost::begin( c); } - -template< typename R > -inline -typename boost::coroutines::pull_coroutine< R >::iterator -end( boost::coroutines::pull_coroutine< R > & c) -{ return boost::end( c); } - -template< typename R > -inline -typename boost::coroutines::pull_coroutine< R >::const_iterator -begin( boost::coroutines::pull_coroutine< R > const& c) -{ return boost::const_begin( c); } - -template< typename R > -inline -typename boost::coroutines::pull_coroutine< R >::const_iterator -end( boost::coroutines::pull_coroutine< R > const& c) -{ return boost::const_end( c); } - -template< typename R > -inline -typename boost::coroutines::push_coroutine< R >::iterator -begin( boost::coroutines::push_coroutine< R > & c) -{ return boost::begin( c); } - -template< typename R > -inline -typename boost::coroutines::push_coroutine< R >::iterator -end( boost::coroutines::push_coroutine< R > & c) -{ return boost::end( c); } - -template< typename R > -inline -typename boost::coroutines::push_coroutine< R >::const_iterator -begin( boost::coroutines::push_coroutine< R > const& c) -{ return boost::const_begin( c); } - -template< typename R > -inline -typename boost::coroutines::push_coroutine< R >::const_iterator -end( boost::coroutines::push_coroutine< R > const& c) -{ return boost::const_end( c); } - -} - -#ifdef BOOST_HAS_ABI_HEADERS -# include BOOST_ABI_SUFFIX -#endif - -#endif // BOOST_COROUTINES_UNIDIRECT_COROUTINE_H diff --git a/performance/performance.cpp b/performance/performance.cpp index 04c4b7f..40c5bbe 100644 --- a/performance/performance.cpp +++ b/performance/performance.cpp @@ -32,7 +32,6 @@ namespace coro = boost::coroutines; # define CALL_COROUTINE(z,n,unused) \ c(); -#ifdef BOOST_COROUTINES_UNIDIRECT void fn( boost::coroutines::coroutine< void >::push_type & c) { while ( true) c(); } @@ -87,64 +86,6 @@ BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_COROUTINE, ~) return total; } # endif -#else -typedef coro::coroutine< void() > coro_t; - -void fn( coro_t::caller_type & c) -{ while ( true) c(); } - -# ifdef BOOST_CONTEXT_CYCLE -cycle_t test_cycles( cycle_t ov, coro::flag_fpu_t preserve_fpu) -{ -# if defined(BOOST_USE_SEGMENTED_STACKS) - coro_t c( fn, coro::attributes( preserve_fpu) ); -# else - coro::simple_stack_allocator< 8 * 1024 * 1024, 64 * 1024, 8 * 1024 > alloc; - coro_t c( fn, coro::attributes( preserve_fpu), alloc); -# endif - - // cache warum-up -BOOST_PP_REPEAT_FROM_TO( 0, COUNTER, CALL_COROUTINE, ~) - - cycle_t start( cycles() ); -BOOST_PP_REPEAT_FROM_TO( 0, COUNTER, CALL_COROUTINE, ~) - cycle_t total( cycles() - start); - - // we have two jumps and two measuremt-overheads - total -= ov; // overhead of measurement - total /= COUNTER; // per call - total /= 2; // 2x jump_to c1->c2 && c2->c1 - - return total; -} -# endif - -# if _POSIX_C_SOURCE >= 199309L -zeit_t test_zeit( zeit_t ov, coro::flag_fpu_t preserve_fpu) -{ -# if defined(BOOST_USE_SEGMENTED_STACKS) - coro_t c( fn, coro::attributes( preserve_fpu) ); -# else - coro::simple_stack_allocator< 8 * 1024 * 1024, 64 * 1024, 8 * 1024 > alloc; - coro_t c( fn, coro::attributes( preserve_fpu), alloc); -# endif - - // cache warum-up -BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_COROUTINE, ~) - - zeit_t start( zeit() ); -BOOST_PP_REPEAT_FROM_TO( 0, BOOST_PP_LIMIT_MAG, CALL_COROUTINE, ~) - zeit_t total( zeit() - start); - - // we have two jumps and two measuremt-overheads - total -= ov; // overhead of measurement - total /= BOOST_PP_LIMIT_MAG; // per call - total /= 2; // 2x jump_to c1->c2 && c2->c1 - - return total; -} -# endif -#endif int main( int argc, char * argv[]) { diff --git a/test/test_coroutine.cpp b/test/test_coroutine.cpp index ae33ef5..e6e2aa1 100644 --- a/test/test_coroutine.cpp +++ b/test/test_coroutine.cpp @@ -37,7 +37,6 @@ int& value7 = value1; int value8 = 0; int value9 = 0; -#ifdef BOOST_COROUTINES_UNIDIRECT struct X : private boost::noncopyable { X() { value1 = 7; } @@ -530,516 +529,6 @@ void test_invalid_result() } BOOST_CHECK( catched); } -#else -typedef coro::coroutine< void() > coro_void_void; -typedef coro::coroutine< int() > coro_int_void; -typedef coro::coroutine< std::string() > coro_string_void; -typedef coro::coroutine< void(int) > coro_void_int; -typedef coro::coroutine< void(std::string const&) > coro_void_string; -typedef coro::coroutine< double(double,double) > coro_double; -typedef coro::coroutine< int(int,int) > coro_int; -typedef coro::coroutine< int(int) > coro_int_int; -typedef coro::coroutine< int*(int*) > coro_ptr; -typedef coro::coroutine< int const*(int const*) > coro_const_ptr; -typedef coro::coroutine< int&(int&) > coro_ref; -typedef coro::coroutine< int const&(int const&) > coro_const_ref; -typedef coro::coroutine< boost::tuple(int&,int&) > coro_tuple; -typedef coro::coroutine< const int *() > coro_const_int_ptr_void; - -struct X : private boost::noncopyable -{ - X() { value1 = 7; } - ~X() { value1 = 0; } -}; - -class copyable -{ -public: - bool state; - - copyable() : - state( false) - {} - - copyable( int) : - state( true) - {} - - void operator()( coro_int_void::caller_type &) - { value3 = state; } -}; - -class moveable -{ -private: - BOOST_MOVABLE_BUT_NOT_COPYABLE( moveable); - -public: - bool state; - - moveable() : - state( false) - {} - - moveable( int) : - state( true) - {} - - moveable( BOOST_RV_REF( moveable) other) : - state( false) - { std::swap( state, other.state); } - - moveable & operator=( BOOST_RV_REF( moveable) other) - { - if ( this == & other) return * this; - moveable tmp( boost::move( other) ); - std::swap( state, tmp.state); - return * this; - } - - void operator()( coro_int_void::caller_type &) - { value3 = state; } -}; - -struct my_exception {}; - -void f1( coro_void_void::caller_type & s) -{ s(); } - -void f2( coro_void_void::caller_type &) -{ ++value1; } - -void f3( coro_void_void::caller_type & self) -{ - ++value1; - self(); - ++value1; -} - -void f4( coro_int_void::caller_type & self) -{ - self( 3); - self( 7); -} - -void f5( coro_string_void::caller_type & self) -{ - std::string res("abc"); - self( res); - res = "xyz"; - self( res); -} - -void f6( coro_void_int::caller_type & self) -{ value1 = self.get(); } - -void f7( coro_void_string::caller_type & self) -{ value2 = self.get(); } - -void f8( coro_double::caller_type & self) -{ - double x = 0, y = 0; - boost::tie( x, y) = self.get(); - self( x + y); - boost::tie( x, y) = self.get(); - self( x + y); -} - -void f9( coro_ptr::caller_type & self) -{ self( self.get() ); } - -void f91( coro_const_ptr::caller_type & self) -{ self( self.get() ); } - -void f10( coro_ref::caller_type & self) -{ self( self.get() ); } - -void f101( coro_const_ref::caller_type & self) -{ self( self.get() ); } - -void f11( coro_tuple::caller_type & self) -{ - boost::tuple tpl( self.get().get< 0 >(), self.get().get< 1 >() ); - self( tpl); - //self( 7, 11); //TODO: does not work -} - -void f12( coro_int::caller_type & self) -{ - X x_; - int x, y; - boost::tie( x, y) = self.get(); - self( x +y); - boost::tie( x, y) = self.get(); - self( x +y); -} - -template< typename E > -void f14( coro_void_void::caller_type & self, E const& e) -{ throw e; } - -void f16( coro_int_void::caller_type & self) -{ - self( 1); - self( 2); - self( 3); - self( 4); - self( 5); -} - -void f17( coro_void_int::caller_type & self, std::vector< int > & vec) -{ - int x = self.get(); - while ( 5 > x) - { - vec.push_back( x); - x = self().get(); - } -} - -void f18( coro_int_int::caller_type & self) -{ - if ( self.has_result() ) - { - int x = self.get(); - self( x + 1); - } - else - { - self( -1); - } -} - -void f19( coro_const_int_ptr_void::caller_type & self, std::vector< const int * > & vec) -{ - BOOST_FOREACH( const int * ptr, vec) - { self( ptr); } -} - -void test_move() -{ - { - coro_void_void coro1; - coro_void_void coro2( f1); - BOOST_CHECK( ! coro1); - BOOST_CHECK( coro1.empty() ); - BOOST_CHECK( coro2); - BOOST_CHECK( ! coro2.empty() ); - coro1 = boost::move( coro2); - BOOST_CHECK( coro1); - BOOST_CHECK( ! coro1.empty() ); - BOOST_CHECK( ! coro2); - BOOST_CHECK( coro2.empty() ); - } - - { - value3 = false; - copyable cp( 3); - BOOST_CHECK( cp.state); - BOOST_CHECK( ! value3); - coro_int_void coro( cp); - BOOST_CHECK( cp.state); - BOOST_CHECK( value3); - } - - { - value3 = false; - moveable mv( 7); - BOOST_CHECK( mv.state); - BOOST_CHECK( ! value3); - coro_int_void coro( boost::move( mv) ); - BOOST_CHECK( ! mv.state); - BOOST_CHECK( value3); - } -} - -void test_complete() -{ - value1 = 0; - - coro_void_void coro( f2); - BOOST_CHECK( ! coro); - BOOST_CHECK_EQUAL( ( int)1, value1); -} - -void test_jump() -{ - value1 = 0; - - coro_void_void coro( f3); - BOOST_CHECK( coro); - BOOST_CHECK_EQUAL( ( int)1, value1); - coro(); - BOOST_CHECK( ! coro); - BOOST_CHECK_EQUAL( ( int)2, value1); -} - -void test_result_int() -{ - coro_int_void coro( f4); - BOOST_CHECK( coro); - int result = coro.get(); - BOOST_CHECK( coro); - BOOST_CHECK_EQUAL( 3, result); - result = coro().get(); - BOOST_CHECK( coro); - BOOST_CHECK_EQUAL( 7, result); - coro(); - BOOST_CHECK( ! coro); -} - -void test_result_string() -{ - coro_string_void coro( f5); - BOOST_CHECK( coro); - std::string result = coro.get(); - BOOST_CHECK( coro); - BOOST_CHECK_EQUAL( std::string("abc"), result); - result = coro().get(); - BOOST_CHECK( coro); - BOOST_CHECK_EQUAL( std::string("xyz"), result); - coro(); - BOOST_CHECK( ! coro); -} - -void test_arg_int() -{ - value1 = 0; - - coro_void_int coro( f6, 3); - BOOST_CHECK( ! coro); - BOOST_CHECK_EQUAL( 3, value1); -} - -void test_arg_string() -{ - value2 = ""; - - coro_void_string coro( f7, std::string("abc") ); - BOOST_CHECK( ! coro); - BOOST_CHECK_EQUAL( std::string("abc"), value2); -} - -void test_fp() -{ - coro_double coro( f8, coro_double::arguments( 7.35, 3.14) ); - BOOST_CHECK( coro); - double res = coro.get(); - BOOST_CHECK( coro); - BOOST_CHECK_EQUAL( ( double) 10.49, res); - res = coro( 1.15, 3.14).get(); - BOOST_CHECK( coro); - BOOST_CHECK_EQUAL( ( double) 4.29, res); - coro( 1.15, 3.14); - BOOST_CHECK( ! coro); -} - -void test_ptr() -{ - int a = 3; - coro_ptr coro( f9, & a); - BOOST_CHECK( coro); - int * res = coro.get(); - BOOST_CHECK( coro); - BOOST_CHECK_EQUAL( & a, res); - coro( & a); - BOOST_CHECK( ! coro); -} - -void test_const_ptr() -{ - int a = 3; - coro_const_ptr coro( f91, & a); - BOOST_CHECK( coro); - int const* res = coro.get(); - BOOST_CHECK( coro); - BOOST_CHECK_EQUAL( & a, res); - coro( & a); - BOOST_CHECK( ! coro); -} - -void test_ref() -{ - int a = 3; - coro_ref coro( f10, a); - BOOST_CHECK( coro); - int const& res = coro.get(); - BOOST_CHECK( coro); - BOOST_CHECK_EQUAL( & a, & res); - coro( a); - BOOST_CHECK( ! coro); -} - -void test_const_ref() -{ - int a = 3; - coro_const_ref coro( f101, a); - BOOST_CHECK( coro); - int const& res = coro.get(); - BOOST_CHECK( coro); - BOOST_CHECK_EQUAL( & a, & res); - coro( a); - BOOST_CHECK( ! coro); -} - -void test_tuple() -{ - int a = 3, b = 7; - coro_tuple coro( f11, coro_tuple::arguments( a, b) ); - BOOST_CHECK( coro); - boost::tuple tpl = coro.get(); - BOOST_CHECK( coro); - BOOST_CHECK_EQUAL( & a, & tpl.get< 0 >() ); - BOOST_CHECK_EQUAL( & b, & tpl.get< 1 >() ); - coro( a, b); - BOOST_CHECK( ! coro); -} - -void test_unwind() -{ - value1 = 0; - { - BOOST_CHECK_EQUAL( ( int) 0, value1); - coro_int coro( f12, coro_int::arguments( 3, 7) ); - BOOST_CHECK( coro); - int res = coro.get(); - BOOST_CHECK_EQUAL( ( int) 7, value1); - BOOST_CHECK( coro); - BOOST_CHECK_EQUAL( ( int) 10, res); - } - BOOST_CHECK_EQUAL( ( int) 0, value1); -} - -void test_no_unwind() -{ - value1 = 0; - { - BOOST_CHECK_EQUAL( ( int) 0, value1); - coro_int coro( - f12, - coro_int::arguments( 3, 7), - coro::attributes( - coro::stack_allocator::default_stacksize(), - coro::no_stack_unwind) ); - BOOST_CHECK( coro); - int res = coro.get(); - BOOST_CHECK( coro); - BOOST_CHECK_EQUAL( ( int) 10, res); - } - BOOST_CHECK_EQUAL( ( int) 7, value1); -} - -void test_exceptions() -{ - bool thrown = false; - std::runtime_error ex("abc"); - try - { - coro_void_void coro( boost::bind( f14< std::runtime_error >, _1, ex) ); - BOOST_CHECK( ! coro); - BOOST_CHECK( false); - } - catch ( std::runtime_error const&) - { thrown = true; } - catch ( std::exception const&) - {} - catch (...) - {} - BOOST_CHECK( thrown); -} - -void test_output_iterator() -{ - { - std::vector< int > vec; - coro_int_void coro( f16); - BOOST_FOREACH( int i, coro) - { vec.push_back( i); } - BOOST_CHECK_EQUAL( ( std::size_t)5, vec.size() ); - BOOST_CHECK_EQUAL( ( int)1, vec[0] ); - BOOST_CHECK_EQUAL( ( int)2, vec[1] ); - BOOST_CHECK_EQUAL( ( int)3, vec[2] ); - BOOST_CHECK_EQUAL( ( int)4, vec[3] ); - BOOST_CHECK_EQUAL( ( int)5, vec[4] ); - } - { - std::vector< int > vec; - coro_int_void coro( f16); - coro_int_void::iterator e = boost::end( coro); - for ( - coro_int_void::iterator i = boost::begin( coro); - i != e; ++i) - { vec.push_back( * i); } - BOOST_CHECK_EQUAL( ( std::size_t)5, vec.size() ); - BOOST_CHECK_EQUAL( ( int)1, vec[0] ); - BOOST_CHECK_EQUAL( ( int)2, vec[1] ); - BOOST_CHECK_EQUAL( ( int)3, vec[2] ); - BOOST_CHECK_EQUAL( ( int)4, vec[3] ); - BOOST_CHECK_EQUAL( ( int)5, vec[4] ); - } - { - int i1 = 1, i2 = 2, i3 = 3; - std::vector< const int* > vec_in; - vec_in.push_back( & i1); - vec_in.push_back( & i2); - vec_in.push_back( & i3); - std::vector< const int* > vec_out; - coro_const_int_ptr_void coro( boost::bind( f19, _1, boost::ref( vec_in) ) ); - coro_const_int_ptr_void::const_iterator e = boost::const_end( coro); - for ( - coro_const_int_ptr_void::const_iterator i = boost::const_begin( coro); - i != e; ++i) - { vec_out.push_back( * i); } - BOOST_CHECK_EQUAL( ( std::size_t)3, vec_out.size() ); - BOOST_CHECK_EQUAL( & i1, vec_out[0] ); - BOOST_CHECK_EQUAL( & i2, vec_out[1] ); - BOOST_CHECK_EQUAL( & i3, vec_out[2] ); - } -} - -void test_input_iterator() -{ - int counter = 0; - std::vector< int > vec; - coro_void_int coro( - boost::bind( f17, _1, boost::ref( vec) ), - counter); - coro_void_int::iterator e( boost::end( coro) ); - for ( coro_void_int::iterator i( boost::begin( coro) ); - i != e; ++i) - { - i = ++counter; - } - BOOST_CHECK_EQUAL( ( std::size_t)5, vec.size() ); - BOOST_CHECK_EQUAL( ( int)0, vec[0] ); - BOOST_CHECK_EQUAL( ( int)1, vec[1] ); - BOOST_CHECK_EQUAL( ( int)2, vec[2] ); - BOOST_CHECK_EQUAL( ( int)3, vec[3] ); - BOOST_CHECK_EQUAL( ( int)4, vec[4] ); -} - -void test_pre() -{ - coro_int_int coro( f18, 0); - BOOST_CHECK( coro); - int res = coro.get(); - BOOST_CHECK_EQUAL( ( int) 1, res); - BOOST_CHECK( coro); - coro( -1); - BOOST_CHECK( ! coro); -} - -void test_post() -{ - coro_int_int coro( f18); - BOOST_CHECK( coro); - int res = coro.get(); - BOOST_CHECK_EQUAL( ( int) -1, res); - BOOST_CHECK( coro); - coro( -1); - BOOST_CHECK( ! coro); -} -#endif boost::unit_test::test_suite * init_unit_test_suite( int, char* []) { @@ -1056,12 +545,7 @@ boost::unit_test::test_suite * init_unit_test_suite( int, char* []) test->add( BOOST_TEST_CASE( & test_fp) ); test->add( BOOST_TEST_CASE( & test_ptr) ); test->add( BOOST_TEST_CASE( & test_const_ptr) ); -#ifndef BOOST_COROUTINES_UNIDIRECT - test->add( BOOST_TEST_CASE( & test_pre) ); - test->add( BOOST_TEST_CASE( & test_post) ); -#else test->add( BOOST_TEST_CASE( & test_invalid_result) ); -#endif test->add( BOOST_TEST_CASE( & test_ref) ); test->add( BOOST_TEST_CASE( & test_const_ref) ); test->add( BOOST_TEST_CASE( & test_tuple) );