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:
@@ -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>
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
633
include/boost/fiber/future/future.hpp
Normal file
633
include/boost/fiber/future/future.hpp
Normal 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
|
||||
@@ -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 {
|
||||
Reference in New Issue
Block a user