summaryrefslogtreecommitdiff
path: root/boost/coroutine2
diff options
context:
space:
mode:
Diffstat (limited to 'boost/coroutine2')
-rw-r--r--boost/coroutine2/detail/config.hpp3
-rw-r--r--boost/coroutine2/detail/coroutine.hpp8
-rw-r--r--boost/coroutine2/detail/forced_unwind.hpp2
-rw-r--r--boost/coroutine2/detail/pull_control_block_cc.hpp (renamed from boost/coroutine2/detail/pull_control_block_ecv2.hpp)40
-rw-r--r--boost/coroutine2/detail/pull_control_block_cc.ipp452
-rw-r--r--boost/coroutine2/detail/pull_control_block_ecv1.ipp22
-rw-r--r--boost/coroutine2/detail/pull_control_block_ecv2.ipp422
-rw-r--r--boost/coroutine2/detail/pull_coroutine.hpp4
-rw-r--r--boost/coroutine2/detail/push_control_block_cc.hpp (renamed from boost/coroutine2/detail/push_control_block_ecv2.hpp)14
-rw-r--r--boost/coroutine2/detail/push_control_block_cc.ipp400
-rw-r--r--boost/coroutine2/detail/push_control_block_ecv1.ipp22
-rw-r--r--boost/coroutine2/detail/push_control_block_ecv2.ipp392
-rw-r--r--boost/coroutine2/detail/push_coroutine.hpp8
-rw-r--r--boost/coroutine2/detail/wrap.hpp112
14 files changed, 1023 insertions, 878 deletions
diff --git a/boost/coroutine2/detail/config.hpp b/boost/coroutine2/detail/config.hpp
index cfb95846a5..307ee4e78a 100644
--- a/boost/coroutine2/detail/config.hpp
+++ b/boost/coroutine2/detail/config.hpp
@@ -18,7 +18,6 @@
#if (defined(BOOST_ALL_DYN_LINK) || defined(BOOST_COROUTINES2_DYN_LINK) ) && ! defined(BOOST_COROUTINES2_STATIC_LINK)
# if defined(BOOST_COROUTINES2_SOURCE)
# define BOOST_COROUTINES2_DECL BOOST_SYMBOL_EXPORT
-# define BOOST_COROUTINES2_BUILD_DLL
# else
# define BOOST_COROUTINES2_DECL BOOST_SYMBOL_IMPORT
# endif
@@ -29,7 +28,7 @@
#endif
#if ! defined(BOOST_COROUTINES2_SOURCE) && ! defined(BOOST_ALL_NO_LIB) && ! defined(BOOST_COROUTINES2_NO_LIB)
-# define BOOST_LIB_NAME boost_coroutine
+# define BOOST_LIB_NAME boost_coroutine2
# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_COROUTINES2_DYN_LINK)
# define BOOST_DYN_LINK
# endif
diff --git a/boost/coroutine2/detail/coroutine.hpp b/boost/coroutine2/detail/coroutine.hpp
index 7c1483d3be..1170590183 100644
--- a/boost/coroutine2/detail/coroutine.hpp
+++ b/boost/coroutine2/detail/coroutine.hpp
@@ -34,8 +34,8 @@ class push_coroutine;
# include <boost/coroutine2/detail/pull_control_block_ecv1.hpp>
# include <boost/coroutine2/detail/push_control_block_ecv1.hpp>
# else
-# include <boost/coroutine2/detail/pull_control_block_ecv2.hpp>
-# include <boost/coroutine2/detail/push_control_block_ecv2.hpp>
+# include <boost/coroutine2/detail/pull_control_block_cc.hpp>
+# include <boost/coroutine2/detail/push_control_block_cc.hpp>
# endif
# include <boost/coroutine2/detail/pull_coroutine.ipp>
@@ -45,8 +45,8 @@ class push_coroutine;
# include <boost/coroutine2/detail/pull_control_block_ecv1.ipp>
# include <boost/coroutine2/detail/push_control_block_ecv1.ipp>
# else
-# include <boost/coroutine2/detail/pull_control_block_ecv2.ipp>
-# include <boost/coroutine2/detail/push_control_block_ecv2.ipp>
+# include <boost/coroutine2/detail/pull_control_block_cc.ipp>
+# include <boost/coroutine2/detail/push_control_block_cc.ipp>
# endif
#endif
diff --git a/boost/coroutine2/detail/forced_unwind.hpp b/boost/coroutine2/detail/forced_unwind.hpp
index 0f67f79a5f..d486ed43dd 100644
--- a/boost/coroutine2/detail/forced_unwind.hpp
+++ b/boost/coroutine2/detail/forced_unwind.hpp
@@ -12,8 +12,6 @@
#include <boost/assert.hpp>
#include <boost/config.hpp>
-#include <boost/context/execution_context.hpp>
-
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
diff --git a/boost/coroutine2/detail/pull_control_block_ecv2.hpp b/boost/coroutine2/detail/pull_control_block_cc.hpp
index 58d248833a..44a14e2102 100644
--- a/boost/coroutine2/detail/pull_control_block_ecv2.hpp
+++ b/boost/coroutine2/detail/pull_control_block_cc.hpp
@@ -1,5 +1,5 @@
-// Copyright Oliver Kowalke 2014.
+// Copyright Oliver Kowalke 2016.
// 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)
@@ -11,7 +11,7 @@
#include <type_traits>
#include <boost/config.hpp>
-#include <boost/context/execution_context.hpp>
+#include <boost/context/continuation.hpp>
#include <boost/coroutine2/detail/state.hpp>
@@ -25,7 +25,7 @@ namespace detail {
template< typename T >
struct pull_coroutine< T >::control_block {
- boost::context::execution_context< T * > ctx;
+ boost::context::continuation c;
typename push_coroutine< T >::control_block * other;
state_t state;
std::exception_ptr except;
@@ -37,7 +37,7 @@ struct pull_coroutine< T >::control_block {
template< typename StackAllocator, typename Fn >
control_block( context::preallocated, StackAllocator, Fn &&);
- control_block( typename push_coroutine< T >::control_block *, boost::context::execution_context< T * > &) noexcept;
+ control_block( typename push_coroutine< T >::control_block *, boost::context::continuation &) noexcept;
~control_block();
@@ -48,7 +48,9 @@ struct pull_coroutine< T >::control_block {
void resume();
- void set( T *);
+ void set( T const&);
+ void set( T &&);
+ void reset();
T & get() noexcept;
@@ -57,18 +59,27 @@ struct pull_coroutine< T >::control_block {
template< typename T >
struct pull_coroutine< T & >::control_block {
- boost::context::execution_context< T * > ctx;
- typename push_coroutine< T & >::control_block * other;
- state_t state;
- std::exception_ptr except;
- T * t;
+ struct holder {
+ T & t;
+
+ holder( T & t_) :
+ t{ t_ } {
+ }
+ };
+
+ boost::context::continuation c;
+ typename push_coroutine< T & >::control_block * other;
+ state_t state;
+ std::exception_ptr except;
+ bool bvalid;
+ typename std::aligned_storage< sizeof( holder), alignof( holder) >::type storage;
static void destroy( control_block * cb) noexcept;
template< typename StackAllocator, typename Fn >
control_block( context::preallocated, StackAllocator, Fn &&);
- control_block( typename push_coroutine< T & >::control_block *, boost::context::execution_context< T * > &) noexcept;
+ control_block( typename push_coroutine< T & >::control_block *, boost::context::continuation &) noexcept;
control_block( control_block &) = delete;
control_block & operator=( control_block &) = delete;
@@ -77,13 +88,16 @@ struct pull_coroutine< T & >::control_block {
void resume();
+ void set( T &);
+ void reset();
+
T & get() noexcept;
bool valid() const noexcept;
};
struct pull_coroutine< void >::control_block {
- boost::context::execution_context< void > ctx;
+ boost::context::continuation c;
push_coroutine< void >::control_block * other;
state_t state;
std::exception_ptr except;
@@ -93,7 +107,7 @@ struct pull_coroutine< void >::control_block {
template< typename StackAllocator, typename Fn >
control_block( context::preallocated, StackAllocator, Fn &&);
- control_block( push_coroutine< void >::control_block *, boost::context::execution_context< void > &) noexcept;
+ control_block( push_coroutine< void >::control_block *, boost::context::continuation &) noexcept;
control_block( control_block &) = delete;
control_block & operator=( control_block &) = delete;
diff --git a/boost/coroutine2/detail/pull_control_block_cc.ipp b/boost/coroutine2/detail/pull_control_block_cc.ipp
new file mode 100644
index 0000000000..0406202016
--- /dev/null
+++ b/boost/coroutine2/detail/pull_control_block_cc.ipp
@@ -0,0 +1,452 @@
+
+// Copyright Oliver Kowalke 2016.
+// 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_COROUTINES2_DETAIL_PULL_CONTROL_BLOCK_IPP
+#define BOOST_COROUTINES2_DETAIL_PULL_CONTROL_BLOCK_IPP
+
+#include <algorithm>
+#include <exception>
+#include <memory>
+#include <tuple>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+
+#include <boost/context/continuation.hpp>
+
+#include <boost/coroutine2/detail/config.hpp>
+#include <boost/coroutine2/detail/forced_unwind.hpp>
+#include <boost/coroutine2/detail/wrap.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines2 {
+namespace detail {
+
+// pull_coroutine< T >
+
+template< typename T >
+void
+pull_coroutine< T >::control_block::destroy( control_block * cb) noexcept {
+ boost::context::continuation c = std::move( cb->c);
+ // destroy control structure
+ cb->~control_block();
+ // destroy coroutine's stack
+ cb->state |= state_t::destroy;
+ c.resume();
+}
+
+template< typename T >
+template< typename StackAllocator, typename Fn >
+pull_coroutine< T >::control_block::control_block( context::preallocated palloc, StackAllocator salloc,
+ Fn && fn) :
+ c{},
+ other{ nullptr },
+ state{ state_t::unwind },
+ except{},
+ bvalid{ false },
+ storage{} {
+#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
+ c = boost::context::callcc(
+ std::allocator_arg, palloc, salloc,
+ wrap( [this](typename std::decay< Fn >::type & fn_,boost::context::continuation && c) mutable {
+ // create synthesized push_coroutine< T >
+ typename push_coroutine< T >::control_block synthesized_cb{ this, c };
+ push_coroutine< T > synthesized{ & synthesized_cb };
+ other = & synthesized_cb;
+ if ( state_t::none == ( state & state_t::destroy) ) {
+ try {
+ auto fn = std::move( fn_);
+ // call coroutine-fn with synthesized push_coroutine as argument
+ fn( synthesized);
+ } catch ( boost::context::detail::forced_unwind const&) {
+ throw;
+ } catch (...) {
+ // store other exceptions in exception-pointer
+ except = std::current_exception();
+ }
+ }
+ // set termination flags
+ state |= state_t::complete;
+ // jump back
+ return other->c.resume();
+ },
+ std::forward< Fn >( fn) ) );
+#else
+ c = boost::context::callcc(
+ std::allocator_arg, palloc, salloc,
+ [this,fn_=std::forward< Fn >( fn)](boost::context::continuation && c) mutable {
+ // create synthesized push_coroutine< T >
+ typename push_coroutine< T >::control_block synthesized_cb{ this, c };
+ push_coroutine< T > synthesized{ & synthesized_cb };
+ other = & synthesized_cb;
+ if ( state_t::none == ( state & state_t::destroy) ) {
+ try {
+ auto fn = std::move( fn_);
+ // call coroutine-fn with synthesized push_coroutine as argument
+ fn( synthesized);
+ } catch ( boost::context::detail::forced_unwind const&) {
+ throw;
+ } catch (...) {
+ // store other exceptions in exception-pointer
+ except = std::current_exception();
+ }
+ }
+ // set termination flags
+ state |= state_t::complete;
+ // jump back
+ return other->c.resume();
+ });
+#endif
+ if ( c.data_available() ) {
+ set( c.get_data< T >() );
+ }
+}
+
+template< typename T >
+pull_coroutine< T >::control_block::control_block( typename push_coroutine< T >::control_block * cb,
+ boost::context::continuation & c_) noexcept :
+ c{ std::move( c_) },
+ other{ cb },
+ state{ state_t::none },
+ except{},
+ bvalid{ false },
+ storage{} {
+}
+
+template< typename T >
+pull_coroutine< T >::control_block::~control_block() {
+ // destroy data if set
+ if ( bvalid) {
+ reinterpret_cast< T * >( std::addressof( storage) )->~T();
+ }
+}
+
+template< typename T >
+void
+pull_coroutine< T >::control_block::deallocate() noexcept {
+ if ( state_t::none != ( state & state_t::unwind) ) {
+ destroy( this);
+ }
+}
+
+template< typename T >
+void
+pull_coroutine< T >::control_block::resume() {
+ c = c.resume();
+ if ( c.data_available() ) {
+ set( c.get_data< T >() );
+ } else {
+ reset();
+ }
+ if ( except) {
+ std::rethrow_exception( except);
+ }
+}
+
+template< typename T >
+void
+pull_coroutine< T >::control_block::set( T const& t) {
+ // destroy data if set
+ if ( bvalid) {
+ reinterpret_cast< T * >( std::addressof( storage) )->~T();
+ }
+ ::new ( static_cast< void * >( std::addressof( storage) ) ) T( t);
+ bvalid = true;
+}
+
+template< typename T >
+void
+pull_coroutine< T >::control_block::set( T && t) {
+ // destroy data if set
+ if ( bvalid) {
+ reinterpret_cast< T * >( std::addressof( storage) )->~T();
+ }
+ ::new ( static_cast< void * >( std::addressof( storage) ) ) T( std::move( t) );
+ bvalid = true;
+}
+
+template< typename T >
+void
+pull_coroutine< T >::control_block::reset() {
+ // destroy data if set
+ if ( bvalid) {
+ reinterpret_cast< T * >( std::addressof( storage) )->~T();
+ }
+ bvalid = false;
+}
+
+template< typename T >
+T &
+pull_coroutine< T >::control_block::get() noexcept {
+ return * reinterpret_cast< T * >( std::addressof( storage) );
+}
+
+template< typename T >
+bool
+pull_coroutine< T >::control_block::valid() const noexcept {
+ return nullptr != other && state_t::none == ( state & state_t::complete) && bvalid;
+}
+
+
+// pull_coroutine< T & >
+
+template< typename T >
+void
+pull_coroutine< T & >::control_block::destroy( control_block * cb) noexcept {
+ boost::context::continuation c = std::move( cb->c);
+ // destroy control structure
+ cb->~control_block();
+ // destroy coroutine's stack
+ cb->state |= state_t::destroy;
+ c.resume();
+}
+
+template< typename T >
+template< typename StackAllocator, typename Fn >
+pull_coroutine< T & >::control_block::control_block( context::preallocated palloc, StackAllocator salloc,
+ Fn && fn) :
+ c{},
+ other{ nullptr },
+ state{ state_t::unwind },
+ except{},
+ bvalid{ false },
+ storage{} {
+#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
+ c = boost::context::callcc(
+ std::allocator_arg, palloc, salloc,
+ wrap( [this](typename std::decay< Fn >::type & fn_,boost::context::continuation && c) mutable {
+ // create synthesized push_coroutine< T & >
+ typename push_coroutine< T & >::control_block synthesized_cb{ this, c };
+ push_coroutine< T & > synthesized{ & synthesized_cb };
+ other = & synthesized_cb;
+ if ( state_t::none == ( state & state_t::destroy) ) {
+ try {
+ auto fn = std::move( fn_);
+ // call coroutine-fn with synthesized push_coroutine as argument
+ fn( synthesized);
+ } catch ( boost::context::detail::forced_unwind const&) {
+ throw;
+ } catch (...) {
+ // store other exceptions in exception-pointer
+ except = std::current_exception();
+ }
+ }
+ // set termination flags
+ state |= state_t::complete;
+ // jump back
+ return other->c.resume();
+ },
+ std::forward< Fn >( fn) ) );
+#else
+ c = boost::context::callcc(
+ std::allocator_arg, palloc, salloc,
+ [this,fn_=std::forward< Fn >( fn)](boost::context::continuation && c) mutable {
+ // create synthesized push_coroutine< T & >
+ typename push_coroutine< T & >::control_block synthesized_cb{ this, c };
+ push_coroutine< T & > synthesized{ & synthesized_cb };
+ other = & synthesized_cb;
+ if ( state_t::none == ( state & state_t::destroy) ) {
+ try {
+ auto fn = std::move( fn_);
+ // call coroutine-fn with synthesized push_coroutine as argument
+ fn( synthesized);
+ } catch ( boost::context::detail::forced_unwind const&) {
+ throw;
+ } catch (...) {
+ // store other exceptions in exception-pointer
+ except = std::current_exception();
+ }
+ }
+ // set termination flags
+ state |= state_t::complete;
+ // jump back
+ return other->c.resume();
+ });
+#endif
+ if ( c.data_available() ) {
+ set( c.get_data< T & >() );
+ }
+}
+
+template< typename T >
+pull_coroutine< T & >::control_block::control_block( typename push_coroutine< T & >::control_block * cb,
+ boost::context::continuation & c_) noexcept :
+ c{ std::move( c_) },
+ other{ cb },
+ state{ state_t::none },
+ except{},
+ bvalid{ false },
+ storage{} {
+}
+
+template< typename T >
+void
+pull_coroutine< T & >::control_block::deallocate() noexcept {
+ if ( state_t::none != ( state & state_t::unwind) ) {
+ destroy( this);
+ }
+}
+
+template< typename T >
+void
+pull_coroutine< T & >::control_block::resume() {
+ c = c.resume();
+ if ( c.data_available() ) {
+ set( c.get_data< T & >() );
+ } else {
+ reset();
+ }
+ if ( except) {
+ std::rethrow_exception( except);
+ }
+}
+
+template< typename T >
+void
+pull_coroutine< T & >::control_block::set( T & t) {
+ ::new ( static_cast< void * >( std::addressof( storage) ) ) holder{ t };
+ bvalid = true;
+}
+
+template< typename T >
+void
+pull_coroutine< T & >::control_block::reset() {
+ if ( bvalid) {
+ reinterpret_cast< holder * >( std::addressof( storage) )->~holder();
+ }
+ bvalid = false;
+}
+
+template< typename T >
+T &
+pull_coroutine< T & >::control_block::get() noexcept {
+ return reinterpret_cast< holder * >( std::addressof( storage) )->t;
+}
+
+template< typename T >
+bool
+pull_coroutine< T & >::control_block::valid() const noexcept {
+ return nullptr != other && state_t::none == ( state & state_t::complete) && bvalid;
+}
+
+
+// pull_coroutine< void >
+
+inline
+void
+pull_coroutine< void >::control_block::destroy( control_block * cb) noexcept {
+ boost::context::continuation c = std::move( cb->c);
+ // destroy control structure
+ cb->~control_block();
+ // destroy coroutine's stack
+ cb->state |= state_t::destroy;
+ c.resume();
+}
+
+template< typename StackAllocator, typename Fn >
+pull_coroutine< void >::control_block::control_block( context::preallocated palloc, StackAllocator salloc,
+ Fn && fn) :
+ c{},
+ other{ nullptr },
+ state{ state_t::unwind },
+ except{} {
+#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
+ c = boost::context::callcc(
+ std::allocator_arg, palloc, salloc,
+ wrap( [this](typename std::decay< Fn >::type & fn_,boost::context::continuation && c) mutable {
+ // create synthesized push_coroutine< void >
+ typename push_coroutine< void >::control_block synthesized_cb{ this, c };
+ push_coroutine< void > synthesized{ & synthesized_cb };
+ other = & synthesized_cb;
+ if ( state_t::none == ( state & state_t::destroy) ) {
+ try {
+ auto fn = std::move( fn_);
+ // call coroutine-fn with synthesized push_coroutine as argument
+ fn( synthesized);
+ } catch ( boost::context::detail::forced_unwind const&) {
+ throw;
+ } catch (...) {
+ // store other exceptions in exception-pointer
+ except = std::current_exception();
+ }
+ }
+ // set termination flags
+ state |= state_t::complete;
+ // jump back
+ return other->c.resume();
+ },
+ std::forward< Fn >( fn) ) );
+#else
+ c = boost::context::callcc(
+ std::allocator_arg, palloc, salloc,
+ [this,fn_=std::forward< Fn >( fn)]( boost::context::continuation && c) mutable {
+ // create synthesized push_coroutine< void >
+ typename push_coroutine< void >::control_block synthesized_cb{ this, c };
+ push_coroutine< void > synthesized{ & synthesized_cb };
+ other = & synthesized_cb;
+ if ( state_t::none == ( state & state_t::destroy) ) {
+ try {
+ auto fn = std::move( fn_);
+ // call coroutine-fn with synthesized push_coroutine as argument
+ fn( synthesized);
+ } catch ( boost::context::detail::forced_unwind const&) {
+ throw;
+ } catch (...) {
+ // store other exceptions in exception-pointer
+ except = std::current_exception();
+ }
+ }
+ // set termination flags
+ state |= state_t::complete;
+ // jump back to ctx
+ return other->c.resume();
+ });
+#endif
+}
+
+inline
+pull_coroutine< void >::control_block::control_block( push_coroutine< void >::control_block * cb,
+ boost::context::continuation & c_) noexcept :
+ c{ std::move( c_) },
+ other{ cb },
+ state{ state_t::none },
+ except{} {
+}
+
+inline
+void
+pull_coroutine< void >::control_block::deallocate() noexcept {
+ if ( state_t::none != ( state & state_t::unwind) ) {
+ destroy( this);
+ }
+}
+
+inline
+void
+pull_coroutine< void >::control_block::resume() {
+ c = c.resume();
+ if ( except) {
+ std::rethrow_exception( except);
+ }
+}
+
+inline
+bool
+pull_coroutine< void >::control_block::valid() const noexcept {
+ return nullptr != other && state_t::none == ( state & state_t::complete);
+}
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES2_DETAIL_PULL_CONTROL_BLOCK_IPP
diff --git a/boost/coroutine2/detail/pull_control_block_ecv1.ipp b/boost/coroutine2/detail/pull_control_block_ecv1.ipp
index eb2ae2778f..77866041fe 100644
--- a/boost/coroutine2/detail/pull_control_block_ecv1.ipp
+++ b/boost/coroutine2/detail/pull_control_block_ecv1.ipp
@@ -20,6 +20,7 @@
#include <boost/coroutine2/detail/decay_copy.hpp>
#include <boost/coroutine2/detail/forced_unwind.hpp>
#include <boost/coroutine2/detail/state.hpp>
+#include <boost/coroutine2/detail/wrap.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
@@ -46,9 +47,7 @@ pull_coroutine< T >::control_block::control_block( context::preallocated palloc,
Fn && fn) :
#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
ctx{ std::allocator_arg, palloc, salloc,
- std::move(
- std::bind(
- [this]( typename std::decay< Fn >::type & fn_, boost::context::execution_context & ctx, void *) mutable noexcept {
+ wrap( [this]( typename std::decay< Fn >::type & fn_, boost::context::execution_context & ctx, void *) mutable noexcept {
// create synthesized push_coroutine< T >
typename push_coroutine< T >::control_block synthesized_cb{ this, ctx };
push_coroutine< T > synthesized{ & synthesized_cb };
@@ -72,8 +71,7 @@ pull_coroutine< T >::control_block::control_block( context::preallocated palloc,
BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
},
std::forward< Fn >( fn),
- boost::context::execution_context::current(),
- std::placeholders::_1))},
+ boost::context::execution_context::current() ) },
#else
ctx{ std::allocator_arg, palloc, salloc,
[this,fn_=decay_copy( std::forward< Fn >( fn) ),ctx=boost::context::execution_context::current()] (void *) mutable noexcept {
@@ -197,9 +195,7 @@ pull_coroutine< T & >::control_block::control_block( context::preallocated pallo
Fn && fn) :
#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
ctx{ std::allocator_arg, palloc, salloc,
- std::move(
- std::bind(
- [this]( typename std::decay< Fn >::type & fn_, boost::context::execution_context & ctx, void *) mutable noexcept {
+ wrap( [this]( typename std::decay< Fn >::type & fn_, boost::context::execution_context & ctx, void *) mutable noexcept {
// create synthesized push_coroutine< T >
typename push_coroutine< T & >::control_block synthesized_cb{ this, ctx };
push_coroutine< T & > synthesized{ & synthesized_cb };
@@ -223,8 +219,7 @@ pull_coroutine< T & >::control_block::control_block( context::preallocated pallo
BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
},
std::forward< Fn >( fn),
- boost::context::execution_context::current(),
- std::placeholders::_1))},
+ boost::context::execution_context::current() ) },
#else
ctx{ std::allocator_arg, palloc, salloc,
[this,fn_=decay_copy( std::forward< Fn >( fn) ),ctx=boost::context::execution_context::current()] (void *) mutable noexcept {
@@ -326,9 +321,7 @@ pull_coroutine< void >::control_block::control_block( context::preallocated pall
Fn && fn) :
#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
ctx{ std::allocator_arg, palloc, salloc,
- std::move(
- std::bind(
- [this]( typename std::decay< Fn >::type & fn_, boost::context::execution_context & ctx, void *) mutable noexcept {
+ wrap( [this]( typename std::decay< Fn >::type & fn_, boost::context::execution_context & ctx, void *) mutable noexcept {
// create synthesized push_coroutine< T >
typename push_coroutine< void >::control_block synthesized_cb{ this, ctx };
push_coroutine< void > synthesized{ & synthesized_cb };
@@ -352,8 +345,7 @@ pull_coroutine< void >::control_block::control_block( context::preallocated pall
BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
},
std::forward< Fn >( fn),
- boost::context::execution_context::current(),
- std::placeholders::_1))},
+ boost::context::execution_context::current() ) },
#else
ctx{ std::allocator_arg, palloc, salloc,
[this,fn_=decay_copy( std::forward< Fn >( fn) ),ctx=boost::context::execution_context::current()] (void *) mutable noexcept {
diff --git a/boost/coroutine2/detail/pull_control_block_ecv2.ipp b/boost/coroutine2/detail/pull_control_block_ecv2.ipp
deleted file mode 100644
index a1c7c93cd0..0000000000
--- a/boost/coroutine2/detail/pull_control_block_ecv2.ipp
+++ /dev/null
@@ -1,422 +0,0 @@
-
-// Copyright Oliver Kowalke 2014.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef BOOST_COROUTINES2_DETAIL_PULL_CONTROL_BLOCK_IPP
-#define BOOST_COROUTINES2_DETAIL_PULL_CONTROL_BLOCK_IPP
-
-#include <algorithm>
-#include <exception>
-#include <memory>
-#include <tuple>
-
-#include <boost/assert.hpp>
-#include <boost/config.hpp>
-
-#include <boost/context/execution_context.hpp>
-
-#include <boost/coroutine2/detail/config.hpp>
-#include <boost/coroutine2/detail/forced_unwind.hpp>
-
-#ifdef BOOST_HAS_ABI_HEADERS
-# include BOOST_ABI_PREFIX
-#endif
-
-namespace boost {
-namespace coroutines2 {
-namespace detail {
-
-// pull_coroutine< T >
-
-template< typename T >
-void
-pull_coroutine< T >::control_block::destroy( control_block * cb) noexcept {
- boost::context::execution_context< T * > ctx = std::move( cb->ctx);
- // destroy control structure
- cb->~control_block();
- // destroy coroutine's stack
- cb->state |= state_t::destroy;
- ctx( nullptr);
-}
-
-template< typename T >
-template< typename StackAllocator, typename Fn >
-pull_coroutine< T >::control_block::control_block( context::preallocated palloc, StackAllocator salloc,
- Fn && fn) :
-#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
- ctx{ std::allocator_arg, palloc, salloc,
- std::move(
- std::bind(
- [this]( typename std::decay< Fn >::type & fn_, boost::context::execution_context< T * > && ctx, T *) mutable {
- // create synthesized push_coroutine< T >
- typename push_coroutine< T >::control_block synthesized_cb{ this, ctx };
- push_coroutine< T > synthesized{ & synthesized_cb };
- other = & synthesized_cb;
- if ( state_t::none == ( state & state_t::destroy) ) {
- try {
- auto fn = std::move( fn_);
- // call coroutine-fn with synthesized push_coroutine as argument
- fn( synthesized);
- } catch ( boost::context::detail::forced_unwind const&) {
- throw;
- } catch (...) {
- // store other exceptions in exception-pointer
- except = std::current_exception();
- }
- }
- // set termination flags
- state |= state_t::complete;
- // jump back to ctx
- auto result = other->ctx( nullptr);
- other->ctx = std::move( std::get< 0 >( result) );
- return std::move( other->ctx);
- },
- std::forward< Fn >( fn),
- std::placeholders::_1,
- std::placeholders::_2))},
-#else
- ctx{ std::allocator_arg, palloc, salloc,
- [this,fn_=std::forward< Fn >( fn)]( boost::context::execution_context< T * > && ctx, T *) mutable {
- // create synthesized push_coroutine< T >
- typename push_coroutine< T >::control_block synthesized_cb{ this, ctx };
- push_coroutine< T > synthesized{ & synthesized_cb };
- other = & synthesized_cb;
- if ( state_t::none == ( state & state_t::destroy) ) {
- try {
- auto fn = std::move( fn_);
- // call coroutine-fn with synthesized push_coroutine as argument
- fn( synthesized);
- } catch ( boost::context::detail::forced_unwind const&) {
- throw;
- } catch (...) {
- // store other exceptions in exception-pointer
- except = std::current_exception();
- }
- }
- // set termination flags
- state |= state_t::complete;
- // jump back to ctx
- auto result = other->ctx( nullptr);
- other->ctx = std::move( std::get< 0 >( result) );
- return std::move( other->ctx);
- }},
-#endif
- other{ nullptr },
- state{ state_t::unwind },
- except{},
- bvalid{ false },
- storage{} {
- // enter coroutine-fn in order to have first value available after ctor (of `*this`) returns
- resume();
-}
-
-template< typename T >
-pull_coroutine< T >::control_block::control_block( typename push_coroutine< T >::control_block * cb,
- boost::context::execution_context< T * > & ctx_) noexcept :
- ctx{ std::move( ctx_) },
- other{ cb },
- state{ state_t::none },
- except{},
- bvalid{ false },
- storage{} {
-}
-
-template< typename T >
-pull_coroutine< T >::control_block::~control_block() {
- // destroy data if set
- if ( bvalid) {
- reinterpret_cast< T * >( std::addressof( storage) )->~T();
- }
-}
-
-template< typename T >
-void
-pull_coroutine< T >::control_block::deallocate() noexcept {
- if ( state_t::none != ( state & state_t::unwind) ) {
- destroy( this);
- }
-}
-
-template< typename T >
-void
-pull_coroutine< T >::control_block::resume() {
- auto result = ctx( nullptr);
- ctx = std::move( std::get< 0 >( result) );
- set( std::get< 1 >( result) );
- if ( except) {
- std::rethrow_exception( except);
- }
-}
-
-template< typename T >
-void
-pull_coroutine< T >::control_block::set( T * t) {
- // destroy data if set
- if ( bvalid) {
- reinterpret_cast< T * >( std::addressof( storage) )->~T();
- }
- if ( nullptr != t) {
- ::new ( static_cast< void * >( std::addressof( storage) ) ) T( std::move( * t) );
- bvalid = true;
- } else {
- bvalid = false;
- }
-}
-
-template< typename T >
-T &
-pull_coroutine< T >::control_block::get() noexcept {
- return * reinterpret_cast< T * >( std::addressof( storage) );
-}
-
-template< typename T >
-bool
-pull_coroutine< T >::control_block::valid() const noexcept {
- return nullptr != other && state_t::none == ( state & state_t::complete) && bvalid;
-}
-
-
-// pull_coroutine< T & >
-
-template< typename T >
-void
-pull_coroutine< T & >::control_block::destroy( control_block * cb) noexcept {
- boost::context::execution_context< T * > ctx = std::move( cb->ctx);
- // destroy control structure
- cb->~control_block();
- // destroy coroutine's stack
- cb->state |= state_t::destroy;
- ctx( nullptr);
-}
-
-template< typename T >
-template< typename StackAllocator, typename Fn >
-pull_coroutine< T & >::control_block::control_block( context::preallocated palloc, StackAllocator salloc,
- Fn && fn) :
-#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
- ctx{ std::allocator_arg, palloc, salloc,
- std::move(
- std::bind(
- [this]( typename std::decay< Fn >::type & fn_, boost::context::execution_context< T *> && ctx, T *) mutable {
- // create synthesized push_coroutine< T & >
- typename push_coroutine< T & >::control_block synthesized_cb{ this, ctx };
- push_coroutine< T & > synthesized{ & synthesized_cb };
- other = & synthesized_cb;
- if ( state_t::none == ( state & state_t::destroy) ) {
- try {
- auto fn = std::move( fn_);
- // call coroutine-fn with synthesized push_coroutine as argument
- fn( synthesized);
- } catch ( boost::context::detail::forced_unwind const&) {
- throw;
- } catch (...) {
- // store other exceptions in exception-pointer
- except = std::current_exception();
- }
- }
- // set termination flags
- state |= state_t::complete;
- // jump back to ctx
- auto result = other->ctx( nullptr);
- other->ctx = std::move( std::get< 0 >( result) );
- return std::move( other->ctx);
- },
- std::forward< Fn >( fn),
- std::placeholders::_1,
- std::placeholders::_2))},
-#else
- ctx{ std::allocator_arg, palloc, salloc,
- [this,fn_=std::forward< Fn >( fn)]( boost::context::execution_context< T * > && ctx, T *) mutable {
- // create synthesized push_coroutine< T & >
- typename push_coroutine< T & >::control_block synthesized_cb{ this, ctx };
- push_coroutine< T & > synthesized{ & synthesized_cb };
- other = & synthesized_cb;
- if ( state_t::none == ( state & state_t::destroy) ) {
- try {
- auto fn = std::move( fn_);
- // call coroutine-fn with synthesized push_coroutine as argument
- fn( synthesized);
- } catch ( boost::context::detail::forced_unwind const&) {
- throw;
- } catch (...) {
- // store other exceptions in exception-pointer
- except = std::current_exception();
- }
- }
- // set termination flags
- state |= state_t::complete;
- // jump back to ctx
- auto result = other->ctx( nullptr);
- other->ctx = std::move( std::get< 0 >( result) );
- return std::move( other->ctx);
- }},
-#endif
- other{ nullptr },
- state{ state_t::unwind },
- except{},
- t{ nullptr } {
- // enter coroutine-fn in order to have first value available after ctor (of `*this`) returns
- resume();
-}
-
-template< typename T >
-pull_coroutine< T & >::control_block::control_block( typename push_coroutine< T & >::control_block * cb,
- boost::context::execution_context< T * > & ctx_) noexcept :
- ctx{ std::move( ctx_) },
- other{ cb },
- state{ state_t::none },
- except{},
- t{ nullptr } {
-}
-
-template< typename T >
-void
-pull_coroutine< T & >::control_block::deallocate() noexcept {
- if ( state_t::none != ( state & state_t::unwind) ) {
- destroy( this);
- }
-}
-
-template< typename T >
-void
-pull_coroutine< T & >::control_block::resume() {
- auto result = ctx( nullptr);
- ctx = std::move( std::get< 0 >( result) );
- t = std::get< 1 >( result);
- if ( except) {
- std::rethrow_exception( except);
- }
-}
-
-template< typename T >
-T &
-pull_coroutine< T & >::control_block::get() noexcept {
- return * t;
-}
-
-template< typename T >
-bool
-pull_coroutine< T & >::control_block::valid() const noexcept {
- return nullptr != other && state_t::none == ( state & state_t::complete) && nullptr != t;
-}
-
-
-// pull_coroutine< void >
-
-inline
-void
-pull_coroutine< void >::control_block::destroy( control_block * cb) noexcept {
- boost::context::execution_context< void > ctx = std::move( cb->ctx);
- // destroy control structure
- cb->~control_block();
- // destroy coroutine's stack
- cb->state |= state_t::destroy;
- ctx();
-}
-
-template< typename StackAllocator, typename Fn >
-pull_coroutine< void >::control_block::control_block( context::preallocated palloc, StackAllocator salloc,
- Fn && fn) :
-#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
- ctx{ std::allocator_arg, palloc, salloc,
- std::move(
- std::bind(
- [this]( typename std::decay< Fn >::type & fn_, boost::context::execution_context< void > && ctx) mutable {
- // create synthesized push_coroutine< void >
- typename push_coroutine< void >::control_block synthesized_cb{ this, ctx };
- push_coroutine< void > synthesized{ & synthesized_cb };
- other = & synthesized_cb;
- if ( state_t::none == ( state & state_t::destroy) ) {
- try {
- auto fn = std::move( fn_);
- // call coroutine-fn with synthesized push_coroutine as argument
- fn( synthesized);
- } catch ( boost::context::detail::forced_unwind const&) {
- throw;
- } catch (...) {
- // store other exceptions in exception-pointer
- except = std::current_exception();
- }
- }
- // set termination flags
- state |= state_t::complete;
- // jump back to ctx
- other->ctx = other->ctx();
- return std::move( other->ctx);
- },
- std::forward< Fn >( fn),
- std::placeholders::_1))},
-#else
- ctx{ std::allocator_arg, palloc, salloc,
- [this,fn_=std::forward< Fn >( fn)]( boost::context::execution_context< void > && ctx) mutable {
- // create synthesized push_coroutine< void >
- typename push_coroutine< void >::control_block synthesized_cb{ this, ctx };
- push_coroutine< void > synthesized{ & synthesized_cb };
- other = & synthesized_cb;
- if ( state_t::none == ( state & state_t::destroy) ) {
- try {
- auto fn = std::move( fn_);
- // call coroutine-fn with synthesized push_coroutine as argument
- fn( synthesized);
- } catch ( boost::context::detail::forced_unwind const&) {
- throw;
- } catch (...) {
- // store other exceptions in exception-pointer
- except = std::current_exception();
- }
- }
- // set termination flags
- state |= state_t::complete;
- // jump back to ctx
- other->ctx = other->ctx();
- return std::move( other->ctx);
- }},
-#endif
- other{ nullptr },
- state{ state_t::unwind },
- except{} {
- // enter coroutine-fn in order to have first value available after ctor (of `*this`) returns
- resume();
-}
-
-inline
-pull_coroutine< void >::control_block::control_block( push_coroutine< void >::control_block * cb,
- boost::context::execution_context< void > & ctx_) noexcept :
- ctx{ std::move( ctx_) },
- other{ cb },
- state{ state_t::none },
- except{} {
-}
-
-inline
-void
-pull_coroutine< void >::control_block::deallocate() noexcept {
- if ( state_t::none != ( state & state_t::unwind) ) {
- destroy( this);
- }
-}
-
-inline
-void
-pull_coroutine< void >::control_block::resume() {
- ctx = ctx();
- if ( except) {
- std::rethrow_exception( except);
- }
-}
-
-inline
-bool
-pull_coroutine< void >::control_block::valid() const noexcept {
- return nullptr != other && state_t::none == ( state & state_t::complete);
-}
-
-}}}
-
-#ifdef BOOST_HAS_ABI_HEADERS
-# include BOOST_ABI_SUFFIX
-#endif
-
-#endif // BOOST_COROUTINES2_DETAIL_PULL_CONTROL_BLOCK_IPP
diff --git a/boost/coroutine2/detail/pull_coroutine.hpp b/boost/coroutine2/detail/pull_coroutine.hpp
index b97bdc3e9c..f4c40733bb 100644
--- a/boost/coroutine2/detail/pull_coroutine.hpp
+++ b/boost/coroutine2/detail/pull_coroutine.hpp
@@ -92,7 +92,7 @@ public:
typedef typename iterator::pointer pointer_t;
typedef typename iterator::reference reference_t;
- constexpr iterator() noexcept = default;
+ iterator() noexcept = default;
explicit iterator( pull_coroutine< T > * c) noexcept :
c_{ c } {
@@ -204,7 +204,7 @@ public:
typedef typename iterator::pointer pointer_t;
typedef typename iterator::reference reference_t;
- constexpr iterator() noexcept = default;
+ iterator() noexcept = default;
explicit iterator( pull_coroutine< T & > * c) noexcept :
c_{ c } {
diff --git a/boost/coroutine2/detail/push_control_block_ecv2.hpp b/boost/coroutine2/detail/push_control_block_cc.hpp
index feb5e4a61c..d01c98f089 100644
--- a/boost/coroutine2/detail/push_control_block_ecv2.hpp
+++ b/boost/coroutine2/detail/push_control_block_cc.hpp
@@ -10,7 +10,7 @@
#include <exception>
#include <boost/config.hpp>
-#include <boost/context/execution_context.hpp>
+#include <boost/context/continuation.hpp>
#include <boost/coroutine2/detail/state.hpp>
@@ -24,7 +24,7 @@ namespace detail {
template< typename T >
struct push_coroutine< T >::control_block {
- boost::context::execution_context< T * > ctx;
+ boost::context::continuation c;
typename pull_coroutine< T >::control_block * other;
state_t state;
std::exception_ptr except;
@@ -34,7 +34,7 @@ struct push_coroutine< T >::control_block {
template< typename StackAllocator, typename Fn >
control_block( context::preallocated, StackAllocator, Fn &&);
- control_block( typename pull_coroutine< T >::control_block *, boost::context::execution_context< T * > &) noexcept;
+ control_block( typename pull_coroutine< T >::control_block *, boost::context::continuation &) noexcept;
control_block( control_block &) = delete;
control_block & operator=( control_block &) = delete;
@@ -50,7 +50,7 @@ struct push_coroutine< T >::control_block {
template< typename T >
struct push_coroutine< T & >::control_block {
- boost::context::execution_context< T * > ctx;
+ boost::context::continuation c;
typename pull_coroutine< T & >::control_block * other;
state_t state;
std::exception_ptr except;
@@ -60,7 +60,7 @@ struct push_coroutine< T & >::control_block {
template< typename StackAllocator, typename Fn >
control_block( context::preallocated, StackAllocator, Fn &&);
- control_block( typename pull_coroutine< T & >::control_block *, boost::context::execution_context< T * > &) noexcept;
+ control_block( typename pull_coroutine< T & >::control_block *, boost::context::continuation &) noexcept;
control_block( control_block &) = delete;
control_block & operator=( control_block &) = delete;
@@ -73,7 +73,7 @@ struct push_coroutine< T & >::control_block {
};
struct push_coroutine< void >::control_block {
- boost::context::execution_context< void > ctx;
+ boost::context::continuation c;
pull_coroutine< void >::control_block * other;
state_t state;
std::exception_ptr except;
@@ -83,7 +83,7 @@ struct push_coroutine< void >::control_block {
template< typename StackAllocator, typename Fn >
control_block( context::preallocated, StackAllocator, Fn &&);
- control_block( pull_coroutine< void >::control_block *, boost::context::execution_context< void > &) noexcept;
+ control_block( pull_coroutine< void >::control_block *, boost::context::continuation &) noexcept;
control_block( control_block &) = delete;
control_block & operator=( control_block &) = delete;
diff --git a/boost/coroutine2/detail/push_control_block_cc.ipp b/boost/coroutine2/detail/push_control_block_cc.ipp
new file mode 100644
index 0000000000..9972c7039f
--- /dev/null
+++ b/boost/coroutine2/detail/push_control_block_cc.ipp
@@ -0,0 +1,400 @@
+
+// Copyright Oliver Kowalke 2014.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_COROUTINES2_DETAIL_PUSH_CONTROL_BLOCK_IPP
+#define BOOST_COROUTINES2_DETAIL_PUSH_CONTROL_BLOCK_IPP
+
+#include <algorithm>
+#include <exception>
+#include <memory>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+
+#include <boost/context/continuation.hpp>
+
+#include <boost/coroutine2/detail/config.hpp>
+#include <boost/coroutine2/detail/forced_unwind.hpp>
+#include <boost/coroutine2/detail/wrap.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines2 {
+namespace detail {
+
+// push_coroutine< T >
+
+template< typename T >
+void
+push_coroutine< T >::control_block::destroy( control_block * cb) noexcept {
+ boost::context::continuation c = std::move( cb->c);
+ // destroy control structure
+ cb->~control_block();
+ // destroy coroutine's stack
+ cb->state |= state_t::destroy;
+ c.resume();
+}
+
+template< typename T >
+template< typename StackAllocator, typename Fn >
+push_coroutine< T >::control_block::control_block( context::preallocated palloc, StackAllocator salloc,
+ Fn && fn) :
+ c{},
+ other{ nullptr },
+ state{ state_t::unwind },
+ except{} {
+#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
+ c = boost::context::callcc(
+ std::allocator_arg, palloc, salloc,
+ wrap( [this](typename std::decay< Fn >::type & fn_,boost::context::continuation && c) mutable {
+ // create synthesized pull_coroutine< T >
+ typename pull_coroutine< T >::control_block synthesized_cb{ this, c };
+ pull_coroutine< T > synthesized{ & synthesized_cb };
+ other = & synthesized_cb;
+ other->c = other->c.resume();
+ // set transferred value
+ if ( other->c.data_available() ) {
+ synthesized_cb.set( other->c.template get_data< T >() );
+ } else {
+ synthesized_cb.reset();
+ }
+ if ( state_t::none == ( state & state_t::destroy) ) {
+ try {
+ auto fn = std::move( fn_);
+ // call coroutine-fn with synthesized pull_coroutine as argument
+ fn( synthesized);
+ } catch ( boost::context::detail::forced_unwind const&) {
+ throw;
+ } catch (...) {
+ // store other exceptions in exception-pointer
+ except = std::current_exception();
+ }
+ }
+ // set termination flags
+ state |= state_t::complete;
+ // jump back
+ return other->c.resume();
+ },
+ std::forward< Fn >( fn) ) );
+#else
+ c = boost::context::callcc(
+ std::allocator_arg, palloc, salloc,
+ [this,fn_=std::forward< Fn >( fn)](boost::context::continuation && c) mutable {
+ // create synthesized pull_coroutine< T >
+ typename pull_coroutine< T >::control_block synthesized_cb{ this, c };
+ pull_coroutine< T > synthesized{ & synthesized_cb };
+ other = & synthesized_cb;
+ other->c = other->c.resume();
+ // set transferred value
+ if ( other->c.data_available() ) {
+ synthesized_cb.set( other->c.template get_data< T >() );
+ } else {
+ synthesized_cb.reset();
+ }
+ if ( state_t::none == ( state & state_t::destroy) ) {
+ try {
+ auto fn = std::move( fn_);
+ // call coroutine-fn with synthesized pull_coroutine as argument
+ fn( synthesized);
+ } catch ( boost::context::detail::forced_unwind const&) {
+ throw;
+ } catch (...) {
+ // store other exceptions in exception-pointer
+ except = std::current_exception();
+ }
+ }
+ // set termination flags
+ state |= state_t::complete;
+ // jump back
+ return other->c.resume();
+ });
+#endif
+}
+
+template< typename T >
+push_coroutine< T >::control_block::control_block( typename pull_coroutine< T >::control_block * cb,
+ boost::context::continuation & c_) noexcept :
+ c{ std::move( c_) },
+ other{ cb },
+ state{ state_t::none },
+ except{} {
+}
+
+template< typename T >
+void
+push_coroutine< T >::control_block::deallocate() noexcept {
+ if ( state_t::none != ( state & state_t::unwind) ) {
+ destroy( this);
+ }
+}
+
+template< typename T >
+void
+push_coroutine< T >::control_block::resume( T const& data) {
+ // pass an pointer to other context
+ c = c.resume( data);
+ if ( except) {
+ std::rethrow_exception( except);
+ }
+}
+
+template< typename T >
+void
+push_coroutine< T >::control_block::resume( T && data) {
+ // pass an pointer to other context
+ c = c.resume( std::move( data) );
+ if ( except) {
+ std::rethrow_exception( except);
+ }
+}
+
+template< typename T >
+bool
+push_coroutine< T >::control_block::valid() const noexcept {
+ return state_t::none == ( state & state_t::complete );
+}
+
+
+// push_coroutine< T & >
+
+template< typename T >
+void
+push_coroutine< T & >::control_block::destroy( control_block * cb) noexcept {
+ boost::context::continuation c = std::move( cb->c);
+ // destroy control structure
+ cb->~control_block();
+ // destroy coroutine's stack
+ cb->state |= state_t::destroy;
+ c.resume();
+}
+
+template< typename T >
+template< typename StackAllocator, typename Fn >
+push_coroutine< T & >::control_block::control_block( context::preallocated palloc, StackAllocator salloc,
+ Fn && fn) :
+ c{},
+ other{ nullptr },
+ state{ state_t::unwind },
+ except{} {
+#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
+ c = boost::context::callcc(
+ std::allocator_arg, palloc, salloc,
+ wrap( [this](typename std::decay< Fn >::type & fn_,boost::context::continuation && c) mutable {
+ // create synthesized pull_coroutine< T & >
+ typename pull_coroutine< T & >::control_block synthesized_cb{ this, c };
+ pull_coroutine< T & > synthesized{ & synthesized_cb };
+ other = & synthesized_cb;
+ other->c = other->c.resume();
+ // set transferred value
+ if ( other->c.data_available() ) {
+ synthesized_cb.set( other->c.template get_data< T & >() );
+ } else {
+ synthesized_cb.reset();
+ }
+ if ( state_t::none == ( state & state_t::destroy) ) {
+ try {
+ auto fn = std::move( fn_);
+ // call coroutine-fn with synthesized pull_coroutine as argument
+ fn( synthesized);
+ } catch ( boost::context::detail::forced_unwind const&) {
+ throw;
+ } catch (...) {
+ // store other exceptions in exception-pointer
+ except = std::current_exception();
+ }
+ }
+ // set termination flags
+ state |= state_t::complete;
+ // jump back
+ return other->c.resume();
+ },
+ std::forward< Fn >( fn) ) );
+#else
+ c = boost::context::callcc(
+ std::allocator_arg, palloc, salloc,
+ [this,fn_=std::forward< Fn >( fn)](boost::context::continuation && c) mutable {
+ // create synthesized pull_coroutine< T & >
+ typename pull_coroutine< T & >::control_block synthesized_cb{ this, c };
+ pull_coroutine< T & > synthesized{ & synthesized_cb };
+ other = & synthesized_cb;
+ other->c = other->c.resume();
+ // set transferred value
+ if ( other->c.data_available() ) {
+ synthesized_cb.set( other->c.template get_data< T & >() );
+ } else {
+ synthesized_cb.reset();
+ }
+ if ( state_t::none == ( state & state_t::destroy) ) {
+ try {
+ auto fn = std::move( fn_);
+ // call coroutine-fn with synthesized pull_coroutine as argument
+ fn( synthesized);
+ } catch ( boost::context::detail::forced_unwind const&) {
+ throw;
+ } catch (...) {
+ // store other exceptions in exception-pointer
+ except = std::current_exception();
+ }
+ }
+ // set termination flags
+ state |= state_t::complete;
+ // jump back
+ return other->c.resume();
+ });
+#endif
+}
+
+template< typename T >
+push_coroutine< T & >::control_block::control_block( typename pull_coroutine< T & >::control_block * cb,
+ boost::context::continuation & c_) noexcept :
+ c{ std::move( c_) },
+ other{ cb },
+ state{ state_t::none },
+ except{} {
+}
+
+template< typename T >
+void
+push_coroutine< T & >::control_block::deallocate() noexcept {
+ if ( state_t::none != ( state & state_t::unwind) ) {
+ destroy( this);
+ }
+}
+
+template< typename T >
+void
+push_coroutine< T & >::control_block::resume( T & t) {
+ // pass an pointer to other context
+ c = c.resume( std::ref( t) );
+ if ( except) {
+ std::rethrow_exception( except);
+ }
+}
+
+template< typename T >
+bool
+push_coroutine< T & >::control_block::valid() const noexcept {
+ return state_t::none == ( state & state_t::complete );
+}
+
+
+// push_coroutine< void >
+
+inline
+void
+push_coroutine< void >::control_block::destroy( control_block * cb) noexcept {
+ boost::context::continuation c = std::move( cb->c);
+ // destroy control structure
+ cb->~control_block();
+ // destroy coroutine's stack
+ cb->state |= state_t::destroy;
+ c.resume();
+}
+
+template< typename StackAllocator, typename Fn >
+push_coroutine< void >::control_block::control_block( context::preallocated palloc, StackAllocator salloc, Fn && fn) :
+ c{},
+ other{ nullptr },
+ state{ state_t::unwind },
+ except{} {
+#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
+ c = boost::context::callcc(
+ std::allocator_arg, palloc, salloc,
+ wrap( [this](typename std::decay< Fn >::type & fn_,boost::context::continuation && c) mutable {
+ // create synthesized pull_coroutine< void >
+ typename pull_coroutine< void >::control_block synthesized_cb{ this, c };
+ pull_coroutine< void > synthesized{ & synthesized_cb };
+ other = & synthesized_cb;
+ other->c = other->c.resume();
+ if ( state_t::none == ( state & state_t::destroy) ) {
+ try {
+ auto fn = std::move( fn_);
+ // call coroutine-fn with synthesized pull_coroutine as argument
+ fn( synthesized);
+ } catch ( boost::context::detail::forced_unwind const&) {
+ throw;
+ } catch (...) {
+ // store other exceptions in exception-pointer
+ except = std::current_exception();
+ }
+ }
+ // set termination flags
+ state |= state_t::complete;
+ // jump back
+ return other->c.resume();
+ },
+ std::forward< Fn >( fn) ) );
+#else
+ c = boost::context::callcc(
+ std::allocator_arg, palloc, salloc,
+ [this,fn_=std::forward< Fn >( fn)](boost::context::continuation && c) mutable {
+ // create synthesized pull_coroutine< void >
+ typename pull_coroutine< void >::control_block synthesized_cb{ this, c};
+ pull_coroutine< void > synthesized{ & synthesized_cb };
+ other = & synthesized_cb;
+ other->c = other->c.resume();
+ if ( state_t::none == ( state & state_t::destroy) ) {
+ try {
+ auto fn = std::move( fn_);
+ // call coroutine-fn with synthesized pull_coroutine as argument
+ fn( synthesized);
+ } catch ( boost::context::detail::forced_unwind const&) {
+ throw;
+ } catch (...) {
+ // store other exceptions in exception-pointer
+ except = std::current_exception();
+ }
+ }
+ // set termination flags
+ state |= state_t::complete;
+ // jump back
+ return other->c.resume();
+ });
+#endif
+}
+
+inline
+push_coroutine< void >::control_block::control_block( pull_coroutine< void >::control_block * cb,
+ boost::context::continuation & c_) noexcept :
+ c{ std::move( c_) },
+ other{ cb },
+ state{ state_t::none },
+ except{} {
+}
+
+inline
+void
+push_coroutine< void >::control_block::deallocate() noexcept {
+ if ( state_t::none != ( state & state_t::unwind) ) {
+ destroy( this);
+ }
+}
+
+inline
+void
+push_coroutine< void >::control_block::resume() {
+ c = c.resume();
+ if ( except) {
+ std::rethrow_exception( except);
+ }
+}
+
+inline
+bool
+push_coroutine< void >::control_block::valid() const noexcept {
+ return state_t::none == ( state & state_t::complete );
+}
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES2_DETAIL_PUSH_CONTROL_BLOCK_IPP
diff --git a/boost/coroutine2/detail/push_control_block_ecv1.ipp b/boost/coroutine2/detail/push_control_block_ecv1.ipp
index cc9622dfbe..8b4ae3fb04 100644
--- a/boost/coroutine2/detail/push_control_block_ecv1.ipp
+++ b/boost/coroutine2/detail/push_control_block_ecv1.ipp
@@ -21,6 +21,7 @@
#include <boost/coroutine2/detail/decay_copy.hpp>
#include <boost/coroutine2/detail/forced_unwind.hpp>
#include <boost/coroutine2/detail/state.hpp>
+#include <boost/coroutine2/detail/wrap.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
@@ -47,9 +48,7 @@ push_coroutine< T >::control_block::control_block( context::preallocated palloc,
Fn && fn) :
#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
ctx{ std::allocator_arg, palloc, salloc,
- std::move(
- std::bind(
- [this]( typename std::decay< Fn >::type & fn_, boost::context::execution_context & ctx, void * vp) mutable noexcept {
+ wrap( [this]( typename std::decay< Fn >::type & fn_, boost::context::execution_context & ctx, void * vp) mutable noexcept {
// create synthesized pull_coroutine< T >
typename pull_coroutine< T >::control_block synthesized_cb{ this, ctx };
pull_coroutine< T > synthesized{ & synthesized_cb };
@@ -77,8 +76,7 @@ push_coroutine< T >::control_block::control_block( context::preallocated palloc,
BOOST_ASSERT_MSG( false, "push_coroutine is complete");
},
std::forward< Fn >( fn),
- boost::context::execution_context::current(),
- std::placeholders::_1))},
+ boost::context::execution_context::current() ) },
#else
ctx{ std::allocator_arg, palloc, salloc,
[this,fn_=decay_copy( std::forward< Fn >( fn) ),ctx=boost::context::execution_context::current()] (void *) mutable noexcept {
@@ -189,9 +187,7 @@ push_coroutine< T & >::control_block::control_block( context::preallocated pallo
Fn && fn) :
#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
ctx{ std::allocator_arg, palloc, salloc,
- std::move(
- std::bind(
- [this]( typename std::decay< Fn >::type & fn_, boost::context::execution_context & ctx, void * vp) mutable noexcept {
+ wrap( [this]( typename std::decay< Fn >::type & fn_, boost::context::execution_context & ctx, void * vp) mutable noexcept {
// create synthesized pull_coroutine< T >
typename pull_coroutine< T & >::control_block synthesized_cb{ this, ctx };
pull_coroutine< T & > synthesized{ & synthesized_cb };
@@ -219,8 +215,7 @@ push_coroutine< T & >::control_block::control_block( context::preallocated pallo
BOOST_ASSERT_MSG( false, "push_coroutine is complete");
},
std::forward< Fn >( fn),
- boost::context::execution_context::current(),
- std::placeholders::_1))},
+ boost::context::execution_context::current() ) },
#else
ctx{ std::allocator_arg, palloc, salloc,
[this,fn_=decay_copy( std::forward< Fn >( fn) ),ctx=boost::context::execution_context::current()] (void *) mutable noexcept {
@@ -318,9 +313,7 @@ template< typename StackAllocator, typename Fn >
push_coroutine< void >::control_block::control_block( context::preallocated palloc, StackAllocator salloc, Fn && fn) :
#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
ctx{ std::allocator_arg, palloc, salloc,
- std::move(
- std::bind(
- [this]( typename std::decay< Fn >::type & fn_, boost::context::execution_context & ctx,
+ wrap( [this]( typename std::decay< Fn >::type & fn_, boost::context::execution_context & ctx,
void * vp) mutable noexcept {
// create synthesized pull_coroutine< T >
typename pull_coroutine< void >::control_block synthesized_cb{ this, ctx };
@@ -347,8 +340,7 @@ push_coroutine< void >::control_block::control_block( context::preallocated pall
BOOST_ASSERT_MSG( false, "push_coroutine is complete");
},
std::forward< Fn >( fn),
- boost::context::execution_context::current(),
- std::placeholders::_1))},
+ boost::context::execution_context::current() ) },
#else
ctx{ std::allocator_arg, palloc, salloc,
[this,fn_=decay_copy( std::forward< Fn >( fn) ),ctx=boost::context::execution_context::current()] (void *) mutable noexcept {
diff --git a/boost/coroutine2/detail/push_control_block_ecv2.ipp b/boost/coroutine2/detail/push_control_block_ecv2.ipp
deleted file mode 100644
index 7ed6c572e1..0000000000
--- a/boost/coroutine2/detail/push_control_block_ecv2.ipp
+++ /dev/null
@@ -1,392 +0,0 @@
-
-// Copyright Oliver Kowalke 2014.
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
-// http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef BOOST_COROUTINES2_DETAIL_PUSH_CONTROL_BLOCK_IPP
-#define BOOST_COROUTINES2_DETAIL_PUSH_CONTROL_BLOCK_IPP
-
-#include <algorithm>
-#include <exception>
-#include <memory>
-
-#include <boost/assert.hpp>
-#include <boost/config.hpp>
-
-#include <boost/context/execution_context.hpp>
-
-#include <boost/coroutine2/detail/config.hpp>
-#include <boost/coroutine2/detail/forced_unwind.hpp>
-
-#ifdef BOOST_HAS_ABI_HEADERS
-# include BOOST_ABI_PREFIX
-#endif
-
-namespace boost {
-namespace coroutines2 {
-namespace detail {
-
-// push_coroutine< T >
-
-template< typename T >
-void
-push_coroutine< T >::control_block::destroy( control_block * cb) noexcept {
- boost::context::execution_context< T * > ctx = std::move( cb->ctx);
- // destroy control structure
- cb->~control_block();
- // destroy coroutine's stack
- cb->state |= state_t::destroy;
- ctx( nullptr);
-}
-
-template< typename T >
-template< typename StackAllocator, typename Fn >
-push_coroutine< T >::control_block::control_block( context::preallocated palloc, StackAllocator salloc,
- Fn && fn) :
-#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
- ctx{ std::allocator_arg, palloc, salloc,
- std::move(
- std::bind(
- [this]( typename std::decay< Fn >::type & fn_, boost::context::execution_context< T * > && ctx, T * data) mutable {
- // create synthesized pull_coroutine< T >
- typename pull_coroutine< T >::control_block synthesized_cb{ this, ctx };
- pull_coroutine< T > synthesized{ & synthesized_cb };
- other = & synthesized_cb;
- // set transferred value
- synthesized_cb.set( data);
- if ( state_t::none == ( state & state_t::destroy) ) {
- try {
- auto fn = std::move( fn_);
- // call coroutine-fn with synthesized pull_coroutine as argument
- fn( synthesized);
- } catch ( boost::context::detail::forced_unwind const&) {
- throw;
- } catch (...) {
- // store other exceptions in exception-pointer
- except = std::current_exception();
- }
- }
- // set termination flags
- state |= state_t::complete;
- // jump back to ctx
- auto result = other->ctx( nullptr);
- other->ctx = std::move( std::get< 0 >( result) );
- return std::move( other->ctx);
- },
- std::forward< Fn >( fn),
- std::placeholders::_1,
- std::placeholders::_2))},
-#else
- ctx{ std::allocator_arg, palloc, salloc,
- [this,fn_=std::forward< Fn >( fn)]( boost::context::execution_context< T * > && ctx, T * data) mutable {
- // create synthesized pull_coroutine< T >
- typename pull_coroutine< T >::control_block synthesized_cb{ this, ctx };
- pull_coroutine< T > synthesized{ & synthesized_cb };
- other = & synthesized_cb;
- // set transferred value
- synthesized_cb.set( data);
- if ( state_t::none == ( state & state_t::destroy) ) {
- try {
- auto fn = std::move( fn_);
- // call coroutine-fn with synthesized pull_coroutine as argument
- fn( synthesized);
- } catch ( boost::context::detail::forced_unwind const&) {
- throw;
- } catch (...) {
- // store other exceptions in exception-pointer
- except = std::current_exception();
- }
- }
- // set termination flags
- state |= state_t::complete;
- // jump back to ctx
- auto result = other->ctx( nullptr);
- other->ctx = std::move( std::get< 0 >( result) );
- return std::move( other->ctx);
- }},
-#endif
- other{ nullptr },
- state{ state_t::unwind },
- except{} {
-}
-
-template< typename T >
-push_coroutine< T >::control_block::control_block( typename pull_coroutine< T >::control_block * cb,
- boost::context::execution_context< T * > & ctx_) noexcept :
- ctx{ std::move( ctx_) },
- other{ cb },
- state{ state_t::none },
- except{} {
-}
-
-template< typename T >
-void
-push_coroutine< T >::control_block::deallocate() noexcept {
- if ( state_t::none != ( state & state_t::unwind) ) {
- destroy( this);
- }
-}
-
-template< typename T >
-void
-push_coroutine< T >::control_block::resume( T const& data) {
- // pass an pointer to other context
- auto result = ctx( const_cast< T * >( & data) );
- ctx = std::move( std::get< 0 >( result) );
- if ( except) {
- std::rethrow_exception( except);
- }
-}
-
-template< typename T >
-void
-push_coroutine< T >::control_block::resume( T && data) {
- // pass an pointer to other context
- auto result = ctx( std::addressof( data) );
- ctx = std::move( std::get< 0 >( result) );
- if ( except) {
- std::rethrow_exception( except);
- }
-}
-
-template< typename T >
-bool
-push_coroutine< T >::control_block::valid() const noexcept {
- return state_t::none == ( state & state_t::complete );
-}
-
-
-// push_coroutine< T & >
-
-template< typename T >
-void
-push_coroutine< T & >::control_block::destroy( control_block * cb) noexcept {
- boost::context::execution_context< T * > ctx = std::move( cb->ctx);
- // destroy control structure
- cb->~control_block();
- // destroy coroutine's stack
- cb->state |= state_t::destroy;
- ctx( nullptr);
-}
-
-template< typename T >
-template< typename StackAllocator, typename Fn >
-push_coroutine< T & >::control_block::control_block( context::preallocated palloc, StackAllocator salloc,
- Fn && fn) :
-#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
- ctx{ std::allocator_arg, palloc, salloc,
- std::move(
- std::bind(
- [this]( typename std::decay< Fn >::type & fn_, boost::context::execution_context< T * > && ctx, T * data) mutable {
- // create synthesized pull_coroutine< T & >
- typename pull_coroutine< T & >::control_block synthesized_cb{ this, ctx };
- pull_coroutine< T & > synthesized{ & synthesized_cb };
- other = & synthesized_cb;
- // set transferred value
- synthesized_cb.t = data;
- if ( state_t::none == ( state & state_t::destroy) ) {
- try {
- auto fn = std::move( fn_);
- // call coroutine-fn with synthesized pull_coroutine as argument
- fn( synthesized);
- } catch ( boost::context::detail::forced_unwind const&) {
- throw;
- } catch (...) {
- // store other exceptions in exception-pointer
- except = std::current_exception();
- }
- }
- // set termination flags
- state |= state_t::complete;
- // jump back to ctx
- auto result = other->ctx( nullptr);
- other->ctx = std::move( std::get< 0 >( result) );
- return std::move( other->ctx);
- },
- std::forward< Fn >( fn),
- std::placeholders::_1,
- std::placeholders::_2))},
-#else
- ctx{ std::allocator_arg, palloc, salloc,
- [this,fn_=std::forward< Fn >( fn)]( boost::context::execution_context< T * > && ctx, T * data) mutable {
- // create synthesized pull_coroutine< T & >
- typename pull_coroutine< T & >::control_block synthesized_cb{ this, ctx };
- pull_coroutine< T & > synthesized{ & synthesized_cb };
- other = & synthesized_cb;
- // set transferred value
- synthesized_cb.t = data;
- if ( state_t::none == ( state & state_t::destroy) ) {
- try {
- auto fn = std::move( fn_);
- // call coroutine-fn with synthesized pull_coroutine as argument
- fn( synthesized);
- } catch ( boost::context::detail::forced_unwind const&) {
- throw;
- } catch (...) {
- // store other exceptions in exception-pointer
- except = std::current_exception();
- }
- }
- // set termination flags
- state |= state_t::complete;
- // jump back to ctx
- auto result = other->ctx( nullptr);
- other->ctx = std::move( std::get< 0 >( result) );
- return std::move( other->ctx);
- }},
-#endif
- other{ nullptr },
- state{ state_t::unwind },
- except{} {
-}
-
-template< typename T >
-push_coroutine< T & >::control_block::control_block( typename pull_coroutine< T & >::control_block * cb,
- boost::context::execution_context< T * > & ctx_) noexcept :
- ctx{ std::move( ctx_) },
- other{ cb },
- state{ state_t::none },
- except{} {
-}
-
-template< typename T >
-void
-push_coroutine< T & >::control_block::deallocate() noexcept {
- if ( state_t::none != ( state & state_t::unwind) ) {
- destroy( this);
- }
-}
-
-template< typename T >
-void
-push_coroutine< T & >::control_block::resume( T & t) {
- // pass an pointer to other context
- auto result = ctx( const_cast< typename std::remove_const< T >::type * >( std::addressof( t) ) );
- ctx = std::move( std::get< 0 >( result) );
- if ( except) {
- std::rethrow_exception( except);
- }
-}
-
-template< typename T >
-bool
-push_coroutine< T & >::control_block::valid() const noexcept {
- return state_t::none == ( state & state_t::complete );
-}
-
-
-// push_coroutine< void >
-
-inline
-void
-push_coroutine< void >::control_block::destroy( control_block * cb) noexcept {
- boost::context::execution_context< void > ctx = std::move( cb->ctx);
- // destroy control structure
- cb->~control_block();
- // destroy coroutine's stack
- cb->state |= state_t::destroy;
- ctx();
-}
-
-template< typename StackAllocator, typename Fn >
-push_coroutine< void >::control_block::control_block( context::preallocated palloc, StackAllocator salloc, Fn && fn) :
-#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
- ctx{ std::allocator_arg, palloc, salloc,
- std::move(
- std::bind(
- [this]( typename std::decay< Fn >::type & fn_, boost::context::execution_context< void > && ctx) mutable {
- // create synthesized pull_coroutine< void >
- typename pull_coroutine< void >::control_block synthesized_cb{ this, ctx };
- pull_coroutine< void > synthesized{ & synthesized_cb };
- other = & synthesized_cb;
- if ( state_t::none == ( state & state_t::destroy) ) {
- try {
- auto fn = std::move( fn_);
- // call coroutine-fn with synthesized pull_coroutine as argument
- fn( synthesized);
- } catch ( boost::context::detail::forced_unwind const&) {
- throw;
- } catch (...) {
- // store other exceptions in exception-pointer
- except = std::current_exception();
- }
- }
- // set termination flags
- state |= state_t::complete;
- // jump back to ctx
- other->ctx = other->ctx();
- return std::move( other->ctx);
- },
- std::forward< Fn >( fn),
- std::placeholders::_1))},
-#else
- ctx{ std::allocator_arg, palloc, salloc,
- [this,fn_=std::forward< Fn >( fn)]( boost::context::execution_context< void > && ctx) mutable {
- // create synthesized pull_coroutine< void >
- typename pull_coroutine< void >::control_block synthesized_cb{ this, ctx};
- pull_coroutine< void > synthesized{ & synthesized_cb };
- other = & synthesized_cb;
- if ( state_t::none == ( state & state_t::destroy) ) {
- try {
- auto fn = std::move( fn_);
- // call coroutine-fn with synthesized pull_coroutine as argument
- fn( synthesized);
- } catch ( boost::context::detail::forced_unwind const&) {
- throw;
- } catch (...) {
- // store other exceptions in exception-pointer
- except = std::current_exception();
- }
- }
- // set termination flags
- state |= state_t::complete;
- // jump back to ctx
- other->ctx = other->ctx();
- return std::move( other->ctx);
- }},
-#endif
- other{ nullptr },
- state{ state_t::unwind },
- except{} {
-}
-
-inline
-push_coroutine< void >::control_block::control_block( pull_coroutine< void >::control_block * cb,
- boost::context::execution_context< void > & ctx_) noexcept :
- ctx{ std::move( ctx_) },
- other{ cb },
- state{ state_t::none },
- except{} {
-}
-
-inline
-void
-push_coroutine< void >::control_block::deallocate() noexcept {
- if ( state_t::none != ( state & state_t::unwind) ) {
- destroy( this);
- }
-}
-
-inline
-void
-push_coroutine< void >::control_block::resume() {
- ctx = ctx();
- if ( except) {
- std::rethrow_exception( except);
- }
-}
-
-inline
-bool
-push_coroutine< void >::control_block::valid() const noexcept {
- return state_t::none == ( state & state_t::complete );
-}
-
-}}}
-
-#ifdef BOOST_HAS_ABI_HEADERS
-# include BOOST_ABI_SUFFIX
-#endif
-
-#endif // BOOST_COROUTINES2_DETAIL_PUSH_CONTROL_BLOCK_IPP
diff --git a/boost/coroutine2/detail/push_coroutine.hpp b/boost/coroutine2/detail/push_coroutine.hpp
index 1b62663ab7..533d4f930f 100644
--- a/boost/coroutine2/detail/push_coroutine.hpp
+++ b/boost/coroutine2/detail/push_coroutine.hpp
@@ -72,14 +72,14 @@ public:
push_coroutine< T > * c_{ nullptr };
public:
- constexpr iterator() noexcept = default;
+ iterator() noexcept = default;
explicit iterator( push_coroutine< T > * c) noexcept :
c_{ c } {
}
iterator & operator=( T t) {
- BOOST_ASSERT( c_);
+ BOOST_ASSERT( nullptr != c_);
if ( ! ( * c_)( t) ) {
c_ = nullptr;
}
@@ -150,14 +150,14 @@ public:
push_coroutine< T & > * c_{ nullptr };
public:
- constexpr iterator() noexcept = default;
+ iterator() noexcept = default;
explicit iterator( push_coroutine< T & > * c) noexcept :
c_{ c } {
}
iterator & operator=( T & t) {
- BOOST_ASSERT( c_);
+ BOOST_ASSERT( nullptr != c_);
if ( ! ( * c_)( t) ) {
c_ = nullptr;
}
diff --git a/boost/coroutine2/detail/wrap.hpp b/boost/coroutine2/detail/wrap.hpp
new file mode 100644
index 0000000000..25abce3b61
--- /dev/null
+++ b/boost/coroutine2/detail/wrap.hpp
@@ -0,0 +1,112 @@
+
+// Copyright Oliver Kowalke 2014.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_COROUTINE2_DETAIL_WRAP_H
+#define BOOST_COROUTINE2_DETAIL_WRAP_H
+
+#include <type_traits>
+
+#include <boost/config.hpp>
+#include <boost/context/detail/invoke.hpp>
+#if (BOOST_EXECUTION_CONTEXT==1)
+# include <boost/context/execution_context.hpp>
+#else
+# include <boost/context/continuation.hpp>
+#endif
+
+#include <boost/fiber/detail/config.hpp>
+#include <boost/fiber/detail/data.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines2 {
+namespace detail {
+
+#if (BOOST_EXECUTION_CONTEXT==1)
+template< typename Fn1, typename Fn2 >
+class wrapper {
+private:
+ typename std::decay< Fn1 >::type fn1_;
+ typename std::decay< Fn2 >::type fn2_;
+ boost::context::execution_context ctx_;
+
+public:
+ wrapper( Fn1 && fn1, Fn2 && fn2,
+ boost::context::execution_context const& ctx) :
+ fn1_( std::move( fn1) ),
+ fn2_( std::move( fn2) ),
+ ctx_{ ctx } {
+ }
+
+ wrapper( wrapper const&) = delete;
+ wrapper & operator=( wrapper const&) = delete;
+
+ wrapper( wrapper && other) = default;
+ wrapper & operator=( wrapper && other) = default;
+
+ void operator()( void * vp) {
+ boost::context::detail::invoke(
+ std::move( fn1_),
+ fn2_, ctx_, vp);
+ }
+};
+
+template< typename Fn1, typename Fn2 >
+wrapper< Fn1, Fn2 >
+wrap( Fn1 && fn1, Fn2 && fn2,
+ boost::context::execution_context const& ctx) {
+ return wrapper< Fn1, Fn2 >(
+ std::forward< Fn1 >( fn1),
+ std::forward< Fn2 >( fn2),
+ ctx);
+}
+#else
+template< typename Fn1, typename Fn2 >
+class wrapper {
+private:
+ typename std::decay< Fn1 >::type fn1_;
+ typename std::decay< Fn2 >::type fn2_;
+
+public:
+ wrapper( Fn1 && fn1, Fn2 && fn2) :
+ fn1_( std::move( fn1) ),
+ fn2_( std::move( fn2) ) {
+ }
+
+ wrapper( wrapper const&) = delete;
+ wrapper & operator=( wrapper const&) = delete;
+
+ wrapper( wrapper && other) = default;
+ wrapper & operator=( wrapper && other) = default;
+
+ boost::context::continuation
+ operator()( boost::context::continuation && c) {
+ return boost::context::detail::invoke(
+ std::move( fn1_),
+ fn2_,
+ std::forward< boost::context::continuation >( c) );
+ }
+};
+
+template< typename Fn1, typename Fn2 >
+wrapper< Fn1, Fn2 >
+wrap( Fn1 && fn1, Fn2 && fn2) {
+ return wrapper< Fn1, Fn2 >(
+ std::forward< Fn1 >( fn1),
+ std::forward< Fn2 >( fn2) );
+}
+#endif
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+#include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINE2_DETAIL_WRAP_H