2
0
mirror of https://github.com/boostorg/fiber.git synced 2026-02-17 13:42:21 +00:00

reorganize files relaed to future

This commit is contained in:
Oliver Kowalke
2013-03-07 17:36:57 +01:00
parent 5cb733ad7d
commit f742b5f4dc
9 changed files with 639 additions and 928 deletions

View File

@@ -19,7 +19,6 @@
#include <boost/fiber/interruption.hpp>
#include <boost/fiber/mutex.hpp>
#include <boost/fiber/operations.hpp>
#include <boost/fiber/promise.hpp>
#include <boost/fiber/round_robin.hpp>
#include <boost/fiber/unbounded_channel.hpp>

View File

@@ -1,45 +0,0 @@
// Copyright (C) 2012 Vicente J. Botet Escriba
//
// 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_FIBERS_DETAIL_DELETE_HPP
#define BOOST_FIBERS_DETAIL_DELETE_HPP
#include <boost/config.hpp>
/**
* BOOST_FIBERS_DELETE_COPY_CTOR deletes the copy constructor when the compiler supports it or
* makes it private.
*
* BOOST_FIBERS_DELETE_COPY_ASSIGN deletes the copy assignment when the compiler supports it or
* makes it private.
*/
#ifndef BOOST_NO_DELETED_FUNCTIONS
#define BOOST_FIBERS_DELETE_COPY_CTOR(CLASS) \
CLASS(CLASS const&) = delete; \
#define BOOST_FIBERS_DELETE_COPY_ASSIGN(CLASS) \
CLASS& operator=(CLASS const&) = delete;
#else // BOOST_NO_DELETED_FUNCTIONS
#define BOOST_FIBERS_DELETE_COPY_CTOR(CLASS) \
private: \
CLASS(CLASS&); \
public:
#define BOOST_FIBERS_DELETE_COPY_ASSIGN(CLASS) \
private: \
CLASS& operator=(CLASS&); \
public:
#endif // BOOST_NO_DELETED_FUNCTIONS
/**
* BOOST_FIBERS_NO_COPYABLE deletes the copy constructor and assignment when the compiler supports it or
* makes them private.
*/
#define BOOST_FIBERS_NO_COPYABLE(CLASS) \
BOOST_FIBERS_DELETE_COPY_CTOR(CLASS) \
BOOST_FIBERS_DELETE_COPY_ASSIGN(CLASS)
#endif // BOOST_FIBERS_DETAIL_DELETE_HPP

View File

@@ -1,245 +0,0 @@
// 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)
// (C) Copyright 2007-8 Anthony Williams
// (C) Copyright 2011-2012 Vicente J. Botet Escriba
#ifndef BOOST_FIBERS_MOVE_HPP
#define BOOST_FIBERS_MOVE_HPP
#include <boost/fiber/detail/config.hpp>
#ifndef BOOST_NO_SFINAE
#include <boost/type_traits/decay.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/utility/enable_if.hpp>
#endif
#include <boost/config/abi_prefix.hpp>
#include <boost/move/move.hpp>
#include <boost/fiber/detail/delete.hpp>
#define BOOST_NOEXCEPT
namespace boost {
namespace detail {
template <typename T>
struct has_move_emulation_enabled_aux_dummy_specialization;
template<typename T>
struct fibers_move_t
{
T& t;
explicit fibers_move_t(T& t_):
t(t_)
{}
T& operator*() const
{
return t;
}
T* operator->() const
{
return &t;
}
private:
void operator=(fibers_move_t&);
};
}
#ifndef BOOST_NO_SFINAE
template<typename T>
typename enable_if<boost::is_convertible<T&,boost::detail::fibers_move_t<T> >, boost::detail::fibers_move_t<T> >::type move(T& t)
{
return boost::detail::fibers_move_t<T>(t);
}
#endif
template<typename T>
boost::detail::fibers_move_t<T> move(boost::detail::fibers_move_t<T> t)
{
return t;
}
}
#if ! defined BOOST_NO_RVALUE_REFERENCES
#define BOOST_FIBERS_RV_REF(TYPE) BOOST_RV_REF(TYPE)
#define BOOST_FIBERS_RV_REF_BEG BOOST_RV_REF_BEG
#define BOOST_FIBERS_RV_REF_END BOOST_RV_REF_END
#define BOOST_FIBERS_RV(V) V
#define BOOST_FIBERS_MAKE_RV_REF(RVALUE) RVALUE
#define BOOST_FIBERS_FWD_REF(TYPE) BOOST_FWD_REF(TYPE)
#define BOOST_FIBERS_DCL_MOVABLE(TYPE)
#define BOOST_FIBERS_DCL_MOVABLE_BEG(T) \
namespace detail { \
template <typename T> \
struct has_move_emulation_enabled_aux_dummy_specialization<
#define BOOST_FIBERS_DCL_MOVABLE_END > \
: integral_constant<bool, true> \
{}; \
}
#elif ! defined BOOST_NO_RVALUE_REFERENCES && defined BOOST_MSVC
#define BOOST_FIBERS_RV_REF(TYPE) BOOST_RV_REF(TYPE)
#define BOOST_FIBERS_RV_REF_BEG BOOST_RV_REF_BEG
#define BOOST_FIBERS_RV_REF_END BOOST_RV_REF_END
#define BOOST_FIBERS_RV(V) V
#define BOOST_FIBERS_MAKE_RV_REF(RVALUE) RVALUE
#define BOOST_FIBERS_FWD_REF(TYPE) BOOST_FWD_REF(TYPE)
#define BOOST_FIBERS_DCL_MOVABLE(TYPE)
#define BOOST_FIBERS_DCL_MOVABLE_BEG(T) \
namespace detail { \
template <typename T> \
struct has_move_emulation_enabled_aux_dummy_specialization<
#define BOOST_FIBERS_DCL_MOVABLE_END > \
: integral_constant<bool, true> \
{}; \
}
#else
#if defined BOOST_FIBERS_USES_MOVE
#define BOOST_FIBERS_RV_REF(TYPE) BOOST_RV_REF(TYPE)
#define BOOST_FIBERS_RV_REF_BEG BOOST_RV_REF_BEG
#define BOOST_FIBERS_RV_REF_END BOOST_RV_REF_END
#define BOOST_FIBERS_RV(V) V
#define BOOST_FIBERS_FWD_REF(TYPE) BOOST_FWD_REF(TYPE)
#define BOOST_FIBERS_DCL_MOVABLE(TYPE)
#define BOOST_FIBERS_DCL_MOVABLE_BEG(T) \
namespace detail { \
template <typename T> \
struct has_move_emulation_enabled_aux_dummy_specialization<
#define BOOST_FIBERS_DCL_MOVABLE_END > \
: integral_constant<bool, true> \
{}; \
}
#else
#define BOOST_FIBERS_RV_REF(TYPE) boost::detail::fibers_move_t< TYPE >
#define BOOST_FIBERS_RV_REF_BEG boost::detail::fibers_move_t<
#define BOOST_FIBERS_RV_REF_END >
#define BOOST_FIBERS_RV(V) (*V)
#define BOOST_FIBERS_FWD_REF(TYPE) BOOST_FWD_REF(TYPE)
#define BOOST_FIBERS_DCL_MOVABLE(TYPE) \
template <> \
struct has_move_emulation_enabled_aux< TYPE > \
: BOOST_MOVE_BOOST_NS::integral_constant<bool, true> \
{};
#define BOOST_FIBERS_DCL_MOVABLE_BEG(T) \
template <typename T> \
struct has_move_emulation_enabled_aux<
#define BOOST_FIBERS_DCL_MOVABLE_END > \
: BOOST_MOVE_BOOST_NS::integral_constant<bool, true> \
{};
#endif
namespace boost {
namespace detail {
template <typename T>
BOOST_FIBERS_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type)
make_rv_ref(T v) BOOST_NOEXCEPT
{
return (BOOST_FIBERS_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type))(v);
}
// template <typename T>
// BOOST_FIBERS_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type)
// make_rv_ref(T &v) BOOST_NOEXCEPT
// {
// return (BOOST_FIBERS_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type))(v);
// }
// template <typename T>
// const BOOST_FIBERS_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type)
// make_rv_ref(T const&v) BOOST_NOEXCEPT
// {
// return (const BOOST_FIBERS_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type))(v);
// }
}}
#define BOOST_FIBERS_MAKE_RV_REF(RVALUE) RVALUE.move()
//#define BOOST_FIBERS_MAKE_RV_REF(RVALUE) boost::detail::make_rv_ref(RVALUE)
#endif
#if ! defined BOOST_NO_RVALUE_REFERENCES
#define BOOST_FIBERS_MOVABLE(TYPE)
#else
#if defined BOOST_FIBERS_USES_MOVE
#define BOOST_FIBERS_MOVABLE(TYPE) \
::boost::rv<TYPE>& move() BOOST_NOEXCEPT \
{ \
return *static_cast< ::boost::rv<TYPE>* >(this); \
} \
const ::boost::rv<TYPE>& move() const BOOST_NOEXCEPT \
{ \
return *static_cast<const ::boost::rv<TYPE>* >(this); \
} \
operator ::boost::rv<TYPE>&() \
{ \
return *static_cast< ::boost::rv<TYPE>* >(this); \
} \
operator const ::boost::rv<TYPE>&() const \
{ \
return *static_cast<const ::boost::rv<TYPE>* >(this); \
}\
#else
#define BOOST_FIBERS_MOVABLE(TYPE) \
operator ::boost::detail::fibers_move_t<TYPE>() BOOST_NOEXCEPT \
{ \
return move(); \
} \
::boost::detail::fibers_move_t<TYPE> move() BOOST_NOEXCEPT \
{ \
::boost::detail::fibers_move_t<TYPE> x(*this); \
return x; \
} \
#endif
#endif
#define BOOST_FIBERS_MOVABLE_ONLY(TYPE) \
BOOST_FIBERS_NO_COPYABLE(TYPE) \
BOOST_FIBERS_MOVABLE(TYPE) \
#define BOOST_FIBERS_COPYABLE_AND_MOVABLE(TYPE) \
BOOST_FIBERS_MOVABLE(TYPE) \
#ifndef BOOST_NO_RVALUE_REFERENCES
namespace boost {
namespace fibers_detail {
template <class T>
typename decay<T>::type
decay_copy(T&& t)
{
return boost::forward<T>(t);
}
}}
#endif
#include <boost/config/abi_suffix.hpp>
#endif

View File

@@ -1,633 +1,2 @@
// 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_FIBERS_FUTURE_HPP
#define BOOST_FIBERS_FUTURE_HPP
#include <boost/config.hpp>
#include <boost/move/move.hpp>
#include <boost/system/system_error.hpp>
#include <boost/throw_exception.hpp>
#include <boost/utility.hpp>
#include <boost/fiber/detail/future_base.hpp>
#include <boost/fiber/exceptions.hpp>
namespace boost {
namespace fibers {
template< typename R >
class promise;
template< typename R >
class shared_future;
template< typename R >
class future : private noncopyable
{
private:
typedef typename detail::future_base< R >::ptr_t ptr_t;
friend class promise< R >;
friend class shared_future< R >;
struct dummy
{ void nonnull() {} };
typedef void ( dummy::*safe_bool)();
ptr_t future_;
BOOST_MOVABLE_BUT_NOT_COPYABLE( future);
future( ptr_t const& p) :
future_( p)
{}
public:
future() BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a future with no shared state
// after construction, valid() == false
}
~future()
{
//TODO: abandon ownership if any
}
#ifndef BOOST_NO_RVALUE_REFERENCES
future( future && other) BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a future with the shared state of other using move semantics
// after construction, other.valid() == false
swap( other);
}
future & operator=( future && other) BOOST_NOEXCEPT
{
//TODO: releases any shared state and move-assigns the contents of other to *this
// after the assignment, other.valid() == false and this->valid() will yield
// the same value as other.valid() before the assignment
future tmp( boost::move( other) );
swap( tmp);
return * this;
}
#else
future( BOOST_RV_REF( future) other) BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a future with the shared state of other using move semantics
// after construction, other.valid() == false
swap( other);
}
future & operator=( BOOST_RV_REF( future) other) BOOST_NOEXCEPT
{
//TODO: releases any shared state and move-assigns the contents of other to *this
// after the assignment, other.valid() == false and this->valid() will yield
// the same value as other.valid() before the assignment
future tmp( boost::move( other) );
swap( tmp);
return * this;
}
#endif
void swap( future & other) BOOST_NOEXCEPT
{
//TODO: exchange the shared states of two futures
future_.swap( other.future_);
}
operator safe_bool() const BOOST_NOEXCEPT
{ return valid() ? & dummy::nonnull : 0; }
bool operator!() const BOOST_NOEXCEPT
{ return ! valid(); }
bool valid() const BOOST_NOEXCEPT
{
//TODO: checks if the future refers to a shared state
// this is the case only for futures returned by
// promise::get_future(), packaged_task::get_future()
// or async() until the first time get()or share() is called
return future_;
}
shared_future< R > share();
R get()
{
//TODO: the get method waits until the future has a valid result and
// (depending on which template is used) retrieves it
// it effectively calls wait() in order to wait for the result
// the value stored in the shared state
// if it satisfies the requirements of MoveAssignable, the value is moved,
// otherwise it is copied
// valid() == false after a call to this method.
// detect the case when valid == false before the call and throw a
// future_error with an error condition of future_errc::no_state
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
ptr_t tmp;
tmp.swap( future_);
return tmp->get();
}
void wait() const
{
//TODO: blocks until the result becomes available
// valid() == true after the call
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
future_->wait();
}
};
template<>
class future< void > : private noncopyable
{
private:
typedef typename detail::future_base< void >::ptr_t ptr_t;
friend class promise< void >;
friend class shared_future< void >;
struct dummy
{ void nonnull() {} };
typedef void ( dummy::*safe_bool)();
ptr_t future_;
BOOST_MOVABLE_BUT_NOT_COPYABLE( future);
future( ptr_t const& p) :
future_( p)
{}
public:
future() BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a future with no shared state
// after construction, valid() == false
}
~future()
{
//TODO: abandon ownership if any
}
#ifndef BOOST_NO_RVALUE_REFERENCES
future( future && other) BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a future with the shared state of other using move semantics
// after construction, other.valid() == false
swap( other);
}
future & operator=( future && other) BOOST_NOEXCEPT
{
//TODO: releases any shared state and move-assigns the contents of other to *this
// after the assignment, other.valid() == false and this->valid() will yield
// the same value as other.valid() before the assignment
future tmp( boost::move( other) );
swap( tmp);
return * this;
}
#else
future( BOOST_RV_REF( future) other) BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a future with the shared state of other using move semantics
// after construction, other.valid() == false
swap( other);
}
future & operator=( BOOST_RV_REF( future) other) BOOST_NOEXCEPT
{
//TODO: releases any shared state and move-assigns the contents of other to *this
// after the assignment, other.valid() == false and this->valid() will yield
// the same value as other.valid() before the assignment
future tmp( boost::move( other) );
swap( tmp);
return * this;
}
#endif
void swap( future & other) BOOST_NOEXCEPT
{
//TODO: exchange the shared states of two futures
future_.swap( other.future_);
}
operator safe_bool() const BOOST_NOEXCEPT
{ return valid() ? & dummy::nonnull : 0; }
bool operator!() const BOOST_NOEXCEPT
{ return ! valid(); }
bool valid() const BOOST_NOEXCEPT
{
//TODO: checks if the future refers to a shared state
// this is the case only for futures returned by
// promise::get_future(), packaged_task::get_future()
// or async() until the first time get()or share() is called
return future_;
}
shared_future< void > share();
void get()
{
//TODO: the get method waits until the future has a valid result and
// (depending on which template is used) retrieves it
// it effectively calls wait() in order to wait for the result
// the value stored in the shared state
// if it satisfies the requirements of MoveAssignable, the value is moved,
// otherwise it is copied
// valid() == false after a call to this method.
// detect the case when valid == false before the call and throw a
// future_error with an error condition of future_errc::no_state
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
ptr_t tmp;
tmp.swap( future_);
tmp->get();
}
void wait() const
{
//TODO: blocks until the result becomes available
// valid() == true after the call
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
future_->wait();
}
};
template< typename R >
void swap( future< R > & l, future< R > & r)
{ l.swap( r); }
template< typename R >
class shared_future
{
private:
typedef typename detail::future_base< R >::ptr_t ptr_t;
friend class future< R >;
struct dummy
{ void nonnull() {} };
typedef void ( dummy::*safe_bool)();
ptr_t future_;
explicit shared_future( ptr_t const& p) :
future_( p)
{}
public:
shared_future() BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a shared_future with no shared state
// after construction, valid() == false
}
~shared_future()
{
//TODO: if *this is the last object referring to the shared state,
// destroys the shared state otherwise does nothing
}
shared_future( shared_future const& other) :
future_( other.future_)
{
//TODO: constructs a shared future that refers to the same shared state,
// as other, if there's any
}
#ifndef BOOST_NO_RVALUE_REFERENCES
shared_future( future< R > && other) BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a shared_future with the shared state of other using move semantics
// after construction, other.valid() == false
future_.swap( other.future_);
}
shared_future( shared_future && other) BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a shared_future with the shared state of other using move semantics
// after construction, other.valid() == false
swap( other);
}
shared_future & operator=( shared_future && other) BOOST_NOEXCEPT
{
//TODO: releases any shared state and move-assigns the contents of other to *this
// after the assignment, other.valid() == false and this->valid() will yield
// the same value as other.valid() before the assignment
shared_future tmp( boost::move( other) );
swap( tmp);
return * this;
}
#else
shared_future( BOOST_RV_REF( future< R >) other) BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a shared_future with the shared state of other using move semantics
// after construction, other.valid() == false
future_.swap( other.future_);
}
shared_future( BOOST_RV_REF( shared_future) other) BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a shared_future with the shared state of other using move semantics
// after construction, other.valid() == false
swap( other);
}
shared_future & operator=( BOOST_RV_REF( shared_future) other) BOOST_NOEXCEPT
{
//TODO: releases any shared state and move-assigns the contents of other to *this
// after the assignment, other.valid() == false and this->valid() will yield
// the same value as other.valid() before the assignment
shared_future tmp( boost::move( other) );
swap( tmp);
return * this;
}
#endif
shared_future & operator=( shared_future const& other) BOOST_NOEXCEPT
{
//TODO:
shared_future tmp( other);
swap( tmp);
return * this;
}
void swap( shared_future & other) BOOST_NOEXCEPT
{
//TODO: exchange the shared states of two shared_futures
future_.swap( other.future_);
}
operator safe_bool() const BOOST_NOEXCEPT
{ return valid() ? & dummy::nonnull : 0; }
bool operator!() const BOOST_NOEXCEPT
{ return ! valid(); }
bool valid() const BOOST_NOEXCEPT
{
//TODO: checks if the shared_future refers to a shared state
// this is the case only for shared_futures returned by
// promise::get_shared_future(), packaged_task::get_shared_future()
// or async() until the first time get()or share() is called
return future_;
}
R get()
{
//TODO: the get method waits until the shared_future has a valid result and
// (depending on which template is used) retrieves it
// it effectively calls wait() in order to wait for the result
// the value stored in the shared state
// if it satisfies the requirements of MoveAssignable, the value is moved,
// otherwise it is copied
// valid() == false after a call to this method.
// detect the case when valid == false before the call and throw a
// future_error with an error condition of future_errc::no_state
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
ptr_t tmp;
tmp.swap( future_);
return tmp->get();
}
void wait() const
{
//TODO: blocks until the result becomes available
// valid() == true after the call
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
future_->wait();
}
};
template<>
class shared_future< void >
{
private:
typedef typename detail::future_base< void >::ptr_t ptr_t;
friend class future< void >;
struct dummy
{ void nonnull() {} };
typedef void ( dummy::*safe_bool)();
ptr_t future_;
shared_future( ptr_t const& p) :
future_( p)
{}
public:
shared_future() BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a shared_future with no shared state
// after construction, valid() == false
}
~shared_future()
{
//TODO: if *this is the last object referring to the shared state,
// destroys the shared state otherwise does nothing
}
shared_future( shared_future const& other) :
future_( other.future_)
{
//TODO: constructs a shared future that refers to the same shared state,
// as other, if there's any
}
#ifndef BOOST_NO_RVALUE_REFERENCES
shared_future( future< R > && other) BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a shared_future with the shared state of other using move semantics
// after construction, other.valid() == false
swap( other);
future_.swap( other.future_);
}
shared_future( shared_future && other) BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a shared_future with the shared state of other using move semantics
// after construction, other.valid() == false
swap( other);
}
shared_future & operator=( shared_future && other) BOOST_NOEXCEPT
{
//TODO: releases any shared state and move-assigns the contents of other to *this
// after the assignment, other.valid() == false and this->valid() will yield
// the same value as other.valid() before the assignment
shared_future tmp( boost::move( other) );
swap( tmp);
return * this;
}
#else
shared_future( BOOST_RV_REF( future< void >) other) BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a shared_future with the shared state of other using move semantics
// after construction, other.valid() == false
future_.swap( other.future_);
}
shared_future( BOOST_RV_REF( shared_future) other) BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a shared_future with the shared state of other using move semantics
// after construction, other.valid() == false
swap( other);
}
shared_future & operator=( BOOST_RV_REF( shared_future) other) BOOST_NOEXCEPT
{
//TODO: releases any shared state and move-assigns the contents of other to *this
// after the assignment, other.valid() == false and this->valid() will yield
// the same value as other.valid() before the assignment
shared_future tmp( boost::move( other) );
swap( tmp);
return * this;
}
#endif
shared_future & operator=( shared_future const& other) BOOST_NOEXCEPT
{
//TODO:
shared_future tmp( other);
swap( tmp);
return * this;
}
void swap( shared_future & other) BOOST_NOEXCEPT
{
//TODO: exchange the shared states of two shared_futures
future_.swap( other.future_);
}
operator safe_bool() const BOOST_NOEXCEPT
{ return valid() ? & dummy::nonnull : 0; }
bool operator!() const BOOST_NOEXCEPT
{ return ! valid(); }
bool valid() const BOOST_NOEXCEPT
{
//TODO: checks if the shared_future refers to a shared state
// this is the case only for shared_futures returned by
// promise::get_shared_future(), packaged_task::get_shared_future()
// or async() until the first time get()or share() is called
return future_;
}
void get()
{
//TODO: the get method waits until the shared_future has a valid result and
// (depending on which template is used) retrieves it
// it effectively calls wait() in order to wait for the result
// the value stored in the shared state
// if it satisfies the requirements of MoveAssignable, the value is moved,
// otherwise it is copied
// valid() == false after a call to this method.
// detect the case when valid == false before the call and throw a
// future_error with an error condition of future_errc::no_state
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
ptr_t tmp;
tmp.swap( future_);
tmp->get();
}
void wait() const
{
//TODO: blocks until the result becomes available
// valid() == true after the call
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
future_->wait();
}
};
template< typename R >
void swap( shared_future< R > & l, shared_future< R > & r)
{ l.swap( r); }
template< typename R >
shared_future< R >
future< R >::share()
{
//TODO: transfer the shared state of *this to a shared_future object
// multiple shared_future objects may reference the same shared state,
// which is not possible with future
// after calling share on a future, valid() == false
// detect the case when valid == false before the call and throw a
// future_error with an error condition of future_errc::no_state
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
return shared_future< R >( boost::move( * this) );
}
inline
shared_future< void >
future< void >::share()
{
//TODO: transfer the shared state of *this to a shared_future object
// multiple shared_future objects may reference the same shared state,
// which is not possible with future
// after calling share on a future, valid() == false
// detect the case when valid == false before the call and throw a
// future_error with an error condition of future_errc::no_state
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
return shared_future< void >( boost::move( * this) );
}
}}
#endif
#include <boost/fiber/future/future.hpp>
#include <boost/fiber/future/promise.hpp>

View File

@@ -10,7 +10,7 @@
#include <boost/config.hpp>
#include <boost/fiber/detail/config.hpp>
#include <boost/fiber/detail/future_base.hpp>
#include <boost/fiber/future/detail/future_base.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX

View File

@@ -0,0 +1,633 @@
// 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_FIBERS_FUTURE_HPP
#define BOOST_FIBERS_FUTURE_HPP
#include <boost/config.hpp>
#include <boost/move/move.hpp>
#include <boost/system/system_error.hpp>
#include <boost/throw_exception.hpp>
#include <boost/utility.hpp>
#include <boost/fiber/exceptions.hpp>
#include <boost/fiber/future/detail/future_base.hpp>
namespace boost {
namespace fibers {
template< typename R >
class promise;
template< typename R >
class shared_future;
template< typename R >
class future : private noncopyable
{
private:
typedef typename detail::future_base< R >::ptr_t ptr_t;
friend class promise< R >;
friend class shared_future< R >;
struct dummy
{ void nonnull() {} };
typedef void ( dummy::*safe_bool)();
ptr_t future_;
BOOST_MOVABLE_BUT_NOT_COPYABLE( future);
future( ptr_t const& p) :
future_( p)
{}
public:
future() BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a future with no shared state
// after construction, valid() == false
}
~future()
{
//TODO: abandon ownership if any
}
#ifndef BOOST_NO_RVALUE_REFERENCES
future( future && other) BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a future with the shared state of other using move semantics
// after construction, other.valid() == false
swap( other);
}
future & operator=( future && other) BOOST_NOEXCEPT
{
//TODO: releases any shared state and move-assigns the contents of other to *this
// after the assignment, other.valid() == false and this->valid() will yield
// the same value as other.valid() before the assignment
future tmp( boost::move( other) );
swap( tmp);
return * this;
}
#else
future( BOOST_RV_REF( future) other) BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a future with the shared state of other using move semantics
// after construction, other.valid() == false
swap( other);
}
future & operator=( BOOST_RV_REF( future) other) BOOST_NOEXCEPT
{
//TODO: releases any shared state and move-assigns the contents of other to *this
// after the assignment, other.valid() == false and this->valid() will yield
// the same value as other.valid() before the assignment
future tmp( boost::move( other) );
swap( tmp);
return * this;
}
#endif
void swap( future & other) BOOST_NOEXCEPT
{
//TODO: exchange the shared states of two futures
future_.swap( other.future_);
}
operator safe_bool() const BOOST_NOEXCEPT
{ return valid() ? & dummy::nonnull : 0; }
bool operator!() const BOOST_NOEXCEPT
{ return ! valid(); }
bool valid() const BOOST_NOEXCEPT
{
//TODO: checks if the future refers to a shared state
// this is the case only for futures returned by
// promise::get_future(), packaged_task::get_future()
// or async() until the first time get()or share() is called
return future_;
}
shared_future< R > share();
R get()
{
//TODO: the get method waits until the future has a valid result and
// (depending on which template is used) retrieves it
// it effectively calls wait() in order to wait for the result
// the value stored in the shared state
// if it satisfies the requirements of MoveAssignable, the value is moved,
// otherwise it is copied
// valid() == false after a call to this method.
// detect the case when valid == false before the call and throw a
// future_error with an error condition of future_errc::no_state
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
ptr_t tmp;
tmp.swap( future_);
return tmp->get();
}
void wait() const
{
//TODO: blocks until the result becomes available
// valid() == true after the call
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
future_->wait();
}
};
template<>
class future< void > : private noncopyable
{
private:
typedef typename detail::future_base< void >::ptr_t ptr_t;
friend class promise< void >;
friend class shared_future< void >;
struct dummy
{ void nonnull() {} };
typedef void ( dummy::*safe_bool)();
ptr_t future_;
BOOST_MOVABLE_BUT_NOT_COPYABLE( future);
future( ptr_t const& p) :
future_( p)
{}
public:
future() BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a future with no shared state
// after construction, valid() == false
}
~future()
{
//TODO: abandon ownership if any
}
#ifndef BOOST_NO_RVALUE_REFERENCES
future( future && other) BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a future with the shared state of other using move semantics
// after construction, other.valid() == false
swap( other);
}
future & operator=( future && other) BOOST_NOEXCEPT
{
//TODO: releases any shared state and move-assigns the contents of other to *this
// after the assignment, other.valid() == false and this->valid() will yield
// the same value as other.valid() before the assignment
future tmp( boost::move( other) );
swap( tmp);
return * this;
}
#else
future( BOOST_RV_REF( future) other) BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a future with the shared state of other using move semantics
// after construction, other.valid() == false
swap( other);
}
future & operator=( BOOST_RV_REF( future) other) BOOST_NOEXCEPT
{
//TODO: releases any shared state and move-assigns the contents of other to *this
// after the assignment, other.valid() == false and this->valid() will yield
// the same value as other.valid() before the assignment
future tmp( boost::move( other) );
swap( tmp);
return * this;
}
#endif
void swap( future & other) BOOST_NOEXCEPT
{
//TODO: exchange the shared states of two futures
future_.swap( other.future_);
}
operator safe_bool() const BOOST_NOEXCEPT
{ return valid() ? & dummy::nonnull : 0; }
bool operator!() const BOOST_NOEXCEPT
{ return ! valid(); }
bool valid() const BOOST_NOEXCEPT
{
//TODO: checks if the future refers to a shared state
// this is the case only for futures returned by
// promise::get_future(), packaged_task::get_future()
// or async() until the first time get()or share() is called
return future_;
}
shared_future< void > share();
void get()
{
//TODO: the get method waits until the future has a valid result and
// (depending on which template is used) retrieves it
// it effectively calls wait() in order to wait for the result
// the value stored in the shared state
// if it satisfies the requirements of MoveAssignable, the value is moved,
// otherwise it is copied
// valid() == false after a call to this method.
// detect the case when valid == false before the call and throw a
// future_error with an error condition of future_errc::no_state
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
ptr_t tmp;
tmp.swap( future_);
tmp->get();
}
void wait() const
{
//TODO: blocks until the result becomes available
// valid() == true after the call
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
future_->wait();
}
};
template< typename R >
void swap( future< R > & l, future< R > & r)
{ l.swap( r); }
template< typename R >
class shared_future
{
private:
typedef typename detail::future_base< R >::ptr_t ptr_t;
friend class future< R >;
struct dummy
{ void nonnull() {} };
typedef void ( dummy::*safe_bool)();
ptr_t future_;
explicit shared_future( ptr_t const& p) :
future_( p)
{}
public:
shared_future() BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a shared_future with no shared state
// after construction, valid() == false
}
~shared_future()
{
//TODO: if *this is the last object referring to the shared state,
// destroys the shared state otherwise does nothing
}
shared_future( shared_future const& other) :
future_( other.future_)
{
//TODO: constructs a shared future that refers to the same shared state,
// as other, if there's any
}
#ifndef BOOST_NO_RVALUE_REFERENCES
shared_future( future< R > && other) BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a shared_future with the shared state of other using move semantics
// after construction, other.valid() == false
future_.swap( other.future_);
}
shared_future( shared_future && other) BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a shared_future with the shared state of other using move semantics
// after construction, other.valid() == false
swap( other);
}
shared_future & operator=( shared_future && other) BOOST_NOEXCEPT
{
//TODO: releases any shared state and move-assigns the contents of other to *this
// after the assignment, other.valid() == false and this->valid() will yield
// the same value as other.valid() before the assignment
shared_future tmp( boost::move( other) );
swap( tmp);
return * this;
}
#else
shared_future( BOOST_RV_REF( future< R >) other) BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a shared_future with the shared state of other using move semantics
// after construction, other.valid() == false
future_.swap( other.future_);
}
shared_future( BOOST_RV_REF( shared_future) other) BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a shared_future with the shared state of other using move semantics
// after construction, other.valid() == false
swap( other);
}
shared_future & operator=( BOOST_RV_REF( shared_future) other) BOOST_NOEXCEPT
{
//TODO: releases any shared state and move-assigns the contents of other to *this
// after the assignment, other.valid() == false and this->valid() will yield
// the same value as other.valid() before the assignment
shared_future tmp( boost::move( other) );
swap( tmp);
return * this;
}
#endif
shared_future & operator=( shared_future const& other) BOOST_NOEXCEPT
{
//TODO:
shared_future tmp( other);
swap( tmp);
return * this;
}
void swap( shared_future & other) BOOST_NOEXCEPT
{
//TODO: exchange the shared states of two shared_futures
future_.swap( other.future_);
}
operator safe_bool() const BOOST_NOEXCEPT
{ return valid() ? & dummy::nonnull : 0; }
bool operator!() const BOOST_NOEXCEPT
{ return ! valid(); }
bool valid() const BOOST_NOEXCEPT
{
//TODO: checks if the shared_future refers to a shared state
// this is the case only for shared_futures returned by
// promise::get_shared_future(), packaged_task::get_shared_future()
// or async() until the first time get()or share() is called
return future_;
}
R get()
{
//TODO: the get method waits until the shared_future has a valid result and
// (depending on which template is used) retrieves it
// it effectively calls wait() in order to wait for the result
// the value stored in the shared state
// if it satisfies the requirements of MoveAssignable, the value is moved,
// otherwise it is copied
// valid() == false after a call to this method.
// detect the case when valid == false before the call and throw a
// future_error with an error condition of future_errc::no_state
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
ptr_t tmp;
tmp.swap( future_);
return tmp->get();
}
void wait() const
{
//TODO: blocks until the result becomes available
// valid() == true after the call
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
future_->wait();
}
};
template<>
class shared_future< void >
{
private:
typedef typename detail::future_base< void >::ptr_t ptr_t;
friend class future< void >;
struct dummy
{ void nonnull() {} };
typedef void ( dummy::*safe_bool)();
ptr_t future_;
shared_future( ptr_t const& p) :
future_( p)
{}
public:
shared_future() BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a shared_future with no shared state
// after construction, valid() == false
}
~shared_future()
{
//TODO: if *this is the last object referring to the shared state,
// destroys the shared state otherwise does nothing
}
shared_future( shared_future const& other) :
future_( other.future_)
{
//TODO: constructs a shared future that refers to the same shared state,
// as other, if there's any
}
#ifndef BOOST_NO_RVALUE_REFERENCES
shared_future( future< R > && other) BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a shared_future with the shared state of other using move semantics
// after construction, other.valid() == false
swap( other);
future_.swap( other.future_);
}
shared_future( shared_future && other) BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a shared_future with the shared state of other using move semantics
// after construction, other.valid() == false
swap( other);
}
shared_future & operator=( shared_future && other) BOOST_NOEXCEPT
{
//TODO: releases any shared state and move-assigns the contents of other to *this
// after the assignment, other.valid() == false and this->valid() will yield
// the same value as other.valid() before the assignment
shared_future tmp( boost::move( other) );
swap( tmp);
return * this;
}
#else
shared_future( BOOST_RV_REF( future< void >) other) BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a shared_future with the shared state of other using move semantics
// after construction, other.valid() == false
future_.swap( other.future_);
}
shared_future( BOOST_RV_REF( shared_future) other) BOOST_NOEXCEPT :
future_()
{
//TODO: constructs a shared_future with the shared state of other using move semantics
// after construction, other.valid() == false
swap( other);
}
shared_future & operator=( BOOST_RV_REF( shared_future) other) BOOST_NOEXCEPT
{
//TODO: releases any shared state and move-assigns the contents of other to *this
// after the assignment, other.valid() == false and this->valid() will yield
// the same value as other.valid() before the assignment
shared_future tmp( boost::move( other) );
swap( tmp);
return * this;
}
#endif
shared_future & operator=( shared_future const& other) BOOST_NOEXCEPT
{
//TODO:
shared_future tmp( other);
swap( tmp);
return * this;
}
void swap( shared_future & other) BOOST_NOEXCEPT
{
//TODO: exchange the shared states of two shared_futures
future_.swap( other.future_);
}
operator safe_bool() const BOOST_NOEXCEPT
{ return valid() ? & dummy::nonnull : 0; }
bool operator!() const BOOST_NOEXCEPT
{ return ! valid(); }
bool valid() const BOOST_NOEXCEPT
{
//TODO: checks if the shared_future refers to a shared state
// this is the case only for shared_futures returned by
// promise::get_shared_future(), packaged_task::get_shared_future()
// or async() until the first time get()or share() is called
return future_;
}
void get()
{
//TODO: the get method waits until the shared_future has a valid result and
// (depending on which template is used) retrieves it
// it effectively calls wait() in order to wait for the result
// the value stored in the shared state
// if it satisfies the requirements of MoveAssignable, the value is moved,
// otherwise it is copied
// valid() == false after a call to this method.
// detect the case when valid == false before the call and throw a
// future_error with an error condition of future_errc::no_state
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
ptr_t tmp;
tmp.swap( future_);
tmp->get();
}
void wait() const
{
//TODO: blocks until the result becomes available
// valid() == true after the call
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
future_->wait();
}
};
template< typename R >
void swap( shared_future< R > & l, shared_future< R > & r)
{ l.swap( r); }
template< typename R >
shared_future< R >
future< R >::share()
{
//TODO: transfer the shared state of *this to a shared_future object
// multiple shared_future objects may reference the same shared state,
// which is not possible with future
// after calling share on a future, valid() == false
// detect the case when valid == false before the call and throw a
// future_error with an error condition of future_errc::no_state
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
return shared_future< R >( boost::move( * this) );
}
inline
shared_future< void >
future< void >::share()
{
//TODO: transfer the shared state of *this to a shared_future object
// multiple shared_future objects may reference the same shared state,
// which is not possible with future
// after calling share on a future, valid() == false
// detect the case when valid == false before the call and throw a
// future_error with an error condition of future_errc::no_state
if ( ! valid() )
boost::throw_exception(
future_uninitialized() );
return shared_future< void >( boost::move( * this) );
}
}}
#endif

View File

@@ -16,10 +16,10 @@
#include <boost/throw_exception.hpp>
#include <boost/utility.hpp>
#include <boost/fiber/detail/future_base.hpp>
#include <boost/fiber/detail/future_object.hpp>
#include <boost/fiber/exceptions.hpp>
#include <boost/fiber/future.hpp>
#include <boost/fiber/future/detail/future_base.hpp>
#include <boost/fiber/future/detail/future_object.hpp>
#include <boost/fiber/future/future.hpp>
namespace boost {
namespace fibers {