|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r84099 - in trunk: boost/coroutine boost/coroutine/detail boost/coroutine/v1 boost/coroutine/v1/detail boost/coroutine/v2 boost/coroutine/v2/detail libs/coroutine/example/c++11 libs/coroutine/src/detail libs/coroutine/test
From: oliver.kowalke_at_[hidden]
Date: 2013-05-01 06:40:10
Author: olli
Date: 2013-05-01 06:40:07 EDT (Wed, 01 May 2013)
New Revision: 84099
URL: http://svn.boost.org/trac/boost/changeset/84099
Log:
coroutine: fix for 8526, reorg. for new interface
Added:
trunk/boost/coroutine/
trunk/boost/coroutine/all.hpp (contents, props changed)
trunk/boost/coroutine/attributes.hpp (contents, props changed)
trunk/boost/coroutine/checkpoint.hpp (contents, props changed)
trunk/boost/coroutine/coroutine.hpp (contents, props changed)
trunk/boost/coroutine/detail/
trunk/boost/coroutine/detail/config.hpp (contents, props changed)
trunk/boost/coroutine/detail/coroutine_context.hpp (contents, props changed)
trunk/boost/coroutine/detail/exceptions.hpp (contents, props changed)
trunk/boost/coroutine/detail/flags.hpp (contents, props changed)
trunk/boost/coroutine/detail/holder.hpp (contents, props changed)
trunk/boost/coroutine/detail/param.hpp (contents, props changed)
trunk/boost/coroutine/detail/segmented_stack_allocator.hpp (contents, props changed)
trunk/boost/coroutine/detail/standard_stack_allocator.hpp (contents, props changed)
trunk/boost/coroutine/flags.hpp (contents, props changed)
trunk/boost/coroutine/stack_allocator.hpp (contents, props changed)
trunk/boost/coroutine/stack_context.hpp (contents, props changed)
trunk/boost/coroutine/v1/
trunk/boost/coroutine/v1/coroutine.hpp (contents, props changed)
trunk/boost/coroutine/v1/detail/
trunk/boost/coroutine/v1/detail/arg.hpp (contents, props changed)
trunk/boost/coroutine/v1/detail/coroutine_base.hpp (contents, props changed)
trunk/boost/coroutine/v1/detail/coroutine_base_resume.hpp (contents, props changed)
trunk/boost/coroutine/v1/detail/coroutine_caller.hpp (contents, props changed)
trunk/boost/coroutine/v1/detail/coroutine_get.hpp (contents, props changed)
trunk/boost/coroutine/v1/detail/coroutine_object.hpp (contents, props changed)
trunk/boost/coroutine/v1/detail/coroutine_object_result_0.ipp (contents, props changed)
trunk/boost/coroutine/v1/detail/coroutine_object_result_1.ipp (contents, props changed)
trunk/boost/coroutine/v1/detail/coroutine_object_result_arity.ipp (contents, props changed)
trunk/boost/coroutine/v1/detail/coroutine_object_void_0.ipp (contents, props changed)
trunk/boost/coroutine/v1/detail/coroutine_object_void_1.ipp (contents, props changed)
trunk/boost/coroutine/v1/detail/coroutine_object_void_arity.ipp (contents, props changed)
trunk/boost/coroutine/v1/detail/coroutine_op.hpp (contents, props changed)
trunk/boost/coroutine/v2/
trunk/boost/coroutine/v2/detail/
trunk/boost/coroutine/v2/detail/coroutine_object.hpp (contents, props changed)
trunk/boost/coroutine/v2/pull_corotuine.hpp (contents, props changed)
trunk/boost/coroutine/v2/push_coroutine.hpp (contents, props changed)
trunk/libs/coroutine/example/c++11/
trunk/libs/coroutine/example/c++11/fibonacci.cpp (contents, props changed)
trunk/libs/coroutine/example/c++11/same_fringe.cpp (contents, props changed)
trunk/libs/coroutine/example/c++11/tree.h (contents, props changed)
Text files modified:
trunk/libs/coroutine/src/detail/coroutine_context.cpp | 20 ++++++++++++--------
trunk/libs/coroutine/src/detail/segmented_stack_allocator.cpp | 2 --
trunk/libs/coroutine/test/test_coroutine.cpp | 1 +
3 files changed, 13 insertions(+), 10 deletions(-)
Added: trunk/boost/coroutine/all.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/all.hpp 2013-05-01 06:40:07 EDT (Wed, 01 May 2013)
@@ -0,0 +1,15 @@
+
+// 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_ALL_H
+#define BOOST_COROUTINES_ALL_H
+
+#include <boost/coroutine/attributes.hpp>
+#include <boost/coroutine/coroutine.hpp>
+#include <boost/coroutine/flags.hpp>
+#include <boost/coroutine/stack_allocator.hpp>
+
+#endif // BOOST_COROUTINES_ALL_H
Added: trunk/boost/coroutine/attributes.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/attributes.hpp 2013-05-01 06:40:07 EDT (Wed, 01 May 2013)
@@ -0,0 +1,85 @@
+
+// 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_ATTRIBUTES_H
+#define BOOST_COROUTINES_ATTRIBUTES_H
+
+#include <cstddef>
+
+#include <boost/config.hpp>
+
+#include <boost/coroutine/flags.hpp>
+#include <boost/coroutine/stack_allocator.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+
+struct attributes
+{
+ std::size_t size;
+ flag_unwind_t do_unwind;
+ flag_fpu_t preserve_fpu;
+
+ attributes() BOOST_NOEXCEPT :
+ size( stack_allocator::default_stacksize() ),
+ do_unwind( stack_unwind),
+ preserve_fpu( fpu_preserved)
+ {}
+
+ explicit attributes( std::size_t size_) BOOST_NOEXCEPT :
+ size( size_),
+ do_unwind( stack_unwind),
+ preserve_fpu( fpu_preserved)
+ {}
+
+ explicit attributes( flag_unwind_t do_unwind_) BOOST_NOEXCEPT :
+ size( stack_allocator::default_stacksize() ),
+ do_unwind( do_unwind_),
+ preserve_fpu( fpu_preserved)
+ {}
+
+ explicit attributes( flag_fpu_t preserve_fpu_) BOOST_NOEXCEPT :
+ size( stack_allocator::default_stacksize() ),
+ do_unwind( stack_unwind),
+ preserve_fpu( preserve_fpu_)
+ {}
+
+ explicit attributes(
+ std::size_t size_,
+ flag_unwind_t do_unwind_) BOOST_NOEXCEPT :
+ size( size_),
+ do_unwind( do_unwind_),
+ preserve_fpu( fpu_preserved)
+ {}
+
+ explicit attributes(
+ std::size_t size_,
+ flag_fpu_t preserve_fpu_) BOOST_NOEXCEPT :
+ size( size_),
+ do_unwind( stack_unwind),
+ preserve_fpu( preserve_fpu_)
+ {}
+
+ explicit attributes(
+ flag_unwind_t do_unwind_,
+ flag_fpu_t preserve_fpu_) BOOST_NOEXCEPT :
+ size( stack_allocator::default_stacksize() ),
+ do_unwind( do_unwind_),
+ preserve_fpu( preserve_fpu_)
+ {}
+};
+
+}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_ATTRIBUTES_H
Added: trunk/boost/coroutine/checkpoint.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/checkpoint.hpp 2013-05-01 06:40:07 EDT (Wed, 01 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
Added: trunk/boost/coroutine/coroutine.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/coroutine.hpp 2013-05-01 06:40:07 EDT (Wed, 01 May 2013)
@@ -0,0 +1,16 @@
+
+// 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_COROUTINE_H
+#define BOOST_COROUTINES_COROUTINE_H
+
+#ifdef BOOST_COROUTINES_V2
+#include <boost/coroutine/v2/coroutine.hpp>
+#else
+#include <boost/coroutine/v1/coroutine.hpp>
+#endif
+
+#endif // BOOST_COROUTINES_COROUTINE_H
Added: trunk/boost/coroutine/detail/config.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/detail/config.hpp 2013-05-01 06:40:07 EDT (Wed, 01 May 2013)
@@ -0,0 +1,53 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_COROUTINES_DETAIL_CONFIG_H
+#define BOOST_COROUTINES_DETAIL_CONFIG_H
+
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+
+#ifdef BOOST_COROUTINES_DECL
+# undef BOOST_COROUTINES_DECL
+#endif
+
+#if defined(BOOST_HAS_DECLSPEC)
+# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_COROUTINES_DYN_LINK)
+# if ! defined(BOOST_DYN_LINK)
+# define BOOST_DYN_LINK
+# endif
+# if defined(BOOST_COROUTINES_SOURCE)
+# define BOOST_COROUTINES_DECL BOOST_SYMBOL_EXPORT
+# else
+# define BOOST_COROUTINES_DECL BOOST_SYMBOL_IMPORT
+# endif
+# endif
+#endif
+
+#if ! defined(BOOST_COROUTINES_DECL)
+# define BOOST_COROUTINES_DECL
+#endif
+
+#if ! defined(BOOST_COROUTINES_SOURCE) && ! defined(BOOST_ALL_NO_LIB) && ! defined(BOOST_COROUTINES_NO_LIB)
+# define BOOST_LIB_NAME boost_context
+# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_COROUTINES_DYN_LINK)
+# define BOOST_DYN_LINK
+# endif
+# include <boost/config/auto_link.hpp>
+#endif
+
+#if defined(BOOST_USE_SEGMENTED_STACKS)
+# if ! (defined(__GNUC__) && __GNUC__ > 3 && __GNUC_MINOR__ > 6)
+# error "compiler does not support segmented stacks"
+# endif
+# define BOOST_COROUTINES_SEGMENTS 10
+#endif
+
+//#ifndef BOOST_COROUTINES_V1
+//# define BOOST_COROUTINES_V2
+//#endif
+
+#endif // BOOST_COROUTINES_DETAIL_CONFIG_H
Added: trunk/boost/coroutine/detail/coroutine_context.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/detail/coroutine_context.hpp 2013-05-01 06:40:07 EDT (Wed, 01 May 2013)
@@ -0,0 +1,61 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_COROUTINES_DETAIL_COROUTINE_CONTEXT_H
+#define BOOST_COROUTINES_DETAIL_COROUTINE_CONTEXT_H
+
+#include <cstddef>
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+#include <boost/context/fcontext.hpp>
+
+#include <boost/coroutine/detail/config.hpp>
+#include "boost/coroutine/stack_context.hpp"
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+#if defined(BOOST_USE_SEGMENTED_STACKS)
+extern "C" void *__splitstack_makecontext(
+ std::size_t, void * [BOOST_COROUTINES_SEGMENTS], std::size_t *);
+#endif
+
+namespace boost {
+namespace coroutines {
+namespace detail {
+
+
+class BOOST_COROUTINES_DECL coroutine_context : private context::fcontext_t,
+ private stack_context
+
+{
+private:
+ stack_context * stack_ctx_;
+ context::fcontext_t * ctx_;
+
+public:
+ typedef void( * ctx_fn)( intptr_t);
+
+ coroutine_context();
+
+ explicit coroutine_context( ctx_fn, stack_context *);
+
+ coroutine_context( coroutine_context const&);
+
+ coroutine_context& operator=( coroutine_context const&);
+
+ intptr_t jump( coroutine_context &, intptr_t = 0, bool = true);
+};
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_DETAIL_COROUTINE_CONTEXT_H
Added: trunk/boost/coroutine/detail/exceptions.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/detail/exceptions.hpp 2013-05-01 06:40:07 EDT (Wed, 01 May 2013)
@@ -0,0 +1,28 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_COROUTINES_DETAIL_EXCEPTIONs_H
+#define BOOST_COROUTINES_DETAIL_EXCEPTIONs_H
+
+#include <boost/config.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+namespace detail {
+
+struct forced_unwind {};
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_DETAIL_EXCEPTIONs_H
Added: trunk/boost/coroutine/detail/flags.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/detail/flags.hpp 2013-05-01 06:40:07 EDT (Wed, 01 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_DETAIL_FLAGS_H
+#define BOOST_COROUTINES_DETAIL_FLAGS_H
+
+#include <boost/config.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+namespace detail {
+
+enum flag_t
+{
+ flag_complete = 1 << 1,
+ flag_unwind_stack = 1 << 2,
+ flag_force_unwind = 1 << 3,
+ flag_preserve_fpu = 1 << 4
+};
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_DETAIL_FLAGS_H
Added: trunk/boost/coroutine/detail/holder.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/detail/holder.hpp 2013-05-01 06:40:07 EDT (Wed, 01 May 2013)
@@ -0,0 +1,90 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_COROUTINES_DETAIL_HOLDER_H
+#define BOOST_COROUTINES_DETAIL_HOLDER_H
+
+#include <boost/assert.hpp>
+#include <boost/config.hpp>
+#include <boost/optional.hpp>
+
+#include <boost/coroutine/detail/coroutine_context.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+namespace detail {
+
+template< typename Data >
+struct holder
+{
+ coroutine_context * ctx;
+ optional< Data > data;
+ bool force_unwind;
+
+ explicit holder( coroutine_context * ctx_) :
+ ctx( ctx_), data(), force_unwind( false)
+ { BOOST_ASSERT( ctx); }
+
+ explicit holder( coroutine_context * ctx_, Data data_) :
+ ctx( ctx_), data( data_), force_unwind( false)
+ { BOOST_ASSERT( ctx); }
+
+ explicit holder( coroutine_context * ctx_, bool force_unwind_) :
+ ctx( ctx_), data(), force_unwind( force_unwind_)
+ {
+ BOOST_ASSERT( ctx);
+ BOOST_ASSERT( force_unwind);
+ }
+
+ holder( holder const& other) :
+ ctx( other.ctx), data( other.data),
+ force_unwind( other.force_unwind)
+ {}
+
+ holder & operator=( holder const& other)
+ {
+ if ( this == & other) return * this;
+ ctx = other.ctx;
+ data = other.data;
+ force_unwind = other.force_unwind;
+ return * this;
+ }
+};
+
+template<>
+struct holder< void >
+{
+ coroutine_context * ctx;
+ bool force_unwind;
+
+ explicit holder( coroutine_context * ctx_, bool force_unwind_ = false) :
+ ctx( ctx_), force_unwind( force_unwind_)
+ { BOOST_ASSERT( ctx); }
+
+ holder( holder const& other) :
+ ctx( other.ctx), force_unwind( other.force_unwind)
+ {}
+
+ holder & operator=( holder const& other)
+ {
+ if ( this == & other) return * this;
+ ctx = other.ctx;
+ force_unwind = other.force_unwind;
+ return * this;
+ }
+};
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_DETAIL_HOLDER_H
Added: trunk/boost/coroutine/detail/param.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/detail/param.hpp 2013-05-01 06:40:07 EDT (Wed, 01 May 2013)
@@ -0,0 +1,46 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_COROUTINES_DETAIL_PARAM_H
+#define BOOST_COROUTINES_DETAIL_PARAM_H
+
+#include <boost/config.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/type_traits/is_reference.hpp>
+#include <boost/type_traits/is_scalar.hpp>
+#include <boost/type_traits/is_stateless.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+namespace detail {
+
+template< typename T >
+struct param :
+ public mpl::eval_if<
+ mpl::or_<
+ is_scalar< T >,
+ is_stateless< T >,
+ is_reference< T >
+ >,
+ mpl::identity< T >,
+ add_reference< T >
+ >
+{};
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_DETAIL_PARAM_H
Added: trunk/boost/coroutine/detail/segmented_stack_allocator.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/detail/segmented_stack_allocator.hpp 2013-05-01 06:40:07 EDT (Wed, 01 May 2013)
@@ -0,0 +1,51 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_COROUTINES_DETAIL_SEGMENTED_STACK_ALLOCATOR_H
+#define BOOST_COROUTINES_DETAIL_SEGMENTED_STACK_ALLOCATOR_H
+
+#include <cstddef>
+
+#include <boost/config.hpp>
+
+#include <boost/coroutine/detail/config.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+
+struct stack_context;
+
+namespace detail {
+
+#if defined(BOOST_USE_SEGMENTED_STACKS)
+class segmented_stack_allocator
+{
+public:
+ static bool is_stack_unbound();
+
+ static std::size_t default_stacksize();
+
+ static std::size_t minimum_stacksize();
+
+ static std::size_t maximum_stacksize();
+
+ void allocate( stack_context &, std::size_t = minimum_stacksize() );
+
+ void deallocate( stack_context &);
+};
+#endif
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_DETAIL_SEGMENTED_STACK_ALLOCATOR_H
Added: trunk/boost/coroutine/detail/standard_stack_allocator.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/detail/standard_stack_allocator.hpp 2013-05-01 06:40:07 EDT (Wed, 01 May 2013)
@@ -0,0 +1,49 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_COROUTINES_DETAIL_STANDARD_STACK_ALLOCATOR_H
+#define BOOST_COROUTINES_DETAIL_STANDARD_STACK_ALLOCATOR_H
+
+#include <cstddef>
+
+#include <boost/config.hpp>
+
+#include <boost/context/detail/config.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+
+struct stack_context;
+
+namespace detail {
+
+class standard_stack_allocator
+{
+public:
+ static bool is_stack_unbound();
+
+ static std::size_t default_stacksize();
+
+ static std::size_t minimum_stacksize();
+
+ static std::size_t maximum_stacksize();
+
+ void allocate( stack_context &, std::size_t);
+
+ void deallocate( stack_context &);
+};
+
+}}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_DETAIL_STANDARD_STACK_ALLOCATOR_H
Added: trunk/boost/coroutine/flags.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/flags.hpp 2013-05-01 06:40:07 EDT (Wed, 01 May 2013)
@@ -0,0 +1,27 @@
+
+// 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_FLAGS_H
+#define BOOST_COROUTINES_FLAGS_H
+
+namespace boost {
+namespace coroutines {
+
+enum flag_unwind_t
+{
+ stack_unwind = 0,
+ no_stack_unwind
+};
+
+enum flag_fpu_t
+{
+ fpu_preserved = 0,
+ fpu_not_preserved
+};
+
+}}
+
+#endif // BOOST_COROUTINES_FLAGS_H
Added: trunk/boost/coroutine/stack_allocator.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/stack_allocator.hpp 2013-05-01 06:40:07 EDT (Wed, 01 May 2013)
@@ -0,0 +1,37 @@
+
+// Copyright Oliver Kowalke 2009.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_COROUTINES_DETAIL_STACK_ALLOCATOR_H
+#define BOOST_COROUTINES_DETAIL_STACK_ALLOCATOR_H
+
+#include <cstddef>
+
+#include <boost/config.hpp>
+
+#include <boost/context/detail/config.hpp>
+#include <boost/coroutine/detail/segmented_stack_allocator.hpp>
+#include <boost/coroutine/detail/standard_stack_allocator.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+
+#if defined(BOOST_USE_SEGMENTED_STACKS)
+typedef detail::segmented_stack_allocator stack_allocator;
+#else
+typedef detail::standard_stack_allocator stack_allocator;
+#endif
+
+}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_DETAIL_STACK_ALLOCATOR_H
Added: trunk/boost/coroutine/stack_context.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/stack_context.hpp 2013-05-01 06:40:07 EDT (Wed, 01 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_STACK_CONTEXT_H
+#define BOOST_COROUTINES_STACK_CONTEXT_H
+
+#include <cstddef>
+
+#include <boost/config.hpp>
+
+#include <boost/coroutine/detail/config.hpp>
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_PREFIX
+#endif
+
+namespace boost {
+namespace coroutines {
+
+#if defined(BOOST_USE_SEGMENTED_STACKS)
+struct stack_context
+{
+ typedef void * segments_context[BOOST_COROUTINES_SEGMENTS];
+
+ std::size_t size;
+ void * sp;
+ segments_context segments_ctx;
+
+ stack_context() :
+ size( 0), sp( 0), segments_ctx()
+ {}
+};
+#else
+struct stack_context
+{
+ std::size_t size;
+ void * sp;
+
+ stack_context() :
+ size( 0), sp( 0)
+ {}
+};
+#endif
+
+}}
+
+#ifdef BOOST_HAS_ABI_HEADERS
+# include BOOST_ABI_SUFFIX
+#endif
+
+#endif // BOOST_COROUTINES_STACK_CONTEXT_H
Added: trunk/boost/coroutine/v1/coroutine.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/v1/coroutine.hpp 2013-05-01 06:40:07 EDT (Wed, 01 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: trunk/boost/coroutine/v1/detail/arg.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/v1/detail/arg.hpp 2013-05-01 06:40:07 EDT (Wed, 01 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: trunk/boost/coroutine/v1/detail/coroutine_base.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/v1/detail/coroutine_base.hpp 2013-05-01 06:40:07 EDT (Wed, 01 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: trunk/boost/coroutine/v1/detail/coroutine_base_resume.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/v1/detail/coroutine_base_resume.hpp 2013-05-01 06:40:07 EDT (Wed, 01 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: trunk/boost/coroutine/v1/detail/coroutine_caller.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/v1/detail/coroutine_caller.hpp 2013-05-01 06:40:07 EDT (Wed, 01 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: trunk/boost/coroutine/v1/detail/coroutine_get.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/v1/detail/coroutine_get.hpp 2013-05-01 06:40:07 EDT (Wed, 01 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: trunk/boost/coroutine/v1/detail/coroutine_object.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/v1/detail/coroutine_object.hpp 2013-05-01 06:40:07 EDT (Wed, 01 May 2013)
@@ -0,0 +1,102 @@
+
+// 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_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
+
+#endif // BOOST_COROUTINES_V1_DETAIL_COROUTINE_OBJECT_H
Added: trunk/boost/coroutine/v1/detail/coroutine_object_result_0.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/v1/detail/coroutine_object_result_0.ipp 2013-05-01 06:40:07 EDT (Wed, 01 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: trunk/boost/coroutine/v1/detail/coroutine_object_result_1.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/v1/detail/coroutine_object_result_1.ipp 2013-05-01 06:40:07 EDT (Wed, 01 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: trunk/boost/coroutine/v1/detail/coroutine_object_result_arity.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/v1/detail/coroutine_object_result_arity.ipp 2013-05-01 06:40:07 EDT (Wed, 01 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: trunk/boost/coroutine/v1/detail/coroutine_object_void_0.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/v1/detail/coroutine_object_void_0.ipp 2013-05-01 06:40:07 EDT (Wed, 01 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: trunk/boost/coroutine/v1/detail/coroutine_object_void_1.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/v1/detail/coroutine_object_void_1.ipp 2013-05-01 06:40:07 EDT (Wed, 01 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: trunk/boost/coroutine/v1/detail/coroutine_object_void_arity.ipp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/v1/detail/coroutine_object_void_arity.ipp 2013-05-01 06:40:07 EDT (Wed, 01 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: trunk/boost/coroutine/v1/detail/coroutine_op.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/v1/detail/coroutine_op.hpp 2013-05-01 06:40:07 EDT (Wed, 01 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: trunk/boost/coroutine/v2/detail/coroutine_object.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/v2/detail/coroutine_object.hpp 2013-05-01 06:40:07 EDT (Wed, 01 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: trunk/boost/coroutine/v2/pull_corotuine.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/v2/pull_corotuine.hpp 2013-05-01 06:40:07 EDT (Wed, 01 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: trunk/boost/coroutine/v2/push_coroutine.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/coroutine/v2/push_coroutine.hpp 2013-05-01 06:40:07 EDT (Wed, 01 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
Added: trunk/libs/coroutine/example/c++11/fibonacci.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/coroutine/example/c++11/fibonacci.cpp 2013-05-01 06:40:07 EDT (Wed, 01 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: trunk/libs/coroutine/example/c++11/same_fringe.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/coroutine/example/c++11/same_fringe.cpp 2013-05-01 06:40:07 EDT (Wed, 01 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: trunk/libs/coroutine/example/c++11/tree.h
==============================================================================
--- (empty file)
+++ trunk/libs/coroutine/example/c++11/tree.h 2013-05-01 06:40:07 EDT (Wed, 01 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: trunk/libs/coroutine/src/detail/coroutine_context.cpp
==============================================================================
--- trunk/libs/coroutine/src/detail/coroutine_context.cpp (original)
+++ trunk/libs/coroutine/src/detail/coroutine_context.cpp 2013-05-01 06:40:07 EDT (Wed, 01 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: trunk/libs/coroutine/src/detail/segmented_stack_allocator.cpp
==============================================================================
--- trunk/libs/coroutine/src/detail/segmented_stack_allocator.cpp (original)
+++ trunk/libs/coroutine/src/detail/segmented_stack_allocator.cpp 2013-05-01 06:40:07 EDT (Wed, 01 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: trunk/libs/coroutine/test/test_coroutine.cpp
==============================================================================
--- trunk/libs/coroutine/test/test_coroutine.cpp (original)
+++ trunk/libs/coroutine/test/test_coroutine.cpp 2013-05-01 06:40:07 EDT (Wed, 01 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