Current File : //proc/self/root/usr/include/boost/coroutine/coroutine.hpp |
// 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
#include <cstddef>
#include <memory>
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/context/fcontext.hpp>
#include <boost/move/move.hpp>
#include <boost/range.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/decay.hpp>
#include <boost/type_traits/function_traits.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/utility/result_of.hpp>
#include <boost/coroutine/attributes.hpp>
#include <boost/coroutine/detail/arg.hpp>
#include <boost/coroutine/detail/coroutine_base.hpp>
#include <boost/coroutine/detail/coroutine_get.hpp>
#include <boost/coroutine/detail/coroutine_object.hpp>
#include <boost/coroutine/detail/coroutine_op.hpp>
#include <boost/coroutine/detail/coroutine_caller.hpp>
#include <boost/coroutine/stack_allocator.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
namespace detail {
template<
typename Signature,
template< class, int > class C,
typename Result = typename function_traits< Signature >::result_type,
int arity = function_traits< Signature >::arity
>
struct caller;
template<
typename Signature,
template< class, int > class C
>
struct caller< Signature, C, void, 0 >
{ typedef C< void(), 0 > type; };
template<
typename Signature,
template< class, int > class C,
typename Result
>
struct caller< Signature, C, Result, 0 >
{ typedef C< void( Result), 1 > type; };
template<
typename Signature,
template< class, int > class C,
int arity
>
struct caller< Signature, C, void, arity >
{ typedef C< typename detail::arg< Signature >::type(), 0 > type; };
template<
typename Signature,
template< class, int > class C,
typename Result, int arity
>
struct caller
{ typedef C< typename detail::arg< Signature >::type( Result), 1 > type; };
}
template< typename Signature, int arity = function_traits< Signature >::arity >
class coroutine;
template< typename Signature >
class coroutine< Signature, 0 > : public detail::coroutine_op<
Signature,
coroutine< Signature >,
typename function_traits< Signature >::result_type,
function_traits< Signature >::arity
>,
public detail::coroutine_get<
coroutine< Signature >,
typename function_traits< Signature >::result_type,
function_traits< Signature >::arity
>
{
private:
typedef detail::coroutine_base< Signature > base_t;
typedef typename base_t::ptr_t ptr_t;
template< typename X, typename Y, int >
friend struct detail::coroutine_get;
template< typename X, typename Y, typename Z, int >
friend struct detail::coroutine_op;
template< typename X, typename Y, typename Z, typename A, typename B, typename C, int >
friend class detail::coroutine_object;
struct dummy
{ void nonnull() {} };
typedef void ( dummy::*safe_bool)();
ptr_t impl_;
BOOST_MOVABLE_BUT_NOT_COPYABLE( coroutine);
template< typename Allocator >
coroutine( context::fcontext_t * 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( context::fcontext_t * 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 > & c)
{ return typename coroutine< Signature >::iterator(); }
template< typename Signature >
inline
typename coroutine< Signature >::const_iterator
range_end( coroutine< Signature > const& c)
{ return typename coroutine< Signature >::const_iterator(); }
}
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_COROUTINE_H