remove pull/push_coroutine_object classes

This commit is contained in:
Oliver Kowalke
2014-01-29 16:59:19 +01:00
parent d5e8413b5d
commit 0223e75a70
16 changed files with 572 additions and 1681 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -4,8 +4,8 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_COROUTINES_DETAIL_PULL_COROUTINE_BASE_H
#define BOOST_COROUTINES_DETAIL_PULL_COROUTINE_BASE_H
#ifndef BOOST_COROUTINES_DETAIL_PULL_COROUTINE_IMPL_H
#define BOOST_COROUTINES_DETAIL_PULL_COROUTINE_IMPL_H
#include <boost/assert.hpp>
#include <boost/config.hpp>
@@ -17,7 +17,7 @@
#include <boost/coroutine/detail/coroutine_context.hpp>
#include <boost/coroutine/detail/flags.hpp>
#include <boost/coroutine/detail/parameters.hpp>
#include <boost/coroutine/detail/trampoline.hpp>
#include <boost/coroutine/detail/trampoline_pull.hpp>
#include <boost/coroutine/exceptions.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
@@ -32,17 +32,16 @@ struct stack_context;
namespace detail {
template< typename R >
class pull_coroutine_base : private noncopyable
class pull_coroutine_impl : private noncopyable
{
private:
template<
typename X, typename Y, typename Z
>
friend class push_coroutine_object;
friend void trampoline_pull( intptr_t);
typedef parameters< R > param_type;
protected:
int flags_;
exception_ptr except_;
coroutine_context * caller_;
@@ -50,7 +49,7 @@ protected:
R * result_;
public:
pull_coroutine_base( coroutine_context * caller,
pull_coroutine_impl( coroutine_context * caller,
coroutine_context * callee,
bool unwind, bool preserve_fpu) :
flags_( 0),
@@ -63,7 +62,7 @@ public:
if ( preserve_fpu) flags_ |= flag_preserve_fpu;
}
pull_coroutine_base( coroutine_context * caller,
pull_coroutine_impl( coroutine_context * caller,
coroutine_context * callee,
bool unwind, bool preserve_fpu,
R * result) :
@@ -77,7 +76,7 @@ public:
if ( preserve_fpu) flags_ |= flag_preserve_fpu;
}
virtual ~pull_coroutine_base()
virtual ~pull_coroutine_impl()
{}
bool force_unwind() const BOOST_NOEXCEPT
@@ -145,17 +144,16 @@ public:
};
template< typename R >
class pull_coroutine_base< R & > : private noncopyable
class pull_coroutine_impl< R & > : private noncopyable
{
private:
template<
typename X, typename Y, typename Z
>
friend class push_coroutine_object;
friend void trampoline_pull( intptr_t);
typedef parameters< R & > param_type;
protected:
int flags_;
exception_ptr except_;
coroutine_context * caller_;
@@ -163,7 +161,7 @@ protected:
R * result_;
public:
pull_coroutine_base( coroutine_context * caller,
pull_coroutine_impl( coroutine_context * caller,
coroutine_context * callee,
bool unwind, bool preserve_fpu) :
flags_( 0),
@@ -176,7 +174,7 @@ public:
if ( preserve_fpu) flags_ |= flag_preserve_fpu;
}
pull_coroutine_base( coroutine_context * caller,
pull_coroutine_impl( coroutine_context * caller,
coroutine_context * callee,
bool unwind, bool preserve_fpu,
R * result) :
@@ -190,7 +188,7 @@ public:
if ( preserve_fpu) flags_ |= flag_preserve_fpu;
}
virtual ~pull_coroutine_base()
virtual ~pull_coroutine_impl()
{}
bool force_unwind() const BOOST_NOEXCEPT
@@ -258,15 +256,13 @@ public:
};
template<>
class pull_coroutine_base< void > : private noncopyable
class pull_coroutine_impl< void > : private noncopyable
{
private:
template< typename X, typename Y, typename Z >
friend class push_coroutine_object;
template<
typename X, typename Y, typename Z
>
friend void trampoline_void( intptr_t);
friend void trampoline_pull_void( intptr_t);
typedef parameters< void > param_type;
@@ -276,7 +272,7 @@ private:
coroutine_context * callee_;
public:
pull_coroutine_base( coroutine_context * caller,
pull_coroutine_impl( coroutine_context * caller,
coroutine_context * callee,
bool unwind, bool preserve_fpu) :
flags_( 0),
@@ -288,7 +284,7 @@ public:
if ( preserve_fpu) flags_ |= flag_preserve_fpu;
}
virtual ~pull_coroutine_base()
virtual ~pull_coroutine_impl()
{}
bool force_unwind() const BOOST_NOEXCEPT
@@ -341,4 +337,4 @@ public:
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_DETAIL_PULL_COROUTINE_BASE_H
#endif // BOOST_COROUTINES_DETAIL_PULL_COROUTINE_IMPL_H

View File

@@ -1,191 +0,0 @@
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_COROUTINES_DETAIL_PULL_COROUTINE_OBJECT_H
#define BOOST_COROUTINES_DETAIL_PULL_COROUTINE_OBJECT_H
#include <cstddef>
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/exception_ptr.hpp>
#include <boost/move/move.hpp>
#include <boost/coroutine/attributes.hpp>
#include <boost/coroutine/detail/config.hpp>
#include <boost/coroutine/exceptions.hpp>
#include <boost/coroutine/detail/flags.hpp>
#include <boost/coroutine/detail/parameters.hpp>
#include <boost/coroutine/flags.hpp>
#include <boost/coroutine/detail/pull_coroutine_base.hpp>
#ifdef BOOST_MSVC
#pragma warning (push)
#pragma warning (disable: 4355) // using 'this' in initializer list
#endif
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
namespace detail {
template< typename R, typename Fn, typename Caller >
class pull_coroutine_object : public pull_coroutine_base< R >
{
private:
typedef pull_coroutine_base< R > base_type;
typedef parameters< R > param_type;
Fn fn_;
pull_coroutine_object( pull_coroutine_object &);
pull_coroutine_object & operator=( pull_coroutine_object const&);
public:
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
pull_coroutine_object( Fn fn, attributes const& attr,
coroutine_context * caller,
coroutine_context * callee) :
base_type( caller, callee,
stack_unwind == attr.do_unwind,
fpu_preserved == attr.preserve_fpu),
fn_( fn)
{}
#endif
pull_coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
coroutine_context * caller,
coroutine_context * callee) :
base_type( caller, callee,
stack_unwind == attr.do_unwind,
fpu_preserved == attr.preserve_fpu),
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
fn_( fn)
#else
fn_( forward< Fn >( fn) )
#endif
{}
void run()
{
{
param_type * from(
reinterpret_cast< param_type * >(
this->callee_->jump(
* this->caller_,
reinterpret_cast< intptr_t >( this),
this->preserve_fpu() ) ) );
this->result_ = from->data;
// create push_coroutine
typename Caller::base_t b( this->callee_, this->caller_, false, this->preserve_fpu() );
Caller c( & b);
try
{ fn_( c); }
catch ( forced_unwind const&)
{}
catch (...)
{ this->except_ = current_exception(); }
}
this->flags_ |= flag_complete;
param_type to;
this->callee_->jump(
* this->caller_,
reinterpret_cast< intptr_t >( & to),
this->preserve_fpu() );
BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
}
};
template< typename R, typename Fn, typename Caller >
class pull_coroutine_object< R &, Fn, Caller > : public pull_coroutine_base< R & >
{
private:
typedef pull_coroutine_base< R & > base_type;
typedef parameters< R & > param_type;
Fn fn_;
pull_coroutine_object( pull_coroutine_object &);
pull_coroutine_object & operator=( pull_coroutine_object const&);
public:
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
pull_coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
coroutine_context * caller,
coroutine_context * callee) :
base_type( caller, callee,
stack_unwind == attr.do_unwind,
fpu_preserved == attr.preserve_fpu),
fn_( forward< Fn >( fn) )
{}
#else
pull_coroutine_object( Fn fn, attributes const& attr,
coroutine_context * caller,
coroutine_context * callee) :
base_type( caller, callee,
stack_unwind == attr.do_unwind,
fpu_preserved == attr.preserve_fpu),
fn_( fn)
{}
pull_coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
coroutine_context * caller,
coroutine_context * callee) :
base_type( caller, callee,
stack_unwind == attr.do_unwind,
fpu_preserved == attr.preserve_fpu),
fn_( fn)
{}
#endif
void run()
{
{
param_type * from(
reinterpret_cast< param_type * >(
this->callee_->jump(
* this->caller_,
reinterpret_cast< intptr_t >( this),
this->preserve_fpu() ) ) );
this->result_ = from->data;
// create push_coroutine
typename Caller::base_t b( this->callee_, this->caller_, false, this->preserve_fpu() );
Caller c( & b);
try
{ fn_( c); }
catch ( forced_unwind const&)
{}
catch (...)
{ this->except_ = current_exception(); }
}
this->flags_ |= flag_complete;
param_type to;
this->callee_->jump(
* this->caller_,
reinterpret_cast< intptr_t >( & to),
this->preserve_fpu() );
BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
}
};
}}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#ifdef BOOST_MSVC
#pragma warning (pop)
#endif
#endif // BOOST_COROUTINES_DETAIL_PULL_COROUTINE_OBJECT_H

View File

@@ -4,8 +4,8 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_BASE_H
#define BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_BASE_H
#ifndef BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_IMPL_H
#define BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_IMPL_H
#include <boost/assert.hpp>
#include <boost/config.hpp>
@@ -17,6 +17,7 @@
#include <boost/coroutine/detail/coroutine_context.hpp>
#include <boost/coroutine/detail/flags.hpp>
#include <boost/coroutine/detail/parameters.hpp>
#include <boost/coroutine/detail/trampoline_push.hpp>
#include <boost/coroutine/exceptions.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
@@ -31,24 +32,23 @@ struct stack_context;
namespace detail {
template< typename Arg >
class push_coroutine_base : private noncopyable
class push_coroutine_impl : private noncopyable
{
private:
template<
typename X, typename Y, typename Z
>
friend class pull_coroutine_object;
friend void trampoline_push( intptr_t);
typedef parameters< Arg > param_type;
protected:
int flags_;
exception_ptr except_;
coroutine_context * caller_;
coroutine_context * callee_;
public:
push_coroutine_base( coroutine_context * caller,
push_coroutine_impl( coroutine_context * caller,
coroutine_context * callee,
bool unwind, bool preserve_fpu) :
flags_( 0),
@@ -60,7 +60,7 @@ public:
if ( preserve_fpu) flags_ |= flag_preserve_fpu;
}
virtual ~push_coroutine_base()
virtual ~push_coroutine_impl()
{}
bool force_unwind() const BOOST_NOEXCEPT
@@ -123,24 +123,23 @@ public:
};
template< typename Arg >
class push_coroutine_base< Arg & > : private noncopyable
class push_coroutine_impl< Arg & > : private noncopyable
{
private:
template<
typename X, typename Y, typename Z
>
friend class pull_coroutine_object;
friend void trampoline_push( intptr_t);
typedef parameters< Arg & > param_type;
protected:
int flags_;
exception_ptr except_;
coroutine_context * caller_;
coroutine_context * callee_;
public:
push_coroutine_base( coroutine_context * caller,
push_coroutine_impl( coroutine_context * caller,
coroutine_context * callee,
bool unwind, bool preserve_fpu) :
flags_( 0),
@@ -152,7 +151,7 @@ public:
if ( preserve_fpu) flags_ |= flag_preserve_fpu;
}
virtual ~push_coroutine_base()
virtual ~push_coroutine_impl()
{}
bool force_unwind() const BOOST_NOEXCEPT
@@ -200,17 +199,13 @@ public:
};
template<>
class push_coroutine_base< void > : private noncopyable
class push_coroutine_impl< void > : private noncopyable
{
private:
template<
typename X, typename Y, typename Z
>
friend class pull_coroutine_object;
template<
typename X, typename Y, typename Z
>
friend void trampoline_void( intptr_t);
friend void trampoline_push_void( intptr_t);
typedef parameters< void > param_type;
@@ -220,7 +215,7 @@ private:
coroutine_context * callee_;
public:
push_coroutine_base( coroutine_context * caller,
push_coroutine_impl( coroutine_context * caller,
coroutine_context * callee,
bool unwind, bool preserve_fpu) :
flags_( 0),
@@ -232,7 +227,7 @@ public:
if ( preserve_fpu) flags_ |= flag_preserve_fpu;
}
virtual ~push_coroutine_base()
virtual ~push_coroutine_impl()
{}
bool force_unwind() const BOOST_NOEXCEPT
@@ -285,4 +280,4 @@ public:
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_BASE_H
#endif // BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_IMPL_H

View File

@@ -1,192 +0,0 @@
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_OBJECT_H
#define BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_OBJECT_H
#include <cstddef>
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/exception_ptr.hpp>
#include <boost/move/move.hpp>
#include <boost/utility.hpp>
#include <boost/coroutine/attributes.hpp>
#include <boost/coroutine/detail/config.hpp>
#include <boost/coroutine/exceptions.hpp>
#include <boost/coroutine/detail/flags.hpp>
#include <boost/coroutine/detail/parameters.hpp>
#include <boost/coroutine/flags.hpp>
#include <boost/coroutine/detail/push_coroutine_base.hpp>
#ifdef BOOST_MSVC
#pragma warning (push)
#pragma warning (disable: 4355) // using 'this' in initializer list
#endif
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
namespace detail {
template< typename Arg, typename Fn, typename Caller >
class push_coroutine_object : public push_coroutine_base< Arg >
{
private:
typedef push_coroutine_base< Arg > base_type;
typedef parameters< Arg > param_type;
Fn fn_;
push_coroutine_object( push_coroutine_object &);
push_coroutine_object & operator=( push_coroutine_object const&);
public:
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
push_coroutine_object( Fn fn, attributes const& attr,
coroutine_context * caller,
coroutine_context * callee) :
base_type( caller, callee,
stack_unwind == attr.do_unwind,
fpu_preserved == attr.preserve_fpu),
fn_( fn)
{}
#endif
push_coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
coroutine_context * caller,
coroutine_context * callee) :
base_type( caller, callee,
stack_unwind == attr.do_unwind,
fpu_preserved == attr.preserve_fpu),
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
fn_( fn)
#else
fn_( forward< Fn >( fn) )
#endif
{}
void run()
{
{
param_type * from(
reinterpret_cast< param_type * >(
this->callee_->jump(
* this->caller_,
reinterpret_cast< intptr_t >( this),
this->preserve_fpu() ) ) );
BOOST_ASSERT( from->data);
// create pull_coroutine
typename Caller::base_t b( this->callee_, this->caller_, false, this->preserve_fpu(), from->data);
Caller c( & b);
try
{ fn_( c); }
catch ( forced_unwind const&)
{}
catch (...)
{ this->except_ = current_exception(); }
}
this->flags_ |= flag_complete;
param_type to;
this->callee_->jump(
* this->caller_,
reinterpret_cast< intptr_t >( & to),
this->preserve_fpu() );
BOOST_ASSERT_MSG( false, "push_coroutine is complete");
}
};
template< typename Arg, typename Fn, typename Caller >
class push_coroutine_object< Arg &, Fn, Caller > : public push_coroutine_base< Arg & >
{
private:
typedef push_coroutine_base< Arg & > base_type;
typedef parameters< Arg & > param_type;
Fn fn_;
push_coroutine_object( push_coroutine_object &);
push_coroutine_object & operator=( push_coroutine_object const&);
public:
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
push_coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
coroutine_context * caller,
coroutine_context * callee) :
base_type( caller, callee,
stack_unwind == attr.do_unwind,
fpu_preserved == attr.preserve_fpu),
fn_( forward< Fn >( fn) )
{}
#else
push_coroutine_object( Fn fn, attributes const& attr,
coroutine_context * caller,
coroutine_context * callee) :
base_type( caller, callee,
stack_unwind == attr.do_unwind,
fpu_preserved == attr.preserve_fpu),
fn_( fn)
{}
push_coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attr,
coroutine_context * caller,
coroutine_context * callee) :
base_type( caller, callee,
stack_unwind == attr.do_unwind,
fpu_preserved == attr.preserve_fpu),
fn_( fn)
{}
#endif
void run()
{
{
param_type * from(
reinterpret_cast< param_type * >(
this->callee_->jump(
* this->caller_,
reinterpret_cast< intptr_t >( this),
this->preserve_fpu() ) ) );
BOOST_ASSERT( from->data);
// create pull_coroutine
typename Caller::base_t b( this->callee_, this->caller_, false, this->preserve_fpu(), from->data);
Caller c( & b);
try
{ fn_( c); }
catch ( forced_unwind const&)
{}
catch (...)
{ this->except_ = current_exception(); }
}
this->flags_ |= flag_complete;
param_type to;
this->callee_->jump(
* this->caller_,
reinterpret_cast< intptr_t >( & to),
this->preserve_fpu() );
BOOST_ASSERT_MSG( false, "push_coroutine is complete");
}
};
}}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#ifdef BOOST_MSVC
#pragma warning (pop)
#endif
#endif // BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_OBJECT_H

View File

@@ -25,7 +25,7 @@ namespace boost {
namespace coroutines {
namespace detail {
template< typename Fn, typename Coro >
template< typename Fn >
struct setup
{
struct dummy {};

View File

@@ -4,8 +4,8 @@
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_COROUTINES_DETAIL_TRAMPOLINE_H
#define BOOST_COROUTINES_DETAIL_TRAMPOLINE_H
#ifndef BOOST_COROUTINES_DETAIL_TRAMPOLINE_PULL_H
#define BOOST_COROUTINES_DETAIL_TRAMPOLINE_PULL_H
#include <cstddef>
@@ -31,32 +31,64 @@ namespace boost {
namespace coroutines {
namespace detail {
template< typename Fn, typename Coro >
void trampoline( intptr_t vp)
template< typename Fn, typename Coro, typename Self >
void trampoline_pull( intptr_t vp)
{
typedef typename Coro::param_type param_type;
BOOST_ASSERT( vp);
setup< Fn, Coro > * from(
reinterpret_cast< setup< Fn, Coro > * >( vp) );
setup< Fn > * from(
reinterpret_cast< setup< Fn > * >( vp) );
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Coro c( forward< Fn >( from->fn), from->attr, from->caller, from->callee);
Fn fn( forward< Fn >( from->fn) );
#else
Coro c( move( from->fn), from->attr, from->caller, from->callee);
Fn fn( move( from->fn) );
#endif
Coro c( from->caller, from->callee,
stack_unwind == from->attr.do_unwind,
fpu_preserved == from->attr.preserve_fpu);
from = 0;
c.run();
{
param_type * from(
reinterpret_cast< param_type * >(
c.callee_->jump(
* c.caller_,
reinterpret_cast< intptr_t >( & c),
c.preserve_fpu() ) ) );
c.result_ = from->data;
// create push_coroutine
typename Self::impl_type b( c.callee_, c.caller_, false, c.preserve_fpu() );
Self self( & b);
try
{ fn( self); }
catch ( forced_unwind const&)
{}
catch (...)
{ c.except_ = current_exception(); }
}
c.flags_ |= flag_complete;
param_type to;
c.callee_->jump(
* c.caller_,
reinterpret_cast< intptr_t >( & to),
c.preserve_fpu() );
BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
}
template< typename Fn, typename Coro, typename Self >
void trampoline_void( intptr_t vp)
void trampoline_pull_void( intptr_t vp)
{
typedef parameters< void > param_type;
typedef typename Coro::param_type param_type;
BOOST_ASSERT( vp);
setup< Fn, Coro > * from(
reinterpret_cast< setup< Fn, Coro > * >( vp) );
setup< Fn > * from(
reinterpret_cast< setup< Fn > * >( vp) );
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Fn fn( forward< Fn >( from->fn) );
@@ -75,7 +107,7 @@ void trampoline_void( intptr_t vp)
c.preserve_fpu() );
// create push_coroutine
typename Self::base_t b( c.callee_, c.caller_, false, c.preserve_fpu() );
typename Self::impl_type b( c.callee_, c.caller_, false, c.preserve_fpu() );
Self self( & b);
try
{ fn( self); }
@@ -100,4 +132,4 @@ void trampoline_void( intptr_t vp)
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_DETAIL_TRAMPOLINE_H
#endif // BOOST_COROUTINES_DETAIL_TRAMPOLINE_PULL_H

View File

@@ -0,0 +1,135 @@
// 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_TRAMPOLINE_PUSH_H
#define BOOST_COROUTINES_DETAIL_TRAMPOLINE_PUSH_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/coroutine/detail/config.hpp>
#include <boost/coroutine/detail/flags.hpp>
#include <boost/coroutine/detail/parameters.hpp>
#include <boost/coroutine/detail/setup.hpp>
#include <boost/coroutine/detail/setup.hpp>
#include <boost/coroutine/exceptions.hpp>
#include <boost/coroutine/flags.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
namespace detail {
template< typename Fn, typename Coro, typename Self >
void trampoline_push( intptr_t vp)
{
typedef typename Coro::param_type param_type;
BOOST_ASSERT( vp);
setup< Fn > * from(
reinterpret_cast< setup< Fn > * >( vp) );
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Fn fn( forward< Fn >( from->fn) );
#else
Fn fn( move( from->fn) );
#endif
Coro c( from->caller, from->callee,
stack_unwind == from->attr.do_unwind,
fpu_preserved == from->attr.preserve_fpu);
from = 0;
{
param_type * from(
reinterpret_cast< param_type * >(
c.callee_->jump(
* c.caller_,
reinterpret_cast< intptr_t >( & c),
c.preserve_fpu() ) ) );
BOOST_ASSERT( from->data);
// create push_coroutine
typename Self::impl_type b( c.callee_, c.caller_, false, c.preserve_fpu(), from->data);
Self self( & b);
try
{ fn( self); }
catch ( forced_unwind const&)
{}
catch (...)
{ c.except_ = current_exception(); }
}
c.flags_ |= flag_complete;
param_type to;
c.callee_->jump(
* c.caller_,
reinterpret_cast< intptr_t >( & to),
c.preserve_fpu() );
BOOST_ASSERT_MSG( false, "push_coroutine is complete");
}
template< typename Fn, typename Coro, typename Self >
void trampoline_push_void( intptr_t vp)
{
typedef typename Coro::param_type param_type;
BOOST_ASSERT( vp);
setup< Fn > * from(
reinterpret_cast< setup< Fn > * >( vp) );
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Fn fn( forward< Fn >( from->fn) );
#else
Fn fn( move( from->fn) );
#endif
Coro c( from->caller, from->callee,
stack_unwind == from->attr.do_unwind,
fpu_preserved == from->attr.preserve_fpu);
from = 0;
{
c.callee_->jump(
* c.caller_,
reinterpret_cast< intptr_t >( & c),
c.preserve_fpu() );
// create push_coroutine
typename Self::impl_type b( c.callee_, c.caller_, false, c.preserve_fpu() );
Self self( & b);
try
{ fn( self); }
catch ( forced_unwind const&)
{}
catch (...)
{ c.except_ = current_exception(); }
}
c.flags_ |= flag_complete;
param_type to;
c.callee_->jump(
* c.caller_,
reinterpret_cast< intptr_t >( & to),
c.preserve_fpu() );
BOOST_ASSERT_MSG( false, "push_coroutine is complete");
}
}}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_DETAIL_TRAMPOLINE_PUSH_H