early-access version 3088

This commit is contained in:
pineappleEA
2022-11-05 15:35:56 +01:00
parent 4e4fc25ce3
commit b601909c6d
35519 changed files with 5996896 additions and 860 deletions

View File

@@ -0,0 +1,2 @@
CRTLinkage: dynamic
LibraryLinkage: dynamic

View File

@@ -0,0 +1,8 @@
Package: boost-coroutine
Version: 1.79.0
Depends: boost-assert, boost-build, boost-config, boost-context, boost-core, boost-exception, boost-modular-build-helper, boost-move, boost-system, boost-throw-exception, boost-type-traits, boost-utility, boost-vcpkg-helpers, vcpkg-cmake
Architecture: x64-windows
Multi-Arch: same
Abi: fe2632001158acdfa35da6165acaae23e81787a8d2ddb5d1719eb7ab84d4f2a7
Description: Boost coroutine module
Type: Port

View File

@@ -0,0 +1,21 @@
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_COROUTINES_ALL_H
#define BOOST_COROUTINES_ALL_H
#include <boost/coroutine/attributes.hpp>
#include <boost/coroutine/coroutine.hpp>
#include <boost/coroutine/exceptions.hpp>
#include <boost/coroutine/flags.hpp>
#include <boost/coroutine/protected_stack_allocator.hpp>
#include <boost/coroutine/segmented_stack_allocator.hpp>
#include <boost/coroutine/stack_allocator.hpp>
#include <boost/coroutine/stack_context.hpp>
#include <boost/coroutine/stack_traits.hpp>
#include <boost/coroutine/standard_stack_allocator.hpp>
#endif // BOOST_COROUTINES_ALL_H

View File

@@ -0,0 +1,58 @@
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_COROUTINES_ATTRIBUTES_H
#define BOOST_COROUTINES_ATTRIBUTES_H
#include <cstddef>
#include <boost/config.hpp>
#include <boost/coroutine/flags.hpp>
#include <boost/coroutine/stack_allocator.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
struct attributes
{
std::size_t size;
flag_unwind_t do_unwind;
attributes() BOOST_NOEXCEPT :
size( stack_allocator::traits_type::default_size() ),
do_unwind( stack_unwind)
{}
explicit attributes( std::size_t size_) BOOST_NOEXCEPT :
size( size_),
do_unwind( stack_unwind)
{}
explicit attributes( flag_unwind_t do_unwind_) BOOST_NOEXCEPT :
size( stack_allocator::traits_type::default_size() ),
do_unwind( do_unwind_)
{}
explicit attributes(
std::size_t size_,
flag_unwind_t do_unwind_) BOOST_NOEXCEPT :
size( size_),
do_unwind( do_unwind_)
{}
};
}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_ATTRIBUTES_H

View File

@@ -0,0 +1,13 @@
// 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 <boost/coroutine/asymmetric_coroutine.hpp>
#include <boost/coroutine/symmetric_coroutine.hpp>
#endif // BOOST_COROUTINES_COROUTINE_H

View File

@@ -0,0 +1,46 @@
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_COROUTINES_DETAIL_CONFIG_H
#define BOOST_COROUTINES_DETAIL_CONFIG_H
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#ifdef BOOST_COROUTINES_DECL
# undef BOOST_COROUTINES_DECL
#endif
#if (defined(BOOST_ALL_DYN_LINK) || defined(BOOST_COROUTINES_DYN_LINK) ) && ! defined(BOOST_COROUTINES_STATIC_LINK)
# if defined(BOOST_COROUTINES_SOURCE)
# define BOOST_COROUTINES_DECL BOOST_SYMBOL_EXPORT
# define BOOST_COROUTINES_BUILD_DLL
# else
# define BOOST_COROUTINES_DECL BOOST_SYMBOL_IMPORT
# endif
#endif
#if ! defined(BOOST_COROUTINES_DECL)
# define BOOST_COROUTINES_DECL
#endif
#if ! defined(BOOST_COROUTINES_SOURCE) && ! defined(BOOST_ALL_NO_LIB) && ! defined(BOOST_COROUTINES_NO_LIB)
# define BOOST_LIB_NAME boost_coroutine
# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_COROUTINES_DYN_LINK)
# define BOOST_DYN_LINK
# endif
# include <boost/config/auto_link.hpp>
#endif
#define BOOST_COROUTINES_UNIDIRECT
#define BOOST_COROUTINES_SYMMETRIC
#if defined(__OpenBSD__)
// stacks need mmap(2) with MAP_STACK
# define BOOST_COROUTINES_USE_MAP_STACK
#endif
#endif // BOOST_COROUTINES_DETAIL_CONFIG_H

View File

@@ -0,0 +1,73 @@
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_COROUTINES_DETAIL_COROUTINE_CONTEXT_H
#define BOOST_COROUTINES_DETAIL_COROUTINE_CONTEXT_H
#include <cstddef>
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/context/detail/fcontext.hpp>
#include <boost/coroutine/detail/config.hpp>
#include <boost/coroutine/detail/preallocated.hpp>
#include <boost/coroutine/stack_context.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
namespace detail {
// class hold stack-context and coroutines execution-context
class BOOST_COROUTINES_DECL coroutine_context
{
private:
template< typename Coro >
friend void trampoline( context::detail::transfer_t);
template< typename Coro >
friend void trampoline_void( context::detail::transfer_t);
template< typename Coro >
friend void trampoline_pull( context::detail::transfer_t);
template< typename Coro >
friend void trampoline_push( context::detail::transfer_t);
template< typename Coro >
friend void trampoline_push_void( context::detail::transfer_t);
preallocated palloc_;
context::detail::fcontext_t ctx_;
public:
typedef void( * ctx_fn)( context::detail::transfer_t);
// default ctor represents the current execution-context
coroutine_context();
// ctor creates a new execution-context running coroutine-fn `fn`
// `ctx_` will be allocated on top of the stack managed by parameter
// `stack_ctx`
coroutine_context( ctx_fn fn, preallocated const& palloc);
coroutine_context( coroutine_context const&);
coroutine_context& operator=( coroutine_context const&);
void * jump( coroutine_context &, void * = 0);
stack_context & stack_ctx()
{ return palloc_.sctx; }
};
}}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_DETAIL_COROUTINE_CONTEXT_H

View File

@@ -0,0 +1,34 @@
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_COROUTINES_DETAIL_DATA_H
#define BOOST_COROUTINES_DETAIL_DATA_H
#include <boost/config.hpp>
#include <boost/coroutine/detail/coroutine_context.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
namespace detail {
struct data_t
{
coroutine_context * from;
void * data;
};
}}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_DETAIL_DATA_H

View File

@@ -0,0 +1,47 @@
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_COROUTINES_DETAIL_FLAGS_H
#define BOOST_COROUTINES_DETAIL_FLAGS_H
#include <boost/config.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
namespace detail {
enum flag_t
{
flag_started = 1 << 1,
flag_running = 1 << 2,
flag_complete = 1 << 3,
flag_unwind_stack = 1 << 4,
flag_force_unwind = 1 << 5
};
struct unwind_t
{
enum flag_t
{ force_unwind = 1 };
};
struct synthesized_t
{
enum flag_t
{ syntesized = 1 };
};
}}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_DETAIL_FLAGS_H

View File

@@ -0,0 +1,102 @@
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_COROUTINES_DETAIL_PARAMETERS_H
#define BOOST_COROUTINES_DETAIL_PARAMETERS_H
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/coroutine/detail/flags.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
namespace detail {
template< typename Data >
struct parameters
{
Data * data;
bool do_unwind;
void * coro;
parameters() :
data( 0), do_unwind( false), coro( 0)
{}
explicit parameters( void * coro_) :
data( 0), do_unwind( false), coro( coro_)
{ BOOST_ASSERT( 0 != coro); }
explicit parameters( Data * data_, void * coro_) :
data( data_), do_unwind( false), coro( coro_)
{
BOOST_ASSERT( 0 != data);
BOOST_ASSERT( 0 != coro);
}
explicit parameters( unwind_t::flag_t) :
data( 0), do_unwind( true)
{}
};
template< typename Data >
struct parameters< Data & >
{
Data * data;
bool do_unwind;
void * coro;
parameters() :
data( 0), do_unwind( false), coro( 0)
{}
explicit parameters( void * coro_) :
data( 0), do_unwind( false), coro( coro_)
{ BOOST_ASSERT( 0 != coro); }
explicit parameters( Data * data_, void * coro_) :
data( data_), do_unwind( false), coro( coro_)
{
BOOST_ASSERT( 0 != data);
BOOST_ASSERT( 0 != coro);
}
explicit parameters( unwind_t::flag_t) :
data( 0), do_unwind( true), coro( 0)
{}
};
template<>
struct parameters< void >
{
bool do_unwind;
void * coro;
parameters() :
do_unwind( false), coro(0)
{}
parameters( void * coro_) :
do_unwind( false), coro( coro_)
{ BOOST_ASSERT( 0 != coro); }
explicit parameters( unwind_t::flag_t) :
do_unwind( true), coro( 0)
{}
};
}}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_DETAIL_PARAMETERS_H

View File

@@ -0,0 +1,45 @@
// Copyright Oliver Kowalke 2015.
// 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_PREALLOCATED_H
#define BOOST_COROUTINES_DETAIL_PREALLOCATED_H
#include <cstddef>
#include <boost/config.hpp>
#include <boost/coroutine/detail/config.hpp>
#include <boost/coroutine/stack_context.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
namespace detail {
struct BOOST_COROUTINES_DECL preallocated {
void * sp;
std::size_t size;
stack_context sctx;
preallocated() BOOST_NOEXCEPT :
sp( 0), size( 0), sctx() {
}
preallocated( void * sp_, std::size_t size_, stack_context sctx_) BOOST_NOEXCEPT :
sp( sp_), size( size_), sctx( sctx_) {
}
};
}}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_DETAIL_PREALLOCATED_H

View File

@@ -0,0 +1,335 @@
// 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_IMPL_H
#define BOOST_COROUTINES_DETAIL_PULL_COROUTINE_IMPL_H
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/exception_ptr.hpp>
#include <boost/throw_exception.hpp>
#include <boost/utility.hpp>
#include <boost/coroutine/detail/config.hpp>
#include <boost/coroutine/detail/coroutine_context.hpp>
#include <boost/coroutine/detail/flags.hpp>
#include <boost/coroutine/detail/parameters.hpp>
#include <boost/coroutine/detail/trampoline_pull.hpp>
#include <boost/coroutine/exceptions.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
struct stack_context;
namespace detail {
template< typename R >
class pull_coroutine_impl : private noncopyable
{
protected:
int flags_;
exception_ptr except_;
coroutine_context * caller_;
coroutine_context * callee_;
R * result_;
public:
typedef parameters< R > param_type;
pull_coroutine_impl( coroutine_context * caller,
coroutine_context * callee,
bool unwind) :
flags_( 0),
except_(),
caller_( caller),
callee_( callee),
result_( 0)
{
if ( unwind) flags_ |= flag_force_unwind;
}
pull_coroutine_impl( coroutine_context * caller,
coroutine_context * callee,
bool unwind,
R * result) :
flags_( 0),
except_(),
caller_( caller),
callee_( callee),
result_( result)
{
if ( unwind) flags_ |= flag_force_unwind;
}
virtual ~pull_coroutine_impl() {}
bool force_unwind() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_force_unwind); }
bool unwind_requested() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_unwind_stack); }
bool is_started() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_started); }
bool is_running() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_running); }
bool is_complete() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_complete); }
void unwind_stack() BOOST_NOEXCEPT
{
if ( is_started() && ! is_complete() && force_unwind() )
{
flags_ |= flag_unwind_stack;
param_type to( unwind_t::force_unwind);
caller_->jump(
* callee_,
& to);
flags_ &= ~flag_unwind_stack;
BOOST_ASSERT( is_complete() );
}
}
void pull()
{
BOOST_ASSERT( ! is_running() );
BOOST_ASSERT( ! is_complete() );
flags_ |= flag_running;
param_type to( this);
param_type * from(
static_cast< param_type * >(
caller_->jump(
* callee_,
& to) ) );
flags_ &= ~flag_running;
result_ = from->data;
if ( from->do_unwind) throw forced_unwind();
if ( except_) rethrow_exception( except_);
}
bool has_result() const
{ return 0 != result_; }
R get() const
{
if ( ! has_result() )
boost::throw_exception(
invalid_result() );
return * result_;
}
R * get_pointer() const
{
if ( ! has_result() )
boost::throw_exception(
invalid_result() );
return result_;
}
virtual void destroy() = 0;
};
template< typename R >
class pull_coroutine_impl< R & > : private noncopyable
{
protected:
int flags_;
exception_ptr except_;
coroutine_context * caller_;
coroutine_context * callee_;
R * result_;
public:
typedef parameters< R & > param_type;
pull_coroutine_impl( coroutine_context * caller,
coroutine_context * callee,
bool unwind) :
flags_( 0),
except_(),
caller_( caller),
callee_( callee),
result_( 0)
{
if ( unwind) flags_ |= flag_force_unwind;
}
pull_coroutine_impl( coroutine_context * caller,
coroutine_context * callee,
bool unwind,
R * result) :
flags_( 0),
except_(),
caller_( caller),
callee_( callee),
result_( result)
{
if ( unwind) flags_ |= flag_force_unwind;
}
virtual ~pull_coroutine_impl() {}
bool force_unwind() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_force_unwind); }
bool unwind_requested() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_unwind_stack); }
bool is_started() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_started); }
bool is_running() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_running); }
bool is_complete() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_complete); }
void unwind_stack() BOOST_NOEXCEPT
{
if ( is_started() && ! is_complete() && force_unwind() )
{
flags_ |= flag_unwind_stack;
param_type to( unwind_t::force_unwind);
caller_->jump(
* callee_,
& to);
flags_ &= ~flag_unwind_stack;
BOOST_ASSERT( is_complete() );
}
}
void pull()
{
BOOST_ASSERT( ! is_running() );
BOOST_ASSERT( ! is_complete() );
flags_ |= flag_running;
param_type to( this);
param_type * from(
static_cast< param_type * >(
caller_->jump(
* callee_,
& to) ) );
flags_ &= ~flag_running;
result_ = from->data;
if ( from->do_unwind) throw forced_unwind();
if ( except_) rethrow_exception( except_);
}
bool has_result() const
{ return 0 != result_; }
R & get() const
{
if ( ! has_result() )
boost::throw_exception(
invalid_result() );
return * result_;
}
R * get_pointer() const
{
if ( ! has_result() )
boost::throw_exception(
invalid_result() );
return result_;
}
virtual void destroy() = 0;
};
template<>
class pull_coroutine_impl< void > : private noncopyable
{
protected:
int flags_;
exception_ptr except_;
coroutine_context * caller_;
coroutine_context * callee_;
public:
typedef parameters< void > param_type;
pull_coroutine_impl( coroutine_context * caller,
coroutine_context * callee,
bool unwind) :
flags_( 0),
except_(),
caller_( caller),
callee_( callee)
{
if ( unwind) flags_ |= flag_force_unwind;
}
virtual ~pull_coroutine_impl() {}
inline bool force_unwind() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_force_unwind); }
inline bool unwind_requested() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_unwind_stack); }
inline bool is_started() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_started); }
inline bool is_running() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_running); }
inline bool is_complete() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_complete); }
inline void unwind_stack() BOOST_NOEXCEPT
{
if ( is_started() && ! is_complete() && force_unwind() )
{
flags_ |= flag_unwind_stack;
param_type to( unwind_t::force_unwind);
caller_->jump(
* callee_,
& to);
flags_ &= ~flag_unwind_stack;
BOOST_ASSERT( is_complete() );
}
}
inline void pull()
{
BOOST_ASSERT( ! is_running() );
BOOST_ASSERT( ! is_complete() );
flags_ |= flag_running;
param_type to( this);
param_type * from(
static_cast< param_type * >(
caller_->jump(
* callee_,
& to) ) );
flags_ &= ~flag_running;
if ( from->do_unwind) throw forced_unwind();
if ( except_) rethrow_exception( except_);
}
virtual void destroy() = 0;
};
}}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_DETAIL_PULL_COROUTINE_IMPL_H

View File

@@ -0,0 +1,323 @@
// 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 <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/context/detail/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/coroutine_context.hpp>
#include <boost/coroutine/detail/flags.hpp>
#include <boost/coroutine/detail/preallocated.hpp>
#include <boost/coroutine/detail/pull_coroutine_impl.hpp>
#include <boost/coroutine/detail/trampoline_pull.hpp>
#include <boost/coroutine/exceptions.hpp>
#include <boost/coroutine/flags.hpp>
#include <boost/coroutine/stack_context.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable:4355)
#endif
namespace boost {
namespace coroutines {
namespace detail {
struct pull_coroutine_context
{
coroutine_context caller;
coroutine_context callee;
template< typename Coro >
pull_coroutine_context( preallocated const& palloc, Coro *) :
caller(),
callee( trampoline_pull< Coro >, palloc)
{}
};
template< typename PushCoro, typename R, typename Fn, typename StackAllocator >
class pull_coroutine_object : private pull_coroutine_context,
public pull_coroutine_impl< R >
{
private:
typedef pull_coroutine_context ctx_t;
typedef pull_coroutine_impl< R > base_t;
typedef pull_coroutine_object< PushCoro, R, Fn, StackAllocator > obj_t;
Fn fn_;
stack_context stack_ctx_;
StackAllocator stack_alloc_;
static void deallocate_( obj_t * obj)
{
stack_context stack_ctx( obj->stack_ctx_);
StackAllocator stack_alloc( obj->stack_alloc_);
obj->unwind_stack();
obj->~obj_t();
stack_alloc.deallocate( stack_ctx);
}
public:
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
pull_coroutine_object( Fn fn, attributes const& attrs,
preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
ctx_t( palloc, this),
base_t( & this->caller,
& this->callee,
stack_unwind == attrs.do_unwind),
fn_( fn),
stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
#endif
pull_coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attrs,
preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
ctx_t( palloc, this),
base_t( & this->caller,
& this->callee,
stack_unwind == attrs.do_unwind),
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
fn_( fn),
#else
fn_( boost::forward< Fn >( fn) ),
#endif
stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
void run()
{
BOOST_ASSERT( ! base_t::unwind_requested() );
base_t::flags_ |= flag_started;
base_t::flags_ |= flag_running;
// create push_coroutine
typename PushCoro::synth_type b( & this->callee, & this->caller, false);
PushCoro push_coro( synthesized_t::syntesized, b);
try
{ fn_( push_coro); }
catch ( forced_unwind const&)
{}
#if defined( BOOST_CONTEXT_HAS_CXXABI_H )
catch ( abi::__forced_unwind const&)
{ throw; }
#endif
catch (...)
{ base_t::except_ = current_exception(); }
base_t::flags_ |= flag_complete;
base_t::flags_ &= ~flag_running;
typename base_t::param_type to;
this->callee.jump(
this->caller,
& to);
BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
}
void destroy()
{ deallocate_( this); }
};
template< typename PushCoro, typename R, typename Fn, typename StackAllocator >
class pull_coroutine_object< PushCoro, R &, Fn, StackAllocator > : private pull_coroutine_context,
public pull_coroutine_impl< R & >
{
private:
typedef pull_coroutine_context ctx_t;
typedef pull_coroutine_impl< R & > base_t;
typedef pull_coroutine_object< PushCoro, R &, Fn, StackAllocator > obj_t;
Fn fn_;
stack_context stack_ctx_;
StackAllocator stack_alloc_;
static void deallocate_( obj_t * obj)
{
stack_context stack_ctx( obj->stack_ctx_);
StackAllocator stack_alloc( obj->stack_alloc_);
obj->unwind_stack();
obj->~obj_t();
stack_alloc.deallocate( stack_ctx);
}
public:
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
pull_coroutine_object( Fn fn, attributes const& attrs,
preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
ctx_t( palloc, this),
base_t( & this->caller,
& this->callee,
stack_unwind == attrs.do_unwind),
fn_( fn),
stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
#endif
pull_coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attrs,
preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
ctx_t( palloc, this),
base_t( & this->caller,
& this->callee,
stack_unwind == attrs.do_unwind),
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
fn_( fn),
#else
fn_( boost::forward< Fn >( fn) ),
#endif
stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
void run()
{
BOOST_ASSERT( ! base_t::unwind_requested() );
base_t::flags_ |= flag_started;
base_t::flags_ |= flag_running;
// create push_coroutine
typename PushCoro::synth_type b( & this->callee, & this->caller, false);
PushCoro push_coro( synthesized_t::syntesized, b);
try
{ fn_( push_coro); }
catch ( forced_unwind const&)
{}
#if defined( BOOST_CONTEXT_HAS_CXXABI_H )
catch ( abi::__forced_unwind const&)
{ throw; }
#endif
catch (...)
{ base_t::except_ = current_exception(); }
base_t::flags_ |= flag_complete;
base_t::flags_ &= ~flag_running;
typename base_t::param_type to;
this->callee.jump(
this->caller,
& to);
BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
}
void destroy()
{ deallocate_( this); }
};
template< typename PushCoro, typename Fn, typename StackAllocator >
class pull_coroutine_object< PushCoro, void, Fn, StackAllocator > : private pull_coroutine_context,
public pull_coroutine_impl< void >
{
private:
typedef pull_coroutine_context ctx_t;
typedef pull_coroutine_impl< void > base_t;
typedef pull_coroutine_object< PushCoro, void, Fn, StackAllocator > obj_t;
Fn fn_;
stack_context stack_ctx_;
StackAllocator stack_alloc_;
static void deallocate_( obj_t * obj)
{
stack_context stack_ctx( obj->stack_ctx_);
StackAllocator stack_alloc( obj->stack_alloc_);
obj->unwind_stack();
obj->~obj_t();
stack_alloc.deallocate( stack_ctx);
}
public:
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
pull_coroutine_object( Fn fn, attributes const& attrs,
preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
ctx_t( palloc, this),
base_t( & this->caller,
& this->callee,
stack_unwind == attrs.do_unwind),
fn_( fn),
stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
#endif
pull_coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attrs,
preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
ctx_t( palloc, this),
base_t( & this->caller,
& this->callee,
stack_unwind == attrs.do_unwind),
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
fn_( fn),
#else
fn_( boost::forward< Fn >( fn) ),
#endif
stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
void run()
{
BOOST_ASSERT( ! base_t::unwind_requested() );
base_t::flags_ |= flag_started;
base_t::flags_ |= flag_running;
// create push_coroutine
typename PushCoro::synth_type b( & this->callee, & this->caller, false);
PushCoro push_coro( synthesized_t::syntesized, b);
try
{ fn_( push_coro); }
catch ( forced_unwind const&)
{}
#if defined( BOOST_CONTEXT_HAS_CXXABI_H )
catch ( abi::__forced_unwind const&)
{ throw; }
#endif
catch (...)
{ base_t::except_ = current_exception(); }
base_t::flags_ |= flag_complete;
base_t::flags_ &= ~flag_running;
typename base_t::param_type to;
this->callee.jump(
this->caller,
& to);
BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
}
void destroy()
{ deallocate_( this); }
};
}}}
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_DETAIL_PULL_COROUTINE_OBJECT_H

View File

@@ -0,0 +1,80 @@
// 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_SYNTHESIZED_H
#define BOOST_COROUTINES_DETAIL_PULL_COROUTINE_SYNTHESIZED_H
#include <boost/config.hpp>
#include <boost/coroutine/detail/config.hpp>
#include <boost/coroutine/detail/coroutine_context.hpp>
#include <boost/coroutine/detail/pull_coroutine_impl.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
namespace detail {
template< typename R >
class pull_coroutine_synthesized : public pull_coroutine_impl< R >
{
private:
typedef pull_coroutine_impl< R > impl_t;
public:
pull_coroutine_synthesized( coroutine_context * caller,
coroutine_context * callee,
bool unwind,
R * result) :
impl_t( caller, callee, unwind, result)
{}
void destroy() {}
};
template< typename R >
class pull_coroutine_synthesized< R & > : public pull_coroutine_impl< R & >
{
private:
typedef pull_coroutine_impl< R & > impl_t;
public:
pull_coroutine_synthesized( coroutine_context * caller,
coroutine_context * callee,
bool unwind,
R * result) :
impl_t( caller, callee, unwind, result)
{}
void destroy() {}
};
template<>
class pull_coroutine_synthesized< void > : public pull_coroutine_impl< void >
{
private:
typedef pull_coroutine_impl< void > impl_t;
public:
pull_coroutine_synthesized( coroutine_context * caller,
coroutine_context * callee,
bool unwind) :
impl_t( caller, callee, unwind)
{}
inline void destroy() {}
};
}}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_DETAIL_PULL_COROUTINE_SYNTHESIZED_H

View File

@@ -0,0 +1,282 @@
// 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_IMPL_H
#define BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_IMPL_H
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/exception_ptr.hpp>
#include <boost/throw_exception.hpp>
#include <boost/utility.hpp>
#include <boost/coroutine/detail/config.hpp>
#include <boost/coroutine/detail/coroutine_context.hpp>
#include <boost/coroutine/detail/flags.hpp>
#include <boost/coroutine/detail/parameters.hpp>
#include <boost/coroutine/detail/trampoline_push.hpp>
#include <boost/coroutine/exceptions.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
struct stack_context;
namespace detail {
template< typename Arg >
class push_coroutine_impl : private noncopyable
{
protected:
int flags_;
exception_ptr except_;
coroutine_context * caller_;
coroutine_context * callee_;
public:
typedef parameters< Arg > param_type;
push_coroutine_impl( coroutine_context * caller,
coroutine_context * callee,
bool unwind) :
flags_( 0),
except_(),
caller_( caller),
callee_( callee)
{
if ( unwind) flags_ |= flag_force_unwind;
}
virtual ~push_coroutine_impl() {}
bool force_unwind() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_force_unwind); }
bool unwind_requested() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_unwind_stack); }
bool is_started() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_started); }
bool is_running() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_running); }
bool is_complete() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_complete); }
void unwind_stack() BOOST_NOEXCEPT
{
if ( is_started() && ! is_complete() && force_unwind() )
{
flags_ |= flag_unwind_stack;
param_type to( unwind_t::force_unwind);
caller_->jump(
* callee_,
& to);
flags_ &= ~flag_unwind_stack;
BOOST_ASSERT( is_complete() );
}
}
void push( Arg const& arg)
{
BOOST_ASSERT( ! is_running() );
BOOST_ASSERT( ! is_complete() );
flags_ |= flag_running;
param_type to( const_cast< Arg * >( & arg), this);
param_type * from(
static_cast< param_type * >(
caller_->jump(
* callee_,
& to) ) );
flags_ &= ~flag_running;
if ( from->do_unwind) throw forced_unwind();
if ( except_) rethrow_exception( except_);
}
void push( BOOST_RV_REF( Arg) arg)
{
BOOST_ASSERT( ! is_running() );
BOOST_ASSERT( ! is_complete() );
flags_ |= flag_running;
param_type to( const_cast< Arg * >( & arg), this);
param_type * from(
static_cast< param_type * >(
caller_->jump(
* callee_,
& to) ) );
flags_ &= ~flag_running;
if ( from->do_unwind) throw forced_unwind();
if ( except_) rethrow_exception( except_);
}
virtual void destroy() = 0;
};
template< typename Arg >
class push_coroutine_impl< Arg & > : private noncopyable
{
protected:
int flags_;
exception_ptr except_;
coroutine_context * caller_;
coroutine_context * callee_;
public:
typedef parameters< Arg & > param_type;
push_coroutine_impl( coroutine_context * caller,
coroutine_context * callee,
bool unwind) :
flags_( 0),
except_(),
caller_( caller),
callee_( callee)
{
if ( unwind) flags_ |= flag_force_unwind;
}
virtual ~push_coroutine_impl() {}
bool force_unwind() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_force_unwind); }
bool unwind_requested() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_unwind_stack); }
bool is_started() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_started); }
bool is_running() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_running); }
bool is_complete() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_complete); }
void unwind_stack() BOOST_NOEXCEPT
{
if ( is_started() && ! is_complete() && force_unwind() )
{
flags_ |= flag_unwind_stack;
param_type to( unwind_t::force_unwind);
caller_->jump(
* callee_,
& to);
flags_ &= ~flag_unwind_stack;
BOOST_ASSERT( is_complete() );
}
}
void push( Arg & arg)
{
BOOST_ASSERT( ! is_running() );
BOOST_ASSERT( ! is_complete() );
flags_ |= flag_running;
param_type to( & arg, this);
param_type * from(
static_cast< param_type * >(
caller_->jump(
* callee_,
& to) ) );
flags_ &= ~flag_running;
if ( from->do_unwind) throw forced_unwind();
if ( except_) rethrow_exception( except_);
}
virtual void destroy() = 0;
};
template<>
class push_coroutine_impl< void > : private noncopyable
{
protected:
int flags_;
exception_ptr except_;
coroutine_context * caller_;
coroutine_context * callee_;
public:
typedef parameters< void > param_type;
push_coroutine_impl( coroutine_context * caller,
coroutine_context * callee,
bool unwind) :
flags_( 0),
except_(),
caller_( caller),
callee_( callee)
{
if ( unwind) flags_ |= flag_force_unwind;
}
virtual ~push_coroutine_impl() {}
inline bool force_unwind() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_force_unwind); }
inline bool unwind_requested() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_unwind_stack); }
inline bool is_started() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_started); }
inline bool is_running() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_running); }
inline bool is_complete() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_complete); }
inline void unwind_stack() BOOST_NOEXCEPT
{
if ( is_started() && ! is_complete() && force_unwind() )
{
flags_ |= flag_unwind_stack;
param_type to( unwind_t::force_unwind);
caller_->jump(
* callee_,
& to);
flags_ &= ~flag_unwind_stack;
BOOST_ASSERT( is_complete() );
}
}
inline void push()
{
BOOST_ASSERT( ! is_running() );
BOOST_ASSERT( ! is_complete() );
flags_ |= flag_running;
param_type to( this);
param_type * from(
static_cast< param_type * >(
caller_->jump(
* callee_,
& to) ) );
flags_ &= ~flag_running;
if ( from->do_unwind) throw forced_unwind();
if ( except_) rethrow_exception( except_);
}
virtual void destroy() = 0;
};
}}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_IMPL_H

View File

@@ -0,0 +1,335 @@
// 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 <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/context/detail/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/coroutine_context.hpp>
#include <boost/coroutine/detail/flags.hpp>
#include <boost/coroutine/detail/preallocated.hpp>
#include <boost/coroutine/detail/push_coroutine_impl.hpp>
#include <boost/coroutine/detail/trampoline_push.hpp>
#include <boost/coroutine/exceptions.hpp>
#include <boost/coroutine/flags.hpp>
#include <boost/coroutine/stack_context.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
#if defined(BOOST_MSVC)
# pragma warning(push)
# pragma warning(disable:4355)
#endif
namespace boost {
namespace coroutines {
namespace detail {
struct push_coroutine_context
{
coroutine_context caller;
coroutine_context callee;
template< typename Coro >
push_coroutine_context( preallocated const& palloc, Coro *) :
caller(),
callee( trampoline_push< Coro >, palloc)
{}
};
struct push_coroutine_context_void
{
coroutine_context caller;
coroutine_context callee;
template< typename Coro >
push_coroutine_context_void( preallocated const& palloc, Coro *) :
caller(),
callee( trampoline_push_void< Coro >, palloc)
{}
};
template< typename PullCoro, typename R, typename Fn, typename StackAllocator >
class push_coroutine_object : private push_coroutine_context,
public push_coroutine_impl< R >
{
private:
typedef push_coroutine_context ctx_t;
typedef push_coroutine_impl< R > base_t;
typedef push_coroutine_object< PullCoro, R, Fn, StackAllocator > obj_t;
Fn fn_;
stack_context stack_ctx_;
StackAllocator stack_alloc_;
static void deallocate_( obj_t * obj)
{
stack_context stack_ctx( obj->stack_ctx_);
StackAllocator stack_alloc( obj->stack_alloc_);
obj->unwind_stack();
obj->~obj_t();
stack_alloc.deallocate( stack_ctx);
}
public:
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
push_coroutine_object( Fn fn, attributes const& attrs,
preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
ctx_t( palloc, this),
base_t( & this->caller,
& this->callee,
stack_unwind == attrs.do_unwind),
fn_( fn),
stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
#endif
push_coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attrs,
preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
ctx_t( palloc, this),
base_t( & this->caller,
& this->callee,
stack_unwind == attrs.do_unwind),
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
fn_( fn),
#else
fn_( boost::forward< Fn >( fn) ),
#endif
stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
void run( R * result)
{
BOOST_ASSERT( ! base_t::unwind_requested() );
base_t::flags_ |= flag_started;
base_t::flags_ |= flag_running;
// create push_coroutine
typename PullCoro::synth_type b( & this->callee, & this->caller, false, result);
PullCoro pull_coro( synthesized_t::syntesized, b);
try
{ fn_( pull_coro); }
catch ( forced_unwind const&)
{}
#if defined( BOOST_CONTEXT_HAS_CXXABI_H )
catch ( abi::__forced_unwind const&)
{ throw; }
#endif
catch (...)
{ base_t::except_ = current_exception(); }
base_t::flags_ |= flag_complete;
base_t::flags_ &= ~flag_running;
typename base_t::param_type to;
this->callee.jump(
this->caller,
& to);
BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
}
void destroy()
{ deallocate_( this); }
};
template< typename PullCoro, typename R, typename Fn, typename StackAllocator >
class push_coroutine_object< PullCoro, R &, Fn, StackAllocator > : private push_coroutine_context,
public push_coroutine_impl< R & >
{
private:
typedef push_coroutine_context ctx_t;
typedef push_coroutine_impl< R & > base_t;
typedef push_coroutine_object< PullCoro, R &, Fn, StackAllocator > obj_t;
Fn fn_;
stack_context stack_ctx_;
StackAllocator stack_alloc_;
static void deallocate_( obj_t * obj)
{
stack_context stack_ctx( obj->stack_ctx_);
StackAllocator stack_alloc( obj->stack_alloc_);
obj->unwind_stack();
obj->~obj_t();
stack_alloc.deallocate( stack_ctx);
}
public:
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
push_coroutine_object( Fn fn, attributes const& attrs,
preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
ctx_t( palloc, this),
base_t( & this->caller,
& this->callee,
stack_unwind == attrs.do_unwind),
fn_( fn),
stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
#endif
push_coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attrs,
preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
ctx_t( palloc, this),
base_t( & this->caller,
& this->callee,
stack_unwind == attrs.do_unwind),
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
fn_( fn),
#else
fn_( boost::forward< Fn >( fn) ),
#endif
stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
void run( R * result)
{
BOOST_ASSERT( ! base_t::unwind_requested() );
base_t::flags_ |= flag_started;
base_t::flags_ |= flag_running;
// create push_coroutine
typename PullCoro::synth_type b( & this->callee, & this->caller, false, result);
PullCoro push_coro( synthesized_t::syntesized, b);
try
{ fn_( push_coro); }
catch ( forced_unwind const&)
{}
#if defined( BOOST_CONTEXT_HAS_CXXABI_H )
catch ( abi::__forced_unwind const&)
{ throw; }
#endif
catch (...)
{ base_t::except_ = current_exception(); }
base_t::flags_ |= flag_complete;
base_t::flags_ &= ~flag_running;
typename base_t::param_type to;
this->callee.jump(
this->caller,
& to);
BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
}
void destroy()
{ deallocate_( this); }
};
template< typename PullCoro, typename Fn, typename StackAllocator >
class push_coroutine_object< PullCoro, void, Fn, StackAllocator > : private push_coroutine_context_void,
public push_coroutine_impl< void >
{
private:
typedef push_coroutine_context_void ctx_t;
typedef push_coroutine_impl< void > base_t;
typedef push_coroutine_object< PullCoro, void, Fn, StackAllocator > obj_t;
Fn fn_;
stack_context stack_ctx_;
StackAllocator stack_alloc_;
static void deallocate_( obj_t * obj)
{
stack_context stack_ctx( obj->stack_ctx_);
StackAllocator stack_alloc( obj->stack_alloc_);
obj->unwind_stack();
obj->~obj_t();
stack_alloc.deallocate( stack_ctx);
}
public:
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
push_coroutine_object( Fn fn, attributes const& attrs,
preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
ctx_t( palloc, this),
base_t( & this->caller,
& this->callee,
stack_unwind == attrs.do_unwind),
fn_( fn),
stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
#endif
push_coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attrs,
preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
ctx_t( palloc, this),
base_t( & this->caller,
& this->callee,
stack_unwind == attrs.do_unwind),
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
fn_( fn),
#else
fn_( boost::forward< Fn >( fn) ),
#endif
stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
void run()
{
BOOST_ASSERT( ! base_t::unwind_requested() );
base_t::flags_ |= flag_started;
base_t::flags_ |= flag_running;
// create push_coroutine
typename PullCoro::synth_type b( & this->callee, & this->caller, false);
PullCoro push_coro( synthesized_t::syntesized, b);
try
{ fn_( push_coro); }
catch ( forced_unwind const&)
{}
#if defined( BOOST_CONTEXT_HAS_CXXABI_H )
catch ( abi::__forced_unwind const&)
{ throw; }
#endif
catch (...)
{ base_t::except_ = current_exception(); }
base_t::flags_ |= flag_complete;
base_t::flags_ &= ~flag_running;
typename base_t::param_type to;
this->callee.jump(
this->caller,
& to);
BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
}
void destroy()
{ deallocate_( this); }
};
}}}
#if defined(BOOST_MSVC)
# pragma warning(pop)
#endif
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_OBJECT_H

View File

@@ -0,0 +1,78 @@
// 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_SYNTHESIZED_H
#define BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_SYNTHESIZED_H
#include <boost/config.hpp>
#include <boost/coroutine/detail/config.hpp>
#include <boost/coroutine/detail/coroutine_context.hpp>
#include <boost/coroutine/detail/push_coroutine_impl.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
namespace detail {
template< typename R >
class push_coroutine_synthesized : public push_coroutine_impl< R >
{
private:
typedef push_coroutine_impl< R > impl_t;
public:
push_coroutine_synthesized( coroutine_context * caller,
coroutine_context * callee,
bool unwind) :
impl_t( caller, callee, unwind)
{}
void destroy() {}
};
template< typename R >
class push_coroutine_synthesized< R & > : public push_coroutine_impl< R & >
{
private:
typedef push_coroutine_impl< R & > impl_t;
public:
push_coroutine_synthesized( coroutine_context * caller,
coroutine_context * callee,
bool unwind) :
impl_t( caller, callee, unwind)
{}
void destroy() {}
};
template<>
class push_coroutine_synthesized< void > : public push_coroutine_impl< void >
{
private:
typedef push_coroutine_impl< void > impl_t;
public:
push_coroutine_synthesized( coroutine_context * caller,
coroutine_context * callee,
bool unwind) :
impl_t( caller, callee, unwind)
{}
inline void destroy() {}
};
}}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_DETAIL_PUSH_COROUTINE_SYNTHESIZED_H

View File

@@ -0,0 +1,75 @@
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_COROUTINES_DETAIL_SETUP_H
#define BOOST_COROUTINES_DETAIL_SETUP_H
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/move/move.hpp>
#include <boost/type_traits/decay.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/coroutine/attributes.hpp>
#include <boost/coroutine/detail/coroutine_context.hpp>
#include <boost/coroutine/detail/flags.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
namespace detail {
template< typename Fn >
struct setup
{
struct dummy {};
Fn fn;
coroutine_context * caller;
coroutine_context * callee;
attributes attr;
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
setup( Fn fn_,
coroutine_context * caller_,
coroutine_context * callee_,
attributes const& attr_) :
fn( boost::forward< Fn >( fn_) ),
caller( caller_),
callee( callee_),
attr( attr_)
{}
#endif
setup( BOOST_RV_REF( Fn) fn_,
coroutine_context * caller_,
coroutine_context * callee_,
attributes const& attr_,
typename disable_if<
is_same< typename decay< Fn >::type, setup >,
dummy*
>::type = 0) :
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
fn( fn_),
#else
fn( boost::forward< Fn >( fn_) ),
#endif
caller( caller_),
callee( callee_),
attr( attr_)
{}
};
}}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_DETAIL_SETUP_H

View File

@@ -0,0 +1,811 @@
// 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_SYMMETRIC_COROUTINE_CALL_H
#define BOOST_COROUTINES_DETAIL_SYMMETRIC_COROUTINE_CALL_H
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/move/move.hpp>
#include <boost/utility/explicit_operator_bool.hpp>
#include <boost/coroutine/attributes.hpp>
#include <boost/coroutine/detail/config.hpp>
#include <boost/coroutine/detail/preallocated.hpp>
#include <boost/coroutine/detail/symmetric_coroutine_impl.hpp>
#include <boost/coroutine/detail/symmetric_coroutine_object.hpp>
#include <boost/coroutine/detail/symmetric_coroutine_yield.hpp>
#include <boost/coroutine/stack_allocator.hpp>
#include <boost/coroutine/stack_context.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
namespace detail {
template< typename Arg >
class symmetric_coroutine_call
{
private:
template< typename X >
friend class symmetric_coroutine_yield;
typedef symmetric_coroutine_impl< Arg > impl_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE( symmetric_coroutine_call)
struct dummy {};
impl_type * impl_;
public:
typedef Arg value_type;
typedef symmetric_coroutine_yield< Arg > yield_type;
symmetric_coroutine_call() BOOST_NOEXCEPT :
impl_( 0)
{}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
# ifdef BOOST_MSVC
typedef void ( * coroutine_fn)( yield_type &);
explicit symmetric_coroutine_call( coroutine_fn fn,
attributes const& attrs = attributes(),
stack_allocator stack_alloc = stack_allocator() ) :
impl_( 0)
{
// create a stack-context
stack_context stack_ctx;
// allocate the coroutine-stack
stack_alloc.allocate( stack_ctx, attrs.size);
BOOST_ASSERT( 0 != stack_ctx.sp);
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg, coroutine_fn, stack_allocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
std::size_t size = stack_ctx.size - sizeof( object_t);
BOOST_ASSERT( 0 != size);
void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
BOOST_ASSERT( 0 != sp);
// placement new for internal coroutine
impl_ = new ( sp) object_t(
boost::forward< coroutine_fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
template< typename StackAllocator >
explicit symmetric_coroutine_call( coroutine_fn fn,
attributes const& attrs,
StackAllocator stack_alloc) :
impl_( 0)
{
// create a stack-context
stack_context stack_ctx;
// allocate the coroutine-stack
stack_alloc.allocate( stack_ctx, attrs.size);
BOOST_ASSERT( 0 != stack_ctx.sp);
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg, coroutine_fn, StackAllocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
std::size_t size = stack_ctx.size - sizeof( object_t);
BOOST_ASSERT( 0 != size);
void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
BOOST_ASSERT( 0 != sp);
// placement new for internal coroutine
impl_ = new ( sp) object_t(
boost::forward< coroutine_fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
# endif
template< typename Fn >
explicit symmetric_coroutine_call( BOOST_RV_REF( Fn) fn,
attributes const& attrs = attributes(),
stack_allocator stack_alloc = stack_allocator() ) :
impl_( 0)
{
// create a stack-context
stack_context stack_ctx;
// allocate the coroutine-stack
stack_alloc.allocate( stack_ctx, attrs.size);
BOOST_ASSERT( 0 != stack_ctx.sp);
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg, Fn, stack_allocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
std::size_t size = stack_ctx.size - sizeof( object_t);
BOOST_ASSERT( 0 != size);
void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
BOOST_ASSERT( 0 != sp);
// placement new for internal coroutine
impl_ = new ( sp) object_t(
boost::forward< Fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
template< typename Fn, typename StackAllocator >
explicit symmetric_coroutine_call( BOOST_RV_REF( Fn) fn,
attributes const& attrs,
StackAllocator stack_alloc) :
impl_( 0)
{
// create a stack-context
stack_context stack_ctx;
// allocate the coroutine-stack
stack_alloc.allocate( stack_ctx, attrs.size);
BOOST_ASSERT( 0 != stack_ctx.sp);
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg, Fn, StackAllocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
std::size_t size = stack_ctx.size - sizeof( object_t);
BOOST_ASSERT( 0 != size);
void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
BOOST_ASSERT( 0 != sp);
// placement new for internal coroutine
impl_ = new ( sp) object_t(
boost::forward< Fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
#else
template< typename Fn >
explicit symmetric_coroutine_call( Fn fn,
attributes const& attrs = attributes(),
stack_allocator stack_alloc = stack_allocator() ) :
impl_( 0)
{
// create a stack-context
stack_context stack_ctx;
// allocate the coroutine-stack
stack_alloc.allocate( stack_ctx, attrs.size);
BOOST_ASSERT( 0 != stack_ctx.sp);
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg, Fn, stack_allocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
std::size_t size = stack_ctx.size - sizeof( object_t);
BOOST_ASSERT( 0 != size);
void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
BOOST_ASSERT( 0 != sp);
// placement new for internal coroutine
impl_ = new ( sp) object_t(
fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
template< typename Fn, typename StackAllocator >
explicit symmetric_coroutine_call( Fn fn,
attributes const& attrs,
StackAllocator stack_alloc) :
impl_( 0)
{
// create a stack-context
stack_context stack_ctx;
// allocate the coroutine-stack
stack_alloc.allocate( stack_ctx, attrs.size);
BOOST_ASSERT( 0 != stack_ctx.sp);
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg, Fn, StackAllocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
std::size_t size = stack_ctx.size - sizeof( object_t);
BOOST_ASSERT( 0 != size);
void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
BOOST_ASSERT( 0 != sp);
// placement new for internal coroutine
impl_ = new ( sp) object_t(
fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
template< typename Fn >
explicit symmetric_coroutine_call( BOOST_RV_REF( Fn) fn,
attributes const& attrs = attributes(),
stack_allocator stack_alloc = stack_allocator() ) :
impl_( 0)
{
// create a stack-context
stack_context stack_ctx;
// allocate the coroutine-stack
stack_alloc.allocate( stack_ctx, attrs.size);
BOOST_ASSERT( 0 != stack_ctx.sp);
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg, Fn, stack_allocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
std::size_t size = stack_ctx.size - sizeof( object_t);
BOOST_ASSERT( 0 != size);
void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
BOOST_ASSERT( 0 != sp);
// placement new for internal coroutine
impl_ = new ( sp) object_t(
fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
template< typename Fn, typename StackAllocator >
explicit symmetric_coroutine_call( BOOST_RV_REF( Fn) fn,
attributes const& attrs,
StackAllocator stack_alloc) :
impl_( 0)
{
// create a stack-context
stack_context stack_ctx;
// allocate the coroutine-stack
stack_alloc.allocate( stack_ctx, attrs.size);
BOOST_ASSERT( 0 != stack_ctx.sp);
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg, Fn, StackAllocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
std::size_t size = stack_ctx.size - sizeof( object_t);
BOOST_ASSERT( 0 != size);
void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
BOOST_ASSERT( 0 != sp);
// placement new for internal coroutine
impl_ = new ( sp) object_t(
fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
#endif
~symmetric_coroutine_call()
{
if ( 0 != impl_)
{
impl_->destroy();
impl_ = 0;
}
}
symmetric_coroutine_call( BOOST_RV_REF( symmetric_coroutine_call) other) BOOST_NOEXCEPT :
impl_( 0)
{ swap( other); }
symmetric_coroutine_call & operator=( BOOST_RV_REF( symmetric_coroutine_call) other) BOOST_NOEXCEPT
{
symmetric_coroutine_call tmp( boost::move( other) );
swap( tmp);
return * this;
}
BOOST_EXPLICIT_OPERATOR_BOOL();
bool operator!() const BOOST_NOEXCEPT
{ return 0 == impl_ || impl_->is_complete() || impl_->is_running(); }
void swap( symmetric_coroutine_call & other) BOOST_NOEXCEPT
{ std::swap( impl_, other.impl_); }
symmetric_coroutine_call & operator()( Arg arg) BOOST_NOEXCEPT
{
BOOST_ASSERT( * this);
impl_->resume( arg);
return * this;
}
};
template< typename Arg >
class symmetric_coroutine_call< Arg & >
{
private:
template< typename X >
friend class symmetric_coroutine_yield;
typedef symmetric_coroutine_impl< Arg & > impl_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE( symmetric_coroutine_call)
struct dummy {};
impl_type * impl_;
public:
typedef Arg value_type;
typedef symmetric_coroutine_yield< Arg & > yield_type;
symmetric_coroutine_call() BOOST_NOEXCEPT :
impl_( 0)
{}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
# ifdef BOOST_MSVC
typedef void ( * coroutine_fn)( yield_type &);
explicit symmetric_coroutine_call( coroutine_fn fn,
attributes const& attrs = attributes(),
stack_allocator stack_alloc = stack_allocator() ) :
impl_( 0)
{
// create a stack-context
stack_context stack_ctx;
// allocate the coroutine-stack
stack_alloc.allocate( stack_ctx, attrs.size);
BOOST_ASSERT( 0 != stack_ctx.sp);
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg &, coroutine_fn, stack_allocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
std::size_t size = stack_ctx.size - sizeof( object_t);
BOOST_ASSERT( 0 != size);
void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
BOOST_ASSERT( 0 != sp);
// placement new for internal coroutine
impl_ = new ( sp) object_t(
boost::forward< coroutine_fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
template< typename StackAllocator >
explicit symmetric_coroutine_call( coroutine_fn fn,
attributes const& attrs,
StackAllocator stack_alloc) :
impl_( 0)
{
// create a stack-context
stack_context stack_ctx;
// allocate the coroutine-stack
stack_alloc.allocate( stack_ctx, attrs.size);
BOOST_ASSERT( 0 != stack_ctx.sp);
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg &, coroutine_fn, StackAllocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
std::size_t size = stack_ctx.size - sizeof( object_t);
BOOST_ASSERT( 0 != size);
void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
BOOST_ASSERT( 0 != sp);
// placement new for internal coroutine
impl_ = new ( sp) object_t(
boost::forward< coroutine_fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
# endif
template< typename Fn >
explicit symmetric_coroutine_call( BOOST_RV_REF( Fn) fn,
attributes const& attrs = attributes(),
stack_allocator stack_alloc = stack_allocator() ) :
impl_( 0)
{
// create a stack-context
stack_context stack_ctx;
// allocate the coroutine-stack
stack_alloc.allocate( stack_ctx, attrs.size);
BOOST_ASSERT( 0 != stack_ctx.sp);
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg &, Fn, stack_allocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
std::size_t size = stack_ctx.size - sizeof( object_t);
BOOST_ASSERT( 0 != size);
void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
BOOST_ASSERT( 0 != sp);
// placement new for internal coroutine
impl_ = new ( sp) object_t(
boost::forward< Fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
template< typename Fn, typename StackAllocator >
explicit symmetric_coroutine_call( BOOST_RV_REF( Fn) fn,
attributes const& attrs,
StackAllocator stack_alloc) :
impl_( 0)
{
// create a stack-context
stack_context stack_ctx;
// allocate the coroutine-stack
stack_alloc.allocate( stack_ctx, attrs.size);
BOOST_ASSERT( 0 != stack_ctx.sp);
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg &, Fn, StackAllocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
std::size_t size = stack_ctx.size - sizeof( object_t);
BOOST_ASSERT( 0 != size);
void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
BOOST_ASSERT( 0 != sp);
// placement new for internal coroutine
impl_ = new ( sp) object_t(
boost::forward< Fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
#else
template< typename Fn >
explicit symmetric_coroutine_call( Fn fn,
attributes const& attrs = attributes(),
stack_allocator stack_alloc = stack_allocator() ) :
impl_( 0)
{
// create a stack-context
stack_context stack_ctx;
// allocate the coroutine-stack
stack_alloc.allocate( stack_ctx, attrs.size);
BOOST_ASSERT( 0 != stack_ctx.sp);
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg &, Fn, stack_allocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
std::size_t size = stack_ctx.size - sizeof( object_t);
BOOST_ASSERT( 0 != size);
void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
BOOST_ASSERT( 0 != sp);
// placement new for internal coroutine
impl_ = new ( sp) object_t(
fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
template< typename Fn, typename StackAllocator >
explicit symmetric_coroutine_call( Fn fn,
attributes const& attrs,
StackAllocator stack_alloc) :
impl_( 0)
{
// create a stack-context
stack_context stack_ctx;
// allocate the coroutine-stack
stack_alloc.allocate( stack_ctx, attrs.size);
BOOST_ASSERT( 0 != stack_ctx.sp);
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg &, Fn, StackAllocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
std::size_t size = stack_ctx.size - sizeof( object_t);
BOOST_ASSERT( 0 != size);
void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
BOOST_ASSERT( 0 != sp);
// placement new for internal coroutine
impl_ = new ( sp) object_t(
fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
template< typename Fn >
explicit symmetric_coroutine_call( BOOST_RV_REF( Fn) fn,
attributes const& attrs = attributes(),
stack_allocator stack_alloc = stack_allocator() ) :
impl_( 0)
{
// create a stack-context
stack_context stack_ctx;
// allocate the coroutine-stack
stack_alloc.allocate( stack_ctx, attrs.size);
BOOST_ASSERT( 0 != stack_ctx.sp);
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg &, Fn, stack_allocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
std::size_t size = stack_ctx.size - sizeof( object_t);
BOOST_ASSERT( 0 != size);
void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
BOOST_ASSERT( 0 != sp);
// placement new for internal coroutine
impl_ = new ( sp) object_t(
fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
template< typename Fn, typename StackAllocator >
explicit symmetric_coroutine_call( BOOST_RV_REF( Fn) fn,
attributes const& attrs,
StackAllocator stack_alloc) :
impl_( 0)
{
// create a stack-context
stack_context stack_ctx;
// allocate the coroutine-stack
stack_alloc.allocate( stack_ctx, attrs.size);
BOOST_ASSERT( 0 != stack_ctx.sp);
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< Arg &, Fn, StackAllocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
std::size_t size = stack_ctx.size - sizeof( object_t);
BOOST_ASSERT( 0 != size);
void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
BOOST_ASSERT( 0 != sp);
// placement new for internal coroutine
impl_ = new ( sp) object_t(
fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
#endif
~symmetric_coroutine_call()
{
if ( 0 != impl_)
{
impl_->destroy();
impl_ = 0;
}
}
symmetric_coroutine_call( BOOST_RV_REF( symmetric_coroutine_call) other) BOOST_NOEXCEPT :
impl_( 0)
{ swap( other); }
symmetric_coroutine_call & operator=( BOOST_RV_REF( symmetric_coroutine_call) other) BOOST_NOEXCEPT
{
symmetric_coroutine_call tmp( boost::move( other) );
swap( tmp);
return * this;
}
BOOST_EXPLICIT_OPERATOR_BOOL();
bool operator!() const BOOST_NOEXCEPT
{ return 0 == impl_ || impl_->is_complete() || impl_->is_running(); }
void swap( symmetric_coroutine_call & other) BOOST_NOEXCEPT
{ std::swap( impl_, other.impl_); }
symmetric_coroutine_call & operator()( Arg & arg) BOOST_NOEXCEPT
{
BOOST_ASSERT( * this);
impl_->resume( arg);
return * this;
}
};
template<>
class symmetric_coroutine_call< void >
{
private:
template< typename X >
friend class symmetric_coroutine_yield;
typedef symmetric_coroutine_impl< void > impl_type;
BOOST_MOVABLE_BUT_NOT_COPYABLE( symmetric_coroutine_call)
struct dummy {};
impl_type * impl_;
public:
typedef void value_type;
typedef symmetric_coroutine_yield< void > yield_type;
symmetric_coroutine_call() BOOST_NOEXCEPT :
impl_( 0)
{}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
# ifdef BOOST_MSVC
typedef void ( * coroutine_fn)( yield_type &);
explicit symmetric_coroutine_call( coroutine_fn fn,
attributes const& attrs = attributes(),
stack_allocator stack_alloc = stack_allocator() ) :
impl_( 0)
{
// create a stack-context
stack_context stack_ctx;
// allocate the coroutine-stack
stack_alloc.allocate( stack_ctx, attrs.size);
BOOST_ASSERT( 0 != stack_ctx.sp);
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< void, coroutine_fn, stack_allocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
std::size_t size = stack_ctx.size - sizeof( object_t);
BOOST_ASSERT( 0 != size);
void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
BOOST_ASSERT( 0 != sp);
// placement new for internal coroutine
impl_ = new ( sp) object_t(
boost::forward< coroutine_fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
template< typename StackAllocator >
explicit symmetric_coroutine_call( coroutine_fn fn,
attributes const& attrs,
StackAllocator stack_alloc) :
impl_( 0)
{
// create a stack-context
stack_context stack_ctx;
// allocate the coroutine-stack
stack_alloc.allocate( stack_ctx, attrs.size);
BOOST_ASSERT( 0 != stack_ctx.sp);
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< void, coroutine_fn, StackAllocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
std::size_t size = stack_ctx.size - sizeof( object_t);
BOOST_ASSERT( 0 != size);
void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
BOOST_ASSERT( 0 != sp);
// placement new for internal coroutine
impl_ = new ( sp) object_t(
boost::forward< coroutine_fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
# endif
template< typename Fn >
explicit symmetric_coroutine_call( BOOST_RV_REF( Fn) fn,
attributes const& attrs = attributes(),
stack_allocator stack_alloc = stack_allocator() ) :
impl_( 0)
{
// create a stack-context
stack_context stack_ctx;
// allocate the coroutine-stack
stack_alloc.allocate( stack_ctx, attrs.size);
BOOST_ASSERT( 0 != stack_ctx.sp);
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< void, Fn, stack_allocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
std::size_t size = stack_ctx.size - sizeof( object_t);
BOOST_ASSERT( 0 != size);
void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
BOOST_ASSERT( 0 != sp);
// placement new for internal coroutine
impl_ = new ( sp) object_t(
boost::forward< Fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
template< typename Fn, typename StackAllocator >
explicit symmetric_coroutine_call( BOOST_RV_REF( Fn) fn,
attributes const& attrs,
StackAllocator stack_alloc) :
impl_( 0)
{
// create a stack-context
stack_context stack_ctx;
// allocate the coroutine-stack
stack_alloc.allocate( stack_ctx, attrs.size);
BOOST_ASSERT( 0 != stack_ctx.sp);
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< void, Fn, StackAllocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
std::size_t size = stack_ctx.size - sizeof( object_t);
BOOST_ASSERT( 0 != size);
void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
BOOST_ASSERT( 0 != sp);
// placement new for internal coroutine
impl_ = new ( sp) object_t(
boost::forward< Fn >( fn), attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
#else
template< typename Fn >
explicit symmetric_coroutine_call( Fn fn,
attributes const& attrs = attributes(),
stack_allocator stack_alloc = stack_allocator() ) :
impl_( 0)
{
// create a stack-context
stack_context stack_ctx;
// allocate the coroutine-stack
stack_alloc.allocate( stack_ctx, attrs.size);
BOOST_ASSERT( 0 != stack_ctx.sp);
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< void, Fn, stack_allocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
std::size_t size = stack_ctx.size - sizeof( object_t);
BOOST_ASSERT( 0 != size);
void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
BOOST_ASSERT( 0 != sp);
// placement new for internal coroutine
impl_ = new ( sp) object_t(
fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
template< typename Fn, typename StackAllocator >
explicit symmetric_coroutine_call( Fn fn,
attributes const& attrs,
StackAllocator stack_alloc) :
impl_( 0)
{
// create a stack-context
stack_context stack_ctx;
// allocate the coroutine-stack
stack_alloc.allocate( stack_ctx, attrs.size);
BOOST_ASSERT( 0 != stack_ctx.sp);
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< void, Fn, StackAllocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
std::size_t size = stack_ctx.size - sizeof( object_t);
BOOST_ASSERT( 0 != size);
void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
BOOST_ASSERT( 0 != sp);
// placement new for internal coroutine
impl_ = new ( sp) object_t(
fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
template< typename Fn >
explicit symmetric_coroutine_call( BOOST_RV_REF( Fn) fn,
attributes const& attrs = attributes(),
stack_allocator stack_alloc = stack_allocator() ) :
impl_( 0)
{
// create a stack-context
stack_context stack_ctx;
// allocate the coroutine-stack
stack_alloc.allocate( stack_ctx, attrs.size);
BOOST_ASSERT( 0 != stack_ctx.sp);
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< void, Fn, stack_allocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
std::size_t size = stack_ctx.size - sizeof( object_t);
BOOST_ASSERT( 0 != size);
void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
BOOST_ASSERT( 0 != sp);
// placement new for internal coroutine
impl_ = new ( sp) object_t(
fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
template< typename Fn, typename StackAllocator >
explicit symmetric_coroutine_call( BOOST_RV_REF( Fn) fn,
attributes const& attrs,
StackAllocator stack_alloc) :
impl_( 0)
{
// create a stack-context
stack_context stack_ctx;
// allocate the coroutine-stack
stack_alloc.allocate( stack_ctx, attrs.size);
BOOST_ASSERT( 0 != stack_ctx.sp);
// typedef of internal coroutine-type
typedef symmetric_coroutine_object< void, Fn, StackAllocator > object_t;
// reserve space on top of coroutine-stack for internal coroutine-type
std::size_t size = stack_ctx.size - sizeof( object_t);
BOOST_ASSERT( 0 != size);
void * sp = static_cast< char * >( stack_ctx.sp) - sizeof( object_t);
BOOST_ASSERT( 0 != sp);
// placement new for internal coroutine
impl_ = new ( sp) object_t(
fn, attrs, preallocated( sp, size, stack_ctx), stack_alloc);
BOOST_ASSERT( impl_);
}
#endif
~symmetric_coroutine_call()
{
if ( 0 != impl_)
{
impl_->destroy();
impl_ = 0;
}
}
inline symmetric_coroutine_call( BOOST_RV_REF( symmetric_coroutine_call) other) BOOST_NOEXCEPT :
impl_( 0)
{ swap( other); }
inline symmetric_coroutine_call & operator=( BOOST_RV_REF( symmetric_coroutine_call) other) BOOST_NOEXCEPT
{
symmetric_coroutine_call tmp( boost::move( other) );
swap( tmp);
return * this;
}
BOOST_EXPLICIT_OPERATOR_BOOL();
inline bool operator!() const BOOST_NOEXCEPT
{ return 0 == impl_ || impl_->is_complete() || impl_->is_running(); }
inline void swap( symmetric_coroutine_call & other) BOOST_NOEXCEPT
{ std::swap( impl_, other.impl_); }
inline symmetric_coroutine_call & operator()() BOOST_NOEXCEPT
{
BOOST_ASSERT( * this);
impl_->resume();
return * this;
}
};
template< typename Arg >
void swap( symmetric_coroutine_call< Arg > & l,
symmetric_coroutine_call< Arg > & r)
{ l.swap( r); }
}}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_DETAIL_SYMMETRIC_COROUTINE_CALL_H

View File

@@ -0,0 +1,449 @@
// 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_SYMMETRIC_COROUTINE_IMPL_H
#define BOOST_COROUTINES_DETAIL_SYMMETRIC_COROUTINE_IMPL_H
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/cstdint.hpp>
#include <boost/utility.hpp>
#include <boost/coroutine/detail/config.hpp>
#include <boost/coroutine/detail/coroutine_context.hpp>
#include <boost/coroutine/detail/flags.hpp>
#include <boost/coroutine/detail/parameters.hpp>
#include <boost/coroutine/detail/preallocated.hpp>
#include <boost/coroutine/detail/trampoline.hpp>
#include <boost/coroutine/exceptions.hpp>
#include <boost/coroutine/stack_context.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
namespace detail {
template< typename R >
class symmetric_coroutine_impl : private noncopyable
{
public:
typedef parameters< R > param_type;
symmetric_coroutine_impl( preallocated const& palloc,
bool unwind) BOOST_NOEXCEPT :
flags_( 0),
caller_(),
callee_( trampoline< symmetric_coroutine_impl< R > >, palloc)
{
if ( unwind) flags_ |= flag_force_unwind;
}
virtual ~symmetric_coroutine_impl() {}
bool force_unwind() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_force_unwind); }
bool unwind_requested() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_unwind_stack); }
bool is_started() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_started); }
bool is_running() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_running); }
bool is_complete() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_complete); }
void unwind_stack() BOOST_NOEXCEPT
{
if ( is_started() && ! is_complete() && force_unwind() )
{
flags_ |= flag_unwind_stack;
flags_ |= flag_running;
param_type to( unwind_t::force_unwind);
caller_.jump(
callee_,
& to);
flags_ &= ~flag_running;
flags_ &= ~flag_unwind_stack;
BOOST_ASSERT( is_complete() );
}
}
void resume( R r) BOOST_NOEXCEPT
{
param_type to( const_cast< R * >( & r), this);
resume_( & to);
}
R * yield()
{
BOOST_ASSERT( is_running() );
BOOST_ASSERT( ! is_complete() );
flags_ &= ~flag_running;
param_type to;
param_type * from(
static_cast< param_type * >(
callee_.jump(
caller_,
& to) ) );
flags_ |= flag_running;
if ( from->do_unwind) throw forced_unwind();
BOOST_ASSERT( from->data);
return from->data;
}
template< typename X >
R * yield_to( symmetric_coroutine_impl< X > * other, X x)
{
typename symmetric_coroutine_impl< X >::param_type to( & x, other);
return yield_to_( other, & to);
}
template< typename X >
R * yield_to( symmetric_coroutine_impl< X & > * other, X & x)
{
typename symmetric_coroutine_impl< X & >::param_type to( & x, other);
return yield_to_( other, & to);
}
template< typename X >
R * yield_to( symmetric_coroutine_impl< X > * other)
{
typename symmetric_coroutine_impl< X >::param_type to( other);
return yield_to_( other, & to);
}
virtual void run( R *) BOOST_NOEXCEPT = 0;
virtual void destroy() = 0;
protected:
template< typename X >
friend class symmetric_coroutine_impl;
int flags_;
coroutine_context caller_;
coroutine_context callee_;
void resume_( param_type * to) BOOST_NOEXCEPT
{
BOOST_ASSERT( ! is_running() );
BOOST_ASSERT( ! is_complete() );
flags_ |= flag_running;
caller_.jump(
callee_,
to);
flags_ &= ~flag_running;
}
template< typename Other >
R * yield_to_( Other * other, typename Other::param_type * to)
{
BOOST_ASSERT( is_running() );
BOOST_ASSERT( ! is_complete() );
BOOST_ASSERT( ! other->is_running() );
BOOST_ASSERT( ! other->is_complete() );
other->caller_ = caller_;
flags_ &= ~flag_running;
param_type * from(
static_cast< param_type * >(
callee_.jump(
other->callee_,
to) ) );
flags_ |= flag_running;
if ( from->do_unwind) throw forced_unwind();
BOOST_ASSERT( from->data);
return from->data;
}
};
template< typename R >
class symmetric_coroutine_impl< R & > : private noncopyable
{
public:
typedef parameters< R & > param_type;
symmetric_coroutine_impl( preallocated const& palloc,
bool unwind) BOOST_NOEXCEPT :
flags_( 0),
caller_(),
callee_( trampoline< symmetric_coroutine_impl< R > >, palloc)
{
if ( unwind) flags_ |= flag_force_unwind;
}
virtual ~symmetric_coroutine_impl() {}
bool force_unwind() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_force_unwind); }
bool unwind_requested() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_unwind_stack); }
bool is_started() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_started); }
bool is_running() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_running); }
bool is_complete() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_complete); }
void unwind_stack() BOOST_NOEXCEPT
{
if ( is_started() && ! is_complete() && force_unwind() )
{
flags_ |= flag_unwind_stack;
flags_ |= flag_running;
param_type to( unwind_t::force_unwind);
caller_.jump(
callee_,
& to);
flags_ &= ~flag_running;
flags_ &= ~flag_unwind_stack;
BOOST_ASSERT( is_complete() );
}
}
void resume( R & arg) BOOST_NOEXCEPT
{
param_type to( & arg, this);
resume_( & to);
}
R * yield()
{
BOOST_ASSERT( is_running() );
BOOST_ASSERT( ! is_complete() );
flags_ &= ~flag_running;
param_type to;
param_type * from(
static_cast< param_type * >(
callee_.jump(
caller_,
& to) ) );
flags_ |= flag_running;
if ( from->do_unwind) throw forced_unwind();
BOOST_ASSERT( from->data);
return from->data;
}
template< typename X >
R * yield_to( symmetric_coroutine_impl< X > * other, X x)
{
typename symmetric_coroutine_impl< X >::param_type to( & x, other);
return yield_to_( other, & to);
}
template< typename X >
R * yield_to( symmetric_coroutine_impl< X & > * other, X & x)
{
typename symmetric_coroutine_impl< X & >::param_type to( & x, other);
return yield_to_( other, & to);
}
template< typename X >
R * yield_to( symmetric_coroutine_impl< X > * other)
{
typename symmetric_coroutine_impl< X >::param_type to( other);
return yield_to_( other, & to);
}
virtual void run( R *) BOOST_NOEXCEPT = 0;
virtual void destroy() = 0;
protected:
template< typename X >
friend class symmetric_coroutine_impl;
int flags_;
coroutine_context caller_;
coroutine_context callee_;
void resume_( param_type * to) BOOST_NOEXCEPT
{
BOOST_ASSERT( ! is_running() );
BOOST_ASSERT( ! is_complete() );
flags_ |= flag_running;
caller_.jump(
callee_,
to);
flags_ &= ~flag_running;
}
template< typename Other >
R * yield_to_( Other * other, typename Other::param_type * to)
{
BOOST_ASSERT( is_running() );
BOOST_ASSERT( ! is_complete() );
BOOST_ASSERT( ! other->is_running() );
BOOST_ASSERT( ! other->is_complete() );
other->caller_ = caller_;
flags_ &= ~flag_running;
param_type * from(
static_cast< param_type * >(
callee_.jump(
other->callee_,
to) ) );
flags_ |= flag_running;
if ( from->do_unwind) throw forced_unwind();
BOOST_ASSERT( from->data);
return from->data;
}
};
template<>
class symmetric_coroutine_impl< void > : private noncopyable
{
public:
typedef parameters< void > param_type;
symmetric_coroutine_impl( preallocated const& palloc,
bool unwind) BOOST_NOEXCEPT :
flags_( 0),
caller_(),
callee_( trampoline_void< symmetric_coroutine_impl< void > >, palloc)
{
if ( unwind) flags_ |= flag_force_unwind;
}
virtual ~symmetric_coroutine_impl() {}
inline bool force_unwind() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_force_unwind); }
inline bool unwind_requested() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_unwind_stack); }
inline bool is_started() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_started); }
inline bool is_running() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_running); }
inline bool is_complete() const BOOST_NOEXCEPT
{ return 0 != ( flags_ & flag_complete); }
inline void unwind_stack() BOOST_NOEXCEPT
{
if ( is_started() && ! is_complete() && force_unwind() )
{
flags_ |= flag_unwind_stack;
flags_ |= flag_running;
param_type to( unwind_t::force_unwind);
caller_.jump(
callee_,
& to);
flags_ &= ~flag_running;
flags_ &= ~flag_unwind_stack;
BOOST_ASSERT( is_complete() );
}
}
inline void resume() BOOST_NOEXCEPT
{
BOOST_ASSERT( ! is_running() );
BOOST_ASSERT( ! is_complete() );
param_type to( this);
flags_ |= flag_running;
caller_.jump(
callee_,
& to);
flags_ &= ~flag_running;
}
inline void yield()
{
BOOST_ASSERT( is_running() );
BOOST_ASSERT( ! is_complete() );
flags_ &= ~flag_running;
param_type to;
param_type * from(
static_cast< param_type * >(
callee_.jump(
caller_,
& to) ) );
flags_ |= flag_running;
if ( from->do_unwind) throw forced_unwind();
}
template< typename X >
void yield_to( symmetric_coroutine_impl< X > * other, X x)
{
typename symmetric_coroutine_impl< X >::param_type to( & x, other);
yield_to_( other, & to);
}
template< typename X >
void yield_to( symmetric_coroutine_impl< X & > * other, X & x)
{
typename symmetric_coroutine_impl< X & >::param_type to( & x, other);
yield_to_( other, & to);
}
template< typename X >
void yield_to( symmetric_coroutine_impl< X > * other)
{
typename symmetric_coroutine_impl< X >::param_type to( other);
yield_to_( other, & to);
}
virtual void run() BOOST_NOEXCEPT = 0;
virtual void destroy() = 0;
protected:
template< typename X >
friend class symmetric_coroutine_impl;
int flags_;
coroutine_context caller_;
coroutine_context callee_;
template< typename Other >
void yield_to_( Other * other, typename Other::param_type * to)
{
BOOST_ASSERT( is_running() );
BOOST_ASSERT( ! is_complete() );
BOOST_ASSERT( ! other->is_running() );
BOOST_ASSERT( ! other->is_complete() );
other->caller_ = caller_;
flags_ &= ~flag_running;
param_type * from(
static_cast< param_type * >(
callee_.jump(
other->callee_,
to) ) );
flags_ |= flag_running;
if ( from->do_unwind) throw forced_unwind();
}
};
}}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_DETAIL_SYMMETRIC_COROUTINE_IMPL_H

View File

@@ -0,0 +1,267 @@
// 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_SYMMETRIC_COROUTINE_OBJECT_H
#define BOOST_COROUTINES_DETAIL_SYMMETRIC_COROUTINE_OBJECT_H
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/move/move.hpp>
#include <boost/coroutine/detail/config.hpp>
#include <boost/coroutine/detail/flags.hpp>
#include <boost/coroutine/detail/preallocated.hpp>
#include <boost/coroutine/detail/symmetric_coroutine_impl.hpp>
#include <boost/coroutine/detail/symmetric_coroutine_yield.hpp>
#include <boost/coroutine/exceptions.hpp>
#include <boost/coroutine/stack_context.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
struct stack_context;
namespace detail {
template< typename R, typename Fn, typename StackAllocator >
class symmetric_coroutine_object : public symmetric_coroutine_impl< R >
{
private:
typedef symmetric_coroutine_impl< R > impl_t;
typedef symmetric_coroutine_object< R, Fn, StackAllocator > obj_t;
Fn fn_;
stack_context stack_ctx_;
StackAllocator stack_alloc_;
static void deallocate_( obj_t * obj)
{
stack_context stack_ctx( obj->stack_ctx_);
StackAllocator stack_alloc( obj->stack_alloc_);
obj->unwind_stack();
obj->~obj_t();
stack_alloc.deallocate( stack_ctx);
}
public:
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
symmetric_coroutine_object( Fn fn, attributes const& attrs,
preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
impl_t( palloc,
stack_unwind == attrs.do_unwind),
fn_( fn),
stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
#endif
symmetric_coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attrs,
preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
impl_t( palloc,
stack_unwind == attrs.do_unwind),
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
fn_( fn),
#else
fn_( boost::forward< Fn >( fn) ),
#endif
stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
void run( R * r) BOOST_NOEXCEPT
{
BOOST_ASSERT( ! impl_t::unwind_requested() );
impl_t::flags_ |= flag_started;
impl_t::flags_ |= flag_running;
try
{
symmetric_coroutine_yield< R > yc( this, r);
fn_( yc);
}
catch ( forced_unwind const&)
{}
catch (...)
{ std::terminate(); }
impl_t::flags_ |= flag_complete;
impl_t::flags_ &= ~flag_running;
typename impl_t::param_type to;
impl_t::callee_.jump(
impl_t::caller_,
& to);
BOOST_ASSERT_MSG( false, "coroutine is complete");
}
void destroy()
{ deallocate_( this); }
};
template< typename R, typename Fn, typename StackAllocator >
class symmetric_coroutine_object< R &, Fn, StackAllocator > : public symmetric_coroutine_impl< R & >
{
private:
typedef symmetric_coroutine_impl< R & > impl_t;
typedef symmetric_coroutine_object< R &, Fn, StackAllocator > obj_t;
Fn fn_;
stack_context stack_ctx_;
StackAllocator stack_alloc_;
static void deallocate_( obj_t * obj)
{
stack_context stack_ctx( obj->stack_ctx_);
StackAllocator stack_alloc( obj->stack_alloc_);
obj->unwind_stack();
obj->~obj_t();
stack_alloc.deallocate( stack_ctx);
}
public:
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
symmetric_coroutine_object( Fn fn, attributes const& attrs,
preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
impl_t( palloc,
stack_unwind == attrs.do_unwind),
fn_( fn),
stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
#endif
symmetric_coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attrs,
preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
impl_t( palloc,
stack_unwind == attrs.do_unwind),
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
fn_( fn),
#else
fn_( boost::forward< Fn >( fn) ),
#endif
stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
void run( R * r) BOOST_NOEXCEPT
{
BOOST_ASSERT( ! impl_t::unwind_requested() );
impl_t::flags_ |= flag_started;
impl_t::flags_ |= flag_running;
try
{
symmetric_coroutine_yield< R & > yc( this, r);
fn_( yc);
}
catch ( forced_unwind const&)
{}
catch (...)
{ std::terminate(); }
impl_t::flags_ |= flag_complete;
impl_t::flags_ &= ~flag_running;
typename impl_t::param_type to;
impl_t::callee_.jump(
impl_t::caller_,
& to);
BOOST_ASSERT_MSG( false, "coroutine is complete");
}
void destroy()
{ deallocate_( this); }
};
template< typename Fn, typename StackAllocator >
class symmetric_coroutine_object< void, Fn, StackAllocator > : public symmetric_coroutine_impl< void >
{
private:
typedef symmetric_coroutine_impl< void > impl_t;
typedef symmetric_coroutine_object< void, Fn, StackAllocator > obj_t;
Fn fn_;
stack_context stack_ctx_;
StackAllocator stack_alloc_;
static void deallocate_( obj_t * obj)
{
stack_context stack_ctx( obj->stack_ctx_);
StackAllocator stack_alloc( obj->stack_alloc_);
obj->unwind_stack();
obj->~obj_t();
stack_alloc.deallocate( stack_ctx);
}
public:
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
symmetric_coroutine_object( Fn fn, attributes const& attrs,
preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
impl_t( palloc,
stack_unwind == attrs.do_unwind),
fn_( fn),
stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
#endif
symmetric_coroutine_object( BOOST_RV_REF( Fn) fn, attributes const& attrs,
preallocated const& palloc,
StackAllocator const& stack_alloc) BOOST_NOEXCEPT :
impl_t( palloc,
stack_unwind == attrs.do_unwind),
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
fn_( fn),
#else
fn_( boost::forward< Fn >( fn) ),
#endif
stack_ctx_( palloc.sctx),
stack_alloc_( stack_alloc)
{}
void run() BOOST_NOEXCEPT
{
BOOST_ASSERT( ! impl_t::unwind_requested() );
impl_t::flags_ |= flag_started;
impl_t::flags_ |= flag_running;
try
{
symmetric_coroutine_yield< void > yc( this);
fn_( yc);
}
catch ( forced_unwind const&)
{}
catch (...)
{ std::terminate(); }
impl_t::flags_ |= flag_complete;
impl_t::flags_ &= ~flag_running;
typename impl_t::param_type to;
impl_t::callee_.jump(
impl_t::caller_,
& to);
BOOST_ASSERT_MSG( false, "coroutine is complete");
}
void destroy()
{ deallocate_( this); }
};
}}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_DETAIL_SYMMETRIC_COROUTINE_OBJECT_H

View File

@@ -0,0 +1,307 @@
// 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_SYMMETRIC_COROUTINE_YIELD_H
#define BOOST_COROUTINES_DETAIL_SYMMETRIC_COROUTINE_YIELD_H
#include <algorithm>
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/move/move.hpp>
#include <boost/throw_exception.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/utility/explicit_operator_bool.hpp>
#include <boost/coroutine/detail/config.hpp>
#include <boost/coroutine/exceptions.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
namespace detail {
template< typename R >
class symmetric_coroutine_yield
{
private:
template< typename X, typename Y, typename Z >
friend class symmetric_coroutine_object;
typedef symmetric_coroutine_impl< R > impl_type;
struct dummy {};
BOOST_MOVABLE_BUT_NOT_COPYABLE( symmetric_coroutine_yield)
impl_type * impl_;
R * result_;
symmetric_coroutine_yield( impl_type * impl, R * result) BOOST_NOEXCEPT :
impl_( impl),
result_( result)
{
BOOST_ASSERT( 0 != impl_);
BOOST_ASSERT( 0 != result_);
}
public:
symmetric_coroutine_yield() BOOST_NOEXCEPT :
impl_( 0),
result_( 0)
{}
symmetric_coroutine_yield( BOOST_RV_REF( symmetric_coroutine_yield) other) BOOST_NOEXCEPT :
impl_( 0),
result_( 0)
{ swap( other); }
symmetric_coroutine_yield & operator=( BOOST_RV_REF( symmetric_coroutine_yield) other) BOOST_NOEXCEPT
{
symmetric_coroutine_yield tmp( boost::move( other) );
swap( tmp);
return * this;
}
BOOST_EXPLICIT_OPERATOR_BOOL();
bool operator!() const BOOST_NOEXCEPT
{ return 0 == impl_; }
void swap( symmetric_coroutine_yield & other) BOOST_NOEXCEPT
{
std::swap( impl_, other.impl_);
std::swap( result_, other.result_);
}
symmetric_coroutine_yield & operator()()
{
result_ = impl_->yield();
return * this;
}
template< typename Coro >
symmetric_coroutine_yield & operator()( Coro & other, typename Coro::value_type x,
typename disable_if<
is_same< typename Coro::value_type, void >,
dummy*
>::type = 0)
{
BOOST_ASSERT( other);
result_ = impl_->yield_to( other.impl_, x);
return * this;
}
template< typename Coro >
symmetric_coroutine_yield & operator()( Coro & other,
typename enable_if<
is_same< typename Coro::value_type, void >,
dummy*
>::type = 0)
{
BOOST_ASSERT( other);
result_ = impl_->yield_to( other.impl_);
return * this;
}
R get() const
{
if ( 0 == result_)
boost::throw_exception(
invalid_result() );
return * result_;
}
};
template< typename R >
class symmetric_coroutine_yield< R & >
{
private:
template< typename X, typename Y, typename Z >
friend class symmetric_coroutine_object;
typedef symmetric_coroutine_impl< R & > impl_type;
struct dummy {};
BOOST_MOVABLE_BUT_NOT_COPYABLE( symmetric_coroutine_yield)
impl_type * impl_;
R * result_;
symmetric_coroutine_yield( impl_type * impl, R * result) BOOST_NOEXCEPT :
impl_( impl),
result_( result)
{
BOOST_ASSERT( 0 != impl_);
BOOST_ASSERT( 0 != result_);
}
public:
symmetric_coroutine_yield() BOOST_NOEXCEPT :
impl_( 0),
result_( 0)
{}
symmetric_coroutine_yield( BOOST_RV_REF( symmetric_coroutine_yield) other) BOOST_NOEXCEPT :
impl_( 0),
result_( 0)
{ swap( other); }
symmetric_coroutine_yield & operator=( BOOST_RV_REF( symmetric_coroutine_yield) other) BOOST_NOEXCEPT
{
symmetric_coroutine_yield tmp( boost::move( other) );
swap( tmp);
return * this;
}
BOOST_EXPLICIT_OPERATOR_BOOL();
bool operator!() const BOOST_NOEXCEPT
{ return 0 == impl_; }
void swap( symmetric_coroutine_yield & other) BOOST_NOEXCEPT
{
std::swap( impl_, other.impl_);
std::swap( result_, other.result_);
}
symmetric_coroutine_yield & operator()()
{
result_ = impl_->yield();
return * this;
}
template< typename Coro >
symmetric_coroutine_yield & operator()( Coro & other, typename Coro::value_type & x,
typename disable_if<
is_same< typename Coro::value_type, void >,
dummy*
>::type = 0)
{
BOOST_ASSERT( other);
result_ = impl_->yield_to( other.impl_, x);
return * this;
}
template< typename Coro >
symmetric_coroutine_yield & operator()( Coro & other,
typename enable_if<
is_same< typename Coro::value_type, void >,
dummy*
>::type = 0)
{
BOOST_ASSERT( other);
result_ = impl_->yield_to( other.impl_);
return * this;
}
R & get() const
{
if ( 0 == result_)
boost::throw_exception(
invalid_result() );
return * result_;
}
};
template<>
class symmetric_coroutine_yield< void >
{
private:
template< typename X, typename Y, typename Z >
friend class symmetric_coroutine_object;
typedef symmetric_coroutine_impl< void > impl_type;
struct dummy {};
BOOST_MOVABLE_BUT_NOT_COPYABLE( symmetric_coroutine_yield)
impl_type * impl_;
symmetric_coroutine_yield( impl_type * impl) BOOST_NOEXCEPT :
impl_( impl)
{ BOOST_ASSERT( 0 != impl_); }
public:
symmetric_coroutine_yield() BOOST_NOEXCEPT :
impl_( 0)
{}
symmetric_coroutine_yield( BOOST_RV_REF( symmetric_coroutine_yield) other) BOOST_NOEXCEPT :
impl_( 0)
{ swap( other); }
symmetric_coroutine_yield & operator=( BOOST_RV_REF( symmetric_coroutine_yield) other) BOOST_NOEXCEPT
{
symmetric_coroutine_yield tmp( boost::move( other) );
swap( tmp);
return * this;
}
BOOST_EXPLICIT_OPERATOR_BOOL();
inline bool operator!() const BOOST_NOEXCEPT
{ return 0 == impl_; }
inline void swap( symmetric_coroutine_yield & other) BOOST_NOEXCEPT
{ std::swap( impl_, other.impl_); }
inline symmetric_coroutine_yield & operator()()
{
impl_->yield();
return * this;
}
template< typename Coro >
symmetric_coroutine_yield & operator()( Coro & other, typename Coro::value_type & x,
typename disable_if<
is_same< typename Coro::value_type, void >,
dummy*
>::type = 0)
{
BOOST_ASSERT( other);
impl_->yield_to( other.impl_, x);
return * this;
}
template< typename Coro >
symmetric_coroutine_yield & operator()( Coro & other,
typename enable_if<
is_same< typename Coro::value_type, void >,
dummy*
>::type = 0)
{
BOOST_ASSERT( other);
impl_->yield_to( other.impl_);
return * this;
}
};
template< typename R >
void swap( symmetric_coroutine_yield< R > & l, symmetric_coroutine_yield< R > & r)
{ l.swap( r); }
}}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_DETAIL_SYMMETRIC_COROUTINE_YIELD_H

View File

@@ -0,0 +1,69 @@
// 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_H
#define BOOST_COROUTINES_DETAIL_TRAMPOLINE_H
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/context/detail/fcontext.hpp>
#include <boost/cstdint.hpp>
#include <boost/coroutine/detail/config.hpp>
#include <boost/coroutine/detail/data.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
namespace detail {
template< typename Coro >
void trampoline( context::detail::transfer_t t)
{
typedef typename Coro::param_type param_type;
data_t * data = static_cast< data_t * >( t.data);
data->from->ctx_ = t.fctx;
param_type * param(
static_cast< param_type * >( data->data) );
BOOST_ASSERT( 0 != param);
BOOST_ASSERT( 0 != param->data);
Coro * coro(
static_cast< Coro * >( param->coro) );
BOOST_ASSERT( 0 != coro);
coro->run( param->data);
}
template< typename Coro >
void trampoline_void( context::detail::transfer_t t)
{
typedef typename Coro::param_type param_type;
data_t * data = static_cast< data_t * >( t.data);
data->from->ctx_ = t.fctx;
param_type * param(
static_cast< param_type * >( data->data) );
BOOST_ASSERT( 0 != param);
Coro * coro(
static_cast< Coro * >( param->coro) );
BOOST_ASSERT( 0 != coro);
coro->run();
}
}}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_DETAIL_TRAMPOLINE_H

View File

@@ -0,0 +1,50 @@
// 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_PULL_H
#define BOOST_COROUTINES_DETAIL_TRAMPOLINE_PULL_H
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/context/detail/fcontext.hpp>
#include <boost/cstdint.hpp>
#include <boost/coroutine/detail/config.hpp>
#include <boost/coroutine/detail/data.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
namespace detail {
template< typename Coro >
void trampoline_pull( context::detail::transfer_t t)
{
typedef typename Coro::param_type param_type;
data_t * data = static_cast< data_t * >( t.data);
data->from->ctx_ = t.fctx;
param_type * param(
static_cast< param_type * >( data->data) );
BOOST_ASSERT( 0 != param);
Coro * coro(
static_cast< Coro * >( param->coro) );
BOOST_ASSERT( 0 != coro);
coro->run();
}
}}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_DETAIL_TRAMPOLINE_PULL_H

View File

@@ -0,0 +1,79 @@
// 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/context/detail/fcontext.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/data.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 Coro >
void trampoline_push( context::detail::transfer_t t)
{
typedef typename Coro::param_type param_type;
data_t * data = static_cast< data_t * >( t.data);
data->from->ctx_ = t.fctx;
param_type * param(
static_cast< param_type * >( data->data) );
BOOST_ASSERT( 0 != param);
BOOST_ASSERT( 0 != param->data);
Coro * coro(
static_cast< Coro * >( param->coro) );
BOOST_ASSERT( 0 != coro);
coro->run( param->data);
}
template< typename Coro >
void trampoline_push_void( context::detail::transfer_t t)
{
typedef typename Coro::param_type param_type;
data_t * data = static_cast< data_t * >( t.data);
data->from->ctx_ = t.fctx;
param_type * param(
static_cast< param_type * >( data->data) );
BOOST_ASSERT( 0 != param);
Coro * coro(
static_cast< Coro * >( param->coro) );
BOOST_ASSERT( 0 != coro);
coro->run();
}
}}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_DETAIL_TRAMPOLINE_PUSH_H

View File

@@ -0,0 +1,103 @@
// 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_EXCEPTIONS_H
#define BOOST_COROUTINES_EXCEPTIONS_H
#include <stdexcept>
#include <string>
#include <boost/config.hpp>
#include <boost/core/scoped_enum.hpp>
#include <boost/system/error_code.hpp>
#include <boost/system/system_error.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <boost/coroutine/detail/config.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
namespace detail {
struct forced_unwind {};
}
BOOST_SCOPED_ENUM_DECLARE_BEGIN(coroutine_errc)
{
no_data = 1
}
BOOST_SCOPED_ENUM_DECLARE_END(coroutine_errc)
BOOST_COROUTINES_DECL
system::error_category const& coroutine_category() BOOST_NOEXCEPT;
}
namespace system {
template<>
struct is_error_code_enum< coroutines::coroutine_errc > : public true_type
{};
#ifdef BOOST_NO_CXX11_SCOPED_ENUMS
template<>
struct is_error_code_enum< coroutines::coroutine_errc::enum_type > : public true_type
{};
#endif
inline
error_code make_error_code( coroutines::coroutine_errc e) //BOOST_NOEXCEPT
{
return error_code( underlying_cast< int >( e), coroutines::coroutine_category() );
}
inline
error_condition make_error_condition( coroutines::coroutine_errc e) //BOOST_NOEXCEPT
{
return error_condition( underlying_cast< int >( e), coroutines::coroutine_category() );
}
}
namespace coroutines {
class coroutine_error : public std::logic_error
{
private:
system::error_code ec_;
public:
coroutine_error( system::error_code ec) :
logic_error( ec.message() ),
ec_( ec)
{}
system::error_code const& code() const BOOST_NOEXCEPT
{ return ec_; }
};
class invalid_result : public coroutine_error
{
public:
invalid_result() :
coroutine_error(
system::make_error_code(
coroutine_errc::no_data) )
{}
};
}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_EXCEPTIONS_H

View File

@@ -0,0 +1,21 @@
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_COROUTINES_FLAGS_H
#define BOOST_COROUTINES_FLAGS_H
namespace boost {
namespace coroutines {
enum flag_unwind_t
{
stack_unwind = 0,
no_stack_unwind
};
}}
#endif // BOOST_COROUTINES_FLAGS_H

View File

@@ -0,0 +1,105 @@
// 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_PROTECTED_STACK_ALLOCATOR_H
#define BOOST_COROUTINES_PROTECTED_STACK_ALLOCATOR_H
extern "C" {
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
}
#if defined(BOOST_USE_VALGRIND)
#include <valgrind/valgrind.h>
#endif
#include <cmath>
#include <cstddef>
#include <new>
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/coroutine/detail/config.hpp>
#include <boost/coroutine/stack_context.hpp>
#include <boost/coroutine/stack_traits.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
template< typename traitsT >
struct basic_protected_stack_allocator
{
typedef traitsT traits_type;
void allocate( stack_context & ctx, std::size_t size = traits_type::minimum_size() )
{
BOOST_ASSERT( traits_type::minimum_size() <= size);
BOOST_ASSERT( traits_type::is_unbounded() || ( traits_type::maximum_size() >= size) );
// page at bottom will be used as guard-page
const std::size_t pages(
static_cast< std::size_t >(
std::floor(
static_cast< float >( size) / traits_type::page_size() ) ) );
BOOST_ASSERT_MSG( 2 <= pages, "at least two pages must fit into stack (one page is guard-page)");
const std::size_t size_( pages * traits_type::page_size() );
BOOST_ASSERT( 0 != size && 0 != size_);
BOOST_ASSERT( size_ <= size);
// conform to POSIX.4 (POSIX.1b-1993, _POSIX_C_SOURCE=199309L)
#if defined(MAP_ANON)
void * limit = ::mmap( 0, size_, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
#else
void * limit = ::mmap( 0, size_, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
#endif
if ( MAP_FAILED == limit) throw std::bad_alloc();
// conforming to POSIX.1-2001
#if defined(BOOST_DISABLE_ASSERTS)
::mprotect( limit, traits_type::page_size(), PROT_NONE);
#else
const int result( ::mprotect( limit, traits_type::page_size(), PROT_NONE) );
BOOST_ASSERT( 0 == result);
#endif
ctx.size = size_;
ctx.sp = static_cast< char * >( limit) + ctx.size;
#if defined(BOOST_USE_VALGRIND)
ctx.valgrind_stack_id = VALGRIND_STACK_REGISTER( ctx.sp, limit);
#endif
}
void deallocate( stack_context & ctx)
{
BOOST_ASSERT( ctx.sp);
BOOST_ASSERT( traits_type::minimum_size() <= ctx.size);
BOOST_ASSERT( traits_type::is_unbounded() || ( traits_type::maximum_size() >= ctx.size) );
#if defined(BOOST_USE_VALGRIND)
VALGRIND_STACK_DEREGISTER( ctx.valgrind_stack_id);
#endif
void * limit = static_cast< char * >( ctx.sp) - ctx.size;
// conform to POSIX.4 (POSIX.1b-1993, _POSIX_C_SOURCE=199309L)
::munmap( limit, ctx.size);
}
};
typedef basic_protected_stack_allocator< stack_traits > protected_stack_allocator;
}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_PROTECTED_STACK_ALLOCATOR_H

View File

@@ -0,0 +1,69 @@
// 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_SEGMENTED_STACK_ALLOCATOR_H
#define BOOST_COROUTINES_SEGMENTED_STACK_ALLOCATOR_H
#include <cstddef>
#include <new>
#include <boost/config.hpp>
#include <boost/coroutine/detail/config.hpp>
#include <boost/coroutine/stack_context.hpp>
#include <boost/coroutine/stack_traits.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
// forward declaration for splitstack-functions defined in libgcc
extern "C" {
void *__splitstack_makecontext( std::size_t,
void * [BOOST_CONTEXT_SEGMENTS],
std::size_t *);
void __splitstack_releasecontext( void * [BOOST_CONTEXT_SEGMENTS]);
void __splitstack_resetcontext( void * [BOOST_CONTEXT_SEGMENTS]);
void __splitstack_block_signals_context( void * [BOOST_CONTEXT_SEGMENTS],
int * new_value, int * old_value);
}
namespace boost {
namespace coroutines {
template< typename traitsT >
struct basic_segmented_stack_allocator
{
typedef traitsT traits_type;
void allocate( stack_context & ctx, std::size_t size = traits_type::minimum_size() )
{
void * limit = __splitstack_makecontext( size, ctx.segments_ctx, & ctx.size);
if ( ! limit) throw std::bad_alloc();
// ctx.size is already filled by __splitstack_makecontext
ctx.sp = static_cast< char * >( limit) + ctx.size;
int off = 0;
__splitstack_block_signals_context( ctx.segments_ctx, & off, 0);
}
void deallocate( stack_context & ctx)
{ __splitstack_releasecontext( ctx.segments_ctx); }
};
typedef basic_segmented_stack_allocator< stack_traits > segmented_stack_allocator;
}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_SEGMENTED_STACK_ALLOCATOR_H

View File

@@ -0,0 +1,13 @@
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/config.hpp>
#if defined(BOOST_WINDOWS)
# include <boost/coroutine/windows/protected_stack_allocator.hpp>
#else
# include <boost/coroutine/posix/protected_stack_allocator.hpp>
#endif

View File

@@ -0,0 +1,15 @@
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/config.hpp>
#if defined(BOOST_USE_SEGMENTED_STACKS)
# if defined(BOOST_WINDOWS)
# error "segmented stacks are not supported by Windows"
# else
# include <boost/coroutine/posix/segmented_stack_allocator.hpp>
# endif
#endif

View File

@@ -0,0 +1,37 @@
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_COROUTINES_STACK_ALLOCATOR_H
#define BOOST_COROUTINES_STACK_ALLOCATOR_H
#include <cstddef>
#include <boost/config.hpp>
#include <boost/context/detail/config.hpp>
#include <boost/coroutine/segmented_stack_allocator.hpp>
#include <boost/coroutine/standard_stack_allocator.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
#if defined(BOOST_USE_SEGMENTED_STACKS)
typedef segmented_stack_allocator stack_allocator;
#else
typedef standard_stack_allocator stack_allocator;
#endif
}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_STACK_ALLOCATOR_H

View File

@@ -0,0 +1,66 @@
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_COROUTINES_STACK_CONTEXT_H
#define BOOST_COROUTINES_STACK_CONTEXT_H
#include <cstddef>
#include <boost/config.hpp>
#include <boost/coroutine/detail/config.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
#if defined(BOOST_USE_SEGMENTED_STACKS)
struct BOOST_COROUTINES_DECL stack_context
{
typedef void * segments_context[BOOST_CONTEXT_SEGMENTS];
std::size_t size;
void * sp;
segments_context segments_ctx;
#if defined(BOOST_USE_VALGRIND)
unsigned valgrind_stack_id;
#endif
stack_context() :
size( 0), sp( 0), segments_ctx()
#if defined(BOOST_USE_VALGRIND)
, valgrind_stack_id( 0)
#endif
{}
};
#else
struct BOOST_COROUTINES_DECL stack_context
{
std::size_t size;
void * sp;
#if defined(BOOST_USE_VALGRIND)
unsigned valgrind_stack_id;
#endif
stack_context() :
size( 0), sp( 0)
#if defined(BOOST_USE_VALGRIND)
, valgrind_stack_id( 0)
#endif
{}
};
#endif
}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_STACK_CONTEXT_H

View File

@@ -0,0 +1,42 @@
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_COROUTINES_STACK_TRAITS_H
#define BOOST_COROUTINES_STACK_TRAITS_H
#include <cstddef>
#include <boost/config.hpp>
#include <boost/coroutine/detail/config.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
struct BOOST_COROUTINES_DECL stack_traits
{
static bool is_unbounded() BOOST_NOEXCEPT;
static std::size_t page_size() BOOST_NOEXCEPT;
static std::size_t default_size() BOOST_NOEXCEPT;
static std::size_t minimum_size() BOOST_NOEXCEPT;
static std::size_t maximum_size() BOOST_NOEXCEPT;
};
}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_STACK_TRAITS_H

View File

@@ -0,0 +1,90 @@
// Copyright Oliver Kowalke 2009.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_COROUTINES_STANDARD_STACK_ALLOCATOR_H
#define BOOST_COROUTINES_STANDARD_STACK_ALLOCATOR_H
#if defined(BOOST_USE_VALGRIND)
#include <valgrind/valgrind.h>
#endif
#include <cstddef>
#include <cstdlib>
#include <new>
#include <boost/assert.hpp>
#include <boost/config.hpp>
#include <boost/coroutine/detail/config.hpp>
#include <boost/coroutine/stack_context.hpp>
#include <boost/coroutine/stack_traits.hpp>
#if defined(BOOST_COROUTINES_USE_MAP_STACK)
extern "C" {
#include <sys/mman.h>
}
#endif
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
template< typename traitsT >
struct basic_standard_stack_allocator
{
typedef traitsT traits_type;
void allocate( stack_context & ctx, std::size_t size = traits_type::minimum_size() )
{
BOOST_ASSERT( traits_type::minimum_size() <= size);
BOOST_ASSERT( traits_type::is_unbounded() || ( traits_type::maximum_size() >= size) );
#if defined(BOOST_COROUTINES_USE_MAP_STACK)
void * limit = ::mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_STACK, -1, 0);
if ( limit == MAP_FAILED ) throw std::bad_alloc();
#else
void * limit = std::malloc( size);
if ( ! limit) throw std::bad_alloc();
#endif
ctx.size = size;
ctx.sp = static_cast< char * >( limit) + ctx.size;
#if defined(BOOST_USE_VALGRIND)
ctx.valgrind_stack_id = VALGRIND_STACK_REGISTER( ctx.sp, limit);
#endif
}
void deallocate( stack_context & ctx)
{
BOOST_ASSERT( ctx.sp);
BOOST_ASSERT( traits_type::minimum_size() <= ctx.size);
BOOST_ASSERT( traits_type::is_unbounded() || ( traits_type::maximum_size() >= ctx.size) );
#if defined(BOOST_USE_VALGRIND)
VALGRIND_STACK_DEREGISTER( ctx.valgrind_stack_id);
#endif
void * limit = static_cast< char * >( ctx.sp) - ctx.size;
#if defined(BOOST_COROUTINES_USE_MAP_STACK)
munmap(limit, ctx.size);
#else
std::free( limit);
#endif
}
};
typedef basic_standard_stack_allocator< stack_traits > standard_stack_allocator;
}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_STANDARD_STACK_ALLOCATOR_H

View File

@@ -0,0 +1,35 @@
// 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_SYMMETRIC_COROUTINE_H
#define BOOST_COROUTINES_SYMMETRIC_COROUTINE_H
#include <boost/config.hpp>
#include <boost/coroutine/detail/symmetric_coroutine_call.hpp>
#include <boost/coroutine/detail/symmetric_coroutine_yield.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
template< typename T >
struct symmetric_coroutine
{
typedef detail::symmetric_coroutine_call< T > call_type;
typedef detail::symmetric_coroutine_yield< T > yield_type;
};
}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_SYMMETRIC_COROUTINE_H

View File

@@ -0,0 +1,87 @@
// 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_PROTECTED_STACK_ALLOCATOR_H
#define BOOST_COROUTINES_PROTECTED_STACK_ALLOCATOR_H
extern "C" {
#include <windows.h>
}
#include <cmath>
#include <cstddef>
#include <new>
#include <boost/config.hpp>
#include <boost/coroutine/detail/config.hpp>
#include <boost/coroutine/stack_traits.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost {
namespace coroutines {
struct stack_context;
template< typename traitsT >
struct basic_protected_stack_allocator
{
typedef traitsT traits_type;
void allocate( stack_context & ctx, std::size_t size)
{
BOOST_ASSERT( traits_type::minimum_size() <= size);
BOOST_ASSERT( traits_type::is_unbounded() || ( traits_type::maximum_size() >= size) );
// page at bottom will be used as guard-page
const std::size_t pages(
static_cast< std::size_t >(
std::floor(
static_cast< float >( size) / traits_type::page_size() ) ) );
BOOST_ASSERT_MSG( 2 <= pages, "at least two pages must fit into stack (one page is guard-page)");
const std::size_t size_ = pages * traits_type::page_size();
BOOST_ASSERT( 0 != size && 0 != size_);
void * limit = ::VirtualAlloc( 0, size_, MEM_COMMIT, PAGE_READWRITE);
if ( ! limit) throw std::bad_alloc();
DWORD old_options;
#if defined(BOOST_DISABLE_ASSERTS)
::VirtualProtect(
limit, traits_type::page_size(), PAGE_READWRITE | PAGE_GUARD /*PAGE_NOACCESS*/, & old_options);
#else
const BOOL result = ::VirtualProtect(
limit, traits_type::page_size(), PAGE_READWRITE | PAGE_GUARD /*PAGE_NOACCESS*/, & old_options);
BOOST_ASSERT( FALSE != result);
#endif
ctx.size = size_;
ctx.sp = static_cast< char * >( limit) + ctx.size;
}
void deallocate( stack_context & ctx)
{
BOOST_ASSERT( ctx.sp);
BOOST_ASSERT( traits_type::minimum_size() <= ctx.size);
BOOST_ASSERT( traits_type::is_unbounded() || ( traits_type::maximum_size() >= ctx.size) );
void * limit = static_cast< char * >( ctx.sp) - ctx.size;
::VirtualFree( limit, 0, MEM_RELEASE);
}
};
typedef basic_protected_stack_allocator< stack_traits > protected_stack_allocator;
}}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif // BOOST_COROUTINES_PROTECTED_STACK_ALLOCATOR_H

View File

@@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,4 @@
The package boost is compatible with built-in CMake targets:
find_package(Boost REQUIRED [COMPONENTS <libs>...])
target_link_libraries(main PRIVATE Boost::boost Boost::<lib1> Boost::<lib2> ...)

View File

@@ -0,0 +1,115 @@
{
"$schema": "https://raw.githubusercontent.com/spdx/spdx-spec/v2.2.1/schemas/spdx-schema.json",
"spdxVersion": "SPDX-2.2",
"dataLicense": "CC0-1.0",
"SPDXID": "SPDXRef-DOCUMENT",
"documentNamespace": "https://spdx.org/spdxdocs/boost-coroutine-x64-windows-1.79.0-6ef72e64-afba-414a-90f0-72ab2b7260dc",
"name": "boost-coroutine:x64-windows@1.79.0 fe2632001158acdfa35da6165acaae23e81787a8d2ddb5d1719eb7ab84d4f2a7",
"creationInfo": {
"creators": [
"Tool: vcpkg-9268e366206712e38102b28dbd1617697a99ff2e"
],
"created": "2022-07-23T08:23:44Z"
},
"relationships": [
{
"spdxElementId": "SPDXRef-port",
"relationshipType": "GENERATES",
"relatedSpdxElement": "SPDXRef-binary"
},
{
"spdxElementId": "SPDXRef-port",
"relationshipType": "CONTAINS",
"relatedSpdxElement": "SPDXRef-file-0"
},
{
"spdxElementId": "SPDXRef-port",
"relationshipType": "CONTAINS",
"relatedSpdxElement": "SPDXRef-file-1"
},
{
"spdxElementId": "SPDXRef-binary",
"relationshipType": "GENERATED_FROM",
"relatedSpdxElement": "SPDXRef-port"
},
{
"spdxElementId": "SPDXRef-file-0",
"relationshipType": "CONTAINED_BY",
"relatedSpdxElement": "SPDXRef-port"
},
{
"spdxElementId": "SPDXRef-file-1",
"relationshipType": "CONTAINED_BY",
"relatedSpdxElement": "SPDXRef-port"
},
{
"spdxElementId": "SPDXRef-file-1",
"relationshipType": "DEPENDENCY_MANIFEST_OF",
"relatedSpdxElement": "SPDXRef-port"
}
],
"packages": [
{
"name": "boost-coroutine",
"SPDXID": "SPDXRef-port",
"versionInfo": "1.79.0",
"downloadLocation": "NOASSERTION",
"homepage": "https://github.com/boostorg/coroutine",
"licenseConcluded": "BSL-1.0",
"licenseDeclared": "NOASSERTION",
"copyrightText": "NOASSERTION",
"description": "Boost coroutine module",
"comment": "This is the port (recipe) consumed by vcpkg."
},
{
"name": "boost-coroutine:x64-windows",
"SPDXID": "SPDXRef-binary",
"versionInfo": "fe2632001158acdfa35da6165acaae23e81787a8d2ddb5d1719eb7ab84d4f2a7",
"downloadLocation": "NONE",
"licenseConcluded": "BSL-1.0",
"licenseDeclared": "NOASSERTION",
"copyrightText": "NOASSERTION",
"comment": "This is a binary package built by vcpkg."
},
{
"SPDXID": "SPDXRef-resource-1",
"name": "boostorg/coroutine",
"downloadLocation": "git+https://github.com/boostorg/coroutine@boost-1.79.0",
"licenseConcluded": "NOASSERTION",
"licenseDeclared": "NOASSERTION",
"copyrightText": "NOASSERTION",
"checksums": [
{
"algorithm": "SHA512",
"checksumValue": "a969a25627713fd0cf440ee1c60979c10465df95589dc829f8ee480c5a5cfd833ee3ea5f90616d175f06cf1b01750d682886e8d7e64038e159bfc15b184a5de4"
}
]
}
],
"files": [
{
"fileName": "./portfile.cmake",
"SPDXID": "SPDXRef-file-0",
"checksums": [
{
"algorithm": "SHA256",
"checksumValue": "32797e582bbec3b8ee731a154ebc0f1138d9384d88c0b0ee3e19ce652b1ad029"
}
],
"licenseConcluded": "NOASSERTION",
"copyrightText": "NOASSERTION"
},
{
"fileName": "./vcpkg.json",
"SPDXID": "SPDXRef-file-1",
"checksums": [
{
"algorithm": "SHA256",
"checksumValue": "da0d67875b6b77f0e2638c978121f6748b183f9075e9bd32e6728601b5e9d00a"
}
],
"licenseConcluded": "NOASSERTION",
"copyrightText": "NOASSERTION"
}
]
}

View File

@@ -0,0 +1,25 @@
boost-assert a50eed453b8be6c8932fb3d5f8feaf194a2ebeaed7982db4e36e3ba17f3ec107
boost-build ae2e04240d11929b681e289a0f6dd881454523061c007bfce13fdb89700330de
boost-config 797535e8975ed7cf5bbe11d9f7fe26caa5da8fe819888564758d82a21109fade
boost-context e94ca7654d66a89fc41232ed8f559b3f0da8bbdf35e7851b96a39f97664a797a
boost-core 498aea0b6b68bcfe1ec683e76c2f0d32477dfe9ba958f518980ff806b6faba90
boost-exception 85c64552480492927af1bfcf8855c2846a3911ea0a33c44aa60d53731d787b0e
boost-modular-build-helper 2a88f7e0b19495c5c387221437d68f0488f9ef0237f86b578a8560ce6e7192c2
boost-move c41e7bcb3cbb57100f8b9da78c55dca8017a976ac084f3a13c28135622927a0b
boost-system 0841ab8607e2170e8715211a791aade47fa5b0600a7d79ee77e6d079bc22e6ec
boost-throw-exception 4bb4a0182f0f071c3c1ffd9cbd82fbc3bc7db4a35346f930bbe504e7e3a94e0a
boost-type-traits 74f62124585467fbb6c4fa16015164d11e1a079d6bdb70ec1c3fe7cf65b9a594
boost-utility cbe2d95223a1f8fb253145878922052018dccca3926ffb59d0e20676d6b0d3ac
boost-vcpkg-helpers c81c7b003df356a1a120a7c0c2f5a2ac95f3c33b006a2a5b4c02dcf0c9f3deaa
cmake 3.23.2
features core
portfile.cmake 32797e582bbec3b8ee731a154ebc0f1138d9384d88c0b0ee3e19ce652b1ad029
ports.cmake 366c60b768113102408b32ac1d7c7b48ef7d30a477af2a220ecc222d9ffa3166
post_build_checks 2
powershell 7.2.5
triplet x64-windows
triplet_abi 4556164a2cd3dd6f4742101eabb46def7e71b6e5856faa88e5d005aac12a803c-c0600b35e024ce0485ed253ef5419f3686f7257cfb58cb6a24febcb600fc4b4c-27ebd443f77a6c449168adfa6ce8def60cf46e88
vcpkg-cmake 8a68341d77ea3fc25cc1a56db9e8d3a5f3cc851fed64c21e39dd6d26f8d28428
vcpkg.json da0d67875b6b77f0e2638c978121f6748b183f9075e9bd32e6728601b5e9d00a
vcpkg_from_git 0aab20e34e84d52ba4763f009e539bfa8f418c41c918c8cf700156f1a8551a10
vcpkg_from_github b743742296a114ea1b18ae99672e02f142c4eb2bef7f57d36c038bedbfb0502f