From f742b5f4dc217644495392ea1ed3d6f216ccd770 Mon Sep 17 00:00:00 2001 From: Oliver Kowalke Date: Thu, 7 Mar 2013 17:36:57 +0100 Subject: [PATCH] reorganize files relaed to future --- include/boost/fiber/all.hpp | 1 - include/boost/fiber/detail/delete.hpp | 45 -- include/boost/fiber/detail/move.hpp | 245 ------- include/boost/fiber/future.hpp | 635 +----------------- .../fiber/{ => future}/detail/future_base.hpp | 0 .../{ => future}/detail/future_object.hpp | 2 +- .../{ => future}/detail/future_traits.hpp | 0 include/boost/fiber/future/future.hpp | 633 +++++++++++++++++ include/boost/fiber/{ => future}/promise.hpp | 6 +- 9 files changed, 639 insertions(+), 928 deletions(-) delete mode 100644 include/boost/fiber/detail/delete.hpp delete mode 100644 include/boost/fiber/detail/move.hpp rename include/boost/fiber/{ => future}/detail/future_base.hpp (100%) rename include/boost/fiber/{ => future}/detail/future_object.hpp (95%) rename include/boost/fiber/{ => future}/detail/future_traits.hpp (100%) create mode 100644 include/boost/fiber/future/future.hpp rename include/boost/fiber/{ => future}/promise.hpp (98%) diff --git a/include/boost/fiber/all.hpp b/include/boost/fiber/all.hpp index 6b1f892b..a1d250f1 100644 --- a/include/boost/fiber/all.hpp +++ b/include/boost/fiber/all.hpp @@ -19,7 +19,6 @@ #include #include #include -#include #include #include diff --git a/include/boost/fiber/detail/delete.hpp b/include/boost/fiber/detail/delete.hpp deleted file mode 100644 index 0dffaebc..00000000 --- a/include/boost/fiber/detail/delete.hpp +++ /dev/null @@ -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_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 diff --git a/include/boost/fiber/detail/move.hpp b/include/boost/fiber/detail/move.hpp deleted file mode 100644 index 7b5837e0..00000000 --- a/include/boost/fiber/detail/move.hpp +++ /dev/null @@ -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 -#ifndef BOOST_NO_SFINAE -#include -#include -#include -#include -#include -#endif - -#include -#include -#include - -#define BOOST_NOEXCEPT - -namespace boost { -namespace detail { - -template -struct has_move_emulation_enabled_aux_dummy_specialization; -template -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 enable_if >, boost::detail::fibers_move_t >::type move(T& t) -{ - return boost::detail::fibers_move_t(t); -} -#endif - -template -boost::detail::fibers_move_t move(boost::detail::fibers_move_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 \ - struct has_move_emulation_enabled_aux_dummy_specialization< - -#define BOOST_FIBERS_DCL_MOVABLE_END > \ - : integral_constant \ - {}; \ - } - -#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 \ - struct has_move_emulation_enabled_aux_dummy_specialization< - -#define BOOST_FIBERS_DCL_MOVABLE_END > \ - : integral_constant \ - {}; \ - } - -#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 \ - struct has_move_emulation_enabled_aux_dummy_specialization< - -#define BOOST_FIBERS_DCL_MOVABLE_END > \ - : integral_constant \ - {}; \ - } - -#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 \ -{}; - -#define BOOST_FIBERS_DCL_MOVABLE_BEG(T) \ -template \ -struct has_move_emulation_enabled_aux< - -#define BOOST_FIBERS_DCL_MOVABLE_END > \ - : BOOST_MOVE_BOOST_NS::integral_constant \ -{}; - -#endif - -namespace boost { -namespace detail { - -template -BOOST_FIBERS_RV_REF(typename ::boost::remove_cv::type>::type) -make_rv_ref(T v) BOOST_NOEXCEPT -{ -return (BOOST_FIBERS_RV_REF(typename ::boost::remove_cv::type>::type))(v); -} -// template -// BOOST_FIBERS_RV_REF(typename ::boost::remove_cv::type>::type) -// make_rv_ref(T &v) BOOST_NOEXCEPT -// { -// return (BOOST_FIBERS_RV_REF(typename ::boost::remove_cv::type>::type))(v); -// } -// template -// const BOOST_FIBERS_RV_REF(typename ::boost::remove_cv::type>::type) -// make_rv_ref(T const&v) BOOST_NOEXCEPT -// { -// return (const BOOST_FIBERS_RV_REF(typename ::boost::remove_cv::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& move() BOOST_NOEXCEPT \ - { \ - return *static_cast< ::boost::rv* >(this); \ - } \ - const ::boost::rv& move() const BOOST_NOEXCEPT \ - { \ - return *static_cast* >(this); \ - } \ - operator ::boost::rv&() \ - { \ - return *static_cast< ::boost::rv* >(this); \ - } \ - operator const ::boost::rv&() const \ - { \ - return *static_cast* >(this); \ - }\ - -#else - -#define BOOST_FIBERS_MOVABLE(TYPE) \ - operator ::boost::detail::fibers_move_t() BOOST_NOEXCEPT \ - { \ - return move(); \ - } \ - ::boost::detail::fibers_move_t move() BOOST_NOEXCEPT \ - { \ - ::boost::detail::fibers_move_t 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 -typename decay::type -decay_copy(T&& t) -{ - return boost::forward(t); -} - -}} -#endif - -#include - -#endif diff --git a/include/boost/fiber/future.hpp b/include/boost/fiber/future.hpp index 81e3368a..0ed43860 100644 --- a/include/boost/fiber/future.hpp +++ b/include/boost/fiber/future.hpp @@ -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 -#include -#include -#include -#include - -#include -#include - -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 +#include diff --git a/include/boost/fiber/detail/future_base.hpp b/include/boost/fiber/future/detail/future_base.hpp similarity index 100% rename from include/boost/fiber/detail/future_base.hpp rename to include/boost/fiber/future/detail/future_base.hpp diff --git a/include/boost/fiber/detail/future_object.hpp b/include/boost/fiber/future/detail/future_object.hpp similarity index 95% rename from include/boost/fiber/detail/future_object.hpp rename to include/boost/fiber/future/detail/future_object.hpp index 67268831..a20f61d6 100644 --- a/include/boost/fiber/detail/future_object.hpp +++ b/include/boost/fiber/future/detail/future_object.hpp @@ -10,7 +10,7 @@ #include #include -#include +#include #ifdef BOOST_HAS_ABI_HEADERS # include BOOST_ABI_PREFIX diff --git a/include/boost/fiber/detail/future_traits.hpp b/include/boost/fiber/future/detail/future_traits.hpp similarity index 100% rename from include/boost/fiber/detail/future_traits.hpp rename to include/boost/fiber/future/detail/future_traits.hpp diff --git a/include/boost/fiber/future/future.hpp b/include/boost/fiber/future/future.hpp new file mode 100644 index 00000000..bed19cb8 --- /dev/null +++ b/include/boost/fiber/future/future.hpp @@ -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 +#include +#include +#include +#include + +#include +#include + +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 diff --git a/include/boost/fiber/promise.hpp b/include/boost/fiber/future/promise.hpp similarity index 98% rename from include/boost/fiber/promise.hpp rename to include/boost/fiber/future/promise.hpp index 93b9f2b5..d0978c58 100644 --- a/include/boost/fiber/promise.hpp +++ b/include/boost/fiber/future/promise.hpp @@ -16,10 +16,10 @@ #include #include -#include -#include #include -#include +#include +#include +#include namespace boost { namespace fibers {