diff options
author | bkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-11-03 00:47:48 +0000 |
---|---|---|
committer | bkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-11-03 00:47:48 +0000 |
commit | 53200162d9ee14633f53f14e03aa565941551dc6 (patch) | |
tree | c654e0ab06b931548a732abc1309e98b6cc75d0a /libstdc++-v3 | |
parent | c356a43c60fe4a7dac807259e42aa6f358d82f10 (diff) | |
download | gcc-53200162d9ee14633f53f14e03aa565941551dc6.tar.gz |
2009-11-02 Benjamin Kosnik <bkoz@redhat.com>
* include/std/future: Use base class with nested types.
(__future_base): New.
(__future_base::_Result_base): From _Future_result_base.
(__future_base::_Result): From _Future_result.
(__future_base::_Move_result): From _Move_future_result.
(__future_base::_Ptr): From _Future_ptr.
(__future_base::_State): From _Future_state.
(__basic_future): From _Future_impl.
* testsuite/30_threads/packaged_task/cons/assign_neg.cc: Adjust line
numbers.
* testsuite/30_threads/packaged_task/cons/copy_neg.cc: Same.
* testsuite/30_threads/shared_future/cons/assign_neg.cc: Same.
* testsuite/30_threads/unique_future/cons/assign_neg.cc: Same.
* testsuite/30_threads/unique_future/cons/copy_neg.cc: Same.
* testsuite/30_threads/promise/cons/assign_neg.cc: Same.
* testsuite/30_threads/promise/cons/copy_neg.cc: Same.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@153834 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3')
9 files changed, 399 insertions, 336 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 91d2a598ee5..589671b470b 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,22 @@ +2009-11-02 Benjamin Kosnik <bkoz@redhat.com> + + * include/std/future: Use base class with nested types. + (__future_base): New. + (__future_base::_Result_base): From _Future_result_base. + (__future_base::_Result): From _Future_result. + (__future_base::_Move_result): From _Move_future_result. + (__future_base::_Ptr): From _Future_ptr. + (__future_base::_State): From _Future_state. + (__basic_future): From _Future_impl. + * testsuite/30_threads/packaged_task/cons/assign_neg.cc: Adjust line + numbers. + * testsuite/30_threads/packaged_task/cons/copy_neg.cc: Same. + * testsuite/30_threads/shared_future/cons/assign_neg.cc: Same. + * testsuite/30_threads/unique_future/cons/assign_neg.cc: Same. + * testsuite/30_threads/unique_future/cons/copy_neg.cc: Same. + * testsuite/30_threads/promise/cons/assign_neg.cc: Same. + * testsuite/30_threads/promise/cons/copy_neg.cc: Same. + 2009-10-31 Paolo Carlini <paolo.carlini@oracle.com> * include/std/chrono (struct __common_rep_type): New. @@ -9,7 +28,7 @@ operator/(const duration<>&, const _Rep2&), time_point_cast(const time_point<>&)): Implement resolution of DR 1177 ([Ready] in Santa Cruz), change to not participate to - overload resolution if the constraints are not met. + overload resolution if the constraints are not met. * testsuite/20_util/duration/cons/1_neg.cc: Adjust dg-errors. * testsuite/20_util/duration/cons/dr974.cc: Likewise. * testsuite/20_util/duration/requirements/typedefs_neg1.cc: Adjust diff --git a/libstdc++-v3/include/std/future b/libstdc++-v3/include/std/future index 00f5c48bcfd..b8c54b6075f 100644 --- a/libstdc++-v3/include/std/future +++ b/libstdc++-v3/include/std/future @@ -79,7 +79,7 @@ namespace std */ class future_error : public logic_error { - error_code _M_code; + error_code _M_code; public: explicit future_error(future_errc __ec) @@ -96,252 +96,286 @@ namespace std }; // Forward declarations. - template<typename _Result> + template<typename _Res> class unique_future; - template<typename _Result> + template<typename _Res> class shared_future; template<typename> class packaged_task; - template<typename _Result> + template<typename _Res> class promise; #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) \ && defined(_GLIBCXX_ATOMIC_BUILTINS_4) - // Holds the result of a future - struct _Future_result_base + /// Base class and enclosing scope. + struct __future_base { - _Future_result_base() = default; - _Future_result_base(const _Future_result_base&) = delete; - _Future_result_base& operator=(const _Future_result_base&) = delete; + /// Base class for results. + struct _Result_base + { + exception_ptr _M_error; - exception_ptr _M_error; + _Result_base() = default; + _Result_base(const _Result_base&) = delete; + _Result_base& operator=(const _Result_base&) = delete; - // _M_destroy() allows derived classes to control deallocation, - // which will be needed when allocator support is added to promise. - // See http://gcc.gnu.org/ml/libstdc++/2009-06/msg00032.html - virtual void _M_destroy() = 0; - struct _Deleter - { - void operator()(_Future_result_base* __fr) const { __fr->_M_destroy(); } - }; + // _M_destroy() allows derived classes to control deallocation, + // which will be needed when allocator support is added to promise. + // See http://gcc.gnu.org/ml/libstdc++/2009-06/msg00032.html + virtual void _M_destroy() = 0; - protected: - ~_Future_result_base(); - }; + struct _Deleter + { + void operator()(_Result_base* __fr) const { __fr->_M_destroy(); } + }; - inline _Future_result_base::~_Future_result_base() = default; + protected: + ~_Result_base(); + }; - // TODO: use template alias when available - /* - template<typename _Res> - using _Future_ptr = unique_ptr<_Res, _Future_result_base::_Deleter>; - */ - template<typename _Res> - struct _Future_ptr - { - typedef unique_ptr<_Res, _Future_result_base::_Deleter> type; + /// Result. + template<typename _Res> + struct _Result : _Result_base + { + private: + typedef alignment_of<_Res> __a_of; + typedef aligned_storage<sizeof(_Res), __a_of::value> __align_storage; + typedef typename __align_storage::type __align_type; + + __align_type _M_storage; + bool _M_initialized; + + public: + _Result() : _M_initialized() { } + + ~_Result() + { + if (_M_initialized) + _M_value().~_Res(); + } + + // Return lvalue, future will add const or rvalue-reference + _Res& + _M_value() { return *static_cast<_Res*>(_M_addr()); } + + void + _M_set(const _Res& __res) + { + ::new (_M_addr()) _Res(__res); + _M_initialized = true; + } + + void + _M_set(_Res&& __res) + { + ::new (_M_addr()) _Res(_Move_result<_Res>::_S_move(__res)); + _M_initialized = true; + } + + private: + void _M_destroy() { delete this; } + + void* _M_addr() { return static_cast<void*>(&_M_storage); } }; - // State shared between a promise and one or more associated futures. - class _Future_state - { - typedef _Future_ptr<_Future_result_base>::type _Future_ptr_type; - public: - _Future_state() : _M_result(), _M_retrieved(ATOMIC_FLAG_INIT) { } + /// Workaround for CWG issue 664 and c++/34022 + template<typename _Res, bool = is_scalar<_Res>::value> + struct _Move_result; - _Future_state(const _Future_state&) = delete; - _Future_state& operator=(const _Future_state&) = delete; + /// Specialization for scalar types returns rvalue not rvalue-reference. + template<typename _Res> + struct _Move_result<_Res, true> + { + typedef _Res __rval_type; + static _Res _S_move(_Res __res) { return __res; } + }; + + /// Specialization for non-scalar types returns rvalue-reference. + template<typename _Res> + struct _Move_result<_Res, false> + { + typedef _Res&& __rval_type; + static _Res&& _S_move(_Res& __res) { return std::move(__res); } + }; + + + // TODO: use template alias when available + /* + template<typename _Res> + using _Ptr = unique_ptr<_Res, _Result_base::_Deleter>; + */ + /// A unique_ptr based on the instantiating type. + template<typename _Res> + struct _Ptr + { + typedef unique_ptr<_Res, _Result_base::_Deleter> type; + }; - bool - is_ready() - { return _M_get() != 0; } - bool - has_exception() + /// Shared state between a promise and one or more associated futures. + class _State { - _Future_result_base* const __res = _M_get(); - return __res && !(__res->_M_error == 0); - } + typedef _Ptr<_Result_base>::type _Ptr_type; - bool - has_value() - { - _Future_result_base* const __res = _M_get(); - return __res && (__res->_M_error == 0); - } + _Ptr_type _M_result; + mutex _M_mutex; + condition_variable _M_cond; + atomic_flag _M_retrieved; - _Future_result_base& - wait() - { - unique_lock<mutex> __lock(_M_mutex); - if (!_M_ready()) - _M_cond.wait(__lock, std::bind(&_Future_state::_M_ready, this)); - return *_M_result; - } + public: + _State() : _M_result(), _M_retrieved(ATOMIC_FLAG_INIT) { } + + _State(const _State&) = delete; + _State& operator=(const _State&) = delete; - template<typename _Rep, typename _Period> bool - wait_for(const chrono::duration<_Rep, _Period>& __rel) - { - unique_lock<mutex> __lock(_M_mutex); - return _M_ready() || _M_cond.wait_for(__lock, __rel, - std::bind(&_Future_state::_M_ready, this)); - } + is_ready() + { return _M_get() != 0; } - template<typename _Clock, typename _Duration> bool - wait_until(const chrono::time_point<_Clock, _Duration>& __abs) + has_exception() { - unique_lock<mutex> __lock(_M_mutex); - return _M_ready() || _M_cond.wait_until(__lock, __abs, - std::bind(&_Future_state::_M_ready, this)); + _Result_base* const __res = _M_get(); + return __res && !(__res->_M_error == 0); } - void - _M_set_result(_Future_ptr_type __res) - { + bool + has_value() { - lock_guard<mutex> __lock(_M_mutex); - if (_M_ready()) - __throw_future_error(int(future_errc::promise_already_satisfied)); - _M_result.swap(__res); + _Result_base* const __res = _M_get(); + return __res && (__res->_M_error == 0); } - _M_cond.notify_all(); - } - void - _M_break_promise(_Future_ptr_type __res) - { - if (static_cast<bool>(__res)) + _Result_base& + wait() { - __res->_M_error - = std::copy_exception(future_error(future_errc::broken_promise)); - { - lock_guard<mutex> __lock(_M_mutex); - _M_result.swap(__res); - } - _M_cond.notify_all(); + unique_lock<mutex> __lock(_M_mutex); + if (!_M_ready()) + _M_cond.wait(__lock, std::bind(&_State::_M_ready, this)); + return *_M_result; } - } - - // called when this object is passed to a unique_future - void - _M_set_retrieved_flag() - { - if (_M_retrieved.test_and_set()) - __throw_future_error(int(future_errc::future_already_retrieved)); - } - - private: - _Future_result_base* - _M_get() - { - lock_guard<mutex> __lock(_M_mutex); - return _M_result.get(); - } - bool _M_ready() const { return static_cast<bool>(_M_result); } - - _Future_ptr_type _M_result; - mutex _M_mutex; - condition_variable _M_cond; - atomic_flag _M_retrieved; - }; - - // workaround for CWG issue 664 and c++/34022 - template<typename _Result, bool = is_scalar<_Result>::value> - struct _Move_future_result - { - typedef _Result&& __rval_type; - static _Result&& _S_move(_Result& __res) { return std::move(__res); } - }; - - // specialization for scalar types returns rvalue not rvalue-reference - template<typename _Result> - struct _Move_future_result<_Result, true> - { - typedef _Result __rval_type; - static _Result _S_move(_Result __res) { return __res; } - }; + template<typename _Rep, typename _Period> + bool + wait_for(const chrono::duration<_Rep, _Period>& __rel) + { + unique_lock<mutex> __lock(_M_mutex); + auto __bound = std::bind(&_State::_M_ready, this); + return _M_ready() || _M_cond.wait_for(__lock, __rel, __bound); + } - template<typename _Result> - struct _Future_result : _Future_result_base - { - _Future_result() : _M_initialized() { } + template<typename _Clock, typename _Duration> + bool + wait_until(const chrono::time_point<_Clock, _Duration>& __abs) + { + unique_lock<mutex> __lock(_M_mutex); + auto __bound = std::bind(&_State::_M_ready, this); + return _M_ready() || _M_cond.wait_until(__lock, __abs, __bound); + } - ~_Future_result() + void + _M_set_result(_Ptr_type __res) { - if (_M_initialized) - _M_value().~_Result(); + { + lock_guard<mutex> __lock(_M_mutex); + if (_M_ready()) + __throw_future_error(int(future_errc::promise_already_satisfied)); + _M_result.swap(__res); + } + _M_cond.notify_all(); } - // return lvalue, future will add const or rvalue-reference - _Result& _M_value() - { return *static_cast<_Result*>(_M_addr()); } - void - _M_set(const _Result& __res) + _M_break_promise(_Ptr_type __res) { - ::new (_M_addr()) _Result(__res); - _M_initialized = true; + if (static_cast<bool>(__res)) + { + future_errc __ec(future_errc::broken_promise); // XXX + __res->_M_error = copy_exception(future_error(__ec)); + { + lock_guard<mutex> __lock(_M_mutex); + _M_result.swap(__res); + } + _M_cond.notify_all(); + } } + // Called when this object is passed to a unique_future. void - _M_set(_Result&& __res) + _M_set_retrieved_flag() { - typedef _Move_future_result<_Result> _Mover; - ::new (_M_addr()) _Result(_Mover::_S_move(__res)); - _M_initialized = true; + if (_M_retrieved.test_and_set()) + __throw_future_error(int(future_errc::future_already_retrieved)); } private: - void _M_destroy() { delete this; } - - void* _M_addr() { return static_cast<void*>(&_M_storage); } + _Result_base* + _M_get() + { + lock_guard<mutex> __lock(_M_mutex); + return _M_result.get(); + } - typename aligned_storage<sizeof(_Result), - alignment_of<_Result>::value>::type _M_storage; - bool _M_initialized; + bool _M_ready() const { return static_cast<bool>(_M_result); } }; + }; - template<typename _Result> - struct _Future_result<_Result&> : _Future_result_base - { - _Future_result() : _M_value_ptr() { } + inline __future_base::_Result_base::~_Result_base() = default; - _Result* _M_value_ptr; + /// Partial specialization for reference types. + template<typename _Res> + struct __future_base::_Result<_Res&> : __future_base::_Result_base + { + _Result() : _M_value_ptr() { } + _Res* _M_value_ptr; + + private: void _M_destroy() { delete this; } }; + /// Explicit specialization for void. template<> - struct _Future_result<void> : _Future_result_base + struct __future_base::_Result<void> : __future_base::_Result_base { + private: void _M_destroy() { delete this; } }; - // common implementation for unique_future and shared_future - template<typename _Result> - class _Future_impl + + /// Common implementation for unique_future and shared_future. + template<typename _Res> + class __basic_future : public __future_base { + protected: + typedef shared_ptr<_State> __state_type; + typedef __future_base::_Result<_Res>& __result_type; + + private: + __state_type _M_state; + public: - // disable copying - _Future_impl(const _Future_impl&) = delete; - _Future_impl& operator=(const _Future_impl&) = delete; + // Disable copying. + __basic_future(const __basic_future&) = delete; + __basic_future& operator=(const __basic_future&) = delete; - // functions to check state and wait for ready - bool is_ready() const { return this->_M_state->is_ready(); } + // Functions to check state and wait for ready. + bool + is_ready() const { return this->_M_state->is_ready(); } - bool has_exception() const { return this->_M_state->has_exception(); } + bool + has_exception() const { return this->_M_state->has_exception(); } - bool has_value() const { return this->_M_state->has_value(); } + bool + has_value() const { return this->_M_state->has_value(); } - void wait() const { this->_M_state->wait(); } + void + wait() const { this->_M_state->wait(); } template<typename _Rep, typename _Period> bool @@ -354,22 +388,19 @@ namespace std { return this->_M_state->wait_until(__abs); } protected: - // wait for the state to be ready and rethrow any stored exception - _Future_result<_Result>& + /// Wait for the state to be ready and rethrow any stored exception + __result_type _M_get_result() { - _Future_result_base& __res = this->_M_state->wait(); + _Result_base& __res = this->_M_state->wait(); if (!(__res._M_error == 0)) rethrow_exception(__res._M_error); - return static_cast<_Future_result<_Result>&>(__res); + return static_cast<__result_type>(__res); } - typedef shared_ptr<_Future_state> _State_ptr; - - // construction of a unique_future by promise::get_future() + // Construction of a unique_future by promise::get_future() explicit - _Future_impl(const _State_ptr& __state) - : _M_state(__state) + __basic_future(const __state_type& __state) : _M_state(__state) { if (static_cast<bool>(this->_M_state)) this->_M_state->_M_set_retrieved_flag(); @@ -377,146 +408,149 @@ namespace std __throw_future_error(int(future_errc::future_already_retrieved)); } - // copy construction from a shared_future + // Copy construction from a shared_future explicit - _Future_impl(const shared_future<_Result>&); + __basic_future(const shared_future<_Res>&); - // move construction from a unique_future + // Move construction from a unique_future explicit - _Future_impl(unique_future<_Result>&&); - - _State_ptr _M_state; + __basic_future(unique_future<_Res>&&); }; - /// primary template for unique_future - template<typename _Result> - class unique_future : public _Future_impl<_Result> + + /// Primary template for unique_future. + template<typename _Res> + class unique_future : public __basic_future<_Res> { - typedef _Move_future_result<_Result> _Mover; + friend class promise<_Res>; + + typedef __basic_future<_Res> _Base_type; + typedef typename _Base_type::__state_type __state_type; + typedef __future_base::_Move_result<_Res> _Mover; + + explicit + unique_future(const __state_type& __state) : _Base_type(__state) { } public: /// Move constructor unique_future(unique_future&& __uf) : _Base_type(std::move(__uf)) { } - // disable copying + // Disable copying unique_future(const unique_future&) = delete; unique_future& operator=(const unique_future&) = delete; - // retrieving the value + /// Retrieving the value typename _Mover::__rval_type get() { return _Mover::_S_move(this->_M_get_result()._M_value()); } - - private: - typedef _Future_impl<_Result> _Base_type; - typedef typename _Base_type::_State_ptr _State_ptr; - - friend class promise<_Result>; - - explicit - unique_future(const _State_ptr& __state) : _Base_type(__state) { } }; - // partial specialization for unique_future<R&> - template<typename _Result> - class unique_future<_Result&> : public _Future_impl<_Result&> + /// Partial specialization for unique_future<R&> + template<typename _Res> + class unique_future<_Res&> : public __basic_future<_Res&> { + friend class promise<_Res&>; + + typedef __basic_future<_Res&> _Base_type; + typedef typename _Base_type::__state_type __state_type; + + explicit + unique_future(const __state_type& __state) : _Base_type(__state) { } + public: /// Move constructor unique_future(unique_future&& __uf) : _Base_type(std::move(__uf)) { } - // disable copying + // Disable copying unique_future(const unique_future&) = delete; unique_future& operator=(const unique_future&) = delete; - // retrieving the value - _Result& get() { return *this->_M_get_result()._M_value_ptr; } + /// Retrieving the value + _Res& + get() { return *this->_M_get_result()._M_value_ptr; } + }; - private: - typedef _Future_impl<_Result&> _Base_type; - typedef typename _Base_type::_State_ptr _State_ptr; + /// Explicit specialization for unique_future<void> + template<> + class unique_future<void> : public __basic_future<void> + { + friend class promise<void>; - friend class promise<_Result&>; + typedef __basic_future<void> _Base_type; + typedef typename _Base_type::__state_type __state_type; explicit - unique_future(const _State_ptr& __state) : _Base_type(__state) { } - }; + unique_future(const __state_type& __state) : _Base_type(__state) { } - // specialization for unique_future<void> - template<> - class unique_future<void> : public _Future_impl<void> - { public: /// Move constructor unique_future(unique_future&& __uf) : _Base_type(std::move(__uf)) { } - // disable copying + // Disable copying unique_future(const unique_future&) = delete; unique_future& operator=(const unique_future&) = delete; - // retrieving the value - void get() { this->_M_get_result(); } - - private: - typedef _Future_impl<void> _Base_type; - typedef _Base_type::_State_ptr _State_ptr; - - friend class promise<void>; - - explicit - unique_future(const _State_ptr& __state) : _Base_type(__state) { } + /// Retrieving the value + void + get() { this->_M_get_result(); } }; - /// primary template for shared_future - template<typename _Result> - class shared_future : public _Future_impl<_Result> + + /// Primary template for shared_future. + template<typename _Res> + class shared_future : public __basic_future<_Res> { + typedef __basic_future<_Res> _Base_type; + public: /// Copy constructor shared_future(const shared_future& __sf) : _Base_type(__sf) { } /// Construct from a unique_future rvalue - shared_future(unique_future<_Result>&& __uf) + shared_future(unique_future<_Res>&& __uf) : _Base_type(std::move(__uf)) { } shared_future& operator=(const shared_future&) = delete; - // retrieving the value - const _Result& + /// Retrieving the value + const _Res& get() - { return this->_M_get_result()._M_value(); } - - private: - typedef _Future_impl<_Result> _Base_type; + { + typename _Base_type::__result_type __r = this->_M_get_result(); + _Res& __rs(__r._M_value()); + return __rs; + } }; - // partial specialization for shared_future<R&> - template<typename _Result> - class shared_future<_Result&> : public _Future_impl<_Result&> + /// Partial specialization for shared_future<R&> + template<typename _Res> + class shared_future<_Res&> : public __basic_future<_Res&> { + typedef __basic_future<_Res&> _Base_type; + public: /// Copy constructor shared_future(const shared_future& __sf) : _Base_type(__sf) { } /// Construct from a unique_future rvalue - shared_future(unique_future<_Result&>&& __uf) + shared_future(unique_future<_Res&>&& __uf) : _Base_type(std::move(__uf)) { } shared_future& operator=(const shared_future&) = delete; - // retrieving the value - _Result& get() { return *this->_M_get_result()._M_value_ptr; } - - private: - typedef _Future_impl<_Result&> _Base_type; + /// Retrieving the value + _Res& + get() { return *this->_M_get_result()._M_value_ptr; } }; - // specialization for shared_future<void> + /// Explicit specialization for shared_future<void> template<> - class shared_future<void> : public _Future_impl<void> + class shared_future<void> : public __basic_future<void> { + typedef __basic_future<void> _Base_type; + public: /// Copy constructor shared_future(const shared_future& __sf) : _Base_type(__sf) { } @@ -528,33 +562,39 @@ namespace std shared_future& operator=(const shared_future&) = delete; - // retrieving the value - void get() { this->_M_get_result(); } - - private: - typedef _Future_impl<void> _Base_type; + // Retrieving the value + void + get() { this->_M_get_result(); } }; - // now we can define the protected _Future_impl constructors - - template<typename _Result> - _Future_impl<_Result>::_Future_impl(const shared_future<_Result>& __sf) + // Now we can define the protected __basic_future constructors. + template<typename _Res> + __basic_future<_Res>::__basic_future(const shared_future<_Res>& __sf) : _M_state(__sf._M_state) { } - template<typename _Result> - _Future_impl<_Result>::_Future_impl(unique_future<_Result>&& __uf) + template<typename _Res> + __basic_future<_Res>::__basic_future(unique_future<_Res>&& __uf) : _M_state(std::move(__uf._M_state)) { } - /// primary template for promise - template<typename _Result> + + /// Primary template for promise + template<typename _Res> class promise { + template<typename> friend class packaged_task; + + typedef __future_base::_State _State; + typedef __future_base::_Move_result<_Res> _Mover; + typedef __future_base::_Result<_Res> result_type; + + shared_ptr<_State> _M_future; + typename __future_base::_Ptr<result_type>::type _M_storage; + public: promise() - : _M_future(std::make_shared<_Future_state>()), - _M_storage(new _Future_result<_Result>()) + : _M_future(std::make_shared<_State>()), _M_storage(new result_type()) { } promise(promise&& __rhs) @@ -579,7 +619,7 @@ namespace std _M_future->_M_break_promise(std::move(_M_storage)); } - // assignment + // Assignment promise& operator=(promise&& __rhs) { @@ -596,14 +636,14 @@ namespace std _M_storage.swap(__rhs._M_storage); } - // retrieving the result - unique_future<_Result> + // Retrieving the result + unique_future<_Res> get_future() - { return unique_future<_Result>(_M_future); } + { return unique_future<_Res>(_M_future); } - // setting the result + // Setting the result void - set_value(const _Result& __r) + set_value(const _Res& __r) { if (!_M_satisfied()) _M_storage->_M_set(__r); @@ -611,7 +651,7 @@ namespace std } void - set_value(_Result&& __r) + set_value(_Res&& __r) { if (!_M_satisfied()) _M_storage->_M_set(_Mover::_S_move(__r)); @@ -627,26 +667,29 @@ namespace std } private: - template<typename> friend class packaged_task; - typedef _Move_future_result<_Result> _Mover; bool _M_satisfied() { return !static_cast<bool>(_M_storage); } - shared_ptr<_Future_state> _M_future; - typename _Future_ptr<_Future_result<_Result>>::type _M_storage; }; - // partial specialization for promise<R&> - template<typename _Result> - class promise<_Result&> + /// Partial specialization for promise<R&> + template<typename _Res> + class promise<_Res&> { + template<typename> friend class packaged_task; + typedef __future_base::_State _State; + + typedef __future_base::_Result<_Res&> result_type; + + shared_ptr<_State> _M_future; + typename __future_base::_Ptr<result_type>::type _M_storage; + public: promise() - : _M_future(std::make_shared<_Future_state>()), - _M_storage(new _Future_result<_Result&>()) + : _M_future(std::make_shared<_State>()), _M_storage(new result_type()) { } promise(promise&& __rhs) - : _M_future(std::move(__rhs._M_future)), - _M_storage(std::move(__rhs._M_storage)) + : _M_future(std::move(__rhs._M_future)), + _M_storage(std::move(__rhs._M_storage)) { } // TODO: requires allocator concepts @@ -666,7 +709,7 @@ namespace std _M_future->_M_break_promise(std::move(_M_storage)); } - // assignment + // Assignment promise& operator=(promise&& __rhs) { @@ -683,14 +726,14 @@ namespace std _M_storage.swap(__rhs._M_storage); } - // retrieving the result - unique_future<_Result&> + // Retrieving the result + unique_future<_Res&> get_future() - { return unique_future<_Result&>(_M_future); } + { return unique_future<_Res&>(_M_future); } - // setting the result + // Setting the result void - set_value(_Result& __r) + set_value(_Res& __r) { if (!_M_satisfied()) _M_storage->_M_value_ptr = &__r; @@ -706,20 +749,24 @@ namespace std } private: - template<typename> friend class packaged_task; bool _M_satisfied() { return !static_cast<bool>(_M_storage); } - shared_ptr<_Future_state> _M_future; - typename _Future_ptr<_Future_result<_Result&>>::type _M_storage; }; - // specialization for promise<void> + /// Explicit specialization for promise<void> template<> class promise<void> { + template<typename> friend class packaged_task; + typedef __future_base::_State _State; + typedef __future_base::_Result<void> result_type; + + shared_ptr<__future_base::_State> _M_future; + typename __future_base::_Ptr<result_type>::type _M_storage; + public: promise() - : _M_future(std::make_shared<_Future_state>()), - _M_storage(new _Future_result<void>()) + : _M_future(std::make_shared<_State>()), + _M_storage(new result_type()) { } promise(promise&& __rhs) @@ -744,7 +791,7 @@ namespace std _M_future->_M_break_promise(std::move(_M_storage)); } - // assignment + // Assignment promise& operator=(promise&& __rhs) { @@ -761,12 +808,12 @@ namespace std _M_storage.swap(__rhs._M_storage); } - // retrieving the result + // Retrieving the result unique_future<void> get_future() { return unique_future<void>(_M_future); } - // setting the result + // Setting the result void set_value() { @@ -782,53 +829,54 @@ namespace std } private: - template<typename> friend class packaged_task; bool _M_satisfied() { return !static_cast<bool>(_M_storage); } - shared_ptr<_Future_state> _M_future; - _Future_ptr<_Future_result<void>>::type _M_storage; }; // TODO: requires allocator concepts /* - template<typename _Result, class Alloc> - concept_map UsesAllocator<promise<_Result>, Alloc> + template<typename _Res, class Alloc> + concept_map UsesAllocator<promise<_Res>, Alloc> { typedef Alloc allocator_type; } */ - - template<typename _Result, typename... _ArgTypes> + /// Primary template. + template<typename _Res, typename... _ArgTypes> struct _Run_task { static void - _S_run(promise<_Result>& __p, function<_Result(_ArgTypes...)>& __f, - _ArgTypes... __args) + _S_run(promise<_Res>& __p, function<_Res(_ArgTypes...)>& __f, + _ArgTypes... __args) { __p.set_value(__f(std::forward<_ArgTypes>(__args)...)); } }; - // specialization used by packaged_task<void(...)> + /// Specialization used by packaged_task<void(...)> template<typename... _ArgTypes> struct _Run_task<void, _ArgTypes...> { static void _S_run(promise<void>& __p, function<void(_ArgTypes...)>& __f, - _ArgTypes... __args) + _ArgTypes... __args) { __f(std::forward<_ArgTypes>(__args)...); __p.set_value(); } }; + /// packaged_task - template<typename _Result, typename... _ArgTypes> - class packaged_task<_Result(_ArgTypes...)> + template<typename _Res, typename... _ArgTypes> + class packaged_task<_Res(_ArgTypes...)> { + function<_Res(_ArgTypes...)> _M_task; + promise<_Res> _M_promise; + public: - typedef _Result result_type; + typedef _Res result_type; - // construction and destruction + // Construction and destruction packaged_task() { } template<typename _Fn> @@ -840,7 +888,7 @@ namespace std packaged_task(_Fn&& __fn) : _M_task(std::move(__fn)) { } explicit - packaged_task(_Result(*__fn)(_ArgTypes...)) : _M_task(__fn) { } + packaged_task(_Res(*__fn)(_ArgTypes...)) : _M_task(__fn) { } // TODO: requires allocator concepts /* @@ -859,11 +907,11 @@ namespace std ~packaged_task() = default; - // no copy + // No copy packaged_task(packaged_task&) = delete; packaged_task& operator=(packaged_task&) = delete; - // move support + // Move support packaged_task(packaged_task&& __other) { this->swap(__other); } @@ -882,8 +930,8 @@ namespace std explicit operator bool() const { return static_cast<bool>(_M_task); } - // result retrieval - unique_future<_Result> + // Result retrieval + unique_future<_Res> get_future() { __try @@ -900,7 +948,7 @@ namespace std } } - // execution + // Execution void operator()(_ArgTypes... __args) { @@ -915,7 +963,7 @@ namespace std __try { - _Run_task<_Result, _ArgTypes...>::_S_run(_M_promise, _M_task, + _Run_task<_Res, _ArgTypes...>::_S_run(_M_promise, _M_task, std::forward<_ArgTypes>(__args)...); } __catch (...) @@ -924,11 +972,7 @@ namespace std } } - void reset() { promise<_Result>().swap(_M_promise); } - - private: - function<_Result(_ArgTypes...)> _M_task; - promise<_Result> _M_promise; + void reset() { promise<_Res>().swap(_M_promise); } }; #endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1 diff --git a/libstdc++-v3/testsuite/30_threads/packaged_task/cons/assign_neg.cc b/libstdc++-v3/testsuite/30_threads/packaged_task/cons/assign_neg.cc index 588a27e0dde..db3baf35772 100644 --- a/libstdc++-v3/testsuite/30_threads/packaged_task/cons/assign_neg.cc +++ b/libstdc++-v3/testsuite/30_threads/packaged_task/cons/assign_neg.cc @@ -33,4 +33,4 @@ void test01() } // { dg-error "used here" "" { target *-*-* } 32 } -// { dg-error "deleted function" "" { target *-*-* } 864 } +// { dg-error "deleted function" "" { target *-*-* } 912 } diff --git a/libstdc++-v3/testsuite/30_threads/packaged_task/cons/copy_neg.cc b/libstdc++-v3/testsuite/30_threads/packaged_task/cons/copy_neg.cc index d0d0622cf59..8e57d3198f4 100644 --- a/libstdc++-v3/testsuite/30_threads/packaged_task/cons/copy_neg.cc +++ b/libstdc++-v3/testsuite/30_threads/packaged_task/cons/copy_neg.cc @@ -32,4 +32,4 @@ void test01() } // { dg-error "used here" "" { target *-*-* } 31 } -// { dg-error "deleted function" "" { target *-*-* } 863 } +// { dg-error "deleted function" "" { target *-*-* } 911 } diff --git a/libstdc++-v3/testsuite/30_threads/promise/cons/assign_neg.cc b/libstdc++-v3/testsuite/30_threads/promise/cons/assign_neg.cc index b97d3ba896e..5e16d145ccc 100644 --- a/libstdc++-v3/testsuite/30_threads/promise/cons/assign_neg.cc +++ b/libstdc++-v3/testsuite/30_threads/promise/cons/assign_neg.cc @@ -33,4 +33,4 @@ void test01() } // { dg-error "used here" "" { target *-*-* } 32 } -// { dg-error "deleted function" "" { target *-*-* } 590 } +// { dg-error "deleted function" "" { target *-*-* } 630 } diff --git a/libstdc++-v3/testsuite/30_threads/promise/cons/copy_neg.cc b/libstdc++-v3/testsuite/30_threads/promise/cons/copy_neg.cc index f94cffb09f3..1e857977927 100644 --- a/libstdc++-v3/testsuite/30_threads/promise/cons/copy_neg.cc +++ b/libstdc++-v3/testsuite/30_threads/promise/cons/copy_neg.cc @@ -32,4 +32,4 @@ void test01() } // { dg-error "used here" "" { target *-*-* } 31 } -// { dg-error "deleted function" "" { target *-*-* } 574 } +// { dg-error "deleted function" "" { target *-*-* } 614 } diff --git a/libstdc++-v3/testsuite/30_threads/shared_future/cons/assign_neg.cc b/libstdc++-v3/testsuite/30_threads/shared_future/cons/assign_neg.cc index 61563e3e3ab..26211fe1c76 100644 --- a/libstdc++-v3/testsuite/30_threads/shared_future/cons/assign_neg.cc +++ b/libstdc++-v3/testsuite/30_threads/shared_future/cons/assign_neg.cc @@ -35,4 +35,4 @@ void test01() } // { dg-error "used here" "" { target *-*-* } 34 } -// { dg-error "deleted function" "" { target *-*-* } 483 } +// { dg-error "deleted function" "" { target *-*-* } 514 } diff --git a/libstdc++-v3/testsuite/30_threads/unique_future/cons/assign_neg.cc b/libstdc++-v3/testsuite/30_threads/unique_future/cons/assign_neg.cc index 9783124d2cb..e29148ee785 100644 --- a/libstdc++-v3/testsuite/30_threads/unique_future/cons/assign_neg.cc +++ b/libstdc++-v3/testsuite/30_threads/unique_future/cons/assign_neg.cc @@ -35,4 +35,4 @@ void test01() } // { dg-error "used here" "" { target *-*-* } 34 } -// { dg-error "deleted function" "" { target *-*-* } 403 } +// { dg-error "deleted function" "" { target *-*-* } 440 } diff --git a/libstdc++-v3/testsuite/30_threads/unique_future/cons/copy_neg.cc b/libstdc++-v3/testsuite/30_threads/unique_future/cons/copy_neg.cc index 4b598997522..8134c7d9219 100644 --- a/libstdc++-v3/testsuite/30_threads/unique_future/cons/copy_neg.cc +++ b/libstdc++-v3/testsuite/30_threads/unique_future/cons/copy_neg.cc @@ -34,4 +34,4 @@ void test01() } // { dg-error "used here" "" { target *-*-* } 33 } -// { dg-error "deleted function" "" { target *-*-* } 402 } +// { dg-error "deleted function" "" { target *-*-* } 439 } |