|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r84416 - in branches/release: boost/coroutine boost/coroutine/detail boost/coroutine/v1 boost/coroutine/v1/detail boost/coroutine/v2 boost/coroutine/v2/detail libs/coroutine/build libs/coroutine/detail libs/coroutine/doc libs/coroutine/example libs/coroutine/example/c++11 libs/coroutine/performance libs/coroutine/src/detail libs/coroutine/test
From: oliver.kowalke_at_[hidden]
Date: 2013-05-22 12:10:55
Author: olli
Date: 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
New Revision: 84416
URL: http://svn.boost.org/trac/boost/changeset/84416
Log:
coroutine: merge from trunk
Added:
branches/release/boost/coroutine/checkpoint.hpp (contents, props changed)
branches/release/boost/coroutine/v1/
branches/release/boost/coroutine/v1/coroutine.hpp (contents, props changed)
branches/release/boost/coroutine/v1/detail/
branches/release/boost/coroutine/v1/detail/arg.hpp (contents, props changed)
branches/release/boost/coroutine/v1/detail/coroutine_base.hpp (contents, props changed)
branches/release/boost/coroutine/v1/detail/coroutine_base_resume.hpp (contents, props changed)
branches/release/boost/coroutine/v1/detail/coroutine_caller.hpp (contents, props changed)
branches/release/boost/coroutine/v1/detail/coroutine_get.hpp (contents, props changed)
branches/release/boost/coroutine/v1/detail/coroutine_object.hpp (contents, props changed)
branches/release/boost/coroutine/v1/detail/coroutine_object_result_0.ipp (contents, props changed)
branches/release/boost/coroutine/v1/detail/coroutine_object_result_1.ipp (contents, props changed)
branches/release/boost/coroutine/v1/detail/coroutine_object_result_arity.ipp (contents, props changed)
branches/release/boost/coroutine/v1/detail/coroutine_object_void_0.ipp (contents, props changed)
branches/release/boost/coroutine/v1/detail/coroutine_object_void_1.ipp (contents, props changed)
branches/release/boost/coroutine/v1/detail/coroutine_object_void_arity.ipp (contents, props changed)
branches/release/boost/coroutine/v1/detail/coroutine_op.hpp (contents, props changed)
branches/release/boost/coroutine/v2/
branches/release/boost/coroutine/v2/detail/
branches/release/boost/coroutine/v2/detail/coroutine_object.hpp (contents, props changed)
branches/release/boost/coroutine/v2/pull_corotuine.hpp (contents, props changed)
branches/release/boost/coroutine/v2/push_coroutine.hpp (contents, props changed)
branches/release/libs/coroutine/example/c++11/
branches/release/libs/coroutine/example/c++11/fibonacci.cpp (contents, props changed)
branches/release/libs/coroutine/example/c++11/same_fringe.cpp (contents, props changed)
branches/release/libs/coroutine/example/c++11/tree.h (contents, props changed)
Text files modified:
branches/release/boost/coroutine/coroutine.hpp | 1419 ---------------------------------------
branches/release/boost/coroutine/detail/config.hpp | 4
branches/release/boost/coroutine/detail/coroutine_context.hpp | 4
branches/release/boost/coroutine/detail/segmented_stack_allocator.hpp | 2
branches/release/libs/coroutine/build/Jamfile.v2 | 2
branches/release/libs/coroutine/detail/coroutine_context.cpp | 20
branches/release/libs/coroutine/doc/Jamfile.v2 | 2
branches/release/libs/coroutine/doc/intro.qbk | 2
branches/release/libs/coroutine/doc/stack.qbk | 2
branches/release/libs/coroutine/example/Jamfile.v2 | 9
branches/release/libs/coroutine/performance/Jamfile.v2 | 1
branches/release/libs/coroutine/src/detail/coroutine_context.cpp | 29
branches/release/libs/coroutine/src/detail/segmented_stack_allocator.cpp | 2
branches/release/libs/coroutine/test/Jamfile.v2 | 1
branches/release/libs/coroutine/test/test_coroutine.cpp | 1
15 files changed, 58 insertions(+), 1442 deletions(-)
Added: branches/release/boost/coroutine/checkpoint.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/coroutine/checkpoint.hpp 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -0,0 +1,34 @@
+
+// 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: branches/release/boost/coroutine/coroutine.hpp
==============================================================================
--- branches/release/boost/coroutine/coroutine.hpp (original)
+++ branches/release/boost/coroutine/coroutine.hpp 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -7,1423 +7,10 @@
#ifndef BOOST_COROUTINES_COROUTINE_H
#define BOOST_COROUTINES_COROUTINE_H
-#include <cstddef>
-#include <memory>
-
-#include <boost/assert.hpp>
-#include <boost/config.hpp>
-#include <boost/move/move.hpp>
-#include <boost/range.hpp>
-#include <boost/static_assert.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/utility/result_of.hpp>
-
-#include <boost/coroutine/attributes.hpp>
-#include <boost/coroutine/detail/arg.hpp>
-#include <boost/coroutine/detail/coroutine_context.hpp>
-#include <boost/coroutine/detail/coroutine_base.hpp>
-#include <boost/coroutine/detail/coroutine_get.hpp>
-#include <boost/coroutine/detail/coroutine_object.hpp>
-#include <boost/coroutine/detail/coroutine_op.hpp>
-#include <boost/coroutine/detail/coroutine_caller.hpp>
-#include <boost/coroutine/stack_allocator.hpp>
-
-#ifdef BOOST_HAS_ABI_HEADERS
-# include BOOST_ABI_PREFIX
-#endif
-
-namespace boost {
-namespace coroutines {
-namespace detail {
-
-template<
- typename Signature,
- template< class, int > class C,
- typename Result = typename function_traits< Signature >::result_type,
- int arity = function_traits< Signature >::arity
->
-struct caller;
-
-template<
- typename Signature,
- template< class, int > class C
->
-struct caller< Signature, C, void, 0 >
-{ typedef C< void(), 0 > type; };
-
-template<
- typename Signature,
- template< class, int > class C,
- typename Result
->
-struct caller< Signature, C, Result, 0 >
-{ typedef C< void( Result), 1 > type; };
-
-template<
- typename Signature,
- template< class, int > class C,
- int arity
->
-struct caller< Signature, C, void, arity >
-{ typedef C< typename detail::arg< Signature >::type(), 0 > type; };
-
-template<
- typename Signature,
- template< class, int > class C,
- typename Result, int arity
->
-struct caller
-{ typedef C< typename detail::arg< Signature >::type( Result), 1 > type; };
-
-}
-
-template< typename Signature, int arity = function_traits< Signature >::arity >
-class coroutine;
-
-template< typename Signature >
-class coroutine< Signature, 0 > : public detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >,
- public detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >
-{
-private:
- typedef detail::coroutine_base< Signature > base_t;
- typedef typename base_t::ptr_t ptr_t;
-
- template< typename X, typename Y, int >
- friend struct detail::coroutine_get;
- template< typename X, typename Y, typename Z, int >
- friend struct detail::coroutine_op;
- template< typename X, typename Y, typename Z, typename A, typename B, typename C, int >
- friend class detail::coroutine_object;
-
- struct dummy
- { void nonnull() {} };
-
- typedef void ( dummy::*safe_bool)();
-
- ptr_t impl_;
-
- BOOST_MOVABLE_BUT_NOT_COPYABLE( coroutine)
-
- template< typename Allocator >
- coroutine( detail::coroutine_context const& callee,
- bool unwind, bool preserve_fpu,
- Allocator const& alloc) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
-
- >(),
- impl_()
- {
- typedef detail::coroutine_caller<
- Signature, Allocator
- > caller_t;
- typename caller_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) caller_t(
- callee, unwind, preserve_fpu, a) );
- }
-
-public:
- typedef typename detail::caller<
- Signature,
- boost::coroutines::coroutine
- >::type caller_type;
-
- coroutine() BOOST_NOEXCEPT :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {}
-
-#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
-#ifdef BOOST_MSVC
- typedef void ( * coroutine_fn) ( caller_type &);
-
- explicit coroutine( coroutine_fn fn, attributes const& attr = attributes(),
- stack_allocator const& stack_alloc =
- stack_allocator(),
- std::allocator< coroutine > const& alloc =
- std::allocator< coroutine >() ) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
- typedef detail::coroutine_object<
- Signature,
- coroutine_fn, stack_allocator, std::allocator< coroutine >,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) );
- }
-
- template< typename StackAllocator >
- explicit coroutine( coroutine_fn fn, attributes const& attr,
- StackAllocator const& stack_alloc,
- std::allocator< coroutine > const& alloc =
- std::allocator< coroutine >() ) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
- typedef detail::coroutine_object<
- Signature,
- coroutine_fn, StackAllocator, std::allocator< coroutine >,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) );
- }
-
- template< typename StackAllocator, typename Allocator >
- explicit coroutine( coroutine_fn fn, attributes const& attr,
- StackAllocator const& stack_alloc,
- Allocator const& alloc) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
- typedef detail::coroutine_object<
- Signature,
- coroutine_fn, StackAllocator, Allocator,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) );
- }
-#endif
- template< typename Fn >
- explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(),
- stack_allocator const& stack_alloc =
- stack_allocator(),
- std::allocator< coroutine > const& alloc =
- std::allocator< coroutine >(),
- typename disable_if<
- is_same< typename decay< Fn >::type, coroutine >,
- dummy *
- >::type = 0) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
-// BOOST_STATIC_ASSERT((
-// is_same< void, typename result_of< Fn() >::type >::value));
- typedef detail::coroutine_object<
- Signature,
- Fn, stack_allocator, std::allocator< coroutine >,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) );
- }
-
- template< typename Fn, typename StackAllocator >
- explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr,
- StackAllocator const& stack_alloc,
- std::allocator< coroutine > const& alloc =
- std::allocator< coroutine >(),
- typename disable_if<
- is_same< typename decay< Fn >::type, coroutine >,
- dummy *
- >::type = 0) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
-// BOOST_STATIC_ASSERT((
-// is_same< void, typename result_of< Fn() >::type >::value));
- typedef detail::coroutine_object<
- Signature,
- Fn, StackAllocator, std::allocator< coroutine >,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) );
- }
-
- template< typename Fn, typename StackAllocator, typename Allocator >
- explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr,
- StackAllocator const& stack_alloc,
- Allocator const& alloc,
- typename disable_if<
- is_same< typename decay< Fn >::type, coroutine >,
- dummy *
- >::type = 0) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
-// BOOST_STATIC_ASSERT((
-// is_same< void, typename result_of< Fn() >::type >::value));
- typedef detail::coroutine_object<
- Signature,
- Fn, StackAllocator, Allocator,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) );
- }
+#ifdef BOOST_COROUTINES_V2
+#include <boost/coroutine/v2/coroutine.hpp>
#else
- template< typename Fn >
- explicit coroutine( Fn fn, attributes const& attr = attributes(),
- stack_allocator const& stack_alloc =
- stack_allocator(),
- std::allocator< coroutine > const& alloc =
- std::allocator< coroutine >(),
- typename disable_if<
- is_convertible< Fn &, BOOST_RV_REF( Fn) >,
- dummy *
- >::type = 0) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
-// BOOST_STATIC_ASSERT((
-// is_same< void, typename result_of< Fn() >::type >::value));
- typedef detail::coroutine_object<
- Signature,
- Fn, stack_allocator, std::allocator< coroutine >,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
- }
-
- template< typename Fn, typename StackAllocator >
- explicit coroutine( Fn fn, attributes const& attr,
- StackAllocator const& stack_alloc,
- std::allocator< coroutine > const& alloc =
- std::allocator< coroutine >(),
- typename disable_if<
- is_convertible< Fn &, BOOST_RV_REF( Fn) >,
- dummy *
- >::type = 0) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
-// BOOST_STATIC_ASSERT((
-// is_same< void, typename result_of< Fn() >::type >::value));
- typedef detail::coroutine_object<
- Signature,
- Fn, StackAllocator, std::allocator< coroutine >,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
- }
-
- template< typename Fn, typename StackAllocator, typename Allocator >
- explicit coroutine( Fn fn, attributes const& attr,
- StackAllocator const& stack_alloc,
- Allocator const& alloc,
- typename disable_if<
- is_convertible< Fn &, BOOST_RV_REF( Fn) >,
- dummy *
- >::type = 0) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
-// BOOST_STATIC_ASSERT((
-// is_same< void, typename result_of< Fn() >::type >::value));
- typedef detail::coroutine_object<
- Signature,
- Fn, StackAllocator, Allocator,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
- }
-
- template< typename Fn >
- explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(),
- stack_allocator const& stack_alloc =
- stack_allocator(),
- std::allocator< coroutine > const& alloc =
- std::allocator< coroutine >(),
- typename disable_if<
- is_same< typename decay< Fn >::type, coroutine >,
- dummy *
- >::type = 0) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
-// BOOST_STATIC_ASSERT((
-// is_same< void, typename result_of< Fn() >::type >::value));
- typedef detail::coroutine_object<
- Signature,
- Fn, stack_allocator, std::allocator< coroutine >,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
- }
-
- template< typename Fn, typename StackAllocator >
- explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr,
- StackAllocator const& stack_alloc,
- std::allocator< coroutine > const& alloc =
- std::allocator< coroutine >(),
- typename disable_if<
- is_same< typename decay< Fn >::type, coroutine >,
- dummy *
- >::type = 0) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
-// BOOST_STATIC_ASSERT((
-// is_same< void, typename result_of< Fn() >::type >::value));
- typedef detail::coroutine_object<
- Signature,
- Fn, StackAllocator, std::allocator< coroutine >,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
- }
-
- template< typename Fn, typename StackAllocator, typename Allocator >
- explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr,
- StackAllocator const& stack_alloc,
- Allocator const& alloc,
- typename disable_if<
- is_same< typename decay< Fn >::type, coroutine >,
- dummy *
- >::type = 0) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
-// BOOST_STATIC_ASSERT((
-// is_same< void, typename result_of< Fn() >::type >::value));
- typedef detail::coroutine_object<
- Signature,
- Fn, StackAllocator, Allocator,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
- }
-#endif
-
- coroutine( BOOST_RV_REF( coroutine) other) BOOST_NOEXCEPT :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- { swap( other); }
-
- coroutine & operator=( BOOST_RV_REF( coroutine) other) BOOST_NOEXCEPT
- {
- coroutine tmp( boost::move( other) );
- swap( tmp);
- return * this;
- }
-
- bool empty() const BOOST_NOEXCEPT
- { return ! impl_; }
-
- operator safe_bool() const BOOST_NOEXCEPT
- { return ( empty() || impl_->is_complete() ) ? 0 : & dummy::nonnull; }
-
- bool operator!() const BOOST_NOEXCEPT
- { return empty() || impl_->is_complete(); }
-
- void swap( coroutine & other) BOOST_NOEXCEPT
- { impl_.swap( other.impl_); }
-};
-
-template< typename Signature, int arity >
-class coroutine : public detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >,
- public detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >
-{
-private:
- typedef detail::coroutine_base< Signature > base_t;
- typedef typename base_t::ptr_t ptr_t;
-
- template< typename X, typename Y, int >
- friend struct detail::coroutine_get;
- template< typename X, typename Y, typename Z, int >
- friend struct detail::coroutine_op;
- template< typename X, typename Y, typename Z, typename A, typename B, typename C, int >
- friend class detail::coroutine_object;
-
- struct dummy
- { void nonnull() {} };
-
- typedef void ( dummy::*safe_bool)();
-
- ptr_t impl_;
-
- BOOST_MOVABLE_BUT_NOT_COPYABLE( coroutine)
-
- template< typename Allocator >
- coroutine( detail::coroutine_context const& callee,
- bool unwind, bool preserve_fpu,
- Allocator const& alloc) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
- typedef detail::coroutine_caller<
- Signature, Allocator
- > caller_t;
- typename caller_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) caller_t(
- callee, unwind, preserve_fpu, a) );
- }
-
-public:
- typedef typename detail::caller<
- Signature,
- boost::coroutines::coroutine
- >::type caller_type;
- typedef typename detail::arg< Signature >::type arguments;
-
- coroutine() BOOST_NOEXCEPT :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {}
-
-#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
-#ifdef BOOST_MSVC
- typedef void ( * coroutine_fn) ( caller_type &);
-
- explicit coroutine( coroutine_fn fn, attributes const& attr = attributes(),
- stack_allocator const& stack_alloc =
- stack_allocator(),
- std::allocator< coroutine > const& alloc =
- std::allocator< coroutine >() ) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
- typedef detail::coroutine_object<
- Signature,
- coroutine_fn, stack_allocator, std::allocator< coroutine >,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) );
- }
-
- explicit coroutine( coroutine_fn fn, arguments arg, attributes const& attr = attributes(),
- stack_allocator const& stack_alloc =
- stack_allocator(),
- std::allocator< coroutine > const& alloc =
- std::allocator< coroutine >() ) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
- typedef detail::coroutine_object<
- Signature,
- coroutine_fn, stack_allocator, std::allocator< coroutine >,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), arg, attr, stack_alloc, a) );
- }
-
- template< typename StackAllocator >
- explicit coroutine( coroutine_fn fn, attributes const& attr,
- StackAllocator const& stack_alloc,
- std::allocator< coroutine > const& alloc =
- std::allocator< coroutine >() ) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
- typedef detail::coroutine_object<
- Signature,
- coroutine_fn, StackAllocator, std::allocator< coroutine >,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) );
- }
-
- template< typename StackAllocator, typename Allocator >
- explicit coroutine( coroutine_fn fn, attributes const& attr,
- StackAllocator const& stack_alloc,
- Allocator const& alloc) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
- typedef detail::coroutine_object<
- Signature,
- coroutine_fn, StackAllocator, Allocator,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) );
- }
-#endif
- template< typename Fn >
- explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(),
- stack_allocator const& stack_alloc =
- stack_allocator(),
- std::allocator< coroutine > const& alloc =
- std::allocator< coroutine >(),
- typename disable_if<
- is_same< typename decay< Fn >::type, coroutine >,
- dummy *
- >::type = 0) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
-// BOOST_STATIC_ASSERT((
-// is_same< void, typename result_of< Fn() >::type >::value));
- typedef detail::coroutine_object<
- Signature,
- Fn, stack_allocator, std::allocator< coroutine >,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) );
- }
-
- template< typename Fn >
- explicit coroutine( BOOST_RV_REF( Fn) fn, arguments arg, attributes const& attr = attributes(),
- stack_allocator const& stack_alloc =
- stack_allocator(),
- std::allocator< coroutine > const& alloc =
- std::allocator< coroutine >(),
- typename disable_if<
- is_same< typename decay< Fn >::type, coroutine >,
- dummy *
- >::type = 0) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
-// BOOST_STATIC_ASSERT((
-// is_same< void, typename result_of< Fn() >::type >::value));
- typedef detail::coroutine_object<
- Signature,
- Fn, stack_allocator, std::allocator< coroutine >,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), arg, attr, stack_alloc, a) );
- }
-
- template< typename Fn, typename StackAllocator >
- explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr,
- StackAllocator const& stack_alloc,
- std::allocator< coroutine > const& alloc =
- std::allocator< coroutine >(),
- typename disable_if<
- is_same< typename decay< Fn >::type, coroutine >,
- dummy *
- >::type = 0) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
-// BOOST_STATIC_ASSERT((
-// is_same< void, typename result_of< Fn() >::type >::value));
- typedef detail::coroutine_object<
- Signature,
- Fn, StackAllocator, std::allocator< coroutine >,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) );
- }
-
- template< typename Fn, typename StackAllocator >
- explicit coroutine( BOOST_RV_REF( Fn) fn, arguments arg, attributes const& attr,
- StackAllocator const& stack_alloc,
- std::allocator< coroutine > const& alloc =
- std::allocator< coroutine >(),
- typename disable_if<
- is_same< typename decay< Fn >::type, coroutine >,
- dummy *
- >::type = 0) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
-// BOOST_STATIC_ASSERT((
-// is_same< void, typename result_of< Fn() >::type >::value));
- typedef detail::coroutine_object<
- Signature,
- Fn, StackAllocator, std::allocator< coroutine >,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), arg, attr, stack_alloc, a) );
- }
-
- template< typename Fn, typename StackAllocator, typename Allocator >
- explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr,
- StackAllocator const& stack_alloc,
- Allocator const& alloc,
- typename disable_if<
- is_same< typename decay< Fn >::type, coroutine >,
- dummy *
- >::type = 0) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
-// BOOST_STATIC_ASSERT((
-// is_same< void, typename result_of< Fn() >::type >::value));
- typedef detail::coroutine_object<
- Signature,
- Fn, StackAllocator, Allocator,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) );
- }
-
- template< typename Fn, typename StackAllocator, typename Allocator >
- explicit coroutine( BOOST_RV_REF( Fn) fn, arguments arg, attributes const& attr,
- StackAllocator const& stack_alloc,
- Allocator const& alloc,
- typename disable_if<
- is_same< typename decay< Fn >::type, coroutine >,
- dummy *
- >::type = 0) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
-// BOOST_STATIC_ASSERT((
-// is_same< void, typename result_of< Fn() >::type >::value));
- typedef detail::coroutine_object<
- Signature,
- Fn, StackAllocator, Allocator,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), arg, attr, stack_alloc, a) );
- }
-#else
- template< typename Fn >
- explicit coroutine( Fn fn, attributes const& attr = attributes(),
- stack_allocator const& stack_alloc =
- stack_allocator(),
- std::allocator< coroutine > const& alloc =
- std::allocator< coroutine >(),
- typename disable_if<
- is_convertible< Fn &, BOOST_RV_REF( Fn) >,
- dummy *
- >::type = 0) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
-// BOOST_STATIC_ASSERT((
-// is_same< void, typename result_of< Fn() >::type >::value));
- typedef detail::coroutine_object<
- Signature,
- Fn, stack_allocator, std::allocator< coroutine >,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
- }
-
- template< typename Fn >
- explicit coroutine( Fn fn, arguments arg, attributes const& attr = attributes(),
- stack_allocator const& stack_alloc =
- stack_allocator(),
- std::allocator< coroutine > const& alloc =
- std::allocator< coroutine >(),
- typename disable_if<
- is_convertible< Fn &, BOOST_RV_REF( Fn) >,
- dummy *
- >::type = 0) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
-// BOOST_STATIC_ASSERT((
-// is_same< void, typename result_of< Fn() >::type >::value));
- typedef detail::coroutine_object<
- Signature,
- Fn, stack_allocator, std::allocator< coroutine >,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( fn, arg, attr, stack_alloc, a) );
- }
-
- template< typename Fn, typename StackAllocator >
- explicit coroutine( Fn fn, attributes const& attr,
- StackAllocator const& stack_alloc,
- std::allocator< coroutine > const& alloc =
- std::allocator< coroutine >(),
- typename disable_if<
- is_convertible< Fn &, BOOST_RV_REF( Fn) >,
- dummy *
- >::type = 0) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
-// BOOST_STATIC_ASSERT((
-// is_same< void, typename result_of< Fn() >::type >::value));
- typedef detail::coroutine_object<
- Signature,
- Fn, StackAllocator, std::allocator< coroutine >,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
- }
-
- template< typename Fn, typename StackAllocator, typename Allocator >
- explicit coroutine( Fn fn, attributes const& attr,
- StackAllocator const& stack_alloc,
- Allocator const& alloc,
- typename disable_if<
- is_convertible< Fn &, BOOST_RV_REF( Fn) >,
- dummy *
- >::type = 0) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
-// BOOST_STATIC_ASSERT((
-// is_same< void, typename result_of< Fn() >::type >::value));
- typedef detail::coroutine_object<
- Signature,
- Fn, StackAllocator, Allocator,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
- }
-
- template< typename Fn >
- explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(),
- stack_allocator const& stack_alloc =
- stack_allocator(),
- std::allocator< coroutine > const& alloc =
- std::allocator< coroutine >(),
- typename disable_if<
- is_same< typename decay< Fn >::type, coroutine >,
- dummy *
- >::type = 0) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
-// BOOST_STATIC_ASSERT((
-// is_same< void, typename result_of< Fn() >::type >::value));
- typedef detail::coroutine_object<
- Signature,
- Fn, stack_allocator, std::allocator< coroutine >,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
- }
-
- template< typename Fn, typename StackAllocator >
- explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr,
- StackAllocator const& stack_alloc,
- std::allocator< coroutine > const& alloc =
- std::allocator< coroutine >(),
- typename disable_if<
- is_same< typename decay< Fn >::type, coroutine >,
- dummy *
- >::type = 0) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
-// BOOST_STATIC_ASSERT((
-// is_same< void, typename result_of< Fn() >::type >::value));
- typedef detail::coroutine_object<
- Signature,
- Fn, StackAllocator, std::allocator< coroutine >,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
- }
-
- template< typename Fn, typename StackAllocator, typename Allocator >
- explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr,
- StackAllocator const& stack_alloc,
- Allocator const& alloc,
- typename disable_if<
- is_same< typename decay< Fn >::type, coroutine >,
- dummy *
- >::type = 0) :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- {
-// BOOST_STATIC_ASSERT((
-// is_same< void, typename result_of< Fn() >::type >::value));
- typedef detail::coroutine_object<
- Signature,
- Fn, StackAllocator, Allocator,
- caller_type,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- > object_t;
- typename object_t::allocator_t a( alloc);
- impl_ = ptr_t(
- // placement new
- ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
- }
-#endif
-
- coroutine( BOOST_RV_REF( coroutine) other) BOOST_NOEXCEPT :
- detail::coroutine_op<
- Signature,
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- detail::coroutine_get<
- coroutine< Signature >,
- typename function_traits< Signature >::result_type,
- function_traits< Signature >::arity
- >(),
- impl_()
- { swap( other); }
-
- coroutine & operator=( BOOST_RV_REF( coroutine) other) BOOST_NOEXCEPT
- {
- coroutine tmp( boost::move( other) );
- swap( tmp);
- return * this;
- }
-
- bool empty() const BOOST_NOEXCEPT
- { return ! impl_; }
-
- operator safe_bool() const BOOST_NOEXCEPT
- { return ( empty() || impl_->is_complete() ) ? 0 : & dummy::nonnull; }
-
- bool operator!() const BOOST_NOEXCEPT
- { return empty() || impl_->is_complete(); }
-
- void swap( coroutine & other) BOOST_NOEXCEPT
- { impl_.swap( other.impl_); }
-};
-
-template< typename Signature >
-void swap( coroutine< Signature > & l, coroutine< Signature > & r) BOOST_NOEXCEPT
-{ l.swap( r); }
-
-template< typename Signature >
-inline
-typename coroutine< Signature >::iterator
-range_begin( coroutine< Signature > & c)
-{ return typename coroutine< Signature >::iterator( & c); }
-
-template< typename Signature >
-inline
-typename coroutine< Signature >::const_iterator
-range_begin( coroutine< Signature > const& c)
-{ return typename coroutine< Signature >::const_iterator( & c); }
-
-template< typename Signature >
-inline
-typename coroutine< Signature >::iterator
-range_end( coroutine< Signature > &)
-{ return typename coroutine< Signature >::iterator(); }
-
-template< typename Signature >
-inline
-typename coroutine< Signature >::const_iterator
-range_end( coroutine< Signature > const&)
-{ return typename coroutine< Signature >::const_iterator(); }
-
-template< typename Signature >
-inline
-typename coroutine< Signature >::iterator
-begin( coroutine< Signature > & c)
-{ return boost::begin( c); }
-
-template< typename Signature >
-inline
-typename coroutine< Signature >::iterator
-end( coroutine< Signature > & c)
-{ return boost::end( c); }
-
-template< typename Signature >
-inline
-typename coroutine< Signature >::const_iterator
-begin( coroutine< Signature > const& c)
-{ return boost::const_begin( c); }
-
-template< typename Signature >
-inline
-typename coroutine< Signature >::const_iterator
-end( coroutine< Signature > const& c)
-{ return boost::const_end( c); }
-
-}
-
-template< typename Signature >
-struct range_mutable_iterator< coroutines::coroutine< Signature > >
-{ typedef typename coroutines::coroutine< Signature >::iterator type; };
-
-template< typename Signature >
-struct range_const_iterator< coroutines::coroutine< Signature > >
-{ typedef typename coroutines::coroutine< Signature >::const_iterator type; };
-
-}
-
-#ifdef BOOST_HAS_ABI_HEADERS
-# include BOOST_ABI_SUFFIX
+#include <boost/coroutine/v1/coroutine.hpp>
#endif
#endif // BOOST_COROUTINES_COROUTINE_H
Modified: branches/release/boost/coroutine/detail/config.hpp
==============================================================================
--- branches/release/boost/coroutine/detail/config.hpp (original)
+++ branches/release/boost/coroutine/detail/config.hpp 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -46,4 +46,8 @@
# define BOOST_COROUTINES_SEGMENTS 10
#endif
+//#ifndef BOOST_COROUTINES_V1
+//# define BOOST_COROUTINES_V2
+//#endif
+
#endif // BOOST_COROUTINES_DETAIL_CONFIG_H
Modified: branches/release/boost/coroutine/detail/coroutine_context.hpp
==============================================================================
--- branches/release/boost/coroutine/detail/coroutine_context.hpp (original)
+++ branches/release/boost/coroutine/detail/coroutine_context.hpp 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -12,7 +12,6 @@
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/context/fcontext.hpp>
-#include <boost/utility.hpp>
#include <boost/coroutine/detail/config.hpp>
#include "boost/coroutine/stack_context.hpp"
@@ -31,8 +30,7 @@
namespace detail {
-class BOOST_COROUTINES_DECL coroutine_context : private noncopyable,
- private context::fcontext_t,
+class BOOST_COROUTINES_DECL coroutine_context : private context::fcontext_t,
private stack_context
{
Modified: branches/release/boost/coroutine/detail/segmented_stack_allocator.hpp
==============================================================================
--- branches/release/boost/coroutine/detail/segmented_stack_allocator.hpp (original)
+++ branches/release/boost/coroutine/detail/segmented_stack_allocator.hpp 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -36,7 +36,7 @@
static std::size_t maximum_stacksize();
- void allocate( stack_context &, std::size_t size);
+ void allocate( stack_context &, std::size_t = minimum_stacksize() );
void deallocate( stack_context &);
};
Added: branches/release/boost/coroutine/v1/coroutine.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/coroutine/v1/coroutine.hpp 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -0,0 +1,1430 @@
+
+// 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_V1_COROUTINE_H
+#define BOOST_COROUTINES_V1_COROUTINE_H
+
+#include <cstddef>
+#include <memory>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+#include <boost/move/move.hpp>
+#include <boost/range.hpp>
+#include <boost/static_assert.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/utility/result_of.hpp>
+
+#include <boost/coroutine/attributes.hpp>
+#include <boost/coroutine/detail/config.hpp>
+#include <boost/coroutine/detail/coroutine_context.hpp>
+#include <boost/coroutine/stack_allocator.hpp>
+#include <boost/coroutine/v1/detail/arg.hpp>
+#include <boost/coroutine/v1/detail/coroutine_base.hpp>
+#include <boost/coroutine/v1/detail/coroutine_caller.hpp>
+#include <boost/coroutine/v1/detail/coroutine_get.hpp>
+#include <boost/coroutine/v1/detail/coroutine_object.hpp>
+#include <boost/coroutine/v1/detail/coroutine_op.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+namespace detail {
+
+template<
+ typename Signature,
+ template< class, int > class C,
+ typename Result = typename function_traits< Signature >::result_type,
+ int arity = function_traits< Signature >::arity
+>
+struct caller;
+
+template<
+ typename Signature,
+ template< class, int > class C
+>
+struct caller< Signature, C, void, 0 >
+{ typedef C< void(), 0 > type; };
+
+template<
+ typename Signature,
+ template< class, int > class C,
+ typename Result
+>
+struct caller< Signature, C, Result, 0 >
+{ typedef C< void( Result), 1 > type; };
+
+template<
+ typename Signature,
+ template< class, int > class C,
+ int arity
+>
+struct caller< Signature, C, void, arity >
+{ typedef C< typename detail::arg< Signature >::type(), 0 > type; };
+
+template<
+ typename Signature,
+ template< class, int > class C,
+ typename Result, int arity
+>
+struct caller
+{ typedef C< typename detail::arg< Signature >::type( Result), 1 > type; };
+
+}
+
+template< typename Signature, int arity = function_traits< Signature >::arity >
+class coroutine;
+
+template< typename Signature >
+class coroutine< Signature, 0 > : public detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >,
+ public detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >
+{
+private:
+ typedef detail::coroutine_base< Signature > base_t;
+ typedef typename base_t::ptr_t ptr_t;
+
+ template< typename X, typename Y, int >
+ friend struct detail::coroutine_get;
+ template< typename X, typename Y, typename Z, int >
+ friend struct detail::coroutine_op;
+ template< typename X, typename Y, typename Z, typename A, typename B, typename C, int >
+ friend class detail::coroutine_object;
+
+ struct dummy
+ { void nonnull() {} };
+
+ typedef void ( dummy::*safe_bool)();
+
+ ptr_t impl_;
+
+ BOOST_MOVABLE_BUT_NOT_COPYABLE( coroutine)
+
+ template< typename Allocator >
+ coroutine( detail::coroutine_context const& callee,
+ bool unwind, bool preserve_fpu,
+ Allocator const& alloc) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+
+ >(),
+ impl_()
+ {
+ typedef detail::coroutine_caller<
+ Signature, Allocator
+ > caller_t;
+ typename caller_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) caller_t(
+ callee, unwind, preserve_fpu, a) );
+ }
+
+public:
+ typedef typename detail::caller<
+ Signature,
+ boost::coroutines::coroutine
+ >::type caller_type;
+
+ coroutine() BOOST_NOEXCEPT :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {}
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+#ifdef BOOST_MSVC
+ typedef void ( * coroutine_fn) ( caller_type &);
+
+ explicit coroutine( coroutine_fn fn, attributes const& attr = attributes(),
+ stack_allocator const& stack_alloc =
+ stack_allocator(),
+ std::allocator< coroutine > const& alloc =
+ std::allocator< coroutine >() ) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+ typedef detail::coroutine_object<
+ Signature,
+ coroutine_fn, stack_allocator, std::allocator< coroutine >,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) );
+ }
+
+ template< typename StackAllocator >
+ explicit coroutine( coroutine_fn fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ std::allocator< coroutine > const& alloc =
+ std::allocator< coroutine >() ) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+ typedef detail::coroutine_object<
+ Signature,
+ coroutine_fn, StackAllocator, std::allocator< coroutine >,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) );
+ }
+
+ template< typename StackAllocator, typename Allocator >
+ explicit coroutine( coroutine_fn fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ Allocator const& alloc) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+ typedef detail::coroutine_object<
+ Signature,
+ coroutine_fn, StackAllocator, Allocator,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) );
+ }
+#endif
+ template< typename Fn >
+ explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(),
+ stack_allocator const& stack_alloc =
+ stack_allocator(),
+ std::allocator< coroutine > const& alloc =
+ std::allocator< coroutine >(),
+ typename disable_if<
+ is_same< typename decay< Fn >::type, coroutine >,
+ dummy *
+ >::type = 0) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+// BOOST_STATIC_ASSERT((
+// is_same< void, typename result_of< Fn() >::type >::value));
+ typedef detail::coroutine_object<
+ Signature,
+ Fn, stack_allocator, std::allocator< coroutine >,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) );
+ }
+
+ template< typename Fn, typename StackAllocator >
+ explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ std::allocator< coroutine > const& alloc =
+ std::allocator< coroutine >(),
+ typename disable_if<
+ is_same< typename decay< Fn >::type, coroutine >,
+ dummy *
+ >::type = 0) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+// BOOST_STATIC_ASSERT((
+// is_same< void, typename result_of< Fn() >::type >::value));
+ typedef detail::coroutine_object<
+ Signature,
+ Fn, StackAllocator, std::allocator< coroutine >,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) );
+ }
+
+ template< typename Fn, typename StackAllocator, typename Allocator >
+ explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ Allocator const& alloc,
+ typename disable_if<
+ is_same< typename decay< Fn >::type, coroutine >,
+ dummy *
+ >::type = 0) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+// BOOST_STATIC_ASSERT((
+// is_same< void, typename result_of< Fn() >::type >::value));
+ typedef detail::coroutine_object<
+ Signature,
+ Fn, StackAllocator, Allocator,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) );
+ }
+#else
+ template< typename Fn >
+ explicit coroutine( Fn fn, attributes const& attr = attributes(),
+ stack_allocator const& stack_alloc =
+ stack_allocator(),
+ std::allocator< coroutine > const& alloc =
+ std::allocator< coroutine >(),
+ typename disable_if<
+ is_convertible< Fn &, BOOST_RV_REF( Fn) >,
+ dummy *
+ >::type = 0) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+// BOOST_STATIC_ASSERT((
+// is_same< void, typename result_of< Fn() >::type >::value));
+ typedef detail::coroutine_object<
+ Signature,
+ Fn, stack_allocator, std::allocator< coroutine >,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
+ }
+
+ template< typename Fn, typename StackAllocator >
+ explicit coroutine( Fn fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ std::allocator< coroutine > const& alloc =
+ std::allocator< coroutine >(),
+ typename disable_if<
+ is_convertible< Fn &, BOOST_RV_REF( Fn) >,
+ dummy *
+ >::type = 0) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+// BOOST_STATIC_ASSERT((
+// is_same< void, typename result_of< Fn() >::type >::value));
+ typedef detail::coroutine_object<
+ Signature,
+ Fn, StackAllocator, std::allocator< coroutine >,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
+ }
+
+ template< typename Fn, typename StackAllocator, typename Allocator >
+ explicit coroutine( Fn fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ Allocator const& alloc,
+ typename disable_if<
+ is_convertible< Fn &, BOOST_RV_REF( Fn) >,
+ dummy *
+ >::type = 0) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+// BOOST_STATIC_ASSERT((
+// is_same< void, typename result_of< Fn() >::type >::value));
+ typedef detail::coroutine_object<
+ Signature,
+ Fn, StackAllocator, Allocator,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
+ }
+
+ template< typename Fn >
+ explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(),
+ stack_allocator const& stack_alloc =
+ stack_allocator(),
+ std::allocator< coroutine > const& alloc =
+ std::allocator< coroutine >(),
+ typename disable_if<
+ is_same< typename decay< Fn >::type, coroutine >,
+ dummy *
+ >::type = 0) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+// BOOST_STATIC_ASSERT((
+// is_same< void, typename result_of< Fn() >::type >::value));
+ typedef detail::coroutine_object<
+ Signature,
+ Fn, stack_allocator, std::allocator< coroutine >,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
+ }
+
+ template< typename Fn, typename StackAllocator >
+ explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ std::allocator< coroutine > const& alloc =
+ std::allocator< coroutine >(),
+ typename disable_if<
+ is_same< typename decay< Fn >::type, coroutine >,
+ dummy *
+ >::type = 0) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+// BOOST_STATIC_ASSERT((
+// is_same< void, typename result_of< Fn() >::type >::value));
+ typedef detail::coroutine_object<
+ Signature,
+ Fn, StackAllocator, std::allocator< coroutine >,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
+ }
+
+ template< typename Fn, typename StackAllocator, typename Allocator >
+ explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ Allocator const& alloc,
+ typename disable_if<
+ is_same< typename decay< Fn >::type, coroutine >,
+ dummy *
+ >::type = 0) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+// BOOST_STATIC_ASSERT((
+// is_same< void, typename result_of< Fn() >::type >::value));
+ typedef detail::coroutine_object<
+ Signature,
+ Fn, StackAllocator, Allocator,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
+ }
+#endif
+
+ coroutine( BOOST_RV_REF( coroutine) other) BOOST_NOEXCEPT :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ { swap( other); }
+
+ coroutine & operator=( BOOST_RV_REF( coroutine) other) BOOST_NOEXCEPT
+ {
+ coroutine tmp( boost::move( other) );
+ swap( tmp);
+ return * this;
+ }
+
+ bool empty() const BOOST_NOEXCEPT
+ { return ! impl_; }
+
+ operator safe_bool() const BOOST_NOEXCEPT
+ { return ( empty() || impl_->is_complete() ) ? 0 : & dummy::nonnull; }
+
+ bool operator!() const BOOST_NOEXCEPT
+ { return empty() || impl_->is_complete(); }
+
+ void swap( coroutine & other) BOOST_NOEXCEPT
+ { impl_.swap( other.impl_); }
+};
+
+template< typename Signature, int arity >
+class coroutine : public detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >,
+ public detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >
+{
+private:
+ typedef detail::coroutine_base< Signature > base_t;
+ typedef typename base_t::ptr_t ptr_t;
+
+ template< typename X, typename Y, int >
+ friend struct detail::coroutine_get;
+ template< typename X, typename Y, typename Z, int >
+ friend struct detail::coroutine_op;
+ template< typename X, typename Y, typename Z, typename A, typename B, typename C, int >
+ friend class detail::coroutine_object;
+
+ struct dummy
+ { void nonnull() {} };
+
+ typedef void ( dummy::*safe_bool)();
+
+ ptr_t impl_;
+
+ BOOST_MOVABLE_BUT_NOT_COPYABLE( coroutine)
+
+ template< typename Allocator >
+ coroutine( detail::coroutine_context const& callee,
+ bool unwind, bool preserve_fpu,
+ Allocator const& alloc) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+ typedef detail::coroutine_caller<
+ Signature, Allocator
+ > caller_t;
+ typename caller_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) caller_t(
+ callee, unwind, preserve_fpu, a) );
+ }
+
+public:
+ typedef typename detail::caller<
+ Signature,
+ boost::coroutines::coroutine
+ >::type caller_type;
+ typedef typename detail::arg< Signature >::type arguments;
+
+ coroutine() BOOST_NOEXCEPT :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {}
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+#ifdef BOOST_MSVC
+ typedef void ( * coroutine_fn) ( caller_type &);
+
+ explicit coroutine( coroutine_fn fn, attributes const& attr = attributes(),
+ stack_allocator const& stack_alloc =
+ stack_allocator(),
+ std::allocator< coroutine > const& alloc =
+ std::allocator< coroutine >() ) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+ typedef detail::coroutine_object<
+ Signature,
+ coroutine_fn, stack_allocator, std::allocator< coroutine >,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) );
+ }
+
+ explicit coroutine( coroutine_fn fn, arguments arg, attributes const& attr = attributes(),
+ stack_allocator const& stack_alloc =
+ stack_allocator(),
+ std::allocator< coroutine > const& alloc =
+ std::allocator< coroutine >() ) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+ typedef detail::coroutine_object<
+ Signature,
+ coroutine_fn, stack_allocator, std::allocator< coroutine >,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), arg, attr, stack_alloc, a) );
+ }
+
+ template< typename StackAllocator >
+ explicit coroutine( coroutine_fn fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ std::allocator< coroutine > const& alloc =
+ std::allocator< coroutine >() ) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+ typedef detail::coroutine_object<
+ Signature,
+ coroutine_fn, StackAllocator, std::allocator< coroutine >,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) );
+ }
+
+ template< typename StackAllocator, typename Allocator >
+ explicit coroutine( coroutine_fn fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ Allocator const& alloc) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+ typedef detail::coroutine_object<
+ Signature,
+ coroutine_fn, StackAllocator, Allocator,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) );
+ }
+#endif
+ template< typename Fn >
+ explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(),
+ stack_allocator const& stack_alloc =
+ stack_allocator(),
+ std::allocator< coroutine > const& alloc =
+ std::allocator< coroutine >(),
+ typename disable_if<
+ is_same< typename decay< Fn >::type, coroutine >,
+ dummy *
+ >::type = 0) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+// BOOST_STATIC_ASSERT((
+// is_same< void, typename result_of< Fn() >::type >::value));
+ typedef detail::coroutine_object<
+ Signature,
+ Fn, stack_allocator, std::allocator< coroutine >,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) );
+ }
+
+ template< typename Fn >
+ explicit coroutine( BOOST_RV_REF( Fn) fn, arguments arg, attributes const& attr = attributes(),
+ stack_allocator const& stack_alloc =
+ stack_allocator(),
+ std::allocator< coroutine > const& alloc =
+ std::allocator< coroutine >(),
+ typename disable_if<
+ is_same< typename decay< Fn >::type, coroutine >,
+ dummy *
+ >::type = 0) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+// BOOST_STATIC_ASSERT((
+// is_same< void, typename result_of< Fn() >::type >::value));
+ typedef detail::coroutine_object<
+ Signature,
+ Fn, stack_allocator, std::allocator< coroutine >,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), arg, attr, stack_alloc, a) );
+ }
+
+ template< typename Fn, typename StackAllocator >
+ explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ std::allocator< coroutine > const& alloc =
+ std::allocator< coroutine >(),
+ typename disable_if<
+ is_same< typename decay< Fn >::type, coroutine >,
+ dummy *
+ >::type = 0) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+// BOOST_STATIC_ASSERT((
+// is_same< void, typename result_of< Fn() >::type >::value));
+ typedef detail::coroutine_object<
+ Signature,
+ Fn, StackAllocator, std::allocator< coroutine >,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) );
+ }
+
+ template< typename Fn, typename StackAllocator >
+ explicit coroutine( BOOST_RV_REF( Fn) fn, arguments arg, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ std::allocator< coroutine > const& alloc =
+ std::allocator< coroutine >(),
+ typename disable_if<
+ is_same< typename decay< Fn >::type, coroutine >,
+ dummy *
+ >::type = 0) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+// BOOST_STATIC_ASSERT((
+// is_same< void, typename result_of< Fn() >::type >::value));
+ typedef detail::coroutine_object<
+ Signature,
+ Fn, StackAllocator, std::allocator< coroutine >,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), arg, attr, stack_alloc, a) );
+ }
+
+ template< typename Fn, typename StackAllocator, typename Allocator >
+ explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ Allocator const& alloc,
+ typename disable_if<
+ is_same< typename decay< Fn >::type, coroutine >,
+ dummy *
+ >::type = 0) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+// BOOST_STATIC_ASSERT((
+// is_same< void, typename result_of< Fn() >::type >::value));
+ typedef detail::coroutine_object<
+ Signature,
+ Fn, StackAllocator, Allocator,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) );
+ }
+
+ template< typename Fn, typename StackAllocator, typename Allocator >
+ explicit coroutine( BOOST_RV_REF( Fn) fn, arguments arg, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ Allocator const& alloc,
+ typename disable_if<
+ is_same< typename decay< Fn >::type, coroutine >,
+ dummy *
+ >::type = 0) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+// BOOST_STATIC_ASSERT((
+// is_same< void, typename result_of< Fn() >::type >::value));
+ typedef detail::coroutine_object<
+ Signature,
+ Fn, StackAllocator, Allocator,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( forward< Fn >( fn), arg, attr, stack_alloc, a) );
+ }
+#else
+ template< typename Fn >
+ explicit coroutine( Fn fn, attributes const& attr = attributes(),
+ stack_allocator const& stack_alloc =
+ stack_allocator(),
+ std::allocator< coroutine > const& alloc =
+ std::allocator< coroutine >(),
+ typename disable_if<
+ is_convertible< Fn &, BOOST_RV_REF( Fn) >,
+ dummy *
+ >::type = 0) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+// BOOST_STATIC_ASSERT((
+// is_same< void, typename result_of< Fn() >::type >::value));
+ typedef detail::coroutine_object<
+ Signature,
+ Fn, stack_allocator, std::allocator< coroutine >,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
+ }
+
+ template< typename Fn >
+ explicit coroutine( Fn fn, arguments arg, attributes const& attr = attributes(),
+ stack_allocator const& stack_alloc =
+ stack_allocator(),
+ std::allocator< coroutine > const& alloc =
+ std::allocator< coroutine >(),
+ typename disable_if<
+ is_convertible< Fn &, BOOST_RV_REF( Fn) >,
+ dummy *
+ >::type = 0) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+// BOOST_STATIC_ASSERT((
+// is_same< void, typename result_of< Fn() >::type >::value));
+ typedef detail::coroutine_object<
+ Signature,
+ Fn, stack_allocator, std::allocator< coroutine >,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( fn, arg, attr, stack_alloc, a) );
+ }
+
+ template< typename Fn, typename StackAllocator >
+ explicit coroutine( Fn fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ std::allocator< coroutine > const& alloc =
+ std::allocator< coroutine >(),
+ typename disable_if<
+ is_convertible< Fn &, BOOST_RV_REF( Fn) >,
+ dummy *
+ >::type = 0) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+// BOOST_STATIC_ASSERT((
+// is_same< void, typename result_of< Fn() >::type >::value));
+ typedef detail::coroutine_object<
+ Signature,
+ Fn, StackAllocator, std::allocator< coroutine >,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
+ }
+
+ template< typename Fn, typename StackAllocator, typename Allocator >
+ explicit coroutine( Fn fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ Allocator const& alloc,
+ typename disable_if<
+ is_convertible< Fn &, BOOST_RV_REF( Fn) >,
+ dummy *
+ >::type = 0) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+// BOOST_STATIC_ASSERT((
+// is_same< void, typename result_of< Fn() >::type >::value));
+ typedef detail::coroutine_object<
+ Signature,
+ Fn, StackAllocator, Allocator,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
+ }
+
+ template< typename Fn >
+ explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(),
+ stack_allocator const& stack_alloc =
+ stack_allocator(),
+ std::allocator< coroutine > const& alloc =
+ std::allocator< coroutine >(),
+ typename disable_if<
+ is_same< typename decay< Fn >::type, coroutine >,
+ dummy *
+ >::type = 0) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+// BOOST_STATIC_ASSERT((
+// is_same< void, typename result_of< Fn() >::type >::value));
+ typedef detail::coroutine_object<
+ Signature,
+ Fn, stack_allocator, std::allocator< coroutine >,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
+ }
+
+ template< typename Fn, typename StackAllocator >
+ explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ std::allocator< coroutine > const& alloc =
+ std::allocator< coroutine >(),
+ typename disable_if<
+ is_same< typename decay< Fn >::type, coroutine >,
+ dummy *
+ >::type = 0) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+// BOOST_STATIC_ASSERT((
+// is_same< void, typename result_of< Fn() >::type >::value));
+ typedef detail::coroutine_object<
+ Signature,
+ Fn, StackAllocator, std::allocator< coroutine >,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
+ }
+
+ template< typename Fn, typename StackAllocator, typename Allocator >
+ explicit coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ Allocator const& alloc,
+ typename disable_if<
+ is_same< typename decay< Fn >::type, coroutine >,
+ dummy *
+ >::type = 0) :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ {
+// BOOST_STATIC_ASSERT((
+// is_same< void, typename result_of< Fn() >::type >::value));
+ typedef detail::coroutine_object<
+ Signature,
+ Fn, StackAllocator, Allocator,
+ caller_type,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ > object_t;
+ typename object_t::allocator_t a( alloc);
+ impl_ = ptr_t(
+ // placement new
+ ::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
+ }
+#endif
+
+ coroutine( BOOST_RV_REF( coroutine) other) BOOST_NOEXCEPT :
+ detail::coroutine_op<
+ Signature,
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ detail::coroutine_get<
+ coroutine< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ impl_()
+ { swap( other); }
+
+ coroutine & operator=( BOOST_RV_REF( coroutine) other) BOOST_NOEXCEPT
+ {
+ coroutine tmp( boost::move( other) );
+ swap( tmp);
+ return * this;
+ }
+
+ bool empty() const BOOST_NOEXCEPT
+ { return ! impl_; }
+
+ operator safe_bool() const BOOST_NOEXCEPT
+ { return ( empty() || impl_->is_complete() ) ? 0 : & dummy::nonnull; }
+
+ bool operator!() const BOOST_NOEXCEPT
+ { return empty() || impl_->is_complete(); }
+
+ void swap( coroutine & other) BOOST_NOEXCEPT
+ { impl_.swap( other.impl_); }
+};
+
+template< typename Signature >
+void swap( coroutine< Signature > & l, coroutine< Signature > & r) BOOST_NOEXCEPT
+{ l.swap( r); }
+
+template< typename Signature >
+inline
+typename coroutine< Signature >::iterator
+range_begin( coroutine< Signature > & c)
+{ return typename coroutine< Signature >::iterator( & c); }
+
+template< typename Signature >
+inline
+typename coroutine< Signature >::const_iterator
+range_begin( coroutine< Signature > const& c)
+{ return typename coroutine< Signature >::const_iterator( & c); }
+
+template< typename Signature >
+inline
+typename coroutine< Signature >::iterator
+range_end( coroutine< Signature > &)
+{ return typename coroutine< Signature >::iterator(); }
+
+template< typename Signature >
+inline
+typename coroutine< Signature >::const_iterator
+range_end( coroutine< Signature > const&)
+{ return typename coroutine< Signature >::const_iterator(); }
+
+template< typename Signature >
+inline
+typename coroutine< Signature >::iterator
+begin( coroutine< Signature > & c)
+{ return boost::begin( c); }
+
+template< typename Signature >
+inline
+typename coroutine< Signature >::iterator
+end( coroutine< Signature > & c)
+{ return boost::end( c); }
+
+template< typename Signature >
+inline
+typename coroutine< Signature >::const_iterator
+begin( coroutine< Signature > const& c)
+{ return boost::const_begin( c); }
+
+template< typename Signature >
+inline
+typename coroutine< Signature >::const_iterator
+end( coroutine< Signature > const& c)
+{ return boost::const_end( c); }
+
+}
+
+template< typename Signature >
+struct range_mutable_iterator< coroutines::coroutine< Signature > >
+{ typedef typename coroutines::coroutine< Signature >::iterator type; };
+
+template< typename Signature >
+struct range_const_iterator< coroutines::coroutine< Signature > >
+{ typedef typename coroutines::coroutine< Signature >::const_iterator type; };
+
+}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_V1_COROUTINE_H
Added: branches/release/boost/coroutine/v1/detail/arg.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/coroutine/v1/detail/arg.hpp 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -0,0 +1,62 @@
+
+// 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_V1_DETAIL_ARG_H
+#define BOOST_COROUTINES_V1_DETAIL_ARG_H
+
+#include <boost/config.hpp>
+#include <boost/preprocessor/arithmetic/add.hpp>
+#include <boost/preprocessor/arithmetic/sub.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/punctuation/comma_if.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <boost/type_traits/function_traits.hpp>
+
+#include <boost/coroutine/detail/config.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+namespace detail {
+
+template<
+ typename Signature,
+ int arity = function_traits< Signature >::arity >
+struct arg;
+
+template< typename Signature >
+struct arg< Signature, 1 >
+{
+ typedef typename function_traits< Signature >::arg1_type type;
+};
+
+#define BOOST_CONTEXT_TUPLE_COMMA(n) BOOST_PP_COMMA_IF(BOOST_PP_SUB(n,1))
+#define BOOST_CONTEXT_TUPLE_TYPE(z,n,unused) \
+ BOOST_CONTEXT_TUPLE_COMMA(n) typename function_traits< Signature >::BOOST_PP_CAT(BOOST_PP_CAT(arg,n),_type)
+#define BOOST_CONTEXT_TUPLE_TYPES(n) BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(n,1),BOOST_CONTEXT_TUPLE_TYPE,~)
+#define BOOST_CONTEXT_TUPLE(z,n,unused) \
+template< typename Signature > \
+struct arg< Signature, n > \
+{ \
+ typedef tuple< BOOST_CONTEXT_TUPLE_TYPES(n) > type; \
+};
+BOOST_PP_REPEAT_FROM_TO(2,11,BOOST_CONTEXT_TUPLE,~)
+#undef BOOST_CONTEXT_TUPLE
+#undef BOOST_CONTEXT_TUPLE_TYPES
+#undef BOOST_CONTEXT_TUPLE_TYPE
+#undef BOOST_CONTEXT_TUPLE_COMMA
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_V1_DETAIL_ARG_H
Added: branches/release/boost/coroutine/v1/detail/coroutine_base.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/coroutine/v1/detail/coroutine_base.hpp 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -0,0 +1,125 @@
+
+// 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_V1_DETAIL_COROUTINE_BASE_H
+#define BOOST_COROUTINES_V1_DETAIL_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/detail/flags.hpp>
+#include <boost/coroutine/v1/detail/coroutine_base_resume.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+
+struct stack_context;
+
+namespace detail {
+
+template< typename Signature >
+class coroutine_base : private noncopyable,
+ public coroutine_base_resume<
+ Signature,
+ coroutine_base< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >
+{
+public:
+ typedef intrusive_ptr< coroutine_base > ptr_t;
+
+private:
+ template< typename X, typename Y, typename Z, int >
+ friend class coroutine_base_resume;
+ template< typename X, typename Y, typename Z, typename A, typename B, typename C, int >
+ friend class coroutine_object;
+
+ unsigned int use_count_;
+ coroutine_context caller_;
+ coroutine_context callee_;
+ int flags_;
+ exception_ptr except_;
+
+protected:
+ virtual void deallocate_object() = 0;
+
+public:
+ coroutine_base( coroutine_context::ctx_fn fn, stack_context * stack_ctx,
+ bool unwind, bool preserve_fpu) :
+ coroutine_base_resume<
+ Signature,
+ coroutine_base< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ use_count_( 0),
+ caller_(),
+ callee_( fn, stack_ctx),
+ flags_( 0),
+ except_()
+ {
+ if ( unwind) flags_ |= flag_force_unwind;
+ if ( preserve_fpu) flags_ |= flag_preserve_fpu;
+ }
+
+ coroutine_base( coroutine_context const& callee, bool unwind, bool preserve_fpu) :
+ coroutine_base_resume<
+ Signature,
+ coroutine_base< Signature >,
+ typename function_traits< Signature >::result_type,
+ function_traits< Signature >::arity
+ >(),
+ use_count_( 0),
+ caller_(),
+ callee_( callee),
+ flags_( 0),
+ except_()
+ {
+ if ( unwind) flags_ |= flag_force_unwind;
+ if ( preserve_fpu) flags_ |= flag_preserve_fpu;
+ }
+
+ virtual ~coroutine_base()
+ {}
+
+ bool force_unwind() const BOOST_NOEXCEPT
+ { return 0 != ( flags_ & flag_force_unwind); }
+
+ bool unwind_requested() const BOOST_NOEXCEPT
+ { return 0 != ( flags_ & flag_unwind_stack); }
+
+ bool preserve_fpu() const BOOST_NOEXCEPT
+ { return 0 != ( flags_ & flag_preserve_fpu); }
+
+ bool is_complete() const BOOST_NOEXCEPT
+ { return 0 != ( flags_ & flag_complete); }
+
+ friend inline void intrusive_ptr_add_ref( coroutine_base * p) BOOST_NOEXCEPT
+ { ++p->use_count_; }
+
+ friend inline void intrusive_ptr_release( coroutine_base * p) BOOST_NOEXCEPT
+ { if ( --p->use_count_ == 0) p->deallocate_object(); }
+};
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_V1_DETAIL_COROUTINE_BASE_H
Added: branches/release/boost/coroutine/v1/detail/coroutine_base_resume.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/coroutine/v1/detail/coroutine_base_resume.hpp 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -0,0 +1,237 @@
+
+// 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_V1_DETAIL_COROUTINE_BASE_RESUME_H
+#define BOOST_COROUTINES_V1_DETAIL_COROUTINE_BASE_RESUME_H
+
+#include <iterator>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+#include <boost/context/fcontext.hpp>
+#include <boost/optional.hpp>
+#include <boost/preprocessor/arithmetic/add.hpp>
+#include <boost/preprocessor/arithmetic/sub.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/punctuation/comma_if.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+#include <boost/range.hpp>
+
+#include <boost/coroutine/detail/config.hpp>
+#include <boost/coroutine/detail/coroutine_context.hpp>
+#include <boost/coroutine/detail/exceptions.hpp>
+#include <boost/coroutine/detail/holder.hpp>
+#include <boost/coroutine/v1/detail/arg.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+namespace detail {
+
+template< typename Signature, typename D, typename Result, int arity >
+class coroutine_base_resume;
+
+template< typename Signature, typename D >
+class coroutine_base_resume< Signature, D, void, 0 >
+{
+public:
+ void resume()
+ {
+ holder< void > hldr_to( & static_cast< D * >( this)->caller_);
+ holder< void > * hldr_from(
+ reinterpret_cast< holder< void > * >(
+ hldr_to.ctx->jump(
+ static_cast< D * >( this)->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ static_cast< D * >( this)->preserve_fpu() ) ) );
+ BOOST_ASSERT( hldr_from->ctx);
+ static_cast< D * >( this)->callee_ = * hldr_from->ctx;
+ if ( hldr_from->force_unwind) throw forced_unwind();
+ if ( static_cast< D * >( this)->except_)
+ rethrow_exception( static_cast< D * >( this)->except_);
+ }
+};
+
+template< typename Signature, typename D, typename Result >
+class coroutine_base_resume< Signature, D, Result, 0 >
+{
+public:
+ void resume()
+ {
+ BOOST_ASSERT( static_cast< D * >( this));
+ BOOST_ASSERT( ! static_cast< D * >( this)->is_complete() );
+
+ holder< void > hldr_to( & static_cast< D * >( this)->caller_);
+ holder< Result > * hldr_from(
+ reinterpret_cast< holder< Result > * >(
+ hldr_to.ctx->jump(
+ static_cast< D * >( this)->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ static_cast< D * >( this)->preserve_fpu() ) ) );
+ BOOST_ASSERT( hldr_from->ctx);
+ static_cast< D * >( this)->callee_ = * hldr_from->ctx;
+ result_ = hldr_from->data;
+ if ( hldr_from->force_unwind) throw forced_unwind();
+ if ( static_cast< D * >( this)->except_)
+ rethrow_exception( static_cast< D * >( this)->except_);
+ }
+
+protected:
+ template< typename X, typename Y, int >
+ friend struct coroutine_get;
+
+ optional< Result > result_;
+};
+
+template< typename Signature, typename D >
+class coroutine_base_resume< Signature, D, void, 1 >
+{
+public:
+ typedef typename arg< Signature >::type arg_type;
+
+ void resume( arg_type a1)
+ {
+ BOOST_ASSERT( static_cast< D * >( this));
+ BOOST_ASSERT( ! static_cast< D * >( this)->is_complete() );
+
+ holder< arg_type > hldr_to( & static_cast< D * >( this)->caller_, a1);
+ holder< void > * hldr_from(
+ reinterpret_cast< holder< void > * >(
+ hldr_to.ctx->jump(
+ static_cast< D * >( this)->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ static_cast< D * >( this)->preserve_fpu() ) ) );
+ BOOST_ASSERT( hldr_from->ctx);
+ static_cast< D * >( this)->callee_ = * hldr_from->ctx;
+ if ( hldr_from->force_unwind) throw forced_unwind();
+ if ( static_cast< D * >( this)->except_)
+ rethrow_exception( static_cast< D * >( this)->except_);
+ }
+};
+
+template< typename Signature, typename D, typename Result >
+class coroutine_base_resume< Signature, D, Result, 1 >
+{
+public:
+ typedef typename arg< Signature >::type arg_type;
+
+ void resume( arg_type a1)
+ {
+ BOOST_ASSERT( static_cast< D * >( this));
+ BOOST_ASSERT( ! static_cast< D * >( this)->is_complete() );
+
+ coroutine_context caller;
+ holder< arg_type > hldr_to( & static_cast< D * >( this)->caller_, a1);
+ holder< Result > * hldr_from(
+ reinterpret_cast< holder< Result > * >(
+ hldr_to.ctx->jump(
+ static_cast< D * >( this)->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ static_cast< D * >( this)->preserve_fpu() ) ) );
+ BOOST_ASSERT( hldr_from->ctx);
+ static_cast< D * >( this)->callee_ = * hldr_from->ctx;
+ result_ = hldr_from->data;
+ if ( hldr_from->force_unwind) throw forced_unwind();
+ if ( static_cast< D * >( this)->except_)
+ rethrow_exception( static_cast< D * >( this)->except_);
+ }
+
+protected:
+ template< typename X, typename Y, int >
+ friend struct coroutine_get;
+
+ optional< Result > result_;
+};
+
+#define BOOST_COROUTINE_BASE_RESUME_COMMA(n) BOOST_PP_COMMA_IF(BOOST_PP_SUB(n,1))
+#define BOOST_COROUTINE_BASE_RESUME_VAL(z,n,unused) BOOST_COROUTINE_BASE_RESUME_COMMA(n) BOOST_PP_CAT(a,n)
+#define BOOST_COROUTINE_BASE_RESUME_VALS(n) BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(n,1),BOOST_COROUTINE_BASE_RESUME_VAL,~)
+#define BOOST_COROUTINE_BASE_RESUME_ARG_TYPE(n) \
+ typename function_traits< Signature >::BOOST_PP_CAT(BOOST_PP_CAT(arg,n),_type)
+#define BOOST_COROUTINE_BASE_RESUME_ARG(z,n,unused) BOOST_COROUTINE_BASE_RESUME_COMMA(n) BOOST_COROUTINE_BASE_RESUME_ARG_TYPE(n) BOOST_PP_CAT(a,n)
+#define BOOST_COROUTINE_BASE_RESUME_ARGS(n) BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(n,1),BOOST_COROUTINE_BASE_RESUME_ARG,~)
+#define BOOST_COROUTINE_BASE_RESUME(z,n,unused) \
+template< typename Signature, typename D > \
+class coroutine_base_resume< Signature, D, void, n > \
+{ \
+public: \
+ typedef typename arg< Signature >::type arg_type; \
+\
+ void resume( BOOST_COROUTINE_BASE_RESUME_ARGS(n)) \
+ { \
+ BOOST_ASSERT( static_cast< D * >( this)); \
+ BOOST_ASSERT( ! static_cast< D * >( this)->is_complete() ); \
+\
+ holder< arg_type > hldr_to( \
+ & static_cast< D * >( this)->caller_, \
+ arg_type(BOOST_COROUTINE_BASE_RESUME_VALS(n) ) ); \
+ holder< void > * hldr_from( \
+ reinterpret_cast< holder< void > * >( \
+ hldr_to.ctx->jump( \
+ static_cast< D * >( this)->callee_, \
+ reinterpret_cast< intptr_t >( & hldr_to), \
+ static_cast< D * >( this)->preserve_fpu() ) ) ); \
+ BOOST_ASSERT( hldr_from->ctx); \
+ static_cast< D * >( this)->callee_ = * hldr_from->ctx; \
+ if ( hldr_from->force_unwind) throw forced_unwind(); \
+ if ( static_cast< D * >( this)->except_) \
+ rethrow_exception( static_cast< D * >( this)->except_); \
+ } \
+}; \
+\
+template< typename Signature, typename D, typename Result > \
+class coroutine_base_resume< Signature, D, Result, n > \
+{ \
+public: \
+ typedef typename arg< Signature >::type arg_type; \
+\
+ void resume( BOOST_COROUTINE_BASE_RESUME_ARGS(n)) \
+ { \
+ BOOST_ASSERT( static_cast< D * >( this)); \
+ BOOST_ASSERT( ! static_cast< D * >( this)->is_complete() ); \
+\
+ holder< arg_type > hldr_to( \
+ & static_cast< D * >( this)->caller_, \
+ arg_type(BOOST_COROUTINE_BASE_RESUME_VALS(n) ) ); \
+ holder< Result > * hldr_from( \
+ reinterpret_cast< holder< Result > * >( \
+ hldr_to.ctx->jump( \
+ static_cast< D * >( this)->callee_, \
+ reinterpret_cast< intptr_t >( & hldr_to), \
+ static_cast< D * >( this)->preserve_fpu() ) ) ); \
+ BOOST_ASSERT( hldr_from->ctx); \
+ static_cast< D * >( this)->callee_ = * hldr_from->ctx; \
+ result_ = hldr_from->data; \
+ if ( hldr_from->force_unwind) throw forced_unwind(); \
+ if ( static_cast< D * >( this)->except_) \
+ rethrow_exception( static_cast< D * >( this)->except_); \
+ } \
+\
+protected: \
+ template< typename X, typename Y, int > \
+ friend struct coroutine_get; \
+\
+ optional< Result > result_; \
+};
+BOOST_PP_REPEAT_FROM_TO(2,11,BOOST_COROUTINE_BASE_RESUME,~)
+#undef BOOST_COROUTINE_BASE_RESUME
+#undef BOOST_COROUTINE_BASE_RESUME_ARGS
+#undef BOOST_COROUTINE_BASE_RESUME_ARG
+#undef BOOST_COROUTINE_BASE_RESUME_ARG_TYPE
+#undef BOOST_COROUTINE_BASE_RESUME_VALS
+#undef BOOST_COROUTINE_BASE_RESUME_VAL
+#undef BOOST_COROUTINE_BASE_RESUME_COMMA
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_V1_DETAIL_coroutine_base_resume_H
Added: branches/release/boost/coroutine/v1/detail/coroutine_caller.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/coroutine/v1/detail/coroutine_caller.hpp 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -0,0 +1,57 @@
+
+// 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_V1_DETAIL_COROUTINE_CALLER_H
+#define BOOST_COROUTINES_V1_DETAIL_COROUTINE_CALLER_H
+
+#include <boost/config.hpp>
+#include <boost/context/fcontext.hpp>
+
+#include <boost/coroutine/detail/config.hpp>
+#include <boost/coroutine/v1/detail/coroutine_base.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+namespace detail {
+
+template< typename Signature, typename Allocator >
+class coroutine_caller : public coroutine_base< Signature >
+{
+public:
+ typedef typename Allocator::template rebind<
+ coroutine_caller< Signature, Allocator >
+ >::other allocator_t;
+
+ coroutine_caller( coroutine_context const& callee, bool unwind, bool preserve_fpu,
+ allocator_t const& alloc) BOOST_NOEXCEPT :
+ coroutine_base< Signature >( callee, unwind, preserve_fpu),
+ alloc_( alloc)
+ {}
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+
+private:
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, coroutine_caller * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+};
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_V1_DETAIL_COROUTINE_CALLER_H
Added: branches/release/boost/coroutine/v1/detail/coroutine_get.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/coroutine/v1/detail/coroutine_get.hpp 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -0,0 +1,54 @@
+
+// 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_V1_DETAIL_COROUTINE_GET_H
+#define BOOST_COROUTINES_V1_DETAIL_COROUTINE_GET_H
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+#include <boost/type_traits/function_traits.hpp>
+
+#include <boost/coroutine/detail/config.hpp>
+#include <boost/coroutine/detail/param.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+namespace detail {
+
+template<
+ typename D,
+ typename Result, int arity
+>
+struct coroutine_get;
+
+template< typename D, int arity >
+struct coroutine_get< D, void, arity >
+{};
+
+template< typename D, typename Result, int arity >
+struct coroutine_get
+{
+ bool has_result() const
+ { return static_cast< D const* >( this)->impl_->result_; }
+
+ typename param< Result >::type get() const
+ {
+ BOOST_ASSERT( static_cast< D const* >( this)->impl_->result_);
+ return static_cast< D const* >( this)->impl_->result_.get();
+ }
+};
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_V1_DETAIL_COROUTINE_GET_H
Added: branches/release/boost/coroutine/v1/detail/coroutine_object.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/coroutine/v1/detail/coroutine_object.hpp 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -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_V1_DETAIL_COROUTINE_OBJECT_H
+#define BOOST_COROUTINES_V1_DETAIL_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/detail/exceptions.hpp>
+#include <boost/coroutine/detail/flags.hpp>
+#include <boost/coroutine/detail/holder.hpp>
+#include <boost/coroutine/detail/param.hpp>
+#include <boost/coroutine/flags.hpp>
+#include <boost/coroutine/stack_context.hpp>
+#include <boost/coroutine/v1/detail/arg.hpp>
+#include <boost/coroutine/v1/detail/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 Coroutine >
+void trampoline1( intptr_t vp)
+{
+ BOOST_ASSERT( vp);
+
+ reinterpret_cast< Coroutine * >( vp)->run();
+}
+
+template< typename Coroutine, typename Arg >
+void trampoline2( intptr_t vp)
+{
+ BOOST_ASSERT( vp);
+
+ tuple< Coroutine *, Arg > * tpl(
+ reinterpret_cast< tuple< Coroutine *, Arg > * >( vp) );
+ Coroutine * coro( get< 0 >( * tpl) );
+ Arg arg( get< 1 >( * tpl) );
+
+ coro->run( arg);
+}
+
+template< typename StackAllocator >
+struct stack_tuple
+{
+ coroutines::stack_context stack_ctx;
+ StackAllocator stack_alloc;
+
+ stack_tuple( StackAllocator const& stack_alloc_, std::size_t size) :
+ stack_ctx(),
+ stack_alloc( stack_alloc_)
+ {
+ stack_alloc.allocate( stack_ctx, size);
+ }
+
+ ~stack_tuple()
+ {
+ stack_alloc.deallocate( stack_ctx);
+ }
+};
+
+template<
+ typename Signature,
+ typename Fn, typename StackAllocator, typename Allocator,
+ typename Caller,
+ typename Result, int arity
+>
+class coroutine_object;
+
+#include <boost/coroutine/v1/detail/coroutine_object_void_0.ipp>
+#include <boost/coroutine/v1/detail/coroutine_object_void_1.ipp>
+#include <boost/coroutine/v1/detail/coroutine_object_void_arity.ipp>
+#include <boost/coroutine/v1/detail/coroutine_object_result_0.ipp>
+#include <boost/coroutine/v1/detail/coroutine_object_result_1.ipp>
+#include <boost/coroutine/v1/detail/coroutine_object_result_arity.ipp>
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#ifdef BOOST_MSVC
+ #pragma warning (pop)
+#endif
+
+#endif // BOOST_COROUTINES_V1_DETAIL_COROUTINE_OBJECT_H
Added: branches/release/boost/coroutine/v1/detail/coroutine_object_result_0.ipp
==============================================================================
--- (empty file)
+++ branches/release/boost/coroutine/v1/detail/coroutine_object_result_0.ipp 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -0,0 +1,363 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+template<
+ typename Signature,
+ typename Fn, typename StackAllocator, typename Allocator,
+ typename Caller,
+ typename Result
+>
+class coroutine_object< Signature, Fn, StackAllocator, Allocator, Caller, Result, 0 > :
+ private stack_tuple< StackAllocator >,
+ public coroutine_base< Signature >
+{
+public:
+ typedef typename Allocator::template rebind<
+ coroutine_object<
+ Signature, Fn, StackAllocator, Allocator, Caller, Result, 0
+ >
+ >::other allocator_t;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef coroutine_base< Signature > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ coroutine_object( coroutine_object const&);
+ coroutine_object & operator=( coroutine_object const&);
+
+ void enter_()
+ {
+ holder< Result > * hldr_from(
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ this->result_ = hldr_from->data;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void unwind_stack_() BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT( ! this->is_complete() );
+
+ this->flags_ |= flag_unwind_stack;
+ holder< void > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ this->flags_ &= ~flag_unwind_stack;
+
+ BOOST_ASSERT( this->is_complete() );
+ }
+
+public:
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( forward< Fn >( fn) ),
+ alloc_( alloc)
+ { enter_(); }
+#else
+ coroutine_object( Fn fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+#endif
+
+ ~coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename Signature,
+ typename Fn, typename StackAllocator, typename Allocator,
+ typename Caller,
+ typename Result
+>
+class coroutine_object< Signature, reference_wrapper< Fn >, StackAllocator, Allocator, Caller, Result, 0 > :
+ private stack_tuple< StackAllocator >,
+ public coroutine_base< Signature >
+{
+public:
+ typedef typename Allocator::template rebind<
+ coroutine_object<
+ Signature, Fn, StackAllocator, Allocator, Caller, Result, 0
+ >
+ >::other allocator_t;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef coroutine_base< Signature > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ coroutine_object( coroutine_object const&);
+ coroutine_object & operator=( coroutine_object const&);
+
+ void enter_()
+ {
+ holder< Result > * hldr_from(
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ this->result_ = hldr_from->data;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void unwind_stack_() BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT( ! this->is_complete() );
+
+ this->flags_ |= flag_unwind_stack;
+ holder< void > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ this->flags_ &= ~flag_unwind_stack;
+
+ BOOST_ASSERT( this->is_complete() );
+ }
+
+public:
+ coroutine_object( reference_wrapper< Fn > fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ ~coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename Signature,
+ typename Fn, typename StackAllocator, typename Allocator,
+ typename Caller,
+ typename Result
+>
+class coroutine_object< Signature, const reference_wrapper< Fn >, StackAllocator, Allocator, Caller, Result, 0 > :
+ private stack_tuple< StackAllocator >,
+ public coroutine_base< Signature >
+{
+public:
+ typedef typename Allocator::template rebind<
+ coroutine_object<
+ Signature, Fn, StackAllocator, Allocator, Caller, Result, 0
+ >
+ >::other allocator_t;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef coroutine_base< Signature > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ coroutine_object( coroutine_object const&);
+ coroutine_object & operator=( coroutine_object const&);
+
+ void enter_()
+ {
+ holder< Result > * hldr_from(
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = hldr_from->ctx;
+ this->result_ = hldr_from->data;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void unwind_stack_() BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT( ! this->is_complete() );
+
+ this->flags_ |= flag_unwind_stack;
+ holder< void > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ this->flags_ &= ~flag_unwind_stack;
+
+ BOOST_ASSERT( this->is_complete() );
+ }
+
+public:
+ coroutine_object( const reference_wrapper< Fn > fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ ~coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
Added: branches/release/boost/coroutine/v1/detail/coroutine_object_result_1.ipp
==============================================================================
--- (empty file)
+++ branches/release/boost/coroutine/v1/detail/coroutine_object_result_1.ipp 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -0,0 +1,557 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+template<
+ typename Signature,
+ typename Fn, typename StackAllocator, typename Allocator,
+ typename Caller,
+ typename Result
+>
+class coroutine_object< Signature, Fn, StackAllocator, Allocator, Caller, Result, 1 > :
+ private stack_tuple< StackAllocator >,
+ public coroutine_base< Signature >
+{
+public:
+ typedef typename Allocator::template rebind<
+ coroutine_object<
+ Signature, Fn, StackAllocator, Allocator, Caller, Result, 1
+ >
+ >::other allocator_t;
+ typedef typename arg< Signature >::type arg_type;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef coroutine_base< Signature > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ coroutine_object( coroutine_object &);
+ coroutine_object & operator=( coroutine_object const&);
+
+ void enter_()
+ {
+ holder< Result > * hldr_from(
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ this->result_ = hldr_from->data;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void enter_( typename detail::param< arg_type >::type arg)
+ {
+ tuple< coroutine_object *,
+ typename detail::param< arg_type >::type
+ > tpl( this, arg);
+ holder< Result > * hldr_from(
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & tpl),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ this->result_ = hldr_from->data;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void unwind_stack_() BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT( ! this->is_complete() );
+
+ this->flags_ |= flag_unwind_stack;
+ holder< arg_type > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ this->flags_ &= ~flag_unwind_stack;
+
+ BOOST_ASSERT( this->is_complete() );
+ }
+
+public:
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( forward< Fn >( fn) ),
+ alloc_( alloc)
+ { enter_(); }
+
+ coroutine_object( BOOST_RV_REF( Fn) fn, typename detail::param< arg_type >::type arg, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( forward< Fn >( fn) ),
+ alloc_( alloc)
+ { enter_( arg); }
+#else
+ coroutine_object( Fn fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ coroutine_object( Fn fn, typename detail::param< arg_type >::type arg, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_( arg); }
+
+ coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ coroutine_object( BOOST_RV_REF( Fn) fn, typename detail::param< arg_type >::type arg, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_( arg); }
+#endif
+
+ ~coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void run( typename detail::param< arg_type >::type arg)
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ c.impl_->result_ = arg;
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename Signature,
+ typename Fn, typename StackAllocator, typename Allocator,
+ typename Caller,
+ typename Result
+>
+class coroutine_object< Signature, reference_wrapper< Fn >, StackAllocator, Allocator, Caller, Result, 1 > :
+ private stack_tuple< StackAllocator >,
+ public coroutine_base< Signature >
+{
+public:
+ typedef typename Allocator::template rebind<
+ coroutine_object<
+ Signature, Fn, StackAllocator, Allocator, Caller, Result, 1
+ >
+ >::other allocator_t;
+ typedef typename arg< Signature >::type arg_type;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef coroutine_base< Signature > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ coroutine_object( coroutine_object &);
+ coroutine_object & operator=( coroutine_object const&);
+
+ void enter_()
+ {
+ holder< Result > * hldr_from(
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ this->result_ = hldr_from->data;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void enter_( typename detail::param< arg_type >::type arg)
+ {
+ tuple< coroutine_object *,
+ typename detail::param< arg_type >::type
+ > tpl( this, arg);
+ holder< Result > * hldr_from(
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & tpl),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ this->result_ = hldr_from->data;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void unwind_stack_() BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT( ! this->is_complete() );
+
+ this->flags_ |= flag_unwind_stack;
+ holder< arg_type > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ this->flags_ &= ~flag_unwind_stack;
+
+ BOOST_ASSERT( this->is_complete() );
+ }
+
+public:
+ coroutine_object( reference_wrapper< Fn > fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ coroutine_object( reference_wrapper< Fn > fn, typename detail::param< arg_type >::type arg, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_( arg); }
+
+ ~coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void run( typename detail::param< arg_type >::type arg)
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ c.impl_->result_ = arg;
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename Signature,
+ typename Fn, typename StackAllocator, typename Allocator,
+ typename Caller,
+ typename Result
+>
+class coroutine_object< Signature, const reference_wrapper< Fn >, StackAllocator, Allocator, Caller, Result, 1 > :
+ private stack_tuple< StackAllocator >,
+ public coroutine_base< Signature >
+{
+public:
+ typedef typename Allocator::template rebind<
+ coroutine_object<
+ Signature, Fn, StackAllocator, Allocator, Caller, Result, 1
+ >
+ >::other allocator_t;
+ typedef typename arg< Signature >::type arg_type;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef coroutine_base< Signature > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ coroutine_object( coroutine_object &);
+ coroutine_object & operator=( coroutine_object const&);
+
+ void enter_()
+ {
+ holder< Result > * hldr_from(
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ this->result_ = hldr_from->data;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void enter_( typename detail::param< arg_type >::type arg)
+ {
+ tuple< coroutine_object *,
+ typename detail::param< arg_type >::type
+ > tpl( this, arg);
+ holder< Result > * hldr_from(
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & tpl),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ this->result_ = hldr_from->data;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void unwind_stack_() BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT( ! this->is_complete() );
+
+ this->flags_ |= flag_unwind_stack;
+ holder< arg_type > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ this->flags_ &= ~flag_unwind_stack;
+
+ BOOST_ASSERT( this->is_complete() );
+ }
+
+public:
+ coroutine_object( const reference_wrapper< Fn > fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ coroutine_object( const reference_wrapper< Fn > fn, typename detail::param< arg_type >::type arg, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_( arg); }
+
+ ~coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void run( typename detail::param< arg_type >::type arg)
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ c.impl_->result_ = arg;
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
Added: branches/release/boost/coroutine/v1/detail/coroutine_object_result_arity.ipp
==============================================================================
--- (empty file)
+++ branches/release/boost/coroutine/v1/detail/coroutine_object_result_arity.ipp 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -0,0 +1,559 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+template<
+ typename Signature,
+ typename Fn, typename StackAllocator, typename Allocator,
+ typename Caller,
+ typename Result, int arity
+>
+class coroutine_object :
+ private stack_tuple< StackAllocator >,
+ public coroutine_base< Signature >
+{
+public:
+ typedef typename Allocator::template rebind<
+ coroutine_object<
+ Signature, Fn, StackAllocator, Allocator, Caller, Result, arity
+ >
+ >::other allocator_t;
+ typedef typename arg< Signature >::type arg_type;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef coroutine_base< Signature > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ coroutine_object( coroutine_object &);
+ coroutine_object & operator=( coroutine_object const&);
+
+ void enter_()
+ {
+ holder< Result > * hldr_from(
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ this->result_ = hldr_from->data;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void enter_( typename detail::param< arg_type >::type arg)
+ {
+ tuple< coroutine_object *,
+ typename detail::param< arg_type >::type
+ > tpl( this, arg);
+ holder< Result > * hldr_from(
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & tpl),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ this->result_ = hldr_from->data;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void unwind_stack_() BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT( ! this->is_complete() );
+
+ this->flags_ |= flag_unwind_stack;
+ holder< arg_type > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ this->flags_ &= ~flag_unwind_stack;
+
+ BOOST_ASSERT( this->is_complete() );
+ }
+
+public:
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( forward< Fn >( fn) ),
+ alloc_( alloc)
+ { enter_(); }
+
+ coroutine_object( BOOST_RV_REF( Fn) fn, typename detail::param< arg_type >::type arg, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( forward< Fn >( fn) ),
+ alloc_( alloc)
+ { enter_( arg); }
+#else
+ coroutine_object( Fn fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ coroutine_object( Fn fn, typename detail::param< arg_type >::type arg, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_( arg); }
+
+ coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ coroutine_object( BOOST_RV_REF( Fn) fn, typename detail::param< arg_type >::type arg, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_( arg); }
+#endif
+
+ ~coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void run( typename detail::param< arg_type >::type arg)
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ c.impl_->result_ = arg;
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename Signature,
+ typename Fn, typename StackAllocator, typename Allocator,
+ typename Caller,
+ typename Result, int arity
+>
+class coroutine_object< Signature, reference_wrapper< Fn >, StackAllocator, Allocator, Caller, Result, arity > :
+ private stack_tuple< StackAllocator >,
+ public coroutine_base< Signature >
+{
+public:
+ typedef typename Allocator::template rebind<
+ coroutine_object<
+ Signature, Fn, StackAllocator, Allocator, Caller, Result, arity
+ >
+ >::other allocator_t;
+ typedef typename arg< Signature >::type arg_type;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef coroutine_base< Signature > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ coroutine_object( coroutine_object &);
+ coroutine_object & operator=( coroutine_object const&);
+
+ void enter_()
+ {
+ holder< Result > * hldr_from(
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ this->result_ = hldr_from->data;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void enter_( typename detail::param< arg_type >::type arg)
+ {
+ tuple< coroutine_object *,
+ typename detail::param< arg_type >::type
+ > tpl( this, arg);
+ holder< Result > * hldr_from(
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & tpl),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ this->result_ = hldr_from->data;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void unwind_stack_() BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT( ! this->is_complete() );
+
+ this->flags_ |= flag_unwind_stack;
+ holder< arg_type > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ this->flags_ &= ~flag_unwind_stack;
+
+ BOOST_ASSERT( this->is_complete() );
+ }
+
+public:
+ coroutine_object( reference_wrapper< Fn > fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ coroutine_object( reference_wrapper< Fn > fn, typename detail::param< arg_type >::type arg, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_( arg); }
+
+ ~coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void run( typename detail::param< arg_type >::type arg)
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ c.impl_->result_ = arg;
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename Signature,
+ typename Fn, typename StackAllocator, typename Allocator,
+ typename Caller,
+ typename Result, int arity
+>
+class coroutine_object< Signature, const reference_wrapper< Fn >, StackAllocator, Allocator, Caller, Result, arity > :
+ private stack_tuple< StackAllocator >,
+ public coroutine_base< Signature >
+{
+public:
+ typedef typename Allocator::template rebind<
+ coroutine_object<
+ Signature, Fn, StackAllocator, Allocator, Caller, Result, arity
+ >
+ >::other allocator_t;
+ typedef typename arg< Signature >::type arg_type;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef coroutine_base< Signature > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ coroutine_object( coroutine_object &);
+ coroutine_object & operator=( coroutine_object const&);
+
+ void enter_()
+ {
+ holder< Result > * hldr_from(
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ this->result_ = hldr_from->data;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void enter_( typename detail::param< arg_type >::type arg)
+ {
+ tuple< coroutine_object *,
+ typename detail::param< arg_type >::type
+ > tpl( this, arg);
+ holder< Result > * hldr_from(
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & tpl),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ this->result_ = hldr_from->data;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void unwind_stack_() BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT( ! this->is_complete() );
+
+ this->flags_ |= flag_unwind_stack;
+ holder< arg_type > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ this->flags_ &= ~flag_unwind_stack;
+
+ BOOST_ASSERT( this->is_complete() );
+ }
+
+public:
+ coroutine_object( const reference_wrapper< Fn > fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ coroutine_object( const reference_wrapper< Fn > fn, typename detail::param< arg_type >::type arg, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_( arg); }
+
+ ~coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void run( typename detail::param< arg_type >::type arg)
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ c.impl_->result_ = arg;
+ try
+ {
+ fn_( c);
+ }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
Added: branches/release/boost/coroutine/v1/detail/coroutine_object_void_0.ipp
==============================================================================
--- (empty file)
+++ branches/release/boost/coroutine/v1/detail/coroutine_object_void_0.ipp 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -0,0 +1,357 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+template<
+ typename Signature,
+ typename Fn, typename StackAllocator, typename Allocator,
+ typename Caller
+>
+class coroutine_object< Signature, Fn, StackAllocator, Allocator, Caller, void, 0 > :
+ private stack_tuple< StackAllocator >,
+ public coroutine_base< Signature >
+{
+public:
+ typedef typename Allocator::template rebind<
+ coroutine_object<
+ Signature, Fn, StackAllocator, Allocator, Caller, void, 0
+ >
+ >::other allocator_t;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef coroutine_base< Signature > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ coroutine_object( coroutine_object const&);
+ coroutine_object & operator=( coroutine_object const&);
+
+ void enter_()
+ {
+ holder< void > * hldr_from(
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void unwind_stack_() BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT( ! this->is_complete() );
+
+ this->flags_ |= flag_unwind_stack;
+ holder< void > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ this->flags_ &= ~flag_unwind_stack;
+
+ BOOST_ASSERT( this->is_complete() );
+ }
+
+public:
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( forward< Fn >( fn) ),
+ alloc_( alloc)
+ { enter_(); }
+#else
+ coroutine_object( Fn fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->pbase_type::stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+#endif
+
+ ~coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename Signature,
+ typename Fn, typename StackAllocator, typename Allocator,
+ typename Caller
+>
+class coroutine_object< Signature, reference_wrapper< Fn >, StackAllocator, Allocator, Caller, void, 0 > :
+ private stack_tuple< StackAllocator >,
+ public coroutine_base< Signature >
+{
+public:
+ typedef typename Allocator::template rebind<
+ coroutine_object<
+ Signature, Fn, StackAllocator, Allocator, Caller, void, 0
+ >
+ >::other allocator_t;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef coroutine_base< Signature > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ coroutine_object( coroutine_object const&);
+ coroutine_object & operator=( coroutine_object const&);
+
+ void enter_()
+ {
+ holder< void > * hldr_from(
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void unwind_stack_() BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT( ! this->is_complete() );
+
+ this->flags_ |= flag_unwind_stack;
+ holder< void > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ this->flags_ &= ~flag_unwind_stack;
+
+ BOOST_ASSERT( this->is_complete() );
+ }
+
+public:
+ coroutine_object( reference_wrapper< Fn > fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ ~coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename Signature,
+ typename Fn, typename StackAllocator, typename Allocator,
+ typename Caller
+>
+class coroutine_object< Signature, const reference_wrapper< Fn >, StackAllocator, Allocator, Caller, void, 0 > :
+ private stack_tuple< StackAllocator >,
+ public coroutine_base< Signature >
+{
+public:
+ typedef typename Allocator::template rebind<
+ coroutine_object<
+ Signature, Fn, StackAllocator, Allocator, Caller, void, 0
+ >
+ >::other allocator_t;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef coroutine_base< Signature > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ coroutine_object( coroutine_object const&);
+ coroutine_object & operator=( coroutine_object const&);
+
+ void enter_()
+ {
+ holder< void > * hldr_from(
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void unwind_stack_() BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT( ! this->is_complete() );
+
+ this->flags_ |= flag_unwind_stack;
+ holder< void > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ this->flags_ &= ~flag_unwind_stack;
+
+ BOOST_ASSERT( this->is_complete() );
+ }
+
+public:
+ coroutine_object( const reference_wrapper< Fn > fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ ~coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
Added: branches/release/boost/coroutine/v1/detail/coroutine_object_void_1.ipp
==============================================================================
--- (empty file)
+++ branches/release/boost/coroutine/v1/detail/coroutine_object_void_1.ipp 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -0,0 +1,550 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+template<
+ typename Signature,
+ typename Fn, typename StackAllocator, typename Allocator,
+ typename Caller
+>
+class coroutine_object< Signature, Fn, StackAllocator, Allocator, Caller, void, 1 > :
+ private stack_tuple< StackAllocator >,
+ public coroutine_base< Signature >
+{
+public:
+ typedef typename Allocator::template rebind<
+ coroutine_object<
+ Signature, Fn, StackAllocator, Allocator, Caller, void, 1
+ >
+ >::other allocator_t;
+ typedef typename arg< Signature >::type arg_type;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef coroutine_base< Signature > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ coroutine_object( coroutine_object &);
+ coroutine_object & operator=( coroutine_object const&);
+
+ void enter_()
+ {
+ holder< void > * hldr_from(
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void enter_( typename detail::param< arg_type >::type arg)
+ {
+ tuple< coroutine_object *,
+ typename detail::param< arg_type >::type
+ > tpl( this, arg);
+ holder< void > * hldr_from(
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & tpl),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void unwind_stack_() BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT( ! this->is_complete() );
+
+ this->flags_ |= flag_unwind_stack;
+ holder< arg_type > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ this->flags_ &= ~flag_unwind_stack;
+
+ BOOST_ASSERT( this->is_complete() );
+ }
+
+public:
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( forward< Fn >( fn) ),
+ alloc_( alloc)
+ { enter_(); }
+
+ coroutine_object( BOOST_RV_REF( Fn) fn, typename detail::param< arg_type >::type arg, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( forward< Fn >( fn) ),
+ alloc_( alloc)
+ { enter_( arg); }
+#else
+ coroutine_object( Fn fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ coroutine_object( Fn fn, typename detail::param< arg_type >::type arg, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_( arg); }
+
+ coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ coroutine_object( BOOST_RV_REF( Fn) fn, typename detail::param< arg_type >::type arg, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_( arg); }
+#endif
+
+ ~coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void run( typename detail::param< arg_type >::type arg)
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ c.impl_->result_ = arg;
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename Signature,
+ typename Fn, typename StackAllocator, typename Allocator,
+ typename Caller
+>
+class coroutine_object< Signature, reference_wrapper< Fn >, StackAllocator, Allocator, Caller, void, 1 > :
+ private stack_tuple< StackAllocator >,
+ public coroutine_base< Signature >
+{
+public:
+ typedef typename Allocator::template rebind<
+ coroutine_object<
+ Signature, Fn, StackAllocator, Allocator, Caller, void, 1
+ >
+ >::other allocator_t;
+ typedef typename arg< Signature >::type arg_type;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef coroutine_base< Signature > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ coroutine_object( coroutine_object &);
+ coroutine_object & operator=( coroutine_object const&);
+
+ void enter_()
+ {
+ holder< void > * hldr_from(
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void enter_( typename detail::param< arg_type >::type arg)
+ {
+ tuple< coroutine_object *,
+ typename detail::param< arg_type >::type
+ > tpl( this, arg);
+ holder< void > * hldr_from(
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & tpl),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void unwind_stack_() BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT( ! this->is_complete() );
+
+ this->flags_ |= flag_unwind_stack;
+ holder< arg_type > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ this->flags_ &= ~flag_unwind_stack;
+
+ BOOST_ASSERT( this->is_complete() );
+ }
+
+public:
+ coroutine_object( reference_wrapper< Fn > fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ coroutine_object( reference_wrapper< Fn > fn,
+ typename detail::param< arg_type >::type arg, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_( arg); }
+
+ ~coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void run( typename detail::param< arg_type >::type arg)
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ c.impl_->result_ = arg;
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename Signature,
+ typename Fn, typename StackAllocator, typename Allocator,
+ typename Caller
+>
+class coroutine_object< Signature, const reference_wrapper< Fn >, StackAllocator, Allocator, Caller, void, 1 > :
+ private stack_tuple< StackAllocator >,
+ public coroutine_base< Signature >
+{
+public:
+ typedef typename Allocator::template rebind<
+ coroutine_object<
+ Signature, Fn, StackAllocator, Allocator, Caller, void, 1
+ >
+ >::other allocator_t;
+ typedef typename arg< Signature >::type arg_type;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef coroutine_base< Signature > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ coroutine_object( coroutine_object &);
+ coroutine_object & operator=( coroutine_object const&);
+
+ void enter_()
+ {
+ holder< void > * hldr_from(
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void enter_( typename detail::param< arg_type >::type arg)
+ {
+ tuple< coroutine_object *,
+ typename detail::param< arg_type >::type
+ > tpl( this, arg);
+ holder< void > * hldr_from(
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & tpl),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void unwind_stack_() BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT( ! this->is_complete() );
+
+ this->flags_ |= flag_unwind_stack;
+ holder< arg_type > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ this->flags_ &= ~flag_unwind_stack;
+
+ BOOST_ASSERT( this->is_complete() );
+ }
+
+public:
+ coroutine_object( const reference_wrapper< Fn > fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ coroutine_object( const reference_wrapper< Fn > fn,
+ typename detail::param< arg_type >::type arg, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_( arg); }
+
+ ~coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void run( typename detail::param< arg_type >::type arg)
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ c.impl_->result_ = arg;
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
Added: branches/release/boost/coroutine/v1/detail/coroutine_object_void_arity.ipp
==============================================================================
--- (empty file)
+++ branches/release/boost/coroutine/v1/detail/coroutine_object_void_arity.ipp 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -0,0 +1,551 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+template<
+ typename Signature,
+ typename Fn, typename StackAllocator, typename Allocator,
+ typename Caller,
+ int arity
+>
+class coroutine_object< Signature, Fn, StackAllocator, Allocator, Caller, void, arity > :
+ private stack_tuple< StackAllocator >,
+ public coroutine_base< Signature >
+{
+public:
+ typedef typename Allocator::template rebind<
+ coroutine_object<
+ Signature, Fn, StackAllocator, Allocator, Caller, void, arity
+ >
+ >::other allocator_t;
+ typedef typename arg< Signature >::type arg_type;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef coroutine_base< Signature > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ coroutine_object( coroutine_object &);
+ coroutine_object & operator=( coroutine_object const&);
+
+ void enter_()
+ {
+ holder< void > * hldr_from(
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void enter_( typename detail::param< arg_type >::type arg)
+ {
+ tuple< coroutine_object *,
+ typename detail::param< arg_type >::type
+ > tpl( this, arg);
+ holder< void > * hldr_from(
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & tpl),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void unwind_stack_() BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT( ! this->is_complete() );
+
+ this->flags_ |= flag_unwind_stack;
+ holder< arg_type > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ this->flags_ &= ~flag_unwind_stack;
+
+ BOOST_ASSERT( this->is_complete() );
+ }
+
+public:
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( forward< Fn >( fn) ),
+ alloc_( alloc)
+ { enter_(); }
+
+ coroutine_object( BOOST_RV_REF( Fn) fn, typename detail::param< arg_type >::type arg, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( forward< Fn >( fn) ),
+ alloc_( alloc)
+ { enter_( arg); }
+#else
+ coroutine_object( Fn fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ coroutine_object( Fn fn, typename detail::param< arg_type >::type arg, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_( arg); }
+
+ coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ coroutine_object( BOOST_RV_REF( Fn) fn, typename detail::param< arg_type >::type arg, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_( arg); }
+#endif
+
+ ~coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void run( typename detail::param< arg_type >::type arg)
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ c.impl_->result_ = arg;
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename Signature,
+ typename Fn, typename StackAllocator, typename Allocator,
+ typename Caller,
+ int arity
+>
+class coroutine_object< Signature, reference_wrapper< Fn >, StackAllocator, Allocator, Caller, void, arity > :
+ private stack_tuple< StackAllocator >,
+ public coroutine_base< Signature >
+{
+public:
+ typedef typename Allocator::template rebind<
+ coroutine_object<
+ Signature, Fn, StackAllocator, Allocator, Caller, void, arity
+ >
+ >::other allocator_t;
+ typedef typename arg< Signature >::type arg_type;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef coroutine_base< Signature > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ coroutine_object( coroutine_object &);
+ coroutine_object & operator=( coroutine_object const&);
+
+ void enter_()
+ {
+ holder< void > * hldr_from(
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void enter_( typename detail::param< arg_type >::type arg)
+ {
+ tuple< coroutine_object *,
+ typename detail::param< arg_type >::type
+ > tpl( this, arg);
+ holder< void > * hldr_from(
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & tpl),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void unwind_stack_() BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT( ! this->is_complete() );
+
+ this->flags_ |= flag_unwind_stack;
+ holder< arg_type > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ this->flags_ &= ~flag_unwind_stack;
+
+ BOOST_ASSERT( this->is_complete() );
+ }
+
+public:
+ coroutine_object( reference_wrapper< Fn > fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ coroutine_object( reference_wrapper< Fn > fn, typename detail::param< arg_type >::type arg, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_( arg); }
+
+ ~coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void run( typename detail::param< arg_type >::type arg)
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ c.impl_->result_ = arg;
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename Signature,
+ typename Fn, typename StackAllocator, typename Allocator,
+ typename Caller,
+ int arity
+>
+class coroutine_object< Signature, const reference_wrapper< Fn >, StackAllocator, Allocator, Caller, void, arity > :
+ private stack_tuple< StackAllocator >,
+ public coroutine_base< Signature >
+{
+public:
+ typedef typename Allocator::template rebind<
+ coroutine_object<
+ Signature, Fn, StackAllocator, Allocator, Caller, void, arity
+ >
+ >::other allocator_t;
+ typedef typename arg< Signature >::type arg_type;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef coroutine_base< Signature > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ coroutine_object( coroutine_object &);
+ coroutine_object & operator=( coroutine_object const&);
+
+ void enter_()
+ {
+ holder< void > * hldr_from(
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void enter_( typename detail::param< arg_type >::type arg)
+ {
+ tuple< coroutine_object *,
+ typename detail::param< arg_type >::type
+ > tpl( this, arg);
+ holder< void > * hldr_from(
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & tpl),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void unwind_stack_() BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT( ! this->is_complete() );
+
+ this->flags_ |= flag_unwind_stack;
+ holder< arg_type > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ this->flags_ &= ~flag_unwind_stack;
+
+ BOOST_ASSERT( this->is_complete() );
+ }
+
+public:
+ coroutine_object( const reference_wrapper< Fn > fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ coroutine_object( const reference_wrapper< Fn > fn, typename detail::param< arg_type >::type arg, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline2< coroutine_object, typename detail::param< arg_type >::type >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_( arg); }
+
+ ~coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void run( typename detail::param< arg_type >::type arg)
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ c.impl_->result_ = arg;
+ try
+ { fn_( c); }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+ callee = c.impl_->callee_;
+ }
+
+ this->flags_ |= flag_complete;
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
Added: branches/release/boost/coroutine/v1/detail/coroutine_op.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/coroutine/v1/detail/coroutine_op.hpp 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -0,0 +1,326 @@
+
+// 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_V1_DETAIL_COROUTINE_OP_H
+#define BOOST_COROUTINES_V1_DETAIL_COROUTINE_OP_H
+
+#include <iterator>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+#include <boost/context/fcontext.hpp>
+#include <boost/optional.hpp>
+#include <boost/preprocessor/arithmetic/add.hpp>
+#include <boost/preprocessor/arithmetic/sub.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/punctuation/comma_if.hpp>
+#include <boost/preprocessor/repetition/repeat_from_to.hpp>
+#include <boost/type_traits/function_traits.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+#include <boost/coroutine/detail/config.hpp>
+#include <boost/coroutine/v1/detail/arg.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+namespace detail {
+
+template< typename Signature, typename D, typename Result, int arity >
+struct coroutine_op;
+
+template< typename Signature, typename D >
+struct coroutine_op< Signature, D, void, 0 >
+{
+ D & operator()()
+ {
+ BOOST_ASSERT( static_cast< D * >( this)->impl_);
+ BOOST_ASSERT( ! static_cast< D * >( this)->impl_->is_complete() );
+
+ static_cast< D * >( this)->impl_->resume();
+
+ return * static_cast< D * >( this);
+ }
+};
+
+template< typename Signature, typename D, typename Result >
+struct coroutine_op< Signature, D, Result, 0 >
+{
+ class iterator : public std::iterator< std::input_iterator_tag, typename remove_reference< Result >::type >
+ {
+ private:
+ D * dp_;
+ optional< Result > val_;
+
+ void fetch_()
+ {
+ BOOST_ASSERT( dp_);
+
+ if ( ! dp_->has_result() )
+ {
+ dp_ = 0;
+ val_ = none;
+ return;
+ }
+ val_ = dp_->get();
+ }
+
+ void increment_()
+ {
+ BOOST_ASSERT( dp_);
+ BOOST_ASSERT( * dp_);
+
+ ( * dp_)();
+ fetch_();
+ }
+
+ public:
+ typedef typename iterator::pointer pointer_t;
+ typedef typename iterator::reference reference_t;
+
+ iterator() :
+ dp_( 0), val_()
+ {}
+
+ explicit iterator( D * dp) :
+ dp_( dp), val_()
+ { fetch_(); }
+
+ iterator( iterator const& other) :
+ dp_( other.dp_), val_( other.val_)
+ {}
+
+ iterator & operator=( iterator const& other)
+ {
+ if ( this == & other) return * this;
+ dp_ = other.dp_;
+ val_ = other.val_;
+ return * this;
+ }
+
+ bool operator==( iterator const& other)
+ { return other.dp_ == dp_ && other.val_ == val_; }
+
+ bool operator!=( iterator const& other)
+ { return other.dp_ != dp_ || other.val_ != val_; }
+
+ iterator & operator++()
+ {
+ increment_();
+ return * this;
+ }
+
+ iterator operator++( int)
+ {
+ iterator tmp( * this);
+ ++*this;
+ return tmp;
+ }
+
+ reference_t operator*() const
+ { return const_cast< optional< Result > & >( val_).get(); }
+
+ pointer_t operator->() const
+ { return const_cast< optional< Result > & >( val_).get_ptr(); }
+ };
+
+ class const_iterator : public std::iterator< std::input_iterator_tag, const typename remove_reference< Result >::type >
+ {
+ private:
+ D * dp_;
+ optional< Result > val_;
+
+ void fetch_()
+ {
+ BOOST_ASSERT( dp_);
+
+ if ( ! dp_->has_result() )
+ {
+ dp_ = 0;
+ val_ = none;
+ return;
+ }
+ val_ = dp_->get();
+ }
+
+ void increment_()
+ {
+ BOOST_ASSERT( dp_);
+ BOOST_ASSERT( * dp_);
+
+ ( * dp_)();
+ fetch_();
+ }
+
+ public:
+ typedef typename const_iterator::pointer pointer_t;
+ typedef typename const_iterator::reference reference_t;
+
+ const_iterator() :
+ dp_( 0), val_()
+ {}
+
+ explicit const_iterator( D const* dp) :
+ dp_( const_cast< D * >( dp) ), val_()
+ { fetch_(); }
+
+ const_iterator( const_iterator const& other) :
+ dp_( other.dp_), val_( other.val_)
+ {}
+
+ const_iterator & operator=( const_iterator const& other)
+ {
+ if ( this == & other) return * this;
+ dp_ = other.dp_;
+ val_ = other.val_;
+ return * this;
+ }
+
+ bool operator==( const_iterator const& other)
+ { return other.dp_ == dp_ && other.val_ == val_; }
+
+ bool operator!=( const_iterator const& other)
+ { return other.dp_ != dp_ || other.val_ != val_; }
+
+ const_iterator & operator++()
+ {
+ increment_();
+ return * this;
+ }
+
+ const_iterator operator++( int)
+ {
+ const_iterator tmp( * this);
+ ++*this;
+ return tmp;
+ }
+
+ reference_t operator*() const
+ { return val_.get(); }
+
+ pointer_t operator->() const
+ { return val_.get_ptr(); }
+ };
+
+ D & operator()()
+ {
+ BOOST_ASSERT( static_cast< D * >( this)->impl_);
+ BOOST_ASSERT( ! static_cast< D * >( this)->impl_->is_complete() );
+
+ static_cast< D * >( this)->impl_->resume();
+
+ return * static_cast< D * >( this);
+ }
+};
+
+template< typename Signature, typename D >
+struct coroutine_op< Signature, D, void, 1 >
+{
+ typedef typename arg< Signature >::type arg_type;
+
+ class iterator : public std::iterator< std::output_iterator_tag, void, void, void, void >
+ {
+ private:
+ D * dp_;
+
+ public:
+ iterator() :
+ dp_( 0)
+ {}
+
+ explicit iterator( D * dp) :
+ dp_( dp)
+ {}
+
+ iterator & operator=( arg_type a1)
+ {
+ BOOST_ASSERT( dp_);
+ if ( ! ( * dp_)( a1) ) dp_ = 0;
+ return * this;
+ }
+
+ bool operator==( iterator const& other)
+ { return other.dp_ == dp_; }
+
+ bool operator!=( iterator const& other)
+ { return other.dp_ != dp_; }
+
+ iterator & operator*()
+ { return * this; }
+
+ iterator & operator++()
+ { return * this; }
+ };
+
+ struct const_iterator;
+
+ D & operator()( arg_type a1)
+ {
+ BOOST_ASSERT( static_cast< D * >( this)->impl_);
+ BOOST_ASSERT( ! static_cast< D * >( this)->impl_->is_complete() );
+
+ static_cast< D * >( this)->impl_->resume( a1);
+
+ return * static_cast< D * >( this);
+ }
+};
+
+template< typename Signature, typename D, typename Result >
+struct coroutine_op< Signature, D, Result, 1 >
+{
+ typedef typename arg< Signature >::type arg_type;
+
+ D & operator()( arg_type a1)
+ {
+ BOOST_ASSERT( static_cast< D * >( this)->impl_);
+ BOOST_ASSERT( ! static_cast< D * >( this)->impl_->is_complete() );
+
+ static_cast< D * >( this)->impl_->resume( a1);
+
+ return * static_cast< D * >( this);
+ }
+};
+
+#define BOOST_COROUTINE_OP_COMMA(n) BOOST_PP_COMMA_IF(BOOST_PP_SUB(n,1))
+#define BOOST_COROUTINE_OP_VAL(z,n,unused) BOOST_COROUTINE_OP_COMMA(n) BOOST_PP_CAT(a,n)
+#define BOOST_COROUTINE_OP_VALS(n) BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(n,1),BOOST_COROUTINE_OP_VAL,~)
+#define BOOST_COROUTINE_OP_ARG_TYPE(n) \
+ typename function_traits< Signature >::BOOST_PP_CAT(BOOST_PP_CAT(arg,n),_type)
+#define BOOST_COROUTINE_OP_ARG(z,n,unused) BOOST_COROUTINE_OP_COMMA(n) BOOST_COROUTINE_OP_ARG_TYPE(n) BOOST_PP_CAT(a,n)
+#define BOOST_COROUTINE_OP_ARGS(n) BOOST_PP_REPEAT_FROM_TO(1,BOOST_PP_ADD(n,1),BOOST_COROUTINE_OP_ARG,~)
+#define BOOST_COROUTINE_OP(z,n,unused) \
+template< typename Signature, typename D, typename Result > \
+struct coroutine_op< Signature, D, Result, n > \
+{ \
+ D & operator()( BOOST_COROUTINE_OP_ARGS(n)) \
+ { \
+ BOOST_ASSERT( static_cast< D * >( this)->impl_); \
+ BOOST_ASSERT( ! static_cast< D * >( this)->impl_->is_complete() ); \
+\
+ static_cast< D * >( this)->impl_->resume(BOOST_COROUTINE_OP_VALS(n)); \
+\
+ return * static_cast< D * >( this); \
+ } \
+};
+BOOST_PP_REPEAT_FROM_TO(2,11,BOOST_COROUTINE_OP,~)
+#undef BOOST_COROUTINE_OP
+#undef BOOST_COROUTINE_OP_ARGS
+#undef BOOST_COROUTINE_OP_ARG
+#undef BOOST_COROUTINE_OP_ARG_TYPE
+#undef BOOST_COROUTINE_OP_VALS
+#undef BOOST_COROUTINE_OP_VAL
+#undef BOOST_COROUTINE_OP_COMMA
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_V1_DETAIL_COROUTINE_OP_H
Added: branches/release/boost/coroutine/v2/detail/coroutine_object.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/coroutine/v2/detail/coroutine_object.hpp 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -0,0 +1,423 @@
+
+// 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_V1_DETAIL_COROUTINE_OBJECT_H
+#define BOOST_COROUTINES_V1_DETAIL_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/detail/exceptions.hpp>
+#include <boost/coroutine/detail/flags.hpp>
+#include <boost/coroutine/detail/holder.hpp>
+#include <boost/coroutine/detail/param.hpp>
+#include <boost/coroutine/flags.hpp>
+#include <boost/coroutine/stack_context.hpp>
+#include <boost/coroutine/v2/detail/arg.hpp>
+#include <boost/coroutine/v2/detail/coroutine_base.hpp>
+
+template<
+ typename Arg,
+ typename Fn, typename StackAllocator, typename Allocator
+>
+class coroutine_object< Arg, Fn, StackAllocator, Allocator > :
+ private stack_tuple< StackAllocator >,
+ public coroutine_base
+{
+public:
+ typedef typename Allocator::template rebind<
+ coroutine_object<
+ Arg, Fn, StackAllocator, Allocator
+ >
+ >::other allocator_t;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef coroutine_base base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ coroutine_object( coroutine_object const&);
+ coroutine_object & operator=( coroutine_object const&);
+
+ void enter_()
+ {
+ holder< void > * hldr_from(
+ reinterpret_cast< holder< void > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ this->result_ = hldr_from->data;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void run_( Caller & c)
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+ try
+ {
+ fn_( c);
+ this->flags_ |= flag_complete;
+ callee = c.impl_->callee_;
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+
+ this->flags_ |= flag_complete;
+ callee = c.impl_->callee_;
+ holder< void > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void unwind_stack_() BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT( ! this->is_complete() );
+
+ this->flags_ |= flag_unwind_stack;
+ holder< void > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ this->flags_ &= ~flag_unwind_stack;
+
+ BOOST_ASSERT( this->is_complete() );
+ }
+
+public:
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( forward< Fn >( fn) ),
+ alloc_( alloc)
+ { enter_(); }
+#else
+ coroutine_object( Fn fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+#endif
+
+ ~coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ run_( c);
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename Arg,
+ typename Fn, typename StackAllocator, typename Allocator,
+ typename Caller,
+ typename Result
+>
+class coroutine_object< Arg, reference_wrapper< Fn >, StackAllocator, Allocator, Caller, Result, 0 > :
+ private stack_tuple< StackAllocator >,
+ public coroutine_base< Arg >
+{
+public:
+ typedef typename Allocator::template rebind<
+ coroutine_object<
+ Arg, Fn, StackAllocator, Allocator, Caller, Result, 0
+ >
+ >::other allocator_t;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef coroutine_base< Arg > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ coroutine_object( coroutine_object const&);
+ coroutine_object & operator=( coroutine_object const&);
+
+ void enter_()
+ {
+ holder< Result > * hldr_from(
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = * hldr_from->ctx;
+ this->result_ = hldr_from->data;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void run_( Caller & c)
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+ try
+ {
+ fn_( c);
+ this->flags_ |= flag_complete;
+ callee = c.impl_->callee_;
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+
+ this->flags_ |= flag_complete;
+ callee = c.impl_->callee_;
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void unwind_stack_() BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT( ! this->is_complete() );
+
+ this->flags_ |= flag_unwind_stack;
+ holder< void > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ this->flags_ &= ~flag_unwind_stack;
+
+ BOOST_ASSERT( this->is_complete() );
+ }
+
+public:
+ coroutine_object( reference_wrapper< Fn > fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ ~coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ Caller c( this->caller_, false, this->preserve_fpu(), alloc_);
+ run_( c);
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
+
+template<
+ typename Arg,
+ typename Fn, typename StackAllocator, typename Allocator,
+ typename Caller,
+ typename Result
+>
+class coroutine_object< Arg, const reference_wrapper< Fn >, StackAllocator, Allocator, Caller, Result, 0 > :
+ private stack_tuple< StackAllocator >,
+ public coroutine_base< Arg >
+{
+public:
+ typedef typename Allocator::template rebind<
+ coroutine_object<
+ Arg, Fn, StackAllocator, Allocator, Caller, Result, 0
+ >
+ >::other allocator_t;
+
+private:
+ typedef stack_tuple< StackAllocator > pbase_type;
+ typedef coroutine_base< Arg > base_type;
+
+ Fn fn_;
+ allocator_t alloc_;
+
+ static void destroy_( allocator_t & alloc, coroutine_object * p)
+ {
+ alloc.destroy( p);
+ alloc.deallocate( p, 1);
+ }
+
+ coroutine_object( coroutine_object const&);
+ coroutine_object & operator=( coroutine_object const&);
+
+ void enter_()
+ {
+ holder< Result > * hldr_from(
+ reinterpret_cast< holder< Result > * >(
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( this),
+ this->preserve_fpu() ) ) );
+ this->callee_ = hldr_from->ctx;
+ this->result_ = hldr_from->data;
+ if ( this->except_) rethrow_exception( this->except_);
+ }
+
+ void run_( Caller & c)
+ {
+ coroutine_context callee;
+ coroutine_context caller;
+ try
+ {
+ fn_( c);
+ this->flags_ |= flag_complete;
+ callee = c.impl_->callee_;
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+ catch ( forced_unwind const&)
+ {}
+ catch (...)
+ { this->except_ = current_exception(); }
+
+ this->flags_ |= flag_complete;
+ callee = c.impl_->callee_;
+ holder< Result > hldr_to( & caller);
+ caller.jump(
+ callee,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ BOOST_ASSERT_MSG( false, "coroutine is complete");
+ }
+
+ void unwind_stack_() BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT( ! this->is_complete() );
+
+ this->flags_ |= flag_unwind_stack;
+ holder< void > hldr_to( & this->caller_, true);
+ this->caller_.jump(
+ this->callee_,
+ reinterpret_cast< intptr_t >( & hldr_to),
+ this->preserve_fpu() );
+ this->flags_ &= ~flag_unwind_stack;
+
+ BOOST_ASSERT( this->is_complete() );
+ }
+
+public:
+ coroutine_object( const reference_wrapper< Fn > fn, attributes const& attr,
+ StackAllocator const& stack_alloc,
+ allocator_t const& alloc) :
+ pbase_type( stack_alloc, attr.size),
+ base_type(
+ trampoline1< coroutine_object >,
+ & this->stack_ctx,
+ stack_unwind == attr.do_unwind,
+ fpu_preserved == attr.preserve_fpu),
+ fn_( fn),
+ alloc_( alloc)
+ { enter_(); }
+
+ ~coroutine_object()
+ {
+ if ( ! this->is_complete() && this->force_unwind() )
+ unwind_stack_();
+ }
+
+ void run()
+ {
+ Caller c( & this->caller_, false, this->preserve_fpu(), alloc_);
+ run_( c);
+ }
+
+ void deallocate_object()
+ { destroy_( alloc_, this); }
+};
Added: branches/release/boost/coroutine/v2/pull_corotuine.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/coroutine/v2/pull_corotuine.hpp 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -0,0 +1,355 @@
+
+// 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_V2_PULL_COROUTINE_H
+#define BOOST_COROUTINES_V2_PULL_COROUTINE_H
+
+#include <cstddef>
+#include <memory>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+#include <boost/move/move.hpp>
+#include <boost/range.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/utility/result_of.hpp>
+
+#include <boost/coroutine/attributes.hpp>
+#include <boost/coroutine/detail/config.hpp>
+#include <boost/coroutine/detail/coroutine_context.hpp>
+#include <boost/coroutine/stack_allocator.hpp>
+#include <boost/coroutine/v2/pull_coroutine_base.hpp.hpp>
+#include <boost/coroutine/v2/pull_coroutine_object.hpp.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+namespace detail {
+
+template< typename R >
+class pull_coroutine
+{
+private:
+ 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)
+
+public:
+ pull_coroutine() BOOST_NOEXCEPT :
+ impl_()
+ {}
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ 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 >
+ > 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 >
+ > 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
+ > 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 >
+ > 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 >
+ > 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
+ > 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 >
+ > 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 >
+ > 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
+ > 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_); }
+
+ void operator()()
+ {
+ BOOST_ASSERT( * this);
+
+ impl_->resume();
+ }
+
+ bool has_result() const
+ {
+ BOOST_ASSERT( * this);
+
+ return impl_->has_result();
+ }
+
+ R get() const
+ {
+ BOOST_ASSERT( * this);
+
+ return impl_->get();
+ }
+};
+
+template< typename R >
+void swap( pull_coroutine< R > & l, pull_coroutine< R > & r) BOOST_NOEXCEPT
+{ l.swap( r); }
+#if 0
+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 R >
+inline
+typename pull_coroutine< R >::iterator
+begin( pull_coroutine< R > & c)
+{ return boost::begin( c); }
+
+template< typename R >
+inline
+typename pull_coroutine< R >::iterator
+end( pull_coroutine< R > & c)
+{ return boost::end( c); }
+
+template< typename R >
+inline
+typename pull_coroutine< R >::const_iterator
+begin( pull_coroutine< R > const& c)
+{ return boost::const_begin( c); }
+
+template< typename R >
+inline
+typename pull_coroutine< R >::const_iterator
+end( pull_coroutine< R > const& c)
+{ return boost::const_end( c); }
+
+}
+
+template< typename R >
+struct range_mutable_iterator< coroutines::coroutine< R > >
+{ typedef typename coroutines::coroutine< R >::iterator type; };
+
+template< typename R >
+struct range_const_iterator< coroutines::coroutine< R > >
+{ typedef typename coroutines::coroutine< R >::const_iterator type; };
+#endif
+}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_V2_PULL_COROUTINE_H
Added: branches/release/boost/coroutine/v2/push_coroutine.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/coroutine/v2/push_coroutine.hpp 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -0,0 +1,357 @@
+
+// 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_V2_PUSH_COROUTINE_H
+#define BOOST_COROUTINES_V2_PUSH_COROUTINE_H
+
+#include <cstddef>
+#include <memory>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+#include <boost/move/move.hpp>
+#include <boost/range.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/utility/result_of.hpp>
+
+#include <boost/coroutine/attributes.hpp>
+#include <boost/coroutine/detail/config.hpp>
+#include <boost/coroutine/detail/coroutine_context.hpp>
+#include <boost/coroutine/stack_allocator.hpp>
+#include <boost/coroutine/v2/push_coroutine_base.hpp>
+#include <boost/coroutine/v2/push_coroutine_object.hpp.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+namespace detail {
+
+template< typename Arg >
+class push_coroutine
+{
+private:
+ 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)
+
+public:
+ push_coroutine() BOOST_NOEXCEPT :
+ impl_()
+ {}
+
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ 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) :
+ impl_()
+ {
+ typedef detail::push_coroutine_object<
+ Arg, Fn, stack_allocator, std::allocator< push_coroutine >
+ > 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 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) :
+ impl_()
+ {
+ typedef detail::push_coroutine_object<
+ Arg, Fn, StackAllocator, std::allocator< push_coroutine >
+ > 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 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) :
+ impl_()
+ {
+ typedef detail::push_coroutine_object<
+ Arg, Fn, StackAllocator, Allocator
+ > 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 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) :
+ impl_()
+ {
+ typedef detail::push_coroutine_object<
+ Arg, Fn, stack_allocator, std::allocator< push_coroutine >
+ > 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 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) :
+ impl_()
+ {
+ typedef detail::push_coroutine_object<
+ Arg, Fn, StackAllocator, std::allocator< push_coroutine >
+ > 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 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) :
+ impl_()
+ {
+ typedef detail::push_coroutine_object<
+ Arg, Fn, StackAllocator, Allocator
+ > 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 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) :
+ impl_()
+ {
+ typedef detail::push_coroutine_object<
+ Arg, Fn, stack_allocator, std::allocator< push_coroutine >
+ > 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 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) :
+ impl_()
+ {
+ typedef detail::push_coroutine_object<
+ Arg, Fn, StackAllocator, std::allocator< push_coroutine >
+ > 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 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) :
+ impl_()
+ {
+ typedef detail::push_coroutine_object<
+ Arg, Fn, StackAllocator, Allocator
+ > 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
+
+ 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
+ void operator()( Arg && arg)
+ {
+ BOOST_ASSERT( * this);
+
+ impl_->resume( boost::forward< Arg >( arg) );
+ }
+#else
+ void operator()( BOOST_RV_REF( Arg) arg)
+ {
+ BOOST_ASSERT( * this);
+
+ impl_->resume( boost::forward< Arg >( arg) );
+ }
+#endif
+
+ void operator()( Arg arg)
+ {
+ BOOST_ASSERT( * this);
+
+ impl_->resume( arg);
+ }
+};
+
+template< typename Arg >
+void swap( push_coroutine< Arg > & l, push_coroutine< Arg > & r) BOOST_NOEXCEPT
+{ l.swap( r); }
+#if 0
+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 Arg >
+inline
+typename push_coroutine< Arg >::iterator
+begin( push_coroutine< Arg > & c)
+{ return boost::begin( c); }
+
+template< typename Arg >
+inline
+typename push_coroutine< Arg >::iterator
+end( push_coroutine< Arg > & c)
+{ return boost::end( c); }
+
+template< typename Arg >
+inline
+typename push_coroutine< Arg >::const_iterator
+begin( push_coroutine< Arg > const& c)
+{ return boost::const_begin( c); }
+
+template< typename Arg >
+inline
+typename push_coroutine< Arg >::const_iterator
+end( push_coroutine< Arg > const& c)
+{ return boost::const_end( c); }
+
+}
+
+template< typename Arg >
+struct range_mutable_iterator< coroutines::coroutine< Arg > >
+{ typedef typename coroutines::coroutine< Arg >::iterator type; };
+
+template< typename Arg >
+struct range_const_iterator< coroutines::coroutine< Arg > >
+{ typedef typename coroutines::coroutine< Arg >::const_iterator type; };
+#endif
+}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_V2_PUSH_COROUTINE_H
Modified: branches/release/libs/coroutine/build/Jamfile.v2
==============================================================================
--- branches/release/libs/coroutine/build/Jamfile.v2 (original)
+++ branches/release/libs/coroutine/build/Jamfile.v2 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -16,6 +16,8 @@
<library>/boost/context//boost_context
<toolset>gcc-4.7,<segmented-stacks>on:<cxxflags>-fsplit-stack
<toolset>gcc-4.7,<segmented-stacks>on:<linkflags>"-static-libgcc"
+ <toolset>gcc-4.8,<segmented-stacks>on:<cxxflags>-fsplit-stack
+ <toolset>gcc-4.8,<segmented-stacks>on:<linkflags>"-static-libgcc"
<link>static
<threading>multi
: source-location ../src
Modified: branches/release/libs/coroutine/detail/coroutine_context.cpp
==============================================================================
--- branches/release/libs/coroutine/detail/coroutine_context.cpp (original)
+++ branches/release/libs/coroutine/detail/coroutine_context.cpp 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -64,15 +64,19 @@
coroutine_context::jump( coroutine_context & other, intptr_t param, bool preserve_fpu)
{
#if defined(BOOST_USE_SEGMENTED_STACKS)
- if ( stack_ctx_)
- __splitstack_getcontext( stack_ctx_->segments_ctx);
- if ( other.stack_ctx_)
- __splitstack_setcontext( other.stack_ctx_->segments_ctx);
-#endif
+ BOOST_ASSERT( stack_ctx_);
+ BOOST_ASSERT( other.stack_ctx_);
+
+ __splitstack_getcontext( stack_ctx_->segments_ctx);
+ __splitstack_setcontext( other.stack_ctx_->segments_ctx);
+ intptr_t ret = context::jump_fcontext( ctx_, other.ctx_, param, preserve_fpu);
+
+ BOOST_ASSERT( stack_ctx_);
+ __splitstack_setcontext( stack_ctx_->segments_ctx);
+
+ return ret;
+#else
return context::jump_fcontext( ctx_, other.ctx_, param, preserve_fpu);
-#if defined(BOOST_USE_SEGMENTED_STACKS)
- if ( stack_ctx_)
- __splitstack_setcontext( stack_ctx_->segments_ctx);
#endif
}
Modified: branches/release/libs/coroutine/doc/Jamfile.v2
==============================================================================
--- branches/release/libs/coroutine/doc/Jamfile.v2 (original)
+++ branches/release/libs/coroutine/doc/Jamfile.v2 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -26,6 +26,4 @@
<xsl:param>toc.max.depth=3
# How far down we go with TOC's
<xsl:param>generate.section.toc.level=10
- <format>pdf:<xsl:param>img.src.path=$(images_location)/
;
-
Modified: branches/release/libs/coroutine/doc/intro.qbk
==============================================================================
--- branches/release/libs/coroutine/doc/intro.qbk (original)
+++ branches/release/libs/coroutine/doc/intro.qbk 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -14,7 +14,7 @@
terminates always before the parent.
Coroutines are a generalization of routines.
The principal difference between coroutines and routines is that a coroutine
-enables explicit suspend and resume their progress via additional operations by
+enables explicit suspend and resume of their progress via additional operations by
preserving local state, e.g. a coroutine is a kind of continuation.
A continuation is a object representing a suspended execution (registers,
stack). Each coroutine has its own stack and local variables, sub-routine calls
Modified: branches/release/libs/coroutine/doc/stack.qbk
==============================================================================
--- branches/release/libs/coroutine/doc/stack.qbk (original)
+++ branches/release/libs/coroutine/doc/stack.qbk 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -155,7 +155,7 @@
Segmented stack are currently only supported by [*gcc] from version [*4.7] onwards.
n order to use __segmented_stack__ compile __boost_coroutine__ with
-[*segmented-stacks=on] at b2/bjam command-line. Application using __boost_coroutine__
+[*toolset=gcc segmented-stacks=on] at b2/bjam command-line. Application using __boost_coroutine__
with enabled __segmented-stack__ must be compiled with compiler-flags
[*-fsplit-stack -DBOOST_USE_SEGMENTED_STACKS].
Modified: branches/release/libs/coroutine/example/Jamfile.v2
==============================================================================
--- branches/release/libs/coroutine/example/Jamfile.v2 (original)
+++ branches/release/libs/coroutine/example/Jamfile.v2 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -36,6 +36,7 @@
<library>/boost/system//boost_system
<library>/boost/thread//boost_thread
<toolset>gcc-4.7,<segmented-stacks>on:<cxxflags>-fsplit-stack
+ <toolset>gcc-4.8,<segmented-stacks>on:<cxxflags>-fsplit-stack
<threading>multi
<link>static
;
@@ -75,3 +76,11 @@
exe asio/stream_server
: asio/stream_server.cpp
;
+
+#exe same_fringe
+# : c++11/same_fringe.cpp
+# ;
+#
+#exe fibonacci
+# : c++11/fibonacci.cpp
+# ;
Added: branches/release/libs/coroutine/example/c++11/fibonacci.cpp
==============================================================================
--- (empty file)
+++ branches/release/libs/coroutine/example/c++11/fibonacci.cpp 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -0,0 +1,32 @@
+
+// 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 <boost/coroutine/all.hpp>
+
+int main()
+{
+ boost::coroutines::coroutine< int() > c(
+ [&]( boost::coroutines::coroutine< void( int) > & c) {
+ int first = 1, second = 1;
+ for ( int i = 0; i < 10; ++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;
+}
Added: branches/release/libs/coroutine/example/c++11/same_fringe.cpp
==============================================================================
--- (empty file)
+++ branches/release/libs/coroutine/example/c++11/same_fringe.cpp 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -0,0 +1,75 @@
+
+// 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 <cstddef>
+#include <cstdlib>
+#include <iostream>
+
+#include "tree.h"
+
+class coro_visitor : public visitor
+{
+private:
+ boost::coroutines::coroutine< void( leaf&) > & c_;
+
+public:
+ coro_visitor( boost::coroutines::coroutine< void( leaf&) > & 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); }
+};
+
+node::ptr_t create_tree1()
+{
+ return branch::create(
+ leaf::create( "A"),
+ branch::create(
+ leaf::create( "B"),
+ leaf::create( "C") ) );
+}
+
+node::ptr_t create_tree2()
+{
+ return branch::create(
+ branch::create(
+ leaf::create( "A"),
+ leaf::create( "B") ),
+ leaf::create( "C") );
+}
+
+int main()
+{
+ node::ptr_t t1 = create_tree1();
+ boost::coroutines::coroutine< leaf&() > c1(
+ [&]( boost::coroutines::coroutine< void( leaf &) > & c) {
+ coro_visitor v( c);
+ t1->accept( v);
+ });
+
+ node::ptr_t t2 = create_tree2();
+ boost::coroutines::coroutine< leaf&() > c2(
+ [&]( boost::coroutines::coroutine< void( leaf &) > & c) {
+ coro_visitor v( c);
+ t2->accept( v);
+ });
+
+ bool result = std::equal(
+ boost::begin( c1),
+ boost::end( c1),
+ boost::begin( c2) );
+
+ std::cout << std::boolalpha << "same fringe == " << result << "\nDone" << std::endl;
+
+ return EXIT_SUCCESS;
+}
Added: branches/release/libs/coroutine/example/c++11/tree.h
==============================================================================
--- (empty file)
+++ branches/release/libs/coroutine/example/c++11/tree.h 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -0,0 +1,98 @@
+
+// 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 TREE_H
+#define TREE_H
+
+#include <cstddef>
+#include <string>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+#include <boost/coroutine/all.hpp>
+#include <boost/intrusive_ptr.hpp>
+
+# if defined(BOOST_MSVC)
+# pragma warning(push)
+# pragma warning(disable:4355)
+# endif
+
+struct branch;
+struct leaf;
+
+struct visitor
+{
+ virtual ~visitor() {};
+
+ virtual void visit( branch & b) = 0;
+ virtual void visit( leaf & l) = 0;
+};
+
+struct node
+{
+ typedef boost::intrusive_ptr< node > ptr_t;
+
+ std::size_t use_count;
+
+ node() :
+ use_count( 0)
+ {}
+
+ virtual ~node() {}
+
+ virtual void accept( visitor & v) = 0;
+
+ friend inline void intrusive_ptr_add_ref( node * p)
+ { ++p->use_count; }
+
+ friend inline void intrusive_ptr_release( node * p)
+ { if ( 0 == --p->use_count) delete p; }
+};
+
+struct branch : public node
+{
+ node::ptr_t left;
+ node::ptr_t right;
+
+ static ptr_t create( node::ptr_t left_, node::ptr_t right_)
+ { return ptr_t( new branch( left_, right_) ); }
+
+ branch( node::ptr_t left_, node::ptr_t right_) :
+ left( left_), right( right_)
+ {}
+
+ void accept( visitor & v)
+ { v.visit( * this); }
+};
+
+struct leaf : public node
+{
+ std::string value;
+
+ static ptr_t create( std::string const& value_)
+ { return ptr_t( new leaf( value_) ); }
+
+ leaf( std::string const& value_) :
+ value( value_)
+ {}
+
+ void accept( visitor & v)
+ { v.visit( * this); }
+};
+
+inline
+bool operator==( leaf const& l, leaf const& r)
+{ return l.value == r.value; }
+
+inline
+bool operator!=( leaf const& l, leaf const& r)
+{ return l.value != r.value; }
+
+# if defined(BOOST_MSVC)
+# pragma warning(pop)
+# endif
+
+#endif // TREE_H
Modified: branches/release/libs/coroutine/performance/Jamfile.v2
==============================================================================
--- branches/release/libs/coroutine/performance/Jamfile.v2 (original)
+++ branches/release/libs/coroutine/performance/Jamfile.v2 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -18,6 +18,7 @@
<library>/boost/context//boost_context
<library>/boost/coroutine//boost_coroutine
<toolset>gcc-4.7,<segmented-stacks>on:<cxxflags>-fsplit-stack
+ <toolset>gcc-4.8,<segmented-stacks>on:<cxxflags>-fsplit-stack
<link>static
<linkflags>"-lrt"
<threading>multi
Modified: branches/release/libs/coroutine/src/detail/coroutine_context.cpp
==============================================================================
--- branches/release/libs/coroutine/src/detail/coroutine_context.cpp (original)
+++ branches/release/libs/coroutine/src/detail/coroutine_context.cpp 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -8,6 +8,11 @@
#include "boost/coroutine/detail/coroutine_context.hpp"
+#ifdef BOOST_MSVC
+ #pragma warning (push)
+ #pragma warning (disable: 4355) // using 'this' in initializer list
+#endif
+
#if defined(BOOST_USE_SEGMENTED_STACKS)
extern "C" {
@@ -64,15 +69,19 @@
coroutine_context::jump( coroutine_context & other, intptr_t param, bool preserve_fpu)
{
#if defined(BOOST_USE_SEGMENTED_STACKS)
- if ( stack_ctx_)
- __splitstack_getcontext( stack_ctx_->segments_ctx);
- if ( other.stack_ctx_)
- __splitstack_setcontext( other.stack_ctx_->segments_ctx);
-#endif
+ BOOST_ASSERT( stack_ctx_);
+ BOOST_ASSERT( other.stack_ctx_);
+
+ __splitstack_getcontext( stack_ctx_->segments_ctx);
+ __splitstack_setcontext( other.stack_ctx_->segments_ctx);
+ intptr_t ret = context::jump_fcontext( ctx_, other.ctx_, param, preserve_fpu);
+
+ BOOST_ASSERT( stack_ctx_);
+ __splitstack_setcontext( stack_ctx_->segments_ctx);
+
+ return ret;
+#else
return context::jump_fcontext( ctx_, other.ctx_, param, preserve_fpu);
-#if defined(BOOST_USE_SEGMENTED_STACKS)
- if ( stack_ctx_)
- __splitstack_setcontext( stack_ctx_->segments_ctx);
#endif
}
@@ -81,3 +90,7 @@
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
+
+#ifdef BOOST_MSVC
+ #pragma warning (pop)
+#endif
Modified: branches/release/libs/coroutine/src/detail/segmented_stack_allocator.cpp
==============================================================================
--- branches/release/libs/coroutine/src/detail/segmented_stack_allocator.cpp (original)
+++ branches/release/libs/coroutine/src/detail/segmented_stack_allocator.cpp 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -62,8 +62,6 @@
void
segmented_stack_allocator::allocate( stack_context & ctx, std::size_t size)
{
- BOOST_ASSERT( default_stacksize() <= size);
-
void * limit = __splitstack_makecontext( size, ctx.segments_ctx, & ctx.size);
BOOST_ASSERT( limit);
ctx.sp = static_cast< char * >( limit) + ctx.size;
Modified: branches/release/libs/coroutine/test/Jamfile.v2
==============================================================================
--- branches/release/libs/coroutine/test/Jamfile.v2 (original)
+++ branches/release/libs/coroutine/test/Jamfile.v2 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -19,6 +19,7 @@
<library>/boost/context//boost_context
<library>/boost/coroutine//boost_coroutine
<toolset>gcc-4.7,<segmented-stacks>on:<cxxflags>-fsplit-stack
+ <toolset>gcc-4.8,<segmented-stacks>on:<cxxflags>-fsplit-stack
<link>static
;
Modified: branches/release/libs/coroutine/test/test_coroutine.cpp
==============================================================================
--- branches/release/libs/coroutine/test/test_coroutine.cpp (original)
+++ branches/release/libs/coroutine/test/test_coroutine.cpp 2013-05-22 12:10:52 EDT (Wed, 22 May 2013)
@@ -153,6 +153,7 @@
{
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)
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