|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r86521 - in trunk: boost/coroutine boost/coroutine/detail boost/coroutine/v1 boost/coroutine/v2 libs/coroutine/example/cpp03 libs/coroutine/example/cpp11 libs/coroutine/performance libs/coroutine/test
From: oliver.kowalke_at_[hidden]
Date: 2013-10-30 04:23:09
Author: olli
Date: 2013-10-30 04:23:09 EDT (Wed, 30 Oct 2013)
New Revision: 86521
URL: http://svn.boost.org/trac/boost/changeset/86521
Log:
coroutine: remove deprecated interface
Added:
trunk/boost/coroutine/detail/pull_coroutine_base.hpp (contents, props changed)
trunk/boost/coroutine/detail/pull_coroutine_caller.hpp (contents, props changed)
trunk/boost/coroutine/detail/pull_coroutine_object.hpp (contents, props changed)
trunk/boost/coroutine/detail/push_coroutine_base.hpp (contents, props changed)
trunk/boost/coroutine/detail/push_coroutine_caller.hpp (contents, props changed)
trunk/boost/coroutine/detail/push_coroutine_object.hpp (contents, props changed)
trunk/libs/coroutine/example/cpp03/exception.cpp (contents, props changed)
Deleted:
trunk/boost/coroutine/checkpoint.hpp
trunk/boost/coroutine/v1/
trunk/boost/coroutine/v2/
Text files modified:
trunk/boost/coroutine/all.hpp | 1
/dev/null | 34
trunk/boost/coroutine/coroutine.hpp | 2991 +++++++++++++++++++++++++++++++++++++++
trunk/boost/coroutine/detail/config.hpp | 16
trunk/boost/coroutine/detail/pull_coroutine_base.hpp | 337 ++++
trunk/boost/coroutine/detail/pull_coroutine_caller.hpp | 111 +
trunk/boost/coroutine/detail/pull_coroutine_object.hpp | 1124 +++++++++++++++
trunk/boost/coroutine/detail/push_coroutine_base.hpp | 354 ++++
trunk/boost/coroutine/detail/push_coroutine_caller.hpp | 56
trunk/boost/coroutine/detail/push_coroutine_object.hpp | 1208 ++++++++++++++++
trunk/libs/coroutine/example/cpp03/Jamfile.v2 | 4
trunk/libs/coroutine/example/cpp03/echo.cpp | 37
trunk/libs/coroutine/example/cpp03/exception.cpp | 52
trunk/libs/coroutine/example/cpp03/fibonacci.cpp | 33
trunk/libs/coroutine/example/cpp03/parallel.cpp | 42
trunk/libs/coroutine/example/cpp03/power.cpp | 39
trunk/libs/coroutine/example/cpp03/segmented_stack.cpp | 18
trunk/libs/coroutine/example/cpp03/tree.h | 30
trunk/libs/coroutine/example/cpp03/unwind.cpp | 37
trunk/libs/coroutine/example/cpp11/await_emu.cpp | 6
trunk/libs/coroutine/example/cpp11/fibonacci.cpp | 26
trunk/libs/coroutine/performance/performance.cpp | 59
trunk/libs/coroutine/test/test_coroutine.cpp | 516 ------
23 files changed, 6236 insertions(+), 895 deletions(-)
Modified: trunk/boost/coroutine/all.hpp
==============================================================================
--- trunk/boost/coroutine/all.hpp Tue Oct 29 23:57:39 2013 (r86520)
+++ trunk/boost/coroutine/all.hpp 2013-10-30 04:23:09 EDT (Wed, 30 Oct 2013) (r86521)
@@ -12,5 +12,6 @@
#include <boost/coroutine/exceptions.hpp>
#include <boost/coroutine/flags.hpp>
#include <boost/coroutine/stack_allocator.hpp>
+#include <boost/coroutine/stack_context.hpp>
#endif // BOOST_COROUTINES_ALL_H
Deleted: trunk/boost/coroutine/checkpoint.hpp
==============================================================================
--- trunk/boost/coroutine/checkpoint.hpp 2013-10-30 04:23:09 EDT (Wed, 30 Oct 2013) (r86520)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -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 <boost/config.hpp>
-#include <boost/context/fcontext.hpp>
-
-#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
Modified: trunk/boost/coroutine/coroutine.hpp
==============================================================================
--- trunk/boost/coroutine/coroutine.hpp Tue Oct 29 23:57:39 2013 (r86520)
+++ trunk/boost/coroutine/coroutine.hpp 2013-10-30 04:23:09 EDT (Wed, 30 Oct 2013) (r86521)
@@ -7,10 +7,2995 @@
#ifndef BOOST_COROUTINES_COROUTINE_H
#define BOOST_COROUTINES_COROUTINE_H
-#ifdef BOOST_COROUTINES_UNIDIRECT
-#include <boost/coroutine/v2/coroutine.hpp>
+#include <cstddef>
+#include <iterator>
+#include <memory>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+#include <boost/move/move.hpp>
+#include <boost/optional.hpp>
+#include <boost/range.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/type_traits/decay.hpp>
+#include <boost/type_traits/function_traits.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/utility/enable_if.hpp>
+
+#include <boost/coroutine/attributes.hpp>
+#include <boost/coroutine/detail/config.hpp>
+#include <boost/coroutine/detail/coroutine_context.hpp>
+#include <boost/coroutine/detail/param.hpp>
+#include <boost/coroutine/exceptions.hpp>
+#include <boost/coroutine/stack_allocator.hpp>
+#include <boost/coroutine/detail/pull_coroutine_base.hpp>
+#include <boost/coroutine/detail/pull_coroutine_caller.hpp>
+#include <boost/coroutine/detail/pull_coroutine_object.hpp>
+#include <boost/coroutine/detail/push_coroutine_base.hpp>
+#include <boost/coroutine/detail/push_coroutine_caller.hpp>
+#include <boost/coroutine/detail/push_coroutine_object.hpp>
+
+#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
-#include <boost/coroutine/v1/coroutine.hpp>
+ 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
Modified: trunk/boost/coroutine/detail/config.hpp
==============================================================================
--- trunk/boost/coroutine/detail/config.hpp Tue Oct 29 23:57:39 2013 (r86520)
+++ trunk/boost/coroutine/detail/config.hpp 2013-10-30 04:23:09 EDT (Wed, 30 Oct 2013) (r86521)
@@ -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
Added: trunk/boost/coroutine/detail/pull_coroutine_base.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/boost/coroutine/detail/pull_coroutine_base.hpp 2013-10-30 04:23:09 EDT (Wed, 30 Oct 2013) (r86521)
@@ -0,0 +1,337 @@
+
+// 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_DETAIL_PULL_COROUTINE_BASE_H
+#define BOOST_COROUTINES_DETAIL_PULL_COROUTINE_BASE_H
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+#include <boost/context/fcontext.hpp>
+#include <boost/exception_ptr.hpp>
+#include <boost/intrusive_ptr.hpp>
+#include <boost/optional.hpp>
+#include <boost/type_traits/function_traits.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/coroutine/detail/config.hpp>
+#include <boost/coroutine/detail/coroutine_context.hpp>
+#include <boost/coroutine/detail/flags.hpp>
+#include <boost/coroutine/detail/holder.hpp>
+#include <boost/coroutine/detail/param.hpp>
+#include <boost/coroutine/exceptions.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+
+struct stack_context;
+
+namespace detail {
+
+template< typename R >
+class pull_coroutine_base : private noncopyable
+{
+public:
+ typedef intrusive_ptr< pull_coroutine_base > ptr_t;
+
+private:
+ template<
+ typename X, typename Y, typename Z, typename V, typename W
+ >
+ friend class push_coroutine_object;
+
+ unsigned int use_count_;
+
+protected:
+ int flags_;
+ exception_ptr except_;
+ coroutine_context caller_;
+ coroutine_context callee_;
+ optional< R > result_;
+
+ virtual void deallocate_object() = 0;
+
+public:
+ pull_coroutine_base( coroutine_context::ctx_fn fn,
+ stack_context * stack_ctx,
+ bool unwind, bool preserve_fpu) :
+ use_count_( 0),
+ flags_( 0),
+ except_(),
+ caller_(),
+ callee_( fn, stack_ctx),
+ result_()
+ {
+ if ( unwind) flags_ |= flag_force_unwind;
+ if ( preserve_fpu) flags_ |= flag_preserve_fpu;
+ }
+
+ pull_coroutine_base( coroutine_context const& callee,
+ bool unwind, bool preserve_fpu,
+ optional< R > const& result) :
+ use_count_( 0),
+ flags_( 0),
+ except_(),
+ caller_(),
+ callee_( callee),
+ result_( result)
+ {
+ if ( unwind) flags_ |= flag_force_unwind;
+ if ( preserve_fpu) flags_ |= flag_preserve_fpu;
+ }
+
+ virtual ~pull_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( pull_coroutine_base * p) BOOST_NOEXCEPT
+ { ++p->use_count_; }
+
+ friend inline void intrusive_ptr_release( pull_coroutine_base * p) BOOST_NOEXCEPT
+ { if ( --p->use_count_ == 0) p->deallocate_object(); }
+
+ void pull()
+ {
+ BOOST_ASSERT( ! is_complete() );
+
+ holder< R > hldr_to( & caller_);
+ holder< R > * hldr_from(
+ reinterpret_cast< holder< R > * >(
+ hldr_to.ctx->jump(
+ callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ preserve_fpu() ) ) );
+ BOOST_ASSERT( hldr_from->ctx);
+ callee_ = * hldr_from->ctx;
+ result_ = hldr_from->data;
+ if ( hldr_from->force_unwind) throw forced_unwind();
+ if ( except_) rethrow_exception( except_);
+ }
+
+ bool has_result() const
+ { return result_; }
+
+ R get() const
+ {
+ if ( ! has_result() )
+ boost::throw_exception(
+ invalid_result() );
+ return result_.get();
+ }
+};
+
+template< typename R >
+class pull_coroutine_base< R & > : private noncopyable
+{
+public:
+ typedef intrusive_ptr< pull_coroutine_base > ptr_t;
+
+private:
+ template<
+ typename X, typename Y, typename Z, typename V, typename W
+ >
+ friend class push_coroutine_object;
+
+ unsigned int use_count_;
+
+protected:
+ int flags_;
+ exception_ptr except_;
+ coroutine_context caller_;
+ coroutine_context callee_;
+ optional< R * > result_;
+
+ virtual void deallocate_object() = 0;
+
+public:
+ pull_coroutine_base( coroutine_context::ctx_fn fn,
+ stack_context * stack_ctx,
+ bool unwind, bool preserve_fpu) :
+ use_count_( 0),
+ flags_( 0),
+ except_(),
+ caller_(),
+ callee_( fn, stack_ctx),
+ result_()
+ {
+ if ( unwind) flags_ |= flag_force_unwind;
+ if ( preserve_fpu) flags_ |= flag_preserve_fpu;
+ }
+
+ pull_coroutine_base( coroutine_context const& callee,
+ bool unwind, bool preserve_fpu,
+ optional< R * > const& result) :
+ use_count_( 0),
+ flags_( 0),
+ except_(),
+ caller_(),
+ callee_( callee),
+ result_( result)
+ {
+ if ( unwind) flags_ |= flag_force_unwind;
+ if ( preserve_fpu) flags_ |= flag_preserve_fpu;
+ }
+
+ virtual ~pull_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( pull_coroutine_base * p) BOOST_NOEXCEPT
+ { ++p->use_count_; }
+
+ friend inline void intrusive_ptr_release( pull_coroutine_base * p) BOOST_NOEXCEPT
+ { if ( --p->use_count_ == 0) p->deallocate_object(); }
+
+ void pull()
+ {
+ BOOST_ASSERT( ! is_complete() );
+
+ holder< R & > hldr_to( & caller_);
+ holder< R & > * hldr_from(
+ reinterpret_cast< holder< R & > * >(
+ hldr_to.ctx->jump(
+ callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ preserve_fpu() ) ) );
+ BOOST_ASSERT( hldr_from->ctx);
+ callee_ = * hldr_from->ctx;
+ result_ = hldr_from->data;
+ if ( hldr_from->force_unwind) throw forced_unwind();
+ if ( except_) rethrow_exception( except_);
+ }
+
+ bool has_result() const
+ { return result_; }
+
+ R & get() const
+ {
+ if ( ! has_result() )
+ boost::throw_exception(
+ invalid_result() );
+ return * result_.get();
+ }
+};
+
+template<>
+class pull_coroutine_base< void > : private noncopyable
+{
+public:
+ typedef intrusive_ptr< pull_coroutine_base > ptr_t;
+
+private:
+ template<
+ typename X, typename Y, typename Z, typename V, typename W
+ >
+ friend class push_coroutine_object;
+
+ unsigned int use_count_;
+
+protected:
+ int flags_;
+ exception_ptr except_;
+ coroutine_context caller_;
+ coroutine_context callee_;
+
+ virtual void deallocate_object() = 0;
+
+public:
+ pull_coroutine_base( coroutine_context::ctx_fn fn,
+ stack_context * stack_ctx,
+ bool unwind, bool preserve_fpu) :
+ use_count_( 0),
+ flags_( 0),
+ except_(),
+ caller_(),
+ callee_( fn, stack_ctx)
+ {
+ if ( unwind) flags_ |= flag_force_unwind;
+ if ( preserve_fpu) flags_ |= flag_preserve_fpu;
+ }
+
+ pull_coroutine_base( coroutine_context const& callee,
+ bool unwind, bool preserve_fpu) :
+ use_count_( 0),
+ flags_( 0),
+ except_(),
+ caller_(),
+ callee_( callee)
+ {
+ if ( unwind) flags_ |= flag_force_unwind;
+ if ( preserve_fpu) flags_ |= flag_preserve_fpu;
+ }
+
+ virtual ~pull_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( pull_coroutine_base * p) BOOST_NOEXCEPT
+ { ++p->use_count_; }
+
+ friend inline void intrusive_ptr_release( pull_coroutine_base * p) BOOST_NOEXCEPT
+ { if ( --p->use_count_ == 0) p->deallocate_object(); }
+
+ void pull()
+ {
+ BOOST_ASSERT( ! is_complete() );
+
+ holder< void > hldr_to( & caller_);
+ holder< void > * hldr_from(
+ reinterpret_cast< holder< void > * >(
+ hldr_to.ctx->jump(
+ callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ preserve_fpu() ) ) );
+ BOOST_ASSERT( hldr_from->ctx);
+ callee_ = * hldr_from->ctx;
+ if ( hldr_from->force_unwind) throw forced_unwind();
+ if ( except_) rethrow_exception( except_);
+ }
+};
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_DETAIL_PULL_COROUTINE_BASE_H
Added: trunk/boost/coroutine/detail/pull_coroutine_caller.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/boost/coroutine/detail/pull_coroutine_caller.hpp 2013-10-30 04:23:09 EDT (Wed, 30 Oct 2013) (r86521)
@@ -0,0 +1,111 @@
+// 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_DETAIL_PULL_COROUTINE_CALLER_H
+#define BOOST_COROUTINES_DETAIL_PULL_COROUTINE_CALLER_H
+
+#include <boost/config.hpp>
+#include <boost/context/fcontext.hpp>
+#include <boost/optional.hpp>
+
+#include <boost/coroutine/detail/config.hpp>
+#include <boost/coroutine/detail/pull_coroutine_base.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+namespace detail {
+
+template< typename R, typename Allocator >
+class pull_coroutine_caller : public pull_coroutine_base< R >
+{
+public:
+ typedef typename Allocator::template rebind<
+ pull_coroutine_caller< R, Allocator >
+ >::other allocator_t;
+
+ pull_coroutine_caller( coroutine_context const& callee, bool unwind, bool preserve_fpu,
+ allocator_t const& alloc, optional< R > const& data) BOOST_NOEXCEPT :
+ pull_coroutine_base< R >( callee, unwind, preserve_fpu, data),
+ alloc_( alloc)
+ {}
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+
+private:
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, pull_coroutine_caller * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+};
+
+template< typename R, typename Allocator >
+class pull_coroutine_caller< R &, Allocator > : public pull_coroutine_base< R & >
+{
+public:
+ typedef typename Allocator::template rebind<
+ pull_coroutine_caller< R &, Allocator >
+ >::other allocator_t;
+
+ pull_coroutine_caller( coroutine_context const& callee, bool unwind, bool preserve_fpu,
+ allocator_t const& alloc, optional< R * > const& data) BOOST_NOEXCEPT :
+ pull_coroutine_base< R & >( callee, unwind, preserve_fpu, data),
+ alloc_( alloc)
+ {}
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+
+private:
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, pull_coroutine_caller * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+};
+
+template< typename Allocator >
+class pull_coroutine_caller< void, Allocator > : public pull_coroutine_base< void >
+{
+public:
+ typedef typename Allocator::template rebind<
+ pull_coroutine_caller< void, Allocator >
+ >::other allocator_t;
+
+ pull_coroutine_caller( coroutine_context const& callee, bool unwind, bool preserve_fpu,
+ allocator_t const& alloc) BOOST_NOEXCEPT :
+ pull_coroutine_base< void >( callee, unwind, preserve_fpu),
+ alloc_( alloc)
+ {}
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+
+private:
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, pull_coroutine_caller * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+};
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_DETAIL_PULL_COROUTINE_CALLER_H
Added: trunk/boost/coroutine/detail/pull_coroutine_object.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/boost/coroutine/detail/pull_coroutine_object.hpp 2013-10-30 04:23:09 EDT (Wed, 30 Oct 2013) (r86521)
@@ -0,0 +1,1124 @@
+
+// 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_DETAIL_PULL_COROUTINE_OBJECT_H
+#define BOOST_COROUTINES_DETAIL_PULL_COROUTINE_OBJECT_H
+
+#include <cstddef>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/exception_ptr.hpp>
+#include <boost/move/move.hpp>
+#include <boost/ref.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/type_traits/function_traits.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/coroutine/attributes.hpp>
+#include <boost/coroutine/detail/config.hpp>
+#include <boost/coroutine/exceptions.hpp>
+#include <boost/coroutine/detail/flags.hpp>
+#include <boost/coroutine/detail/holder.hpp>
+#include <boost/coroutine/detail/param.hpp>
+#include <boost/coroutine/detail/stack_tuple.hpp>
+#include <boost/coroutine/detail/trampoline.hpp>
+#include <boost/coroutine/flags.hpp>
+#include <boost/coroutine/stack_context.hpp>
+#include <boost/coroutine/detail/pull_coroutine_base.hpp>
+
+#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 R, typename Fn,
+ typename StackAllocator, typename Allocator,
+ typename Caller
+>
+class pull_coroutine_object : private stack_tuple< StackAllocator >,
+ public pull_coroutine_base< R >
+{
+public:
+ typedef typename Allocator::template rebind<
+ pull_coroutine_object<
+ R, Fn, StackAllocator, Allocator, Caller
+ >
+ >::other allocator_t;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef pull_coroutine_base< R > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, pull_coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ pull_coroutine_object( pull_coroutine_object &);
+ pull_coroutine_object & operator=( pull_coroutine_object const&);
+
+ void enter_()
+ {
+ holder< R > * hldr_from(
+ reinterpret_cast< holder< R > * >(
+ 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< R > 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
+ pull_coroutine_object( Fn && fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< pull_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( forward< Fn >( fn) ),
+ alloc_( alloc)
+ { enter_(); }
+#else
+ pull_coroutine_object( Fn fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< pull_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ pull_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< pull_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+#endif
+
+ ~pull_coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ // create push_coroutine
+ 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< R > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename R, typename Fn,
+ typename StackAllocator, typename Allocator,
+ typename Caller
+>
+class pull_coroutine_object< R, reference_wrapper< Fn >, StackAllocator, Allocator, Caller > :
+ private stack_tuple< StackAllocator >,
+ public pull_coroutine_base< R >
+{
+public:
+ typedef typename Allocator::template rebind<
+ pull_coroutine_object<
+ R, Fn, StackAllocator, Allocator, Caller
+ >
+ >::other allocator_t;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef pull_coroutine_base< R > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, pull_coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ pull_coroutine_object( pull_coroutine_object &);
+ pull_coroutine_object & operator=( pull_coroutine_object const&);
+
+ void enter_()
+ {
+ holder< R > * hldr_from(
+ reinterpret_cast< holder< R > * >(
+ 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< R > 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:
+ pull_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< pull_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ ~pull_coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ // create pull_coroutine
+ 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< R > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename R, typename Fn,
+ typename StackAllocator, typename Allocator,
+ typename Caller
+>
+class pull_coroutine_object< R, const reference_wrapper< Fn >, StackAllocator, Allocator, Caller > :
+ private stack_tuple< StackAllocator >,
+ public pull_coroutine_base< R >
+{
+public:
+ typedef typename Allocator::template rebind<
+ pull_coroutine_object<
+ R, Fn, StackAllocator, Allocator, Caller
+ >
+ >::other allocator_t;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef pull_coroutine_base< R > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, pull_coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ pull_coroutine_object( pull_coroutine_object &);
+ pull_coroutine_object & operator=( pull_coroutine_object const&);
+
+ void enter_()
+ {
+ holder< R > * hldr_from(
+ reinterpret_cast< holder< R > * >(
+ 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< R > 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:
+ pull_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< pull_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ ~pull_coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ // create pull_coroutine
+ 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< R > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename R, typename Fn,
+ typename StackAllocator, typename Allocator,
+ typename Caller
+>
+class pull_coroutine_object< R &, Fn, StackAllocator, Allocator, Caller > :
+ private stack_tuple< StackAllocator >,
+ public pull_coroutine_base< R & >
+{
+public:
+ typedef typename Allocator::template rebind<
+ pull_coroutine_object<
+ R &, Fn, StackAllocator, Allocator, Caller
+ >
+ >::other allocator_t;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef pull_coroutine_base< R & > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, pull_coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ pull_coroutine_object( pull_coroutine_object &);
+ pull_coroutine_object & operator=( pull_coroutine_object const&);
+
+ void enter_()
+ {
+ holder< R * > * hldr_from(
+ reinterpret_cast< holder< R * > * >(
+ 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< R * > 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
+ pull_coroutine_object( Fn && fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< pull_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( forward< Fn >( fn) ),
+ alloc_( alloc)
+ { enter_(); }
+#else
+ pull_coroutine_object( Fn fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< pull_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ pull_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< pull_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+#endif
+
+ ~pull_coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ // create push_coroutine
+ 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< R * > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename R, typename Fn,
+ typename StackAllocator, typename Allocator,
+ typename Caller
+>
+class pull_coroutine_object< R &, reference_wrapper< Fn >, StackAllocator, Allocator, Caller > :
+ private stack_tuple< StackAllocator >,
+ public pull_coroutine_base< R & >
+{
+public:
+ typedef typename Allocator::template rebind<
+ pull_coroutine_object<
+ R &, Fn, StackAllocator, Allocator, Caller
+ >
+ >::other allocator_t;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef pull_coroutine_base< R & > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, pull_coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ pull_coroutine_object( pull_coroutine_object &);
+ pull_coroutine_object & operator=( pull_coroutine_object const&);
+
+ void enter_()
+ {
+ holder< R * > * hldr_from(
+ reinterpret_cast< holder< R * > * >(
+ 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< R * > 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:
+ pull_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< pull_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ ~pull_coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ // create pull_coroutine
+ 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< R * > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename R, typename Fn,
+ typename StackAllocator, typename Allocator,
+ typename Caller
+>
+class pull_coroutine_object< R &, const reference_wrapper< Fn >, StackAllocator, Allocator, Caller > :
+ private stack_tuple< StackAllocator >,
+ public pull_coroutine_base< R & >
+{
+public:
+ typedef typename Allocator::template rebind<
+ pull_coroutine_object<
+ R &, Fn, StackAllocator, Allocator, Caller
+ >
+ >::other allocator_t;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef pull_coroutine_base< R & > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, pull_coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ pull_coroutine_object( pull_coroutine_object &);
+ pull_coroutine_object & operator=( pull_coroutine_object const&);
+
+ void enter_()
+ {
+ holder< R * > * hldr_from(
+ reinterpret_cast< holder< R * > * >(
+ 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< R * > 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:
+ pull_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< pull_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ ~pull_coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ // create pull_coroutine
+ 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< R * > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename Fn,
+ typename StackAllocator, typename Allocator,
+ typename Caller
+>
+class pull_coroutine_object< void, Fn, StackAllocator, Allocator, Caller > :
+ private stack_tuple< StackAllocator >,
+ public pull_coroutine_base< void >
+{
+public:
+ typedef typename Allocator::template rebind<
+ pull_coroutine_object<
+ void, Fn, StackAllocator, Allocator, Caller
+ >
+ >::other allocator_t;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef pull_coroutine_base< void > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, pull_coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ pull_coroutine_object( pull_coroutine_object &);
+ pull_coroutine_object & operator=( pull_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
+ pull_coroutine_object( Fn && fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< pull_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( forward< Fn >( fn) ),
+ alloc_( alloc)
+ { enter_(); }
+#else
+ pull_coroutine_object( Fn fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< pull_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ pull_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< pull_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+#endif
+
+ ~pull_coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ // create push_coroutine
+ 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, "pull_coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename Fn,
+ typename StackAllocator, typename Allocator,
+ typename Caller
+>
+class pull_coroutine_object< void, reference_wrapper< Fn >, StackAllocator, Allocator, Caller > :
+ private stack_tuple< StackAllocator >,
+ public pull_coroutine_base< void >
+{
+public:
+ typedef typename Allocator::template rebind<
+ pull_coroutine_object<
+ void, Fn, StackAllocator, Allocator, Caller
+ >
+ >::other allocator_t;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef pull_coroutine_base< void > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, pull_coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ pull_coroutine_object( pull_coroutine_object &);
+ pull_coroutine_object & operator=( pull_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:
+ pull_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< pull_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ ~pull_coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ // create pull_coroutine
+ 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, "pull_coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename Fn,
+ typename StackAllocator, typename Allocator,
+ typename Caller
+>
+class pull_coroutine_object< void, const reference_wrapper< Fn >, StackAllocator, Allocator, Caller > :
+ private stack_tuple< StackAllocator >,
+ public pull_coroutine_base< void >
+{
+public:
+ typedef typename Allocator::template rebind<
+ pull_coroutine_object<
+ void, Fn, StackAllocator, Allocator, Caller
+ >
+ >::other allocator_t;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef pull_coroutine_base< void > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, pull_coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ pull_coroutine_object( pull_coroutine_object &);
+ pull_coroutine_object & operator=( pull_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:
+ pull_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< pull_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ ~pull_coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ // create pull_coroutine
+ 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, "pull_coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#ifdef BOOST_MSVC
+ #pragma warning (pop)
+#endif
+
+#endif // BOOST_COROUTINES_DETAIL_PULL_COROUTINE_OBJECT_H
Added: trunk/boost/coroutine/detail/push_coroutine_base.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/boost/coroutine/detail/push_coroutine_base.hpp 2013-10-30 04:23:09 EDT (Wed, 30 Oct 2013) (r86521)
@@ -0,0 +1,354 @@
+
+// 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_DETAIL_PUSH_COROUTINE_BASE_H
+#define BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_BASE_H
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+#include <boost/context/fcontext.hpp>
+#include <boost/exception_ptr.hpp>
+#include <boost/intrusive_ptr.hpp>
+#include <boost/type_traits/function_traits.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/coroutine/detail/config.hpp>
+#include <boost/coroutine/detail/coroutine_context.hpp>
+#include <boost/coroutine/exceptions.hpp>
+#include <boost/coroutine/detail/flags.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+
+struct stack_context;
+
+namespace detail {
+
+template< typename Arg >
+class push_coroutine_base : private noncopyable
+{
+public:
+ typedef intrusive_ptr< push_coroutine_base > ptr_t;
+
+private:
+ template<
+ typename X, typename Y, typename Z, typename V, typename W
+ >
+ friend class pull_coroutine_object;
+
+ unsigned int use_count_;
+
+protected:
+ int flags_;
+ exception_ptr except_;
+ coroutine_context caller_;
+ coroutine_context callee_;
+
+ virtual void deallocate_object() = 0;
+
+public:
+ push_coroutine_base( coroutine_context::ctx_fn fn,
+ stack_context * stack_ctx,
+ bool unwind, bool preserve_fpu) :
+ use_count_( 0),
+ flags_( 0),
+ except_(),
+ caller_(),
+ callee_( fn, stack_ctx)
+ {
+ if ( unwind) flags_ |= flag_force_unwind;
+ if ( preserve_fpu) flags_ |= flag_preserve_fpu;
+ }
+
+ push_coroutine_base( coroutine_context const& callee,
+ bool unwind, bool preserve_fpu) :
+ use_count_( 0),
+ flags_( 0),
+ except_(),
+ caller_(),
+ callee_( callee)
+ {
+ if ( unwind) flags_ |= flag_force_unwind;
+ if ( preserve_fpu) flags_ |= flag_preserve_fpu;
+ }
+
+ virtual ~push_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( push_coroutine_base * p) BOOST_NOEXCEPT
+ { ++p->use_count_; }
+
+ friend inline void intrusive_ptr_release( push_coroutine_base * p) BOOST_NOEXCEPT
+ { if ( --p->use_count_ == 0) p->deallocate_object(); }
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ void push( Arg const& arg)
+ {
+ BOOST_ASSERT( ! is_complete() );
+
+ holder< Arg > hldr_to( & caller_, arg);
+ holder< Arg > * hldr_from(
+ reinterpret_cast< holder< Arg > * >(
+ hldr_to.ctx->jump(
+ callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ preserve_fpu() ) ) );
+ BOOST_ASSERT( hldr_from->ctx);
+ callee_ = * hldr_from->ctx;
+ if ( hldr_from->force_unwind) throw forced_unwind();
+ if ( except_) rethrow_exception( except_);
+ }
+
+ void push( Arg && arg)
+ {
+ BOOST_ASSERT( ! is_complete() );
+
+ holder< Arg > hldr_to( & caller_, boost::forward( arg) );
+ holder< Arg > * hldr_from(
+ reinterpret_cast< holder< Arg > * >(
+ hldr_to.ctx->jump(
+ callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ preserve_fpu() ) ) );
+ BOOST_ASSERT( hldr_from->ctx);
+ callee_ = * hldr_from->ctx;
+ if ( hldr_from->force_unwind) throw forced_unwind();
+ if ( except_) rethrow_exception( except_);
+ }
+#else
+ void push( Arg const& arg)
+ {
+ BOOST_ASSERT( ! is_complete() );
+
+ holder< Arg > hldr_to( & caller_, arg);
+ holder< Arg > * hldr_from(
+ reinterpret_cast< holder< Arg > * >(
+ hldr_to.ctx->jump(
+ callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ preserve_fpu() ) ) );
+ BOOST_ASSERT( hldr_from->ctx);
+ callee_ = * hldr_from->ctx;
+ if ( hldr_from->force_unwind) throw forced_unwind();
+ if ( except_) rethrow_exception( except_);
+ }
+
+ void push( BOOST_RV_REF( Arg) arg)
+ {
+ BOOST_ASSERT( ! is_complete() );
+
+ holder< Arg > hldr_to( & caller_, arg);
+ holder< Arg > * hldr_from(
+ reinterpret_cast< holder< Arg > * >(
+ hldr_to.ctx->jump(
+ callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ preserve_fpu() ) ) );
+ BOOST_ASSERT( hldr_from->ctx);
+ callee_ = * hldr_from->ctx;
+ if ( hldr_from->force_unwind) throw forced_unwind();
+ if ( except_) rethrow_exception( except_);
+ }
+#endif
+};
+
+template< typename Arg >
+class push_coroutine_base< Arg & > : private noncopyable
+{
+public:
+ typedef intrusive_ptr< push_coroutine_base > ptr_t;
+
+private:
+ template<
+ typename X, typename Y, typename Z, typename V, typename W
+ >
+ friend class pull_coroutine_object;
+
+ unsigned int use_count_;
+
+protected:
+ int flags_;
+ exception_ptr except_;
+ coroutine_context caller_;
+ coroutine_context callee_;
+
+ virtual void deallocate_object() = 0;
+
+public:
+ push_coroutine_base( coroutine_context::ctx_fn fn,
+ stack_context * stack_ctx,
+ bool unwind, bool preserve_fpu) :
+ use_count_( 0),
+ flags_( 0),
+ except_(),
+ caller_(),
+ callee_( fn, stack_ctx)
+ {
+ if ( unwind) flags_ |= flag_force_unwind;
+ if ( preserve_fpu) flags_ |= flag_preserve_fpu;
+ }
+
+ push_coroutine_base( coroutine_context const& callee,
+ bool unwind, bool preserve_fpu) :
+ use_count_( 0),
+ flags_( 0),
+ except_(),
+ caller_(),
+ callee_( callee)
+ {
+ if ( unwind) flags_ |= flag_force_unwind;
+ if ( preserve_fpu) flags_ |= flag_preserve_fpu;
+ }
+
+ virtual ~push_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( push_coroutine_base * p) BOOST_NOEXCEPT
+ { ++p->use_count_; }
+
+ friend inline void intrusive_ptr_release( push_coroutine_base * p) BOOST_NOEXCEPT
+ { if ( --p->use_count_ == 0) p->deallocate_object(); }
+
+ void push( Arg & arg)
+ {
+ BOOST_ASSERT( ! is_complete() );
+
+ holder< Arg * > hldr_to( & caller_, & arg);
+ holder< Arg * > * hldr_from(
+ reinterpret_cast< holder< Arg * > * >(
+ hldr_to.ctx->jump(
+ callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ preserve_fpu() ) ) );
+ BOOST_ASSERT( hldr_from->ctx);
+ callee_ = * hldr_from->ctx;
+ if ( hldr_from->force_unwind) throw forced_unwind();
+ if ( except_) rethrow_exception( except_);
+ }
+};
+
+template<>
+class push_coroutine_base< void > : private noncopyable
+{
+public:
+ typedef intrusive_ptr< push_coroutine_base > ptr_t;
+
+private:
+ template<
+ typename X, typename Y, typename Z, typename V, typename W
+ >
+ friend class pull_coroutine_object;
+
+ unsigned int use_count_;
+
+protected:
+ int flags_;
+ exception_ptr except_;
+ coroutine_context caller_;
+ coroutine_context callee_;
+
+ virtual void deallocate_object() = 0;
+
+public:
+ push_coroutine_base( coroutine_context::ctx_fn fn,
+ stack_context * stack_ctx,
+ bool unwind, bool preserve_fpu) :
+ use_count_( 0),
+ flags_( 0),
+ except_(),
+ caller_(),
+ callee_( fn, stack_ctx)
+ {
+ if ( unwind) flags_ |= flag_force_unwind;
+ if ( preserve_fpu) flags_ |= flag_preserve_fpu;
+ }
+
+ push_coroutine_base( coroutine_context const& callee,
+ bool unwind, bool preserve_fpu) :
+ use_count_( 0),
+ flags_( 0),
+ except_(),
+ caller_(),
+ callee_( callee)
+ {
+ if ( unwind) flags_ |= flag_force_unwind;
+ if ( preserve_fpu) flags_ |= flag_preserve_fpu;
+ }
+
+ virtual ~push_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( push_coroutine_base * p) BOOST_NOEXCEPT
+ { ++p->use_count_; }
+
+ friend inline void intrusive_ptr_release( push_coroutine_base * p) BOOST_NOEXCEPT
+ { if ( --p->use_count_ == 0) p->deallocate_object(); }
+
+ void push()
+ {
+ BOOST_ASSERT( ! is_complete() );
+
+ holder< void > hldr_to( & caller_);
+ holder< void > * hldr_from(
+ reinterpret_cast< holder< void > * >(
+ hldr_to.ctx->jump(
+ callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ preserve_fpu() ) ) );
+ BOOST_ASSERT( hldr_from->ctx);
+ callee_ = * hldr_from->ctx;
+ if ( hldr_from->force_unwind) throw forced_unwind();
+ if ( except_) rethrow_exception( except_);
+ }
+};
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_BASE_H
Added: trunk/boost/coroutine/detail/push_coroutine_caller.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/boost/coroutine/detail/push_coroutine_caller.hpp 2013-10-30 04:23:09 EDT (Wed, 30 Oct 2013) (r86521)
@@ -0,0 +1,56 @@
+// 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_DETAIL_PUSH_COROUTINE_CALLER_H
+#define BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_CALLER_H
+
+#include <boost/config.hpp>
+#include <boost/context/fcontext.hpp>
+
+#include <boost/coroutine/detail/config.hpp>
+#include <boost/coroutine/detail/push_coroutine_base.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+namespace detail {
+
+template< typename Arg, typename Allocator >
+class push_coroutine_caller : public push_coroutine_base< Arg >
+{
+public:
+ typedef typename Allocator::template rebind<
+ push_coroutine_caller< Arg, Allocator >
+ >::other allocator_t;
+
+ push_coroutine_caller( coroutine_context const& callee, bool unwind,
+ bool preserve_fpu, allocator_t const& alloc) BOOST_NOEXCEPT :
+ push_coroutine_base< Arg >( callee, unwind, preserve_fpu),
+ alloc_( alloc)
+ {}
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+
+private:
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, push_coroutine_caller * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+};
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_CALLER_H
Added: trunk/boost/coroutine/detail/push_coroutine_object.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/boost/coroutine/detail/push_coroutine_object.hpp 2013-10-30 04:23:09 EDT (Wed, 30 Oct 2013) (r86521)
@@ -0,0 +1,1208 @@
+
+// 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_DETAIL_PUSH_COROUTINE_OBJECT_H
+#define BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_OBJECT_H
+
+#include <cstddef>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/exception_ptr.hpp>
+#include <boost/move/move.hpp>
+#include <boost/ref.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/type_traits/function_traits.hpp>
+#include <boost/utility.hpp>
+
+#include <boost/coroutine/attributes.hpp>
+#include <boost/coroutine/detail/config.hpp>
+#include <boost/coroutine/exceptions.hpp>
+#include <boost/coroutine/detail/flags.hpp>
+#include <boost/coroutine/detail/holder.hpp>
+#include <boost/coroutine/detail/param.hpp>
+#include <boost/coroutine/detail/stack_tuple.hpp>
+#include <boost/coroutine/detail/trampoline.hpp>
+#include <boost/coroutine/flags.hpp>
+#include <boost/coroutine/stack_context.hpp>
+#include <boost/coroutine/detail/push_coroutine_base.hpp>
+
+#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 Arg, typename Fn,
+ typename StackAllocator, typename Allocator,
+ typename Caller
+>
+class push_coroutine_object : private stack_tuple< StackAllocator >,
+ public push_coroutine_base< Arg >
+{
+public:
+ typedef typename Allocator::template rebind<
+ push_coroutine_object<
+ Arg, Fn, StackAllocator, Allocator, Caller
+ >
+ >::other allocator_t;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef push_coroutine_base< Arg > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, push_coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ push_coroutine_object( push_coroutine_object &);
+ push_coroutine_object & operator=( push_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< Arg > 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
+ push_coroutine_object( Fn && fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< push_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( forward< Fn >( fn) ),
+ alloc_( alloc)
+ { enter_(); }
+#else
+ push_coroutine_object( Fn fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< push_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ push_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< push_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+#endif
+
+ ~push_coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ holder< void > hldr_to( & caller);
+ holder< Arg > * hldr_from(
+ reinterpret_cast< holder< Arg > * >(
+ caller.jump(
+ this->caller_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() ) ) );
+ BOOST_ASSERT( hldr_from->ctx);
+ BOOST_ASSERT( hldr_from->data);
+
+ // create pull_coroutine
+ Caller c( * hldr_from->ctx, false, this->preserve_fpu(), alloc_, hldr_from->data);
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< Arg > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "push_coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename Arg, typename Fn,
+ typename StackAllocator, typename Allocator,
+ typename Caller
+>
+class push_coroutine_object< Arg, reference_wrapper< Fn >, StackAllocator, Allocator, Caller > :
+ private stack_tuple< StackAllocator >,
+ public push_coroutine_base< Arg >
+{
+public:
+ typedef typename Allocator::template rebind<
+ push_coroutine_object<
+ Arg, Fn, StackAllocator, Allocator, Caller
+ >
+ >::other allocator_t;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef push_coroutine_base< Arg > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, push_coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ push_coroutine_object( push_coroutine_object &);
+ push_coroutine_object & operator=( push_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< Arg > 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:
+ push_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< push_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ ~push_coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ holder< void > hldr_to( & caller);
+ holder< Arg > * hldr_from(
+ reinterpret_cast< holder< Arg > * >(
+ caller.jump(
+ this->caller_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() ) ) );
+ BOOST_ASSERT( hldr_from->ctx);
+ BOOST_ASSERT( hldr_from->data);
+
+ // create pull_coroutine
+ Caller c( * hldr_from->ctx, false, this->preserve_fpu(), alloc_, hldr_from->data);
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< Arg > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "push_coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename Arg, typename Fn,
+ typename StackAllocator, typename Allocator,
+ typename Caller
+>
+class push_coroutine_object< Arg, const reference_wrapper< Fn >, StackAllocator, Allocator, Caller > :
+ private stack_tuple< StackAllocator >,
+ public push_coroutine_base< Arg >
+{
+public:
+ typedef typename Allocator::template rebind<
+ push_coroutine_object<
+ Arg, Fn, StackAllocator, Allocator, Caller
+ >
+ >::other allocator_t;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef push_coroutine_base< Arg > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, push_coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ push_coroutine_object( push_coroutine_object &);
+ push_coroutine_object & operator=( push_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< Arg > 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:
+ push_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< push_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ ~push_coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ holder< void > hldr_to( & caller);
+ holder< Arg > * hldr_from(
+ reinterpret_cast< holder< Arg > * >(
+ caller.jump(
+ this->caller_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() ) ) );
+ BOOST_ASSERT( hldr_from->ctx);
+ BOOST_ASSERT( hldr_from->data);
+
+ // create pull_coroutine
+ Caller c( * hldr_from->ctx, false, this->preserve_fpu(), alloc_, hldr_from->data);
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< Arg > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "push_coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename Arg, typename Fn,
+ typename StackAllocator, typename Allocator,
+ typename Caller
+>
+class push_coroutine_object< Arg &, Fn, StackAllocator, Allocator, Caller > :
+ private stack_tuple< StackAllocator >,
+ public push_coroutine_base< Arg & >
+{
+public:
+ typedef typename Allocator::template rebind<
+ push_coroutine_object<
+ Arg &, Fn, StackAllocator, Allocator, Caller
+ >
+ >::other allocator_t;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef push_coroutine_base< Arg & > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, push_coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ push_coroutine_object( push_coroutine_object &);
+ push_coroutine_object & operator=( push_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< Arg * > 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
+ push_coroutine_object( Fn && fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< push_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( forward< Fn >( fn) ),
+ alloc_( alloc)
+ { enter_(); }
+#else
+ push_coroutine_object( Fn fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< push_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ push_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< push_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+#endif
+
+ ~push_coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ holder< void > hldr_to( & caller);
+ holder< Arg * > * hldr_from(
+ reinterpret_cast< holder< Arg * > * >(
+ caller.jump(
+ this->caller_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() ) ) );
+ BOOST_ASSERT( hldr_from->ctx);
+ BOOST_ASSERT( hldr_from->data);
+
+ // create pull_coroutine
+ Caller c( * hldr_from->ctx, false, this->preserve_fpu(), alloc_, hldr_from->data);
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< Arg * > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "push_coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename Arg, typename Fn,
+ typename StackAllocator, typename Allocator,
+ typename Caller
+>
+class push_coroutine_object< Arg &, reference_wrapper< Fn >, StackAllocator, Allocator, Caller > :
+ private stack_tuple< StackAllocator >,
+ public push_coroutine_base< Arg & >
+{
+public:
+ typedef typename Allocator::template rebind<
+ push_coroutine_object<
+ Arg &, Fn, StackAllocator, Allocator, Caller
+ >
+ >::other allocator_t;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef push_coroutine_base< Arg & > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, push_coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ push_coroutine_object( push_coroutine_object &);
+ push_coroutine_object & operator=( push_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< Arg * > 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:
+ push_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< push_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ ~push_coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ holder< void > hldr_to( & caller);
+ holder< Arg * > * hldr_from(
+ reinterpret_cast< holder< Arg * > * >(
+ caller.jump(
+ this->caller_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() ) ) );
+ BOOST_ASSERT( hldr_from->ctx);
+ BOOST_ASSERT( hldr_from->data);
+
+ // create pull_coroutine
+ Caller c( * hldr_from->ctx, false, this->preserve_fpu(), alloc_, hldr_from->data);
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< Arg * > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "push_coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename Arg, typename Fn,
+ typename StackAllocator, typename Allocator,
+ typename Caller
+>
+class push_coroutine_object< Arg &, const reference_wrapper< Fn >, StackAllocator, Allocator, Caller > :
+ private stack_tuple< StackAllocator >,
+ public push_coroutine_base< Arg & >
+{
+public:
+ typedef typename Allocator::template rebind<
+ push_coroutine_object<
+ Arg, Fn, StackAllocator, Allocator, Caller
+ >
+ >::other allocator_t;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef push_coroutine_base< Arg & > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, push_coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ push_coroutine_object( push_coroutine_object &);
+ push_coroutine_object & operator=( push_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< Arg * > 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:
+ push_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< push_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ ~push_coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ holder< void > hldr_to( & caller);
+ holder< Arg * > * hldr_from(
+ reinterpret_cast< holder< Arg * > * >(
+ caller.jump(
+ this->caller_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() ) ) );
+ BOOST_ASSERT( hldr_from->ctx);
+ BOOST_ASSERT( hldr_from->data);
+
+ // create pull_coroutine
+ Caller c( * hldr_from->ctx, false, this->preserve_fpu(), alloc_, hldr_from->data);
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< Arg * > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "push_coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename Fn,
+ typename StackAllocator, typename Allocator,
+ typename Caller
+>
+class push_coroutine_object< void, Fn, StackAllocator, Allocator, Caller > :
+ private stack_tuple< StackAllocator >,
+ public push_coroutine_base< void >
+{
+public:
+ typedef typename Allocator::template rebind<
+ push_coroutine_object<
+ void, Fn, StackAllocator, Allocator, Caller
+ >
+ >::other allocator_t;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef push_coroutine_base< void > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, push_coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ push_coroutine_object( push_coroutine_object &);
+ push_coroutine_object & operator=( push_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
+ push_coroutine_object( Fn && fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< push_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( forward< Fn >( fn) ),
+ alloc_( alloc)
+ { enter_(); }
+#else
+ push_coroutine_object( Fn fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< push_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ push_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< push_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+#endif
+
+ ~push_coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ holder< void > hldr_to( & caller);
+ holder< void > * hldr_from(
+ reinterpret_cast< holder< void > * >(
+ caller.jump(
+ this->caller_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() ) ) );
+ BOOST_ASSERT( hldr_from->ctx);
+
+ // create pull_coroutine
+ Caller c( * hldr_from->ctx, 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, "push_coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename Fn,
+ typename StackAllocator, typename Allocator,
+ typename Caller
+>
+class push_coroutine_object< void, reference_wrapper< Fn >, StackAllocator, Allocator, Caller > :
+ private stack_tuple< StackAllocator >,
+ public push_coroutine_base< void >
+{
+public:
+ typedef typename Allocator::template rebind<
+ push_coroutine_object<
+ void, Fn, StackAllocator, Allocator, Caller
+ >
+ >::other allocator_t;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef push_coroutine_base< void > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, push_coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ push_coroutine_object( push_coroutine_object &);
+ push_coroutine_object & operator=( push_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:
+ push_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< push_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ ~push_coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ holder< void > hldr_to( & caller);
+ holder< void > * hldr_from(
+ reinterpret_cast< holder< void > * >(
+ caller.jump(
+ this->caller_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() ) ) );
+ BOOST_ASSERT( hldr_from->ctx);
+
+ // create pull_coroutine
+ Caller c( * hldr_from->ctx, 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, "push_coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename Fn,
+ typename StackAllocator, typename Allocator,
+ typename Caller
+>
+class push_coroutine_object< void, const reference_wrapper< Fn >, StackAllocator, Allocator, Caller > :
+ private stack_tuple< StackAllocator >,
+ public push_coroutine_base< void >
+{
+public:
+ typedef typename Allocator::template rebind<
+ push_coroutine_object<
+ void, Fn, StackAllocator, Allocator, Caller
+ >
+ >::other allocator_t;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef push_coroutine_base< void > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, push_coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ push_coroutine_object( push_coroutine_object &);
+ push_coroutine_object & operator=( push_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:
+ push_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< push_coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ ~push_coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ holder< void > hldr_to( & caller);
+ holder< void > * hldr_from(
+ reinterpret_cast< holder< void > * >(
+ caller.jump(
+ this->caller_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() ) ) );
+ BOOST_ASSERT( hldr_from->ctx);
+
+ // create pull_coroutine
+ Caller c( * hldr_from->ctx, 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, "push_coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#ifdef BOOST_MSVC
+ #pragma warning (pop)
+#endif
+
+#endif // BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_OBJECT_H
Modified: trunk/libs/coroutine/example/cpp03/Jamfile.v2
==============================================================================
--- trunk/libs/coroutine/example/cpp03/Jamfile.v2 Tue Oct 29 23:57:39 2013 (r86520)
+++ trunk/libs/coroutine/example/cpp03/Jamfile.v2 2013-10-30 04:23:09 EDT (Wed, 30 Oct 2013) (r86521)
@@ -75,3 +75,7 @@
exe chaining
: chaining.cpp
;
+
+exe exception
+ : exception.cpp
+ ;
Modified: trunk/libs/coroutine/example/cpp03/echo.cpp
==============================================================================
--- trunk/libs/coroutine/example/cpp03/echo.cpp Tue Oct 29 23:57:39 2013 (r86520)
+++ trunk/libs/coroutine/example/cpp03/echo.cpp 2013-10-30 04:23:09 EDT (Wed, 30 Oct 2013) (r86521)
@@ -10,7 +10,6 @@
#include <boost/bind.hpp>
#include <boost/coroutine/all.hpp>
-#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 @@
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
Added: trunk/libs/coroutine/example/cpp03/exception.cpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/libs/coroutine/example/cpp03/exception.cpp 2013-10-30 04:23:09 EDT (Wed, 30 Oct 2013) (r86521)
@@ -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 <cstdlib>
+#include <iostream>
+#include <stdexcept>
+#include <string>
+
+#include <boost/bind.hpp>
+#include <boost/coroutine/all.hpp>
+#include <boost/throw_exception.hpp>
+
+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;
+}
Modified: trunk/libs/coroutine/example/cpp03/fibonacci.cpp
==============================================================================
--- trunk/libs/coroutine/example/cpp03/fibonacci.cpp Tue Oct 29 23:57:39 2013 (r86520)
+++ trunk/libs/coroutine/example/cpp03/fibonacci.cpp 2013-10-30 04:23:09 EDT (Wed, 30 Oct 2013) (r86521)
@@ -10,7 +10,6 @@
#include <boost/range.hpp>
#include <boost/coroutine/all.hpp>
-#ifdef BOOST_COROUTINES_UNIDIRECT
void fibonacci( boost::coroutines::coroutine< int >::push_type & sink)
{
int first = 1, second = 1;
@@ -41,35 +40,3 @@
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
Modified: trunk/libs/coroutine/example/cpp03/parallel.cpp
==============================================================================
--- trunk/libs/coroutine/example/cpp03/parallel.cpp Tue Oct 29 23:57:39 2013 (r86520)
+++ trunk/libs/coroutine/example/cpp03/parallel.cpp 2013-10-30 04:23:09 EDT (Wed, 30 Oct 2013) (r86521)
@@ -10,7 +10,6 @@
#include <boost/bind.hpp>
#include <boost/coroutine/all.hpp>
-#ifdef BOOST_COROUTINES_UNIDIRECT
void first( boost::coroutines::coroutine< void >::push_type & sink)
{
std::cout << "started first! ";
@@ -48,44 +47,3 @@
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
Modified: trunk/libs/coroutine/example/cpp03/power.cpp
==============================================================================
--- trunk/libs/coroutine/example/cpp03/power.cpp Tue Oct 29 23:57:39 2013 (r86520)
+++ trunk/libs/coroutine/example/cpp03/power.cpp 2013-10-30 04:23:09 EDT (Wed, 30 Oct 2013) (r86521)
@@ -12,7 +12,6 @@
#include <boost/range.hpp>
#include <boost/coroutine/all.hpp>
-#ifdef BOOST_COROUTINES_UNIDIRECT
void power( boost::coroutines::coroutine< int >::push_type & sink, int number, int exponent)
{
int counter = 0;
@@ -46,41 +45,3 @@
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
Modified: trunk/libs/coroutine/example/cpp03/segmented_stack.cpp
==============================================================================
--- trunk/libs/coroutine/example/cpp03/segmented_stack.cpp Tue Oct 29 23:57:39 2013 (r86520)
+++ trunk/libs/coroutine/example/cpp03/segmented_stack.cpp 2013-10-30 04:23:09 EDT (Wed, 30 Oct 2013) (r86521)
@@ -35,7 +35,6 @@
}
}
-#ifdef BOOST_COROUTINES_UNIDIRECT
void foo( boost::coroutines::coroutine< void >::pull_type & source)
{
bar( count);
@@ -49,23 +48,6 @@
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[])
{
Modified: trunk/libs/coroutine/example/cpp03/tree.h
==============================================================================
--- trunk/libs/coroutine/example/cpp03/tree.h Tue Oct 29 23:57:39 2013 (r86520)
+++ trunk/libs/coroutine/example/cpp03/tree.h 2013-10-30 04:23:09 EDT (Wed, 30 Oct 2013) (r86521)
@@ -91,7 +91,6 @@
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 @@
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)
Modified: trunk/libs/coroutine/example/cpp03/unwind.cpp
==============================================================================
--- trunk/libs/coroutine/example/cpp03/unwind.cpp Tue Oct 29 23:57:39 2013 (r86520)
+++ trunk/libs/coroutine/example/cpp03/unwind.cpp 2013-10-30 04:23:09 EDT (Wed, 30 Oct 2013) (r86521)
@@ -10,7 +10,6 @@
#include <boost/bind.hpp>
#include <boost/coroutine/all.hpp>
-#ifdef BOOST_COROUTINES_UNIDIRECT
struct X : private boost::noncopyable
{
X() { std::cout << "X()" << std::endl; }
@@ -43,39 +42,3 @@
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
Modified: trunk/libs/coroutine/example/cpp11/await_emu.cpp
==============================================================================
--- trunk/libs/coroutine/example/cpp11/await_emu.cpp Tue Oct 29 23:57:39 2013 (r86520)
+++ trunk/libs/coroutine/example/cpp11/await_emu.cpp 2013-10-30 04:23:09 EDT (Wed, 30 Oct 2013) (r86521)
@@ -70,13 +70,9 @@
// ___________________________________________________________ //
-#ifdef BOOST_COROUTINES_UNIDIRECT
typedef coroutines::coroutine<void>::pull_type coro_pull;
typedef coroutines::coroutine<void>::push_type coro_push;
-#else
-typedef coroutines::coroutine<void()> coro_pull;
-typedef coroutines::coroutine<void()>::caller_type coro_push;
-#endif
+
struct CurrentCoro
{
std::shared_ptr<coro_pull> coro;
Modified: trunk/libs/coroutine/example/cpp11/fibonacci.cpp
==============================================================================
--- trunk/libs/coroutine/example/cpp11/fibonacci.cpp Tue Oct 29 23:57:39 2013 (r86520)
+++ trunk/libs/coroutine/example/cpp11/fibonacci.cpp 2013-10-30 04:23:09 EDT (Wed, 30 Oct 2013) (r86521)
@@ -9,7 +9,6 @@
#include <boost/coroutine/all.hpp>
-#ifdef BOOST_COROUTINES_UNIDIRECT
int main()
{
boost::coroutines::coroutine< int >::pull_type source(
@@ -33,28 +32,3 @@
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
Modified: trunk/libs/coroutine/performance/performance.cpp
==============================================================================
--- trunk/libs/coroutine/performance/performance.cpp Tue Oct 29 23:57:39 2013 (r86520)
+++ trunk/libs/coroutine/performance/performance.cpp 2013-10-30 04:23:09 EDT (Wed, 30 Oct 2013) (r86521)
@@ -32,7 +32,6 @@
# 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 @@
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[])
{
Modified: trunk/libs/coroutine/test/test_coroutine.cpp
==============================================================================
--- trunk/libs/coroutine/test/test_coroutine.cpp Tue Oct 29 23:57:39 2013 (r86520)
+++ trunk/libs/coroutine/test/test_coroutine.cpp 2013-10-30 04:23:09 EDT (Wed, 30 Oct 2013) (r86521)
@@ -37,7 +37,6 @@
int value8 = 0;
int value9 = 0;
-#ifdef BOOST_COROUTINES_UNIDIRECT
struct X : private boost::noncopyable
{
X() { value1 = 7; }
@@ -530,516 +529,6 @@
}
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&>(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<int&,int&> 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<int&,int&> 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 @@
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) );
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk