remove optional<>

This commit is contained in:
Oliver Kowalke
2014-01-21 19:07:13 +01:00
parent cd88c751db
commit 3675d0146e
9 changed files with 643 additions and 2042 deletions

View File

@@ -14,7 +14,6 @@
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/move/move.hpp>
#include <boost/optional.hpp>
#include <boost/range.hpp>
#include <boost/throw_exception.hpp>
#include <boost/type_traits/decay.hpp>
@@ -596,7 +595,7 @@ private:
pull_coroutine( detail::coroutine_context const& callee,
bool unwind, bool preserve_fpu,
Allocator const& alloc,
optional< R > const& result) :
R * result) :
impl_()
{
typedef detail::pull_coroutine_caller<
@@ -870,7 +869,7 @@ public:
{
private:
pull_coroutine< R > * c_;
optional< R > val_;
R * val_;
void fetch_()
{
@@ -879,7 +878,7 @@ public:
if ( ! c_->has_result() )
{
c_ = 0;
val_ = none;
val_ = 0;
return;
}
val_ = c_->get();
@@ -899,11 +898,11 @@ public:
typedef typename iterator::reference reference_t;
iterator() :
c_( 0), val_()
c_( 0), val_( 0)
{}
explicit iterator( pull_coroutine< R > * c) :
c_( c), val_()
c_( c), val_( 0)
{ fetch_(); }
iterator( iterator const& other) :
@@ -942,7 +941,7 @@ public:
if ( ! val_)
boost::throw_exception(
invalid_result() );
return const_cast< optional< R > & >( val_).get();
return * val_;
}
pointer_t operator->() const
@@ -950,7 +949,387 @@ public:
if ( ! val_)
boost::throw_exception(
invalid_result() );
return const_cast< optional< R > & >( val_).get_ptr();
return val_;
}
};
struct const_iterator;
};
template< typename R >
class pull_coroutine< R * >
{
private:
template<
typename X, typename Y, typename Z, typename V, typename W
>
friend class detail::push_coroutine_object;
typedef detail::pull_coroutine_base< R * > base_t;
typedef typename base_t::ptr_t ptr_t;
struct dummy
{ void nonnull() {} };
ptr_t impl_;
BOOST_MOVABLE_BUT_NOT_COPYABLE( pull_coroutine)
template< typename Allocator >
pull_coroutine( detail::coroutine_context const& callee,
bool unwind, bool preserve_fpu,
Allocator const& alloc,
R ** result) :
impl_()
{
typedef detail::pull_coroutine_caller<
R *, Allocator
> caller_t;
typename caller_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) caller_t(
callee, unwind, preserve_fpu, a, result) );
}
public:
pull_coroutine() BOOST_NOEXCEPT :
impl_()
{}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
# ifdef BOOST_MSVC
typedef void ( * coroutine_fn)( push_coroutine< R * > &);
explicit pull_coroutine( coroutine_fn fn, attributes const& attr = attributes(),
stack_allocator const& stack_alloc = stack_allocator(),
std::allocator< pull_coroutine > const& alloc = std::allocator< pull_coroutine >() ) :
impl_()
{
typedef detail::pull_coroutine_object<
R *, coroutine_fn, stack_allocator, std::allocator< pull_coroutine >,
push_coroutine< R * >
> object_t;
object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) );
}
template< typename StackAllocator >
explicit pull_coroutine( coroutine_fn fn, attributes const& attr,
StackAllocator const& stack_alloc,
std::allocator< pull_coroutine > const& alloc = std::allocator< pull_coroutine >() ) :
impl_()
{
typedef detail::pull_coroutine_object<
R *, coroutine_fn, StackAllocator, std::allocator< pull_coroutine >,
push_coroutine< R * >
> object_t;
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) );
}
template< typename StackAllocator, typename Allocator >
explicit pull_coroutine( coroutine_fn fn, attributes const& attr,
StackAllocator const& stack_alloc,
Allocator const& alloc) :
impl_()
{
typedef detail::pull_coroutine_object<
R *, coroutine_fn, StackAllocator, Allocator,
push_coroutine< R * >
> object_t;
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( forward< coroutine_fn >( fn), attr, stack_alloc, a) );
}
# endif
template< typename Fn >
explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(),
stack_allocator const& stack_alloc = stack_allocator(),
std::allocator< pull_coroutine > const& alloc = std::allocator< pull_coroutine >() ) :
impl_()
{
typedef detail::pull_coroutine_object<
R *, Fn, stack_allocator, std::allocator< pull_coroutine >,
push_coroutine< R * >
> object_t;
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) );
}
template< typename Fn, typename StackAllocator >
explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr,
StackAllocator const& stack_alloc,
std::allocator< pull_coroutine > const& alloc = std::allocator< pull_coroutine >() ) :
impl_()
{
typedef detail::pull_coroutine_object<
R *, Fn, StackAllocator, std::allocator< pull_coroutine >,
push_coroutine< R * >
> object_t;
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) );
}
template< typename Fn, typename StackAllocator, typename Allocator >
explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr,
StackAllocator const& stack_alloc,
Allocator const& alloc) :
impl_()
{
typedef detail::pull_coroutine_object<
R *, Fn, StackAllocator, Allocator,
push_coroutine< R * >
> object_t;
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( forward< Fn >( fn), attr, stack_alloc, a) );
}
#else
template< typename Fn >
explicit pull_coroutine( Fn fn, attributes const& attr = attributes(),
stack_allocator const& stack_alloc = stack_allocator(),
std::allocator< pull_coroutine > const& alloc = std::allocator< pull_coroutine >(),
typename disable_if< is_convertible< Fn &, BOOST_RV_REF(Fn) >, dummy* >::type = 0) :
impl_()
{
typedef detail::pull_coroutine_object<
R *, Fn, stack_allocator, std::allocator< pull_coroutine >,
push_coroutine< R * >
> object_t;
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
}
template< typename Fn, typename StackAllocator >
explicit pull_coroutine( Fn fn, attributes const& attr,
StackAllocator const& stack_alloc,
std::allocator< pull_coroutine > const& alloc = std::allocator< pull_coroutine >(),
typename disable_if< is_convertible< Fn &, BOOST_RV_REF(Fn) >, dummy* >::type = 0) :
impl_()
{
typedef detail::pull_coroutine_object<
R *, Fn, StackAllocator, std::allocator< pull_coroutine >,
push_coroutine< R * >
> object_t;
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
}
template< typename Fn, typename StackAllocator, typename Allocator >
explicit pull_coroutine( Fn fn, attributes const& attr,
StackAllocator const& stack_alloc,
Allocator const& alloc,
typename disable_if< is_convertible< Fn &, BOOST_RV_REF(Fn) >, dummy* >::type = 0) :
impl_()
{
typedef detail::pull_coroutine_object<
R *, Fn, StackAllocator, Allocator,
push_coroutine< R * >
> object_t;
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
}
template< typename Fn >
explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr = attributes(),
stack_allocator const& stack_alloc = stack_allocator(),
std::allocator< pull_coroutine > const& alloc = std::allocator< pull_coroutine >(),
typename disable_if<
is_same< typename decay< Fn >::type, pull_coroutine >, dummy*
>::type = 0) :
impl_()
{
typedef detail::pull_coroutine_object<
R *, Fn, stack_allocator, std::allocator< pull_coroutine >,
push_coroutine< R * >
> object_t;
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
}
template< typename Fn, typename StackAllocator >
explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr,
StackAllocator const& stack_alloc,
std::allocator< pull_coroutine > const& alloc = std::allocator< pull_coroutine >(),
typename disable_if<
is_same< typename decay< Fn >::type, pull_coroutine >, dummy*
>::type = 0) :
impl_()
{
typedef detail::pull_coroutine_object<
R *, Fn, StackAllocator, std::allocator< pull_coroutine >,
push_coroutine< R * >
> object_t;
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
}
template< typename Fn, typename StackAllocator, typename Allocator >
explicit pull_coroutine( BOOST_RV_REF( Fn) fn, attributes const& attr,
StackAllocator const& stack_alloc,
Allocator const& alloc,
typename disable_if<
is_same< typename decay< Fn >::type, pull_coroutine >, dummy*
>::type = 0) :
impl_()
{
typedef detail::pull_coroutine_object<
R *, Fn, StackAllocator, Allocator,
push_coroutine< R * >
> object_t;
typename object_t::allocator_t a( alloc);
impl_ = ptr_t(
// placement new
::new( a.allocate( 1) ) object_t( fn, attr, stack_alloc, a) );
}
#endif
pull_coroutine( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT :
impl_()
{ swap( other); }
pull_coroutine & operator=( BOOST_RV_REF( pull_coroutine) other) BOOST_NOEXCEPT
{
pull_coroutine tmp( boost::move( other) );
swap( tmp);
return * this;
}
bool empty() const BOOST_NOEXCEPT
{ return ! impl_; }
BOOST_EXPLICIT_OPERATOR_BOOL();
bool operator!() const BOOST_NOEXCEPT
{ return empty() || impl_->is_complete(); }
void swap( pull_coroutine & other) BOOST_NOEXCEPT
{ impl_.swap( other.impl_); }
pull_coroutine & operator()()
{
BOOST_ASSERT( * this);
impl_->pull();
return * this;
}
bool has_result() const
{
BOOST_ASSERT( ! empty() );
return impl_->has_result();
}
R * get() const
{ return impl_->get(); }
class iterator : public std::iterator< std::input_iterator_tag, R >
{
private:
pull_coroutine< R * > * c_;
R ** val_;
void fetch_()
{
BOOST_ASSERT( c_);
if ( ! c_->has_result() )
{
c_ = 0;
val_ = 0;
return;
}
val_ = c_->get();
}
void increment_()
{
BOOST_ASSERT( c_);
BOOST_ASSERT( * c_);
( * c_)();
fetch_();
}
public:
typedef typename iterator::pointer pointer_t;
typedef typename iterator::reference reference_t;
iterator() :
c_( 0), val_( 0)
{}
explicit iterator( pull_coroutine< R * > * c) :
c_( c), val_( 0)
{ fetch_(); }
iterator( iterator const& other) :
c_( other.c_), val_( other.val_)
{}
iterator & operator=( iterator const& other)
{
if ( this == & other) return * this;
c_ = other.c_;
val_ = other.val_;
return * this;
}
bool operator==( iterator const& other)
{ return other.c_ == c_ && other.val_ == val_; }
bool operator!=( iterator const& other)
{ return other.c_ != c_ || other.val_ != val_; }
iterator & operator++()
{
increment_();
return * this;
}
iterator operator++( int)
{
iterator tmp( * this);
++*this;
return tmp;
}
reference_t operator*() const
{
if ( ! val_)
boost::throw_exception(
invalid_result() );
return * val_;
}
pointer_t operator->() const
{
if ( ! val_)
boost::throw_exception(
invalid_result() );
return val_;
}
};
@@ -980,7 +1359,7 @@ private:
pull_coroutine( detail::coroutine_context const& callee,
bool unwind, bool preserve_fpu,
Allocator const& alloc,
optional< R * > const& result) :
R * result) :
impl_()
{
typedef detail::pull_coroutine_caller<
@@ -1249,8 +1628,8 @@ public:
class iterator : public std::iterator< std::input_iterator_tag, R >
{
private:
pull_coroutine< R & > * c_;
optional< R & > val_;
pull_coroutine< R & > * c_;
R * val_;
void fetch_()
{
@@ -1259,7 +1638,7 @@ public:
if ( ! c_->has_result() )
{
c_ = 0;
val_ = none;
val_ = 0;
return;
}
val_ = c_->get();
@@ -1279,11 +1658,11 @@ public:
typedef typename iterator::reference reference_t;
iterator() :
c_( 0), val_()
c_( 0), val_( 0)
{}
explicit iterator( pull_coroutine< R & > * c) :
c_( c), val_()
c_( c), val_( 0)
{ fetch_(); }
iterator( iterator const& other) :
@@ -1322,7 +1701,7 @@ public:
if ( ! val_)
boost::throw_exception(
invalid_result() );
return const_cast< optional< R & > & >( val_).get();
return * val_;
}
pointer_t operator->() const
@@ -1330,7 +1709,7 @@ public:
if ( ! val_)
boost::throw_exception(
invalid_result() );
return const_cast< optional< R & > & >( val_).get_ptr();
return val_;
}
};

View File

@@ -25,6 +25,12 @@ enum flag_t
flag_preserve_fpu = 1 << 4
};
struct unwind_t
{
enum flag_t
{ force_unwind = 1 };
};
}}}
#ifdef BOOST_HAS_ABI_HEADERS

View File

@@ -11,6 +11,7 @@
#include <boost/config.hpp>
#include <boost/coroutine/detail/coroutine_context.hpp>
#include <boost/coroutine/detail/flags.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
@@ -24,27 +25,27 @@ template< typename Data >
struct parameters
{
coroutine_context * ctx;
Data const* data;
bool force_unwind;
Data * data;
bool do_unwind;
explicit parameters( coroutine_context * ctx_) :
ctx( ctx_), data( 0), force_unwind( false)
ctx( ctx_), data( 0), do_unwind( false)
{ BOOST_ASSERT( ctx); }
explicit parameters( coroutine_context * ctx_, Data const* data_) :
ctx( ctx_), data( data_), force_unwind( false)
explicit parameters( coroutine_context * ctx_, Data * data_) :
ctx( ctx_), data( data_), do_unwind( false)
{ BOOST_ASSERT( ctx); }
explicit parameters( coroutine_context * ctx_, bool force_unwind_) :
ctx( ctx_), data( 0), force_unwind( force_unwind_)
explicit parameters( coroutine_context * ctx_, unwind_t::flag_t) :
ctx( ctx_), data( 0), do_unwind( true)
{
BOOST_ASSERT( ctx);
BOOST_ASSERT( force_unwind);
BOOST_ASSERT( do_unwind);
}
parameters( parameters const& other) :
ctx( other.ctx), data( other.data),
force_unwind( other.force_unwind)
do_unwind( other.do_unwind)
{}
parameters & operator=( parameters const& other)
@@ -52,7 +53,7 @@ struct parameters
if ( this == & other) return * this;
ctx = other.ctx;
data = other.data;
force_unwind = other.force_unwind;
do_unwind = other.do_unwind;
return * this;
}
};
@@ -61,27 +62,27 @@ template< typename Data >
struct parameters< Data & >
{
coroutine_context * ctx;
Data const* data;
bool force_unwind;
Data * data;
bool do_unwind;
explicit parameters( coroutine_context * ctx_) :
ctx( ctx_), data( 0), force_unwind( false)
ctx( ctx_), data( 0), do_unwind( false)
{ BOOST_ASSERT( ctx); }
explicit parameters( coroutine_context * ctx_, Data const* data_) :
ctx( ctx_), data( data_), force_unwind( false)
explicit parameters( coroutine_context * ctx_, Data * data_) :
ctx( ctx_), data( data_), do_unwind( false)
{ BOOST_ASSERT( ctx); }
explicit parameters( coroutine_context * ctx_, bool force_unwind_) :
ctx( ctx_), data( 0), force_unwind( force_unwind_)
explicit parameters( coroutine_context * ctx_, unwind_t::flag_t) :
ctx( ctx_), data( 0), do_unwind( true)
{
BOOST_ASSERT( ctx);
BOOST_ASSERT( force_unwind);
BOOST_ASSERT( do_unwind);
}
parameters( parameters const& other) :
ctx( other.ctx), data( other.data),
force_unwind( other.force_unwind)
do_unwind( other.do_unwind)
{}
parameters & operator=( parameters const& other)
@@ -89,7 +90,7 @@ struct parameters< Data & >
if ( this == & other) return * this;
ctx = other.ctx;
data = other.data;
force_unwind = other.force_unwind;
do_unwind = other.do_unwind;
return * this;
}
};
@@ -98,27 +99,27 @@ template< typename Data >
struct parameters< Data * >
{
coroutine_context * ctx;
Data const* data;
bool force_unwind;
Data ** data;
bool do_unwind;
explicit parameters( coroutine_context * ctx_) :
ctx( ctx_), data( 0), force_unwind( false)
ctx( ctx_), data( 0), do_unwind( false)
{ BOOST_ASSERT( ctx); }
explicit parameters( coroutine_context * ctx_, Data const* data_) :
ctx( ctx_), data( data_), force_unwind( false)
explicit parameters( coroutine_context * ctx_, Data ** data_) :
ctx( ctx_), data( data_), do_unwind( false)
{ BOOST_ASSERT( ctx); }
explicit parameters( coroutine_context * ctx_, bool force_unwind_) :
ctx( ctx_), data( 0), force_unwind( force_unwind_)
explicit parameters( coroutine_context * ctx_, unwind_t::flag_t) :
ctx( ctx_), data( 0), do_unwind( true)
{
BOOST_ASSERT( ctx);
BOOST_ASSERT( force_unwind);
BOOST_ASSERT( do_unwind);
}
parameters( parameters const& other) :
ctx( other.ctx), data( other.data),
force_unwind( other.force_unwind)
do_unwind( other.do_unwind)
{}
parameters & operator=( parameters const& other)
@@ -126,7 +127,7 @@ struct parameters< Data * >
if ( this == & other) return * this;
ctx = other.ctx;
data = other.data;
force_unwind = other.force_unwind;
do_unwind = other.do_unwind;
return * this;
}
};
@@ -134,22 +135,26 @@ struct parameters< Data * >
template<>
struct parameters< void >
{
coroutine_context * ctx;
bool force_unwind;
coroutine_context * ctx;
bool do_unwind;
explicit parameters( coroutine_context * ctx_, bool force_unwind_ = false) :
ctx( ctx_), force_unwind( force_unwind_)
explicit parameters( coroutine_context * ctx_) :
ctx( ctx_), do_unwind( false)
{ BOOST_ASSERT( ctx); }
explicit parameters( coroutine_context * ctx_, unwind_t::flag_t) :
ctx( ctx_), do_unwind( true)
{ BOOST_ASSERT( ctx); }
parameters( parameters const& other) :
ctx( other.ctx), force_unwind( other.force_unwind)
ctx( other.ctx), do_unwind( other.do_unwind)
{}
parameters & operator=( parameters const& other)
{
if ( this == & other) return * this;
ctx = other.ctx;
force_unwind = other.force_unwind;
do_unwind = other.do_unwind;
return * this;
}
};

View File

@@ -12,8 +12,6 @@
#include <boost/context/fcontext.hpp>
#include <boost/exception_ptr.hpp>
#include <boost/intrusive_ptr.hpp>
#include <boost/optional.hpp>
#include <boost/type_traits/function_traits.hpp>
#include <boost/throw_exception.hpp>
#include <boost/utility.hpp>
@@ -47,6 +45,8 @@ private:
>
friend class push_coroutine_object;
typedef parameters< R > param_type;
unsigned int use_count_;
protected:
@@ -54,7 +54,7 @@ protected:
exception_ptr except_;
coroutine_context caller_;
coroutine_context callee_;
optional< R > result_;
R * result_;
virtual void deallocate_object() = 0;
@@ -67,7 +67,7 @@ public:
except_(),
caller_(),
callee_( fn, stack_ctx),
result_()
result_( 0)
{
if ( unwind) flags_ |= flag_force_unwind;
if ( preserve_fpu) flags_ |= flag_preserve_fpu;
@@ -75,7 +75,7 @@ public:
pull_coroutine_base( coroutine_context const& callee,
bool unwind, bool preserve_fpu,
optional< R > const& result) :
R * result) :
use_count_( 0),
flags_( 0),
except_(),
@@ -102,48 +102,47 @@ public:
bool is_complete() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_complete); }
friend inline void intrusive_ptr_add_ref( pull_coroutine_base * p) BOOST_NOEXCEPT
{ ++p->use_count_; }
friend inline void intrusive_ptr_release( pull_coroutine_base * p) BOOST_NOEXCEPT
{ if ( --p->use_count_ == 0) p->deallocate_object(); }
void pull()
{
BOOST_ASSERT( ! is_complete() );
parameters< R > to( & caller_);
parameters< R > * from(
reinterpret_cast< parameters< R > * >(
param_type to( & caller_);
param_type * from(
reinterpret_cast< param_type * >(
to.ctx->jump(
callee_,
reinterpret_cast< intptr_t >( & to),
preserve_fpu() ) ) );
BOOST_ASSERT( from->ctx);
callee_ = * from->ctx;
if ( from->data) result_ = * from->data;
else result_ = none;
if ( from->force_unwind) throw forced_unwind();
result_ = from->data;
if ( from->do_unwind) throw forced_unwind();
if ( except_) rethrow_exception( except_);
}
bool has_result() const
{ return result_; }
{ return 0 != result_; }
R get() const
{
if ( ! has_result() )
boost::throw_exception(
invalid_result() );
return result_.get();
return * result_;
}
friend inline void intrusive_ptr_add_ref( pull_coroutine_base * p) BOOST_NOEXCEPT
{ ++p->use_count_; }
friend inline void intrusive_ptr_release( pull_coroutine_base * p) BOOST_NOEXCEPT
{ if ( --p->use_count_ == 0) p->deallocate_object(); }
};
template< typename R >
class pull_coroutine_base< R * > : private noncopyable
{
public:
typedef intrusive_ptr< pull_coroutine_base > ptr_t;
typedef intrusive_ptr< pull_coroutine_base > ptr_t;
private:
template<
@@ -151,6 +150,8 @@ private:
>
friend class push_coroutine_object;
typedef parameters< R * > param_type;
unsigned int use_count_;
protected:
@@ -158,7 +159,7 @@ protected:
exception_ptr except_;
coroutine_context caller_;
coroutine_context callee_;
optional< R * > result_;
R ** result_;
virtual void deallocate_object() = 0;
@@ -171,7 +172,7 @@ public:
except_(),
caller_(),
callee_( fn, stack_ctx),
result_()
result_( 0)
{
if ( unwind) flags_ |= flag_force_unwind;
if ( preserve_fpu) flags_ |= flag_preserve_fpu;
@@ -179,7 +180,7 @@ public:
pull_coroutine_base( coroutine_context const& callee,
bool unwind, bool preserve_fpu,
optional< R * > const& result) :
R ** result) :
use_count_( 0),
flags_( 0),
except_(),
@@ -206,48 +207,47 @@ public:
bool is_complete() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_complete); }
friend inline void intrusive_ptr_add_ref( pull_coroutine_base * p) BOOST_NOEXCEPT
{ ++p->use_count_; }
friend inline void intrusive_ptr_release( pull_coroutine_base * p) BOOST_NOEXCEPT
{ if ( --p->use_count_ == 0) p->deallocate_object(); }
void pull()
{
BOOST_ASSERT( ! is_complete() );
parameters< R * > to( & caller_);
parameters< R * > * from(
reinterpret_cast< parameters< R * > * >(
param_type to( & caller_);
param_type * from(
reinterpret_cast< param_type * >(
to.ctx->jump(
callee_,
reinterpret_cast< intptr_t >( & to),
preserve_fpu() ) ) );
BOOST_ASSERT( from->ctx);
callee_ = * from->ctx;
if ( from->data) result_ = const_cast< R * >( from->data);
else this->result_ = none;
if ( from->force_unwind) throw forced_unwind();
result_ = from->data;
if ( from->do_unwind) throw forced_unwind();
if ( except_) rethrow_exception( except_);
}
bool has_result() const
{ return result_; }
{ return 0 != result_; }
R * get() const
{
if ( ! has_result() )
boost::throw_exception(
invalid_result() );
return result_.get();
return * result_;
}
friend inline void intrusive_ptr_add_ref( pull_coroutine_base * p) BOOST_NOEXCEPT
{ ++p->use_count_; }
friend inline void intrusive_ptr_release( pull_coroutine_base * p) BOOST_NOEXCEPT
{ if ( --p->use_count_ == 0) p->deallocate_object(); }
};
template< typename R >
class pull_coroutine_base< R & > : private noncopyable
{
public:
typedef intrusive_ptr< pull_coroutine_base > ptr_t;
typedef intrusive_ptr< pull_coroutine_base > ptr_t;
private:
template<
@@ -255,6 +255,8 @@ private:
>
friend class push_coroutine_object;
typedef parameters< R & > param_type;
unsigned int use_count_;
protected:
@@ -262,7 +264,7 @@ protected:
exception_ptr except_;
coroutine_context caller_;
coroutine_context callee_;
optional< R * > result_;
R * result_;
virtual void deallocate_object() = 0;
@@ -275,7 +277,7 @@ public:
except_(),
caller_(),
callee_( fn, stack_ctx),
result_()
result_( 0)
{
if ( unwind) flags_ |= flag_force_unwind;
if ( preserve_fpu) flags_ |= flag_preserve_fpu;
@@ -283,7 +285,7 @@ public:
pull_coroutine_base( coroutine_context const& callee,
bool unwind, bool preserve_fpu,
optional< R * > const& result) :
R * result) :
use_count_( 0),
flags_( 0),
except_(),
@@ -310,48 +312,47 @@ public:
bool is_complete() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_complete); }
friend inline void intrusive_ptr_add_ref( pull_coroutine_base * p) BOOST_NOEXCEPT
{ ++p->use_count_; }
friend inline void intrusive_ptr_release( pull_coroutine_base * p) BOOST_NOEXCEPT
{ if ( --p->use_count_ == 0) p->deallocate_object(); }
void pull()
{
BOOST_ASSERT( ! is_complete() );
parameters< R & > to( & caller_);
parameters< R & > * from(
reinterpret_cast< parameters< R & > * >(
param_type to( & caller_);
param_type * from(
reinterpret_cast< param_type * >(
to.ctx->jump(
callee_,
reinterpret_cast< intptr_t >( & to),
preserve_fpu() ) ) );
BOOST_ASSERT( from->ctx);
callee_ = * from->ctx;
if ( from->data) result_ = const_cast< R * >( from->data);
else this->result_ = none;
if ( from->force_unwind) throw forced_unwind();
result_ = from->data;
if ( from->do_unwind) throw forced_unwind();
if ( except_) rethrow_exception( except_);
}
bool has_result() const
{ return result_; }
{ return 0 != result_; }
R & get() const
{
if ( ! has_result() )
boost::throw_exception(
invalid_result() );
return * result_.get();
return * result_;
}
friend inline void intrusive_ptr_add_ref( pull_coroutine_base * p) BOOST_NOEXCEPT
{ ++p->use_count_; }
friend inline void intrusive_ptr_release( pull_coroutine_base * p) BOOST_NOEXCEPT
{ if ( --p->use_count_ == 0) p->deallocate_object(); }
};
template<>
class pull_coroutine_base< void > : private noncopyable
{
public:
typedef intrusive_ptr< pull_coroutine_base > ptr_t;
typedef intrusive_ptr< pull_coroutine_base > ptr_t;
private:
template<
@@ -359,6 +360,8 @@ private:
>
friend class push_coroutine_object;
typedef parameters< void > param_type;
unsigned int use_count_;
protected:
@@ -410,28 +413,28 @@ public:
bool is_complete() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_complete); }
friend inline void intrusive_ptr_add_ref( pull_coroutine_base * p) BOOST_NOEXCEPT
{ ++p->use_count_; }
friend inline void intrusive_ptr_release( pull_coroutine_base * p) BOOST_NOEXCEPT
{ if ( --p->use_count_ == 0) p->deallocate_object(); }
void pull()
{
BOOST_ASSERT( ! is_complete() );
parameters< void > to( & caller_);
parameters< void > * from(
reinterpret_cast< parameters< void > * >(
param_type to( & caller_);
param_type * from(
reinterpret_cast< param_type * >(
to.ctx->jump(
callee_,
reinterpret_cast< intptr_t >( & to),
preserve_fpu() ) ) );
BOOST_ASSERT( from->ctx);
callee_ = * from->ctx;
if ( from->force_unwind) throw forced_unwind();
if ( from->do_unwind) throw forced_unwind();
if ( except_) rethrow_exception( except_);
}
friend inline void intrusive_ptr_add_ref( pull_coroutine_base * p) BOOST_NOEXCEPT
{ ++p->use_count_; }
friend inline void intrusive_ptr_release( pull_coroutine_base * p) BOOST_NOEXCEPT
{ if ( --p->use_count_ == 0) p->deallocate_object(); }
};
}}}

View File

@@ -8,7 +8,6 @@
#include <boost/config.hpp>
#include <boost/context/fcontext.hpp>
#include <boost/optional.hpp>
#include <boost/coroutine/detail/config.hpp>
#include <boost/coroutine/detail/pull_coroutine_base.hpp>
@@ -30,7 +29,7 @@ public:
>::other allocator_t;
pull_coroutine_caller( coroutine_context const& callee, bool unwind, bool preserve_fpu,
allocator_t const& alloc, optional< R > const& data) BOOST_NOEXCEPT :
allocator_t const& alloc, R * data) BOOST_NOEXCEPT :
pull_coroutine_base< R >( callee, unwind, preserve_fpu, data),
alloc_( alloc)
{}
@@ -48,6 +47,33 @@ private:
}
};
template< typename R, typename Allocator >
class pull_coroutine_caller< R *, Allocator > : public pull_coroutine_base< R * >
{
public:
typedef typename Allocator::template rebind<
pull_coroutine_caller< R *, Allocator >
>::other allocator_t;
pull_coroutine_caller( coroutine_context const& callee, bool unwind, bool preserve_fpu,
allocator_t const& alloc, R ** data) BOOST_NOEXCEPT :
pull_coroutine_base< R * >( callee, unwind, preserve_fpu, data),
alloc_( alloc)
{}
void deallocate_object()
{ destroy_( alloc_, this); }
private:
allocator_t alloc_;
static void destroy_( allocator_t & alloc, pull_coroutine_caller * p)
{
alloc.destroy( p);
alloc.deallocate( p, 1);
}
};
template< typename R, typename Allocator >
class pull_coroutine_caller< R &, Allocator > : public pull_coroutine_base< R & >
{
@@ -57,7 +83,7 @@ public:
>::other allocator_t;
pull_coroutine_caller( coroutine_context const& callee, bool unwind, bool preserve_fpu,
allocator_t const& alloc, optional< R * > const& data) BOOST_NOEXCEPT :
allocator_t const& alloc, R * data) BOOST_NOEXCEPT :
pull_coroutine_base< R & >( callee, unwind, preserve_fpu, data),
alloc_( alloc)
{}

File diff suppressed because it is too large Load Diff

View File

@@ -12,7 +12,6 @@
#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>
@@ -35,7 +34,7 @@ template< typename Arg >
class push_coroutine_base : private noncopyable
{
public:
typedef intrusive_ptr< push_coroutine_base > ptr_t;
typedef intrusive_ptr< push_coroutine_base > ptr_t;
private:
template<
@@ -43,6 +42,8 @@ private:
>
friend class pull_coroutine_object;
typedef parameters< Arg > param_type;
unsigned int use_count_;
protected:
@@ -94,26 +95,20 @@ public:
bool is_complete() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_complete); }
friend inline void intrusive_ptr_add_ref( push_coroutine_base * p) BOOST_NOEXCEPT
{ ++p->use_count_; }
friend inline void intrusive_ptr_release( push_coroutine_base * p) BOOST_NOEXCEPT
{ if ( --p->use_count_ == 0) p->deallocate_object(); }
void push( Arg const& arg)
{
BOOST_ASSERT( ! is_complete() );
parameters< Arg > to( & caller_, & arg);
parameters< Arg > * from(
reinterpret_cast< parameters< Arg > * >(
param_type to( & caller_, const_cast< Arg * >( & arg) );
param_type * from(
reinterpret_cast< param_type * >(
to.ctx->jump(
callee_,
reinterpret_cast< intptr_t >( & to),
preserve_fpu() ) ) );
BOOST_ASSERT( from->ctx);
callee_ = * from->ctx;
if ( from->force_unwind) throw forced_unwind();
if ( from->do_unwind) throw forced_unwind();
if ( except_) rethrow_exception( except_);
}
@@ -121,25 +116,31 @@ public:
{
BOOST_ASSERT( ! is_complete() );
parameters< Arg > to( & caller_, & arg);
parameters< Arg > * from(
reinterpret_cast< parameters< Arg > * >(
param_type to( & caller_, const_cast< Arg * >( & arg) );
param_type * from(
reinterpret_cast< param_type * >(
to.ctx->jump(
callee_,
reinterpret_cast< intptr_t >( & to),
preserve_fpu() ) ) );
BOOST_ASSERT( from->ctx);
callee_ = * from->ctx;
if ( from->force_unwind) throw forced_unwind();
if ( from->do_unwind) throw forced_unwind();
if ( except_) rethrow_exception( except_);
}
friend inline void intrusive_ptr_add_ref( push_coroutine_base * p) BOOST_NOEXCEPT
{ ++p->use_count_; }
friend inline void intrusive_ptr_release( push_coroutine_base * p) BOOST_NOEXCEPT
{ if ( --p->use_count_ == 0) p->deallocate_object(); }
};
template< typename Arg >
class push_coroutine_base< Arg * > : private noncopyable
{
public:
typedef intrusive_ptr< push_coroutine_base > ptr_t;
typedef intrusive_ptr< push_coroutine_base > ptr_t;
private:
template<
@@ -147,6 +148,8 @@ private:
>
friend class pull_coroutine_object;
typedef parameters< Arg * > param_type;
unsigned int use_count_;
protected:
@@ -198,35 +201,35 @@ public:
bool is_complete() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_complete); }
friend inline void intrusive_ptr_add_ref( push_coroutine_base * p) BOOST_NOEXCEPT
{ ++p->use_count_; }
friend inline void intrusive_ptr_release( push_coroutine_base * p) BOOST_NOEXCEPT
{ if ( --p->use_count_ == 0) p->deallocate_object(); }
void push( Arg * arg)
{
BOOST_ASSERT( ! is_complete() );
parameters< Arg * > to( & caller_, arg);
parameters< Arg * > * from(
reinterpret_cast< parameters< Arg * > * >(
param_type to( & caller_, & arg);
param_type * from(
reinterpret_cast< param_type * >(
to.ctx->jump(
callee_,
reinterpret_cast< intptr_t >( & to),
preserve_fpu() ) ) );
BOOST_ASSERT( from->ctx);
callee_ = * from->ctx;
if ( from->force_unwind) throw forced_unwind();
if ( from->do_unwind) throw forced_unwind();
if ( except_) rethrow_exception( except_);
}
friend inline void intrusive_ptr_add_ref( push_coroutine_base * p) BOOST_NOEXCEPT
{ ++p->use_count_; }
friend inline void intrusive_ptr_release( push_coroutine_base * p) BOOST_NOEXCEPT
{ if ( --p->use_count_ == 0) p->deallocate_object(); }
};
template< typename Arg >
class push_coroutine_base< Arg & > : private noncopyable
{
public:
typedef intrusive_ptr< push_coroutine_base > ptr_t;
typedef intrusive_ptr< push_coroutine_base > ptr_t;
private:
template<
@@ -234,6 +237,8 @@ private:
>
friend class pull_coroutine_object;
typedef parameters< Arg & > param_type;
unsigned int use_count_;
protected:
@@ -285,35 +290,35 @@ public:
bool is_complete() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_complete); }
friend inline void intrusive_ptr_add_ref( push_coroutine_base * p) BOOST_NOEXCEPT
{ ++p->use_count_; }
friend inline void intrusive_ptr_release( push_coroutine_base * p) BOOST_NOEXCEPT
{ if ( --p->use_count_ == 0) p->deallocate_object(); }
void push( Arg & arg)
{
BOOST_ASSERT( ! is_complete() );
parameters< Arg * > to( & caller_, & arg);
parameters< Arg * > * from(
reinterpret_cast< parameters< Arg * > * >(
param_type to( & caller_, & arg);
param_type * from(
reinterpret_cast< param_type * >(
to.ctx->jump(
callee_,
reinterpret_cast< intptr_t >( & to),
preserve_fpu() ) ) );
BOOST_ASSERT( from->ctx);
callee_ = * from->ctx;
if ( from->force_unwind) throw forced_unwind();
if ( from->do_unwind) throw forced_unwind();
if ( except_) rethrow_exception( except_);
}
friend inline void intrusive_ptr_add_ref( push_coroutine_base * p) BOOST_NOEXCEPT
{ ++p->use_count_; }
friend inline void intrusive_ptr_release( push_coroutine_base * p) BOOST_NOEXCEPT
{ if ( --p->use_count_ == 0) p->deallocate_object(); }
};
template<>
class push_coroutine_base< void > : private noncopyable
{
public:
typedef intrusive_ptr< push_coroutine_base > ptr_t;
typedef intrusive_ptr< push_coroutine_base > ptr_t;
private:
template<
@@ -321,6 +326,8 @@ private:
>
friend class pull_coroutine_object;
typedef parameters< void > param_type;
unsigned int use_count_;
protected:
@@ -372,28 +379,28 @@ public:
bool is_complete() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_complete); }
friend inline void intrusive_ptr_add_ref( push_coroutine_base * p) BOOST_NOEXCEPT
{ ++p->use_count_; }
friend inline void intrusive_ptr_release( push_coroutine_base * p) BOOST_NOEXCEPT
{ if ( --p->use_count_ == 0) p->deallocate_object(); }
void push()
{
BOOST_ASSERT( ! is_complete() );
parameters< void > to( & caller_);
parameters< void > * from(
reinterpret_cast< parameters< void > * >(
param_type to( & caller_);
param_type * from(
reinterpret_cast< param_type * >(
to.ctx->jump(
callee_,
reinterpret_cast< intptr_t >( & to),
preserve_fpu() ) ) );
BOOST_ASSERT( from->ctx);
callee_ = * from->ctx;
if ( from->force_unwind) throw forced_unwind();
if ( from->do_unwind) throw forced_unwind();
if ( except_) rethrow_exception( except_);
}
friend inline void intrusive_ptr_add_ref( push_coroutine_base * p) BOOST_NOEXCEPT
{ ++p->use_count_; }
friend inline void intrusive_ptr_release( push_coroutine_base * p) BOOST_NOEXCEPT
{ if ( --p->use_count_ == 0) p->deallocate_object(); }
};
}}}

File diff suppressed because it is too large Load Diff