From b3eed6fe78a26e3d93e9755ee908cebd10e8ac7d Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Thu, 21 Jan 2010 00:01:47 +0000 Subject: [PATCH] re PR libstdc++/42201 ([C++0x] std::vector>::push_back fails) 2010-01-21 Jonathan Wakely PR libstdc++/42201 * include/std/future: Update to latest WP. * src/functexcept.cc (__throw_future_error): Use make_error_code. * testsuite/30_threads/async/any.cc: New. * testsuite/30_threads/async/async.cc: New. * testsuite/30_threads/async/sync.cc: New. * testsuite/30_threads/packaged_task/cons/alloc.cc: New. * testsuite/30_threads/packaged_task/cons/assign_neg.cc: Adjust. * testsuite/30_threads/packaged_task/cons/copy_neg.cc: Adjust. * testsuite/30_threads/packaged_task/members/get_future.cc: Adjust. * testsuite/30_threads/packaged_task/members/get_future2.cc: Likewise. * testsuite/30_threads/packaged_task/members/invoke.cc: Adjust. * testsuite/30_threads/packaged_task/members/invoke2.cc: Adjust. * testsuite/30_threads/packaged_task/members/invoke3.cc: Adjust. * testsuite/30_threads/packaged_task/members/invoke4.cc: Adjust. * testsuite/30_threads/packaged_task/members/reset.cc: Adjust. * testsuite/30_threads/packaged_task/members/reset2.cc: Adjust. * testsuite/30_threads/shared_future/cons/assign_neg.cc: Remove. * testsuite/30_threads/shared_future/cons/default_neg.cc: Remove. * testsuite/30_threads/shared_future/cons/default.cc: New. * testsuite/30_threads/shared_future/cons/assign.cc: New. * testsuite/30_threads/shared_future/cons/copy.cc: Adjust. * testsuite/30_threads/shared_future/cons/move.cc: Adjust. * testsuite/30_threads/shared_future/cons/move_assign.cc: New. * testsuite/30_threads/shared_future/members/is_ready.cc: Remove. * testsuite/30_threads/shared_future/members/has_value.cc: Remove. * testsuite/30_threads/shared_future/members/has_exception.cc: Remove. * testsuite/30_threads/shared_future/members/valid.cc: New. * testsuite/30_threads/unique_future/cons/default_neg.cc: Remove. * testsuite/30_threads/unique_future/cons/default.cc: New. * testsuite/30_threads/unique_future/cons/move_assign.cc: New. * testsuite/30_threads/unique_future/cons/assign_neg.cc: Adjust. * testsuite/30_threads/unique_future/cons/copy_neg.cc: Adjust. * testsuite/30_threads/unique_future/cons/move.cc: Adjust. * testsuite/30_threads/unique_future/requirements/ explicit_instantiation.cc: Adjust. * testsuite/30_threads/unique_future/members/is_ready.cc: Remove. * testsuite/30_threads/unique_future/members/has_value.cc: Remove. * testsuite/30_threads/unique_future/members/has_exception.cc: Remove. * testsuite/30_threads/unique_future/members/valid.cc: New. * testsuite/30_threads/unique_future/members/get.cc: Adjust. * testsuite/30_threads/unique_future/members/get2.cc: Adjust. * testsuite/30_threads/unique_future/members/wait.cc: Adjust. * testsuite/30_threads/unique_future/members/wait_for.cc: Adjust. * testsuite/30_threads/unique_future/members/wait_until.cc: Adjust. * testsuite/30_threads/headers/future/types_std_c++0x.cc: Adjust. * testsuite/30_threads/promise/cons/alloc.cc: New. * testsuite/30_threads/promise/cons/assign_neg.cc: Adjust. * testsuite/30_threads/promise/cons/copy_neg.cc: Adjust. * testsuite/30_threads/promise/cons/move.cc: Adjust. * testsuite/30_threads/promise/cons/move_assign.cc: Adjust. * testsuite/30_threads/promise/members/get_future.cc: Adjust. * testsuite/30_threads/promise/members/set_value.cc: Adjust. * testsuite/30_threads/promise/members/set_exception.cc: Adjust. * testsuite/30_threads/promise/members/set_exception2.cc: Adjust. * testsuite/30_threads/promise/members/set_value2.cc: Adjust. * testsuite/30_threads/promise/members/set_value3.cc: Adjust. * testsuite/30_threads/promise/members/swap.cc: Adjust. From-SVN: r156097 --- libstdc++-v3/ChangeLog | 61 ++ libstdc++-v3/include/std/future | 861 +++++++++++++----- libstdc++-v3/src/functexcept.cc | 2 +- .../members/has_exception.cc => async/any.cc} | 40 +- .../testsuite/30_threads/async/async.cc | 57 ++ .../members/is_ready.cc => async/sync.cc} | 20 +- .../headers/future/types_std_c++0x.cc | 8 +- .../30_threads/packaged_task/cons/alloc.cc | 52 ++ .../packaged_task/cons/assign_neg.cc | 2 +- .../30_threads/packaged_task/cons/copy_neg.cc | 2 +- .../packaged_task/members/get_future.cc | 5 +- .../packaged_task/members/get_future2.cc | 3 +- .../packaged_task/members/invoke.cc | 4 +- .../packaged_task/members/invoke2.cc | 3 +- .../packaged_task/members/invoke3.cc | 3 +- .../packaged_task/members/invoke4.cc | 11 +- .../30_threads/packaged_task/members/reset.cc | 6 +- .../packaged_task/members/reset2.cc | 13 +- .../30_threads/promise/cons/alloc.cc | 47 + .../30_threads/promise/cons/assign_neg.cc | 2 +- .../30_threads/promise/cons/copy_neg.cc | 2 +- .../testsuite/30_threads/promise/cons/move.cc | 2 +- .../30_threads/promise/cons/move_assign.cc | 2 +- .../30_threads/promise/members/get_future.cc | 4 +- .../promise/members/set_exception.cc | 18 +- .../promise/members/set_exception2.cc | 6 +- .../30_threads/promise/members/set_value.cc | 21 +- .../30_threads/promise/members/set_value2.cc | 9 +- .../30_threads/promise/members/set_value3.cc | 12 +- .../30_threads/promise/members/swap.cc | 4 +- .../cons/{assign_neg.cc => assign.cc} | 20 +- .../30_threads/shared_future/cons/copy.cc | 2 +- .../cons/{default_neg.cc => default.cc} | 22 +- .../30_threads/shared_future/cons/move.cc | 4 +- .../shared_future/cons/move_assign.cc | 43 + .../shared_future/members/has_exception.cc | 70 -- .../shared_future/members/has_value.cc | 70 -- .../members/valid.cc} | 36 +- .../unique_future/cons/assign_neg.cc | 8 +- .../30_threads/unique_future/cons/copy_neg.cc | 8 +- .../cons/{default_neg.cc => default.cc} | 24 +- .../30_threads/unique_future/cons/move.cc | 4 +- .../unique_future/cons/move_assign.cc | 43 + .../30_threads/unique_future/members/get.cc | 9 +- .../30_threads/unique_future/members/get2.cc | 9 +- .../members/valid.cc} | 21 +- .../30_threads/unique_future/members/wait.cc | 4 +- .../unique_future/members/wait_for.cc | 2 +- .../unique_future/members/wait_until.cc | 2 +- .../requirements/explicit_instantiation.cc | 12 +- 50 files changed, 1141 insertions(+), 554 deletions(-) rename libstdc++-v3/testsuite/30_threads/{unique_future/members/has_exception.cc => async/any.cc} (74%) create mode 100644 libstdc++-v3/testsuite/30_threads/async/async.cc rename libstdc++-v3/testsuite/30_threads/{unique_future/members/is_ready.cc => async/sync.cc} (79%) create mode 100644 libstdc++-v3/testsuite/30_threads/packaged_task/cons/alloc.cc create mode 100644 libstdc++-v3/testsuite/30_threads/promise/cons/alloc.cc rename libstdc++-v3/testsuite/30_threads/shared_future/cons/{assign_neg.cc => assign.cc} (74%) rename libstdc++-v3/testsuite/30_threads/shared_future/cons/{default_neg.cc => default.cc} (67%) create mode 100644 libstdc++-v3/testsuite/30_threads/shared_future/cons/move_assign.cc delete mode 100644 libstdc++-v3/testsuite/30_threads/shared_future/members/has_exception.cc delete mode 100644 libstdc++-v3/testsuite/30_threads/shared_future/members/has_value.cc rename libstdc++-v3/testsuite/30_threads/{unique_future/members/has_value.cc => shared_future/members/valid.cc} (77%) rename libstdc++-v3/testsuite/30_threads/unique_future/cons/{default_neg.cc => default.cc} (65%) create mode 100644 libstdc++-v3/testsuite/30_threads/unique_future/cons/move_assign.cc rename libstdc++-v3/testsuite/30_threads/{shared_future/members/is_ready.cc => unique_future/members/valid.cc} (84%) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index d7661bb0204..c0558f86d26 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,64 @@ +2010-01-21 Jonathan Wakely + + PR libstdc++/42201 + * include/std/future: Update to latest WP. + * src/functexcept.cc (__throw_future_error): Use make_error_code. + * testsuite/30_threads/async/any.cc: New. + * testsuite/30_threads/async/async.cc: New. + * testsuite/30_threads/async/sync.cc: New. + * testsuite/30_threads/packaged_task/cons/alloc.cc: New. + * testsuite/30_threads/packaged_task/cons/assign_neg.cc: Adjust. + * testsuite/30_threads/packaged_task/cons/copy_neg.cc: Adjust. + * testsuite/30_threads/packaged_task/members/get_future.cc: Adjust. + * testsuite/30_threads/packaged_task/members/get_future2.cc: Likewise. + * testsuite/30_threads/packaged_task/members/invoke.cc: Adjust. + * testsuite/30_threads/packaged_task/members/invoke2.cc: Adjust. + * testsuite/30_threads/packaged_task/members/invoke3.cc: Adjust. + * testsuite/30_threads/packaged_task/members/invoke4.cc: Adjust. + * testsuite/30_threads/packaged_task/members/reset.cc: Adjust. + * testsuite/30_threads/packaged_task/members/reset2.cc: Adjust. + * testsuite/30_threads/shared_future/cons/assign_neg.cc: Remove. + * testsuite/30_threads/shared_future/cons/default_neg.cc: Remove. + * testsuite/30_threads/shared_future/cons/default.cc: New. + * testsuite/30_threads/shared_future/cons/assign.cc: New. + * testsuite/30_threads/shared_future/cons/copy.cc: Adjust. + * testsuite/30_threads/shared_future/cons/move.cc: Adjust. + * testsuite/30_threads/shared_future/cons/move_assign.cc: New. + * testsuite/30_threads/shared_future/members/is_ready.cc: Remove. + * testsuite/30_threads/shared_future/members/has_value.cc: Remove. + * testsuite/30_threads/shared_future/members/has_exception.cc: Remove. + * testsuite/30_threads/shared_future/members/valid.cc: New. + * testsuite/30_threads/unique_future/cons/default_neg.cc: Remove. + * testsuite/30_threads/unique_future/cons/default.cc: New. + * testsuite/30_threads/unique_future/cons/move_assign.cc: New. + * testsuite/30_threads/unique_future/cons/assign_neg.cc: Adjust. + * testsuite/30_threads/unique_future/cons/copy_neg.cc: Adjust. + * testsuite/30_threads/unique_future/cons/move.cc: Adjust. + * testsuite/30_threads/unique_future/requirements/ + explicit_instantiation.cc: Adjust. + * testsuite/30_threads/unique_future/members/is_ready.cc: Remove. + * testsuite/30_threads/unique_future/members/has_value.cc: Remove. + * testsuite/30_threads/unique_future/members/has_exception.cc: Remove. + * testsuite/30_threads/unique_future/members/valid.cc: New. + * testsuite/30_threads/unique_future/members/get.cc: Adjust. + * testsuite/30_threads/unique_future/members/get2.cc: Adjust. + * testsuite/30_threads/unique_future/members/wait.cc: Adjust. + * testsuite/30_threads/unique_future/members/wait_for.cc: Adjust. + * testsuite/30_threads/unique_future/members/wait_until.cc: Adjust. + * testsuite/30_threads/headers/future/types_std_c++0x.cc: Adjust. + * testsuite/30_threads/promise/cons/alloc.cc: New. + * testsuite/30_threads/promise/cons/assign_neg.cc: Adjust. + * testsuite/30_threads/promise/cons/copy_neg.cc: Adjust. + * testsuite/30_threads/promise/cons/move.cc: Adjust. + * testsuite/30_threads/promise/cons/move_assign.cc: Adjust. + * testsuite/30_threads/promise/members/get_future.cc: Adjust. + * testsuite/30_threads/promise/members/set_value.cc: Adjust. + * testsuite/30_threads/promise/members/set_exception.cc: Adjust. + * testsuite/30_threads/promise/members/set_exception2.cc: Adjust. + * testsuite/30_threads/promise/members/set_value2.cc: Adjust. + * testsuite/30_threads/promise/members/set_value3.cc: Adjust. + * testsuite/30_threads/promise/members/swap.cc: Adjust. + 2010-01-20 Janis Johnson Paolo Carlini diff --git a/libstdc++-v3/include/std/future b/libstdc++-v3/include/std/future index 44f2ec83e58..629d61aec22 100644 --- a/libstdc++-v3/include/std/future +++ b/libstdc++-v3/include/std/future @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -56,10 +57,13 @@ namespace std /// Error code for futures enum class future_errc - { broken_promise, future_already_retrieved, promise_already_satisfied }; + { + broken_promise, + future_already_retrieved, + promise_already_satisfied, + no_state + }; - // TODO: requires concepts - // concept_map ErrorCodeEnum { } template<> struct is_error_code_enum : public true_type { }; @@ -83,8 +87,8 @@ namespace std error_code _M_code; public: - explicit future_error(future_errc __ec) - : logic_error("std::future_error"), _M_code(make_error_code(__ec)) + explicit future_error(error_code __ec) + : logic_error("std::future_error"), _M_code(__ec) { } virtual ~future_error() throw(); @@ -98,17 +102,30 @@ namespace std // Forward declarations. template - class unique_future; + class future; template class shared_future; - template + template + class atomic_future; + + template class packaged_task; template class promise; + enum class launch { any, async, sync }; + + template + future + async(launch __policy, _Fn&& __fn, _Args&&... __args); + + template + future + async(_Fn&& __fn, _Args&&... __args); + #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) \ && defined(_GLIBCXX_ATOMIC_BUILTINS_4) @@ -124,9 +141,7 @@ namespace std _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 + // _M_destroy() allows derived classes to control deallocation virtual void _M_destroy() = 0; struct _Deleter @@ -183,7 +198,6 @@ namespace std void* _M_addr() { return static_cast(&_M_storage); } }; - // TODO: use template alias when available /* template @@ -196,6 +210,50 @@ namespace std typedef unique_ptr<_Res, _Result_base::_Deleter> type; }; + // TODO: use when allocator_arg_t available + /* + /// Result_alloc. + template + struct _Result_alloc : _Result<_Res> + { + typedef typename _Alloc::template rebind<_Result_alloc>::other + __allocator_type; + + explicit + _Result_alloc(const _Alloc& __a) : _Result<_Res>(), _M_alloc(__a) + { } + + private: + void _M_destroy() + { + __allocator_type __a(_M_alloc); + __a.destroy(this); + __a.deallocate(this, 1); + } + + __allocator_type _M_alloc; + }; + + template + static typename _Ptr<_Result_alloc<_Res, _Allocator>>::type + _S_allocate_result(const _Allocator& __a) + { + typedef _Result_alloc<_Res, _Allocator> __result_type; + typename __result_type::__allocator_type __a2(__a); + __result_type* __p = __a2.allocate(1); + __try + { + __a2.construct(__p, __a); + } + __catch(...) + { + __a2.deallocate(__p, 1); + __throw_exception_again; + } + return typename _Ptr<__result_type>::type(__p); + } + */ + /// Shared state between a promise and one or more associated futures. class _State @@ -206,6 +264,7 @@ namespace std mutex _M_mutex; condition_variable _M_cond; atomic_flag _M_retrieved; + once_flag _M_once; public: _State() : _M_result(), _M_retrieved(ATOMIC_FLAG_INIT) { } @@ -213,30 +272,13 @@ namespace std _State(const _State&) = delete; _State& operator=(const _State&) = delete; - bool - is_ready() - { return _M_get() != 0; } - - bool - has_exception() - { - _Result_base* const __res = _M_get(); - return __res && !(__res->_M_error == 0); - } - - bool - has_value() - { - _Result_base* const __res = _M_get(); - return __res && (__res->_M_error == 0); - } - _Result_base& wait() { + _M_run_deferred(); unique_lock __lock(_M_mutex); if (!_M_ready()) - _M_cond.wait(__lock, std::bind(&_State::_M_ready, this)); + _M_cond.wait(__lock, std::bind(&_State::_M_ready, this)); return *_M_result; } @@ -245,7 +287,7 @@ namespace std wait_for(const chrono::duration<_Rep, _Period>& __rel) { unique_lock __lock(_M_mutex); - auto __bound = std::bind(&_State::_M_ready, this); + auto __bound = std::bind(&_State::_M_ready, this); return _M_ready() || _M_cond.wait_for(__lock, __rel, __bound); } @@ -254,20 +296,20 @@ namespace std wait_until(const chrono::time_point<_Clock, _Duration>& __abs) { unique_lock __lock(_M_mutex); - auto __bound = std::bind(&_State::_M_ready, this); + auto __bound = std::bind(&_State::_M_ready, this); return _M_ready() || _M_cond.wait_until(__lock, __abs, __bound); } void - _M_set_result(_Ptr_type __res) + _M_set_result(function<_Ptr_type()> __res, bool __ignore_failure = false) { - { - lock_guard __lock(_M_mutex); - if (_M_ready()) - __throw_future_error(int(future_errc::promise_already_satisfied)); - _M_result.swap(__res); - } - _M_cond.notify_all(); + bool __set = __ignore_failure; + // all calls to this function are serialized, + // side-effects of invoking __res only happen once + call_once(_M_once, mem_fn(&_State::_M_do_set), this, ref(__res), + ref(__set)); + if (!__set) + __throw_future_error(int(future_errc::promise_already_satisfied)); } void @@ -275,7 +317,7 @@ namespace std { if (static_cast(__res)) { - future_errc __ec(future_errc::broken_promise); // XXX + error_code __ec(make_error_code(future_errc::broken_promise)); __res->_M_error = copy_exception(future_error(__ec)); { lock_guard __lock(_M_mutex); @@ -285,7 +327,7 @@ namespace std } } - // Called when this object is passed to a unique_future. + // Called when this object is passed to a future. void _M_set_retrieved_flag() { @@ -293,16 +335,114 @@ namespace std __throw_future_error(int(future_errc::future_already_retrieved)); } + template + struct _Setter; + + // set lvalues + template + struct _Setter<_Res, _Arg&> + { + // check this is only used by promise::set_value(const R&) + // or promise::set_value(R&) + static_assert(is_same<_Res, _Arg&>::value // promise + || is_same::value, // promise + "Invalid specialisation"); + + typename promise<_Res>::_Ptr_type operator()() + { + _State::_S_check(_M_promise->_M_future); + _M_promise->_M_storage->_M_set(_M_arg); + return std::move(_M_promise->_M_storage); + } + promise<_Res>* _M_promise; + _Arg& _M_arg; + }; + + // set rvalues + template + struct _Setter<_Res, _Res&&> + { + typename promise<_Res>::_Ptr_type operator()() + { + _State::_S_check(_M_promise->_M_future); + _M_promise->_M_storage->_M_set(std::move(_M_arg)); + return std::move(_M_promise->_M_storage); + } + promise<_Res>* _M_promise; + _Res& _M_arg; + }; + + struct __exception_ptr_tag { }; + + // set exceptions + template + struct _Setter<_Res, __exception_ptr_tag> + { + typename promise<_Res>::_Ptr_type operator()() + { + _State::_S_check(_M_promise->_M_future); + _M_promise->_M_storage->_M_error = _M_ex; + return std::move(_M_promise->_M_storage); + } + + promise<_Res>* _M_promise; + exception_ptr& _M_ex; + }; + + template + static _Setter<_Res, _Arg&&> + __setter(promise<_Res>* __prom, _Arg&& __arg) + { + return _Setter<_Res, _Arg&&>{ __prom, __arg }; + } + + template + static _Setter<_Res, __exception_ptr_tag> + __setter(exception_ptr& __ex, promise<_Res>* __prom) + { + return _Setter<_Res, __exception_ptr_tag>{ __prom, __ex }; + } + + static _Setter + __setter(promise* __prom); + + template + static bool + _S_check(const shared_ptr<_Tp>& __p) + { + if (!static_cast(__p)) + __throw_future_error((int)future_errc::no_state); + } + private: - _Result_base* - _M_get() + void + _M_do_set(function<_Ptr_type()>& __f, bool& __set) { - lock_guard __lock(_M_mutex); - return _M_result.get(); + _Ptr_type __res = __f(); + { + lock_guard __lock(_M_mutex); + _M_result.swap(__res); + } + _M_cond.notify_all(); + __set = true; } bool _M_ready() const { return static_cast(_M_result); } + + virtual void _M_run_deferred() { } }; + + template + class _Deferred_state; + + template + class _Async_state; + + template + class _Task_state; + + template + struct _Task_setter; }; inline __future_base::_Result_base::~_Result_base() = default; @@ -313,9 +453,13 @@ namespace std { _Result() : _M_value_ptr() { } + void _M_set(_Res& __res) { _M_value_ptr = &__res; } + + _Res& _M_get() { return *_M_value_ptr; } + + private: _Res* _M_value_ptr; - private: void _M_destroy() { delete this; } }; @@ -328,7 +472,7 @@ namespace std }; - /// Common implementation for unique_future and shared_future. + /// Common implementation for future and shared_future. template class __basic_future : public __future_base { @@ -344,134 +488,190 @@ namespace std __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(); } - - bool - has_exception() const { return this->_M_state->has_exception(); } - - bool - has_value() const { return this->_M_state->has_value(); } + valid() const { return static_cast(_M_state); } void - wait() const { this->_M_state->wait(); } + wait() const { _M_state->wait(); } template bool wait_for(const chrono::duration<_Rep, _Period>& __rel) const - { return this->_M_state->wait_for(__rel); } + { return _M_state->wait_for(__rel); } template bool wait_until(const chrono::time_point<_Clock, _Duration>& __abs) const - { return this->_M_state->wait_until(__abs); } + { return _M_state->wait_until(__abs); } protected: /// Wait for the state to be ready and rethrow any stored exception __result_type _M_get_result() { - _Result_base& __res = this->_M_state->wait(); + _Result_base& __res = _M_state->wait(); if (!(__res._M_error == 0)) rethrow_exception(__res._M_error); return static_cast<__result_type>(__res); } - // Construction of a unique_future by promise::get_future() + void _M_swap(__basic_future& __that) + { + _M_state.swap(__that._M_state); + } + + // Construction of a future by promise::get_future() explicit __basic_future(const __state_type& __state) : _M_state(__state) { - if (static_cast(this->_M_state)) - this->_M_state->_M_set_retrieved_flag(); - else - __throw_future_error(int(future_errc::future_already_retrieved)); + _State::_S_check(_M_state); + _M_state->_M_set_retrieved_flag(); } // Copy construction from a shared_future explicit __basic_future(const shared_future<_Res>&); - // Move construction from a unique_future + // Move construction from a shared_future explicit - __basic_future(unique_future<_Res>&&); + __basic_future(shared_future<_Res>&&); + + // Move construction from a future + explicit + __basic_future(future<_Res>&&); + + __basic_future() { } + + struct _Reset + { + explicit _Reset(__basic_future& __fut) : _M_fut(__fut) { } + ~_Reset() { _M_fut._M_state.reset(); } + __basic_future& _M_fut; + }; }; - /// Primary template for unique_future. + /// Primary template for future. template - class unique_future : public __basic_future<_Res> + class future : public __basic_future<_Res> { friend class promise<_Res>; + template friend class packaged_task; + template + friend future + async(launch, _Fn&&, _Args&&...); typedef __basic_future<_Res> _Base_type; typedef typename _Base_type::__state_type __state_type; explicit - unique_future(const __state_type& __state) : _Base_type(__state) { } + future(const __state_type& __state) : _Base_type(__state) { } public: + future() : _Base_type() { } + /// Move constructor - unique_future(unique_future&& __uf) : _Base_type(std::move(__uf)) { } + future(future&& __uf) : _Base_type(std::move(__uf)) { } // Disable copying - unique_future(const unique_future&) = delete; - unique_future& operator=(const unique_future&) = delete; + future(const future&) = delete; + future& operator=(const future&) = delete; + + future& operator=(future&& __fut) + { + future(std::move(__fut))._M_swap(*this); + return *this; + } /// Retrieving the value - _Res&& + _Res get() - { return std::move(this->_M_get_result()._M_value()); } + { + typename _Base_type::_Reset __reset(*this); + return std::move(this->_M_get_result()._M_value()); + } }; - /// Partial specialization for unique_future + /// Partial specialization for future template - class unique_future<_Res&> : public __basic_future<_Res&> + class future<_Res&> : public __basic_future<_Res&> { friend class promise<_Res&>; + template friend class packaged_task; + template + friend future + async(launch, _Fn&&, _Args&&...); typedef __basic_future<_Res&> _Base_type; typedef typename _Base_type::__state_type __state_type; explicit - unique_future(const __state_type& __state) : _Base_type(__state) { } + future(const __state_type& __state) : _Base_type(__state) { } public: + future() : _Base_type() { } + /// Move constructor - unique_future(unique_future&& __uf) : _Base_type(std::move(__uf)) { } + future(future&& __uf) : _Base_type(std::move(__uf)) { } // Disable copying - unique_future(const unique_future&) = delete; - unique_future& operator=(const unique_future&) = delete; + future(const future&) = delete; + future& operator=(const future&) = delete; + + future& operator=(future&& __fut) + { + future(std::move(__fut))._M_swap(*this); + return *this; + } /// Retrieving the value _Res& - get() { return *this->_M_get_result()._M_value_ptr; } + get() + { + typename _Base_type::_Reset __reset(*this); + return this->_M_get_result()._M_get(); + } }; - /// Explicit specialization for unique_future + /// Explicit specialization for future template<> - class unique_future : public __basic_future + class future : public __basic_future { friend class promise; + template friend class packaged_task; + template + friend future + async(launch, _Fn&&, _Args&&...); typedef __basic_future _Base_type; typedef typename _Base_type::__state_type __state_type; explicit - unique_future(const __state_type& __state) : _Base_type(__state) { } + future(const __state_type& __state) : _Base_type(__state) { } public: + future() : _Base_type() { } + /// Move constructor - unique_future(unique_future&& __uf) : _Base_type(std::move(__uf)) { } + future(future&& __uf) : _Base_type(std::move(__uf)) { } // Disable copying - unique_future(const unique_future&) = delete; - unique_future& operator=(const unique_future&) = delete; + future(const future&) = delete; + future& operator=(const future&) = delete; + + future& operator=(future&& __fut) + { + future(std::move(__fut))._M_swap(*this); + return *this; + } /// Retrieving the value void - get() { this->_M_get_result(); } + get() + { + typename _Base_type::_Reset __reset(*this); + this->_M_get_result(); + } }; @@ -482,20 +682,37 @@ namespace std typedef __basic_future<_Res> _Base_type; public: + shared_future() : _Base_type() { } + /// Copy constructor shared_future(const shared_future& __sf) : _Base_type(__sf) { } - /// Construct from a unique_future rvalue - shared_future(unique_future<_Res>&& __uf) + /// Construct from a future rvalue + shared_future(future<_Res>&& __uf) : _Base_type(std::move(__uf)) { } - shared_future& operator=(const shared_future&) = delete; + /// Construct from a shared_future rvalue + shared_future(shared_future&& __sf) + : _Base_type(std::move(__sf)) + { } + + shared_future& operator=(const shared_future& __sf) + { + shared_future(__sf)._M_swap(*this); + return *this; + } + + shared_future& operator=(shared_future&& __sf) + { + shared_future(std::move(__sf))._M_swap(*this); + return *this; + } /// Retrieving the value const _Res& get() - { + { typename _Base_type::__result_type __r = this->_M_get_result(); _Res& __rs(__r._M_value()); return __rs; @@ -509,19 +726,36 @@ namespace std typedef __basic_future<_Res&> _Base_type; public: + shared_future() : _Base_type() { } + /// Copy constructor shared_future(const shared_future& __sf) : _Base_type(__sf) { } - /// Construct from a unique_future rvalue - shared_future(unique_future<_Res&>&& __uf) + /// Construct from a future rvalue + shared_future(future<_Res&>&& __uf) : _Base_type(std::move(__uf)) { } - shared_future& operator=(const shared_future&) = delete; + /// Construct from a shared_future rvalue + shared_future(shared_future&& __sf) + : _Base_type(std::move(__sf)) + { } + + shared_future& operator=(const shared_future& __sf) + { + shared_future(__sf)._M_swap(*this); + return *this; + } + + shared_future& operator=(shared_future&& __sf) + { + shared_future(std::move(__sf))._M_swap(*this); + return *this; + } /// Retrieving the value _Res& - get() { return *this->_M_get_result()._M_value_ptr; } + get() { return this->_M_get_result()._M_get(); } }; /// Explicit specialization for shared_future @@ -531,15 +765,32 @@ namespace std typedef __basic_future _Base_type; public: + shared_future() : _Base_type() { } + /// Copy constructor shared_future(const shared_future& __sf) : _Base_type(__sf) { } - /// Construct from a unique_future rvalue - shared_future(unique_future&& __uf) + /// Construct from a future rvalue + shared_future(future&& __uf) : _Base_type(std::move(__uf)) { } - shared_future& operator=(const shared_future&) = delete; + /// Construct from a shared_future rvalue + shared_future(shared_future&& __sf) + : _Base_type(std::move(__sf)) + { } + + shared_future& operator=(const shared_future& __sf) + { + shared_future(__sf)._M_swap(*this); + return *this; + } + + shared_future& operator=(shared_future&& __sf) + { + shared_future(std::move(__sf))._M_swap(*this); + return *this; + } // Retrieving the value void @@ -553,7 +804,12 @@ namespace std { } template - __basic_future<_Res>::__basic_future(unique_future<_Res>&& __uf) + __basic_future<_Res>::__basic_future(shared_future<_Res>&& __sf) + : _M_state(std::move(__sf._M_state)) + { } + + template + __basic_future<_Res>::__basic_future(future<_Res>&& __uf) : _M_state(std::move(__uf._M_state)) { } @@ -562,17 +818,17 @@ namespace std template class promise { - template friend class packaged_task; - typedef __future_base::_State _State; - typedef __future_base::_Result<_Res> result_type; + typedef __future_base::_Result<_Res> _Res_type; + typedef typename __future_base::_Ptr<_Res_type>::type _Ptr_type; + template friend class _State::_Setter; shared_ptr<_State> _M_future; - typename __future_base::_Ptr::type _M_storage; + _Ptr_type _M_storage; public: promise() - : _M_future(std::make_shared<_State>()), _M_storage(new result_type()) + : _M_future(std::make_shared<_State>()), _M_storage(new _Res_type()) { } promise(promise&& __rhs) @@ -580,14 +836,14 @@ namespace std _M_storage(std::move(__rhs._M_storage)) { } - // TODO: requires allocator concepts + // TODO: needs allocator_arg_t /* template - promise(allocator_arg_t, const _Allocator& __a); - - template - promise(allocator_arg_t, const _Allocator&, promise&& __rhs); - */ + promise(allocator_arg_t, const _Allocator& __a) + : _M_future(std::allocate_shared<_State>(__a)), + _M_storage(__future_base::_S_allocate_result<_Res>(__a)) + { } + */ promise(const promise&) = delete; @@ -615,54 +871,48 @@ namespace std } // Retrieving the result - unique_future<_Res> + future<_Res> get_future() - { return unique_future<_Res>(_M_future); } + { return future<_Res>(_M_future); } // Setting the result void set_value(const _Res& __r) { - if (!_M_satisfied()) - _M_storage->_M_set(__r); - _M_future->_M_set_result(std::move(_M_storage)); + auto __setter = _State::__setter(this, __r); + _M_future->_M_set_result(std::move(__setter)); } void set_value(_Res&& __r) { - if (!_M_satisfied()) - _M_storage->_M_set(std::move(__r)); - _M_future->_M_set_result(std::move(_M_storage)); + auto __setter = _State::__setter(this, std::move(__r)); + _M_future->_M_set_result(std::move(__setter)); } void set_exception(exception_ptr __p) { - if (!_M_satisfied()) - _M_storage->_M_error = __p; - _M_future->_M_set_result(std::move(_M_storage)); + auto __setter = _State::__setter(__p, this); + _M_future->_M_set_result(std::move(__setter)); } - - private: - bool _M_satisfied() { return !static_cast(_M_storage); } }; /// Partial specialization for promise template class promise<_Res&> { - template friend class packaged_task; typedef __future_base::_State _State; - - typedef __future_base::_Result<_Res&> result_type; + typedef __future_base::_Result<_Res&> _Res_type; + typedef typename __future_base::_Ptr<_Res_type>::type _Ptr_type; + template friend class _State::_Setter; shared_ptr<_State> _M_future; - typename __future_base::_Ptr::type _M_storage; + _Ptr_type _M_storage; public: promise() - : _M_future(std::make_shared<_State>()), _M_storage(new result_type()) + : _M_future(std::make_shared<_State>()), _M_storage(new _Res_type()) { } promise(promise&& __rhs) @@ -670,14 +920,14 @@ namespace std _M_storage(std::move(__rhs._M_storage)) { } - // TODO: requires allocator concepts + // TODO: needs allocator_arg_t /* template - promise(allocator_arg_t, const _Allocator& __a); - - template - promise(allocator_arg_t, const _Allocator&, promise&& __rhs); - */ + promise(allocator_arg_t, const _Allocator& __a) + : _M_future(std::allocate_shared<_State>(__a)), + _M_storage(__future_base::_S_allocate_result<_Res&>(__a)) + { } + */ promise(const promise&) = delete; @@ -705,46 +955,42 @@ namespace std } // Retrieving the result - unique_future<_Res&> + future<_Res&> get_future() - { return unique_future<_Res&>(_M_future); } + { return future<_Res&>(_M_future); } // Setting the result void set_value(_Res& __r) { - if (!_M_satisfied()) - _M_storage->_M_value_ptr = &__r; - _M_future->_M_set_result(std::move(_M_storage)); + auto __setter = _State::__setter(this, __r); + _M_future->_M_set_result(std::move(__setter)); } void set_exception(exception_ptr __p) { - if (!_M_satisfied()) - _M_storage->_M_error = __p; - _M_future->_M_set_result(std::move(_M_storage)); + auto __setter = _State::__setter(__p, this); + _M_future->_M_set_result(std::move(__setter)); } - - private: - bool _M_satisfied() { return !static_cast(_M_storage); } }; /// Explicit specialization for promise template<> class promise { - template friend class packaged_task; typedef __future_base::_State _State; - typedef __future_base::_Result result_type; + typedef __future_base::_Result _Res_type; + typedef typename __future_base::_Ptr<_Res_type>::type _Ptr_type; + template friend class _State::_Setter; - shared_ptr<__future_base::_State> _M_future; - typename __future_base::_Ptr::type _M_storage; + shared_ptr<_State> _M_future; + _Ptr_type _M_storage; public: promise() : _M_future(std::make_shared<_State>()), - _M_storage(new result_type()) + _M_storage(new _Res_type()) { } promise(promise&& __rhs) @@ -752,14 +998,15 @@ namespace std _M_storage(std::move(__rhs._M_storage)) { } - // TODO: requires allocator concepts + + // TODO: needs allocator_arg_t /* template - promise(allocator_arg_t, const _Allocator& __a); - - template - promise(allocator_arg_t, const _Allocator&, promise&& __rhs); - */ + promise(allocator_arg_t, const _Allocator& __a) + : _M_future(std::allocate_shared<_State>(__a)), + _M_storage(__future_base::_S_allocate_result(__a)) + { } + */ promise(const promise&) = delete; @@ -787,69 +1034,137 @@ namespace std } // Retrieving the result - unique_future + future get_future() - { return unique_future(_M_future); } + { return future(_M_future); } // Setting the result - void - set_value() - { - _M_future->_M_set_result(std::move(_M_storage)); - } + void set_value(); void set_exception(exception_ptr __p) { - if (!_M_satisfied()) - _M_storage->_M_error = __p; - _M_future->_M_set_result(std::move(_M_storage)); + auto __setter = _State::__setter(__p, this); + _M_future->_M_set_result(std::move(__setter)); } - - private: - bool _M_satisfied() { return !static_cast(_M_storage); } }; - // TODO: requires allocator concepts + // set void + template<> + struct __future_base::_State::_Setter + { + promise::_Ptr_type operator()() + { + _State::_S_check(_M_promise->_M_future); + return std::move(_M_promise->_M_storage); + } + + promise* _M_promise; + }; + + inline __future_base::_State::_Setter + __future_base::_State::__setter(promise* __prom) + { + return _Setter{ __prom }; + } + + inline void + promise::set_value() + { + auto __setter = _State::__setter(this); + _M_future->_M_set_result(std::move(__setter)); + } + + // TODO: needs allocators /* template - concept_map UsesAllocator, Alloc> + struct uses_allocator, Alloc> : true_type { }; + */ + + + template + struct __future_base::_Task_setter { - typedef Alloc allocator_type; - } - */ - /// Primary template. - template - struct _Run_task - { - static void - _S_run(promise<_Res>& __p, function<_Res(_ArgTypes...)>& __f, - _ArgTypes... __args) + typename _StateT::_Ptr_type operator()() { - __p.set_value(__f(std::forward<_ArgTypes>(__args)...)); + __try { + _M_state->_M_result->_M_set(_M_fn()); + } __catch(...) { + _M_state->_M_result->_M_error = current_exception(); + } + return std::move(_M_state->_M_result); } + _StateT* _M_state; + std::function<_Res()> _M_fn; }; - /// Specialization used by packaged_task - template - struct _Run_task + template + struct __future_base::_Task_setter<_StateT, void> { - static void - _S_run(promise& __p, function& __f, - _ArgTypes... __args) + typename _StateT::_Ptr_type operator()() { - __f(std::forward<_ArgTypes>(__args)...); - __p.set_value(); + __try { + _M_fn(); + } __catch(...) { + _M_state->_M_result->_M_error = current_exception(); + } + return std::move(_M_state->_M_result); } + _StateT* _M_state; + std::function _M_fn; }; + template + struct __future_base::_Task_state<_Res(_Args...)> : __future_base::_State + { + typedef _Res _Res_type; + + _Task_state(std::function<_Res(_Args...)> __task) + : _M_result(new _Result<_Res>()), _M_task(std::move(__task)) + { } + + // TODO: needs allocator_arg_t + /* + template + _Task_state(_Func&& __task, const _Alloc& __a) + : _M_result(_S_allocate_result<_Res>(__a)) + , _M_task(allocator_arg, __a, std::move(__task)) + { } + */ + + void + _M_run(_Args... __args) + { + // bound arguments decay so wrap lvalue references + auto __bound = std::bind<_Res>(_M_task, + _S_maybe_wrap_ref(std::forward<_Args>(__args))...); + _Task_setter<_Task_state> __setter{ this, std::move(__bound) }; + _M_set_result(std::move(__setter)); + } + + template friend class _Task_setter; + typedef typename __future_base::_Ptr<_Result<_Res>>::type _Ptr_type; + _Ptr_type _M_result; + std::function<_Res(_Args...)> _M_task; + + template + static reference_wrapper<_Tp> + _S_maybe_wrap_ref(_Tp& __t) + { return std::ref(__t); } + + template + static typename enable_if::value, + _Tp>::type&& + _S_maybe_wrap_ref(_Tp&& __t) + { return std::forward<_Tp>(__t); } + }; /// packaged_task template class packaged_task<_Res(_ArgTypes...)> { - function<_Res(_ArgTypes...)> _M_task; - promise<_Res> _M_promise; + typedef __future_base::_Task_state<_Res(_ArgTypes...)> _State_type; + shared_ptr<_State_type> _M_state; public: typedef _Res result_type; @@ -859,31 +1174,35 @@ namespace std template explicit - packaged_task(const _Fn& __fn) : _M_task(__fn) { } + packaged_task(const _Fn& __fn) + : _M_state(std::make_shared<_State_type>(__fn)) + { } template explicit - packaged_task(_Fn&& __fn) : _M_task(std::move(__fn)) { } + packaged_task(_Fn&& __fn) + : _M_state(std::make_shared<_State_type>(std::move(__fn))) + { } explicit - packaged_task(_Res(*__fn)(_ArgTypes...)) : _M_task(__fn) { } + packaged_task(_Res(*__fn)(_ArgTypes...)) + : _M_state(std::make_shared<_State_type>(__fn)) + { } - // TODO: requires allocator concepts + // TODO: needs allocator_arg_t /* template explicit packaged_task(allocator_arg_t __tag, const _Allocator& __a, _Fn __fn) - : _M_task(__tag, __a, __fn), _M_promise(__tag, __a) + : _M_state(std::allocate_shared<_State_type>(__a, std::move(__fn))) { } + */ - template - explicit - packaged_task(allocator_arg_t __tag, const _Allocator& __a, _Fn&& __fn) - : _M_task(__tag, __a, std::move(__fn)), _M_promise(__tag, __a) - { } - */ - - ~packaged_task() = default; + ~packaged_task() + { + if (static_cast(_M_state) && !_M_state.unique()) + _M_state->_M_break_promise(std::move(_M_state->_M_result)); + } // No copy packaged_task(packaged_task&) = delete; @@ -901,50 +1220,114 @@ namespace std void swap(packaged_task& __other) - { - _M_task.swap(__other._M_task); - _M_promise.swap(__other._M_promise); - } + { _M_state.swap(__other._M_state); } - explicit operator bool() const { return static_cast(_M_task); } + explicit operator bool() const { return static_cast(_M_state); } // Result retrieval - unique_future<_Res> + future<_Res> get_future() - { - __try - { - return _M_promise.get_future(); - } - __catch (const future_error& __e) - { - if (__e.code() == future_errc::future_already_retrieved) - __throw_bad_function_call(); - __throw_exception_again; - } - } + { return future<_Res>(_M_state); } // Execution void operator()(_ArgTypes... __args) { - if (!static_cast(_M_task) || _M_promise._M_satisfied()) - __throw_bad_function_call(); - - __try - { - _Run_task<_Res, _ArgTypes...>::_S_run(_M_promise, _M_task, - std::forward<_ArgTypes>(__args)...); - } - __catch (...) - { - _M_promise.set_exception(current_exception()); - } + __future_base::_State::_S_check(_M_state); + _M_state->_M_run(std::forward<_ArgTypes>(__args)...); } - void reset() { promise<_Res>().swap(_M_promise); } + void + reset() + { + __future_base::_State::_S_check(_M_state); + packaged_task(std::move(_M_state->_M_task)).swap(*this); + } }; + template + class __future_base::_Deferred_state : public __future_base::_State + { + public: + typedef _Res _Res_type; + + explicit + _Deferred_state(std::function<_Res()>&& __fn) + : _M_result(new _Result<_Res>()), _M_fn(std::move(__fn)) + { } + + private: + template friend class _Task_setter; + typedef typename __future_base::_Ptr<_Result<_Res>>::type _Ptr_type; + _Ptr_type _M_result; + std::function<_Res()> _M_fn; + + virtual void + _M_run_deferred() + { + _Task_setter<_Deferred_state> __setter{ this, _M_fn }; + // safe to call multiple times so ignore failure + _M_set_result(std::move(__setter), true); + } + }; + + template + class __future_base::_Async_state : public __future_base::_State + { + public: + typedef _Res _Res_type; + + explicit + _Async_state(std::function<_Res()>&& __fn) + : _M_result(new _Result<_Res>()), _M_fn(std::move(__fn)), + _M_thread(mem_fn(&_Async_state::_M_do_run), this) + { } + + ~_Async_state() { _M_thread.join(); } + + private: + void _M_do_run() + { + _Task_setter<_Async_state> __setter{ this, std::move(_M_fn) }; + _M_set_result(std::move(__setter)); + } + + template friend class _Task_setter; + typedef typename __future_base::_Ptr<_Result<_Res>>::type _Ptr_type; + _Ptr_type _M_result; + std::function<_Res()> _M_fn; + thread _M_thread; + }; + + template + future + async(launch __policy, _Fn&& __fn, _Args&&... __args) + { + typedef typename _Fn::result_type result_type; + std::shared_ptr<__future_base::_State> __state; + if (__policy == launch::async) + { + typedef typename __future_base::_Async_state _State; + __state = std::make_shared<_State>(std::bind( + std::forward<_Fn>(__fn), std::forward<_Args>(__args)...)); + } + else + { + typedef typename __future_base::_Deferred_state _State; + __state = std::make_shared<_State>(std::bind( + std::forward<_Fn>(__fn), std::forward<_Args>(__args)...)); + } + return future(__state); + } + + template + future + async(_Fn&& __fn, _Args&&... __args) + { + return async(launch::any, std::forward<_Fn>(__fn), + std::forward<_Args>(__args)...); + } + #endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1 // && _GLIBCXX_ATOMIC_BUILTINS_4 diff --git a/libstdc++-v3/src/functexcept.cc b/libstdc++-v3/src/functexcept.cc index d47eccbe11c..c5c3e37809e 100644 --- a/libstdc++-v3/src/functexcept.cc +++ b/libstdc++-v3/src/functexcept.cc @@ -103,7 +103,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) void __throw_future_error(int __i) - { throw future_error(future_errc(__i)); } + { throw future_error(make_error_code(future_errc(__i))); } void __throw_bad_function_call() diff --git a/libstdc++-v3/testsuite/30_threads/unique_future/members/has_exception.cc b/libstdc++-v3/testsuite/30_threads/async/any.cc similarity index 74% rename from libstdc++-v3/testsuite/30_threads/unique_future/members/has_exception.cc rename to libstdc++-v3/testsuite/30_threads/async/any.cc index 1d5baf88393..40c103f9601 100644 --- a/libstdc++-v3/testsuite/30_threads/unique_future/members/has_exception.cc +++ b/libstdc++-v3/testsuite/30_threads/async/any.cc @@ -6,7 +6,7 @@ // { dg-require-gthreads "" } // { dg-require-atomic-builtins "" } -// Copyright (C) 2009 Free Software Foundation, Inc. +// Copyright (C) 2010 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -27,38 +27,32 @@ #include #include +struct sum { + typedef int result_type; + int operator()(int i, int& j, const int& k) { return i + j + k; } +}; + void test01() { bool test __attribute__((unused)) = true; - std::promise p1; - std::unique_future f1(p1.get_future()); + using namespace std; - VERIFY( !f1.has_exception() ); + int a = 1; + int b = 10; + int c = 100; + future f1 = async(launch::any, sum(), a, ref(b), cref(c)); + future f2 = async(sum(), a, ref(b), cref(c)); - p1.set_exception(std::copy_exception(1)); - - VERIFY( f1.has_exception() ); -} - -void test02() -{ - bool test __attribute__((unused)) = true; - - std::promise p1; - std::unique_future f1(p1.get_future()); - - VERIFY( !f1.has_exception() ); - - p1.set_value(1); - - VERIFY( !f1.has_exception() ); + VERIFY( f1.valid() ); + VERIFY( f2.valid() ); + int r1 = f1.get(); + int r2 = f2.get(); + VERIFY( r1 == r2 ); } int main() { test01(); - test02(); - return 0; } diff --git a/libstdc++-v3/testsuite/30_threads/async/async.cc b/libstdc++-v3/testsuite/30_threads/async/async.cc new file mode 100644 index 00000000000..5335dfc57a6 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/async/async.cc @@ -0,0 +1,57 @@ +// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* alpha*-*-osf* mips-sgi-irix6* } } +// { dg-options " -std=gnu++0x -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* alpha*-*-osf* mips-sgi-irix6* } } +// { dg-options " -std=gnu++0x -pthreads" { target *-*-solaris* } } +// { dg-options " -std=gnu++0x " { target *-*-cygwin *-*-darwin* } } +// { dg-require-cstdint "" } +// { dg-require-gthreads "" } +// { dg-require-atomic-builtins "" } + +// Copyright (C) 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + + +#include +#include + +using namespace std; + +struct work { + typedef void result_type; + void operator()(mutex& m, condition_variable& cv) + { + unique_lock l(m); + cv.notify_one(); + } +}; + +void test01() +{ + bool test __attribute__((unused)) = true; + + mutex m; + condition_variable cv; + unique_lock l(m); + future f1 = async(launch::async, work(), ref(m), ref(cv)); + cv.wait(l); + f1.get(); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/30_threads/unique_future/members/is_ready.cc b/libstdc++-v3/testsuite/30_threads/async/sync.cc similarity index 79% rename from libstdc++-v3/testsuite/30_threads/unique_future/members/is_ready.cc rename to libstdc++-v3/testsuite/30_threads/async/sync.cc index 6f2b6885595..f1d13773773 100644 --- a/libstdc++-v3/testsuite/30_threads/unique_future/members/is_ready.cc +++ b/libstdc++-v3/testsuite/30_threads/async/sync.cc @@ -6,7 +6,7 @@ // { dg-require-gthreads "" } // { dg-require-atomic-builtins "" } -// Copyright (C) 2009 Free Software Foundation, Inc. +// Copyright (C) 2010 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -27,18 +27,24 @@ #include #include +struct sum { + typedef int result_type; + int operator()(int i, int& j, const int& k) { return i + j + k; } +}; + void test01() { bool test __attribute__((unused)) = true; - std::promise p1; - std::unique_future f1(p1.get_future()); + using namespace std; - VERIFY( !f1.is_ready() ); + int a = 1; + int b = 10; + int c = 100; + future f1 = async(launch::sync, sum(), a, ref(b), cref(c)); - p1.set_value(1); - - VERIFY( f1.is_ready() ); + VERIFY( f1.valid() ); + VERIFY( f1.get() == 111 ); } int main() diff --git a/libstdc++-v3/testsuite/30_threads/headers/future/types_std_c++0x.cc b/libstdc++-v3/testsuite/30_threads/headers/future/types_std_c++0x.cc index 16a54b4147a..fe040ec2ab2 100644 --- a/libstdc++-v3/testsuite/30_threads/headers/future/types_std_c++0x.cc +++ b/libstdc++-v3/testsuite/30_threads/headers/future/types_std_c++0x.cc @@ -31,9 +31,9 @@ void test01() typedef std::future_error error_t; - typedef std::unique_future uniq_t; - typedef std::unique_future uniqr_t; - typedef std::unique_future uniqv_t; + typedef std::future uniq_t; + typedef std::future uniqr_t; + typedef std::future uniqv_t; typedef std::shared_future shar_t; typedef std::shared_future sharr_t; @@ -46,4 +46,6 @@ void test01() typedef std::packaged_task ptask_t; typedef std::packaged_task ptaskr_t; typedef std::packaged_task ptaskv_t; + + using std::async; } diff --git a/libstdc++-v3/testsuite/30_threads/packaged_task/cons/alloc.cc b/libstdc++-v3/testsuite/30_threads/packaged_task/cons/alloc.cc new file mode 100644 index 00000000000..2565b61b24d --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/packaged_task/cons/alloc.cc @@ -0,0 +1,52 @@ +// { dg-do compile { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* alpha*-*-osf* mips-sgi-irix6* } } +// { dg-options " -std=gnu++0x -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* alpha*-*-osf* mips-sgi-irix6* } } +// { dg-options " -std=gnu++0x -pthreads" { target *-*-solaris* } } +// { dg-options " -std=gnu++0x " { target *-*-cygwin *-*-darwin* } } +// { dg-require-cstdint "" } +// { dg-require-gthreads "" } +// { dg-require-atomic-builtins "" } + +// Copyright (C) 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +#include +#include +#include + +int f() { return 5; } + +void test01() +{ + bool test __attribute__((unused)) = true; + + using std::packaged_task; + using std::allocator_arg; + using __gnu_test::uneq_allocator; + + uneq_allocator alloc(99); + + packaged_task p1(allocator_arg, alloc, f); // { dg-excess-errors "" } + VERIFY( static_cast(p1) ); + p1(); + VERIFY( p1.get_future().get() == 5 ); +} + +int main() +{ + test01(); + return 0; +} 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 031ce0ba38e..8b724d502da 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 *-*-* } 890 } +// { dg-error "deleted function" "" { target *-*-* } 1209 } 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 65cf9fdbf9c..82a330fef2e 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 *-*-* } 889 } +// { dg-error "deleted function" "" { target *-*-* } 1208 } diff --git a/libstdc++-v3/testsuite/30_threads/packaged_task/members/get_future.cc b/libstdc++-v3/testsuite/30_threads/packaged_task/members/get_future.cc index c1bc129e26f..b44891be861 100644 --- a/libstdc++-v3/testsuite/30_threads/packaged_task/members/get_future.cc +++ b/libstdc++-v3/testsuite/30_threads/packaged_task/members/get_future.cc @@ -34,9 +34,10 @@ void test01() bool test __attribute__((unused)) = true; std::packaged_task p1(inc); - std::unique_future f1 = p1.get_future(); + std::future f1 = p1.get_future(); - VERIFY( !f1.is_ready() ); + VERIFY( f1.valid() ); + VERIFY( !f1.wait_for(std::chrono::milliseconds(1)) ); int i1 = 0; diff --git a/libstdc++-v3/testsuite/30_threads/packaged_task/members/get_future2.cc b/libstdc++-v3/testsuite/30_threads/packaged_task/members/get_future2.cc index a6c9c61e5c8..5c6d67b9776 100644 --- a/libstdc++-v3/testsuite/30_threads/packaged_task/members/get_future2.cc +++ b/libstdc++-v3/testsuite/30_threads/packaged_task/members/get_future2.cc @@ -42,8 +42,9 @@ void test01() p1.get_future(); VERIFY( false ); } - catch (std::bad_function_call&) + catch (const std::future_error& e) { + VERIFY( e.code() == std::future_errc::future_already_retrieved ); test = true; } diff --git a/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke.cc b/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke.cc index 2797b0606bd..cce7b54e269 100644 --- a/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke.cc +++ b/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke.cc @@ -34,12 +34,12 @@ void test01() bool test __attribute__((unused)) = true; std::packaged_task p1(zero); - std::unique_future f1 = p1.get_future(); + std::future f1 = p1.get_future(); p1(); VERIFY( static_cast(p1) ); - VERIFY( f1.has_value() ); + VERIFY( f1.get() == 0 ); } int main() diff --git a/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke2.cc b/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke2.cc index fae15dcac65..e29852c4834 100644 --- a/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke2.cc +++ b/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke2.cc @@ -41,8 +41,9 @@ void test01() { p1(4); } - catch (std::bad_function_call&) + catch (const std::future_error& e) { + VERIFY( e.code() == std::future_errc::promise_already_satisfied ); test = true; } diff --git a/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke3.cc b/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke3.cc index 91d43413d35..7ae6106a242 100644 --- a/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke3.cc +++ b/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke3.cc @@ -44,8 +44,9 @@ void test01() { p1(i1); } - catch (std::bad_function_call&) + catch (const std::future_error& e) { + VERIFY( e.code() == std::future_errc::promise_already_satisfied ); test = true; } diff --git a/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke4.cc b/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke4.cc index eefb313b7a4..6f0013f3005 100644 --- a/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke4.cc +++ b/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke4.cc @@ -31,14 +31,19 @@ void thrower() { throw 0; } void test01() { - bool test __attribute__((unused)) = true; + bool test = false; std::packaged_task p1(thrower); - std::unique_future f1 = p1.get_future(); + std::future f1 = p1.get_future(); p1(); - VERIFY( f1.has_exception() ); + try { + f1.get(); + } catch (int) { + test = true; + } + VERIFY( test ); } int main() diff --git a/libstdc++-v3/testsuite/30_threads/packaged_task/members/reset.cc b/libstdc++-v3/testsuite/30_threads/packaged_task/members/reset.cc index 66b9f3da669..a126c3ace88 100644 --- a/libstdc++-v3/testsuite/30_threads/packaged_task/members/reset.cc +++ b/libstdc++-v3/testsuite/30_threads/packaged_task/members/reset.cc @@ -36,15 +36,13 @@ void test01() using namespace std; packaged_task p1(zero); - unique_future f1 = p1.get_future(); + future f1 = p1.get_future(); p1.reset(); VERIFY( static_cast(p1) ); - unique_future f2 = p1.get_future(); - VERIFY( !f2.is_ready() ); + future f2 = p1.get_future(); - VERIFY( f1.has_exception() ); try { f1.get(); diff --git a/libstdc++-v3/testsuite/30_threads/packaged_task/members/reset2.cc b/libstdc++-v3/testsuite/30_threads/packaged_task/members/reset2.cc index 69ee9a99213..e38d0478662 100644 --- a/libstdc++-v3/testsuite/30_threads/packaged_task/members/reset2.cc +++ b/libstdc++-v3/testsuite/30_threads/packaged_task/members/reset2.cc @@ -27,23 +27,24 @@ #include #include -int zero() { return 0; } +int iota() { static int i = 0; return i++; } void test01() { bool test __attribute__((unused)) = true; - std::packaged_task p1(zero); - std::unique_future f1 = p1.get_future(); + std::packaged_task p1(iota); + std::future f1 = p1.get_future(); p1(); p1.reset(); VERIFY( static_cast(p1) ); - VERIFY( f1.has_value() ); + VERIFY( f1.get() == 0 ); - std::unique_future f2 = p1.get_future(); - VERIFY( !f2.is_ready() ); + std::future f2 = p1.get_future(); + p1(); + VERIFY( f2.get() == 1 ); } int main() diff --git a/libstdc++-v3/testsuite/30_threads/promise/cons/alloc.cc b/libstdc++-v3/testsuite/30_threads/promise/cons/alloc.cc new file mode 100644 index 00000000000..6d53f4444db --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/promise/cons/alloc.cc @@ -0,0 +1,47 @@ +// { dg-do compile { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* alpha*-*-osf* mips-sgi-irix6* } } +// { dg-options " -std=gnu++0x -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* alpha*-*-osf* mips-sgi-irix6* } } +// { dg-options " -std=gnu++0x -pthreads" { target *-*-solaris* } } +// { dg-options " -std=gnu++0x " { target *-*-cygwin *-*-darwin* } } +// { dg-require-cstdint "" } +// { dg-require-gthreads "" } +// { dg-require-atomic-builtins "" } + +// Copyright (C) 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +#include +#include +#include + +void test01() +{ + using std::promise; + using std::allocator_arg; + using __gnu_test::uneq_allocator; + + uneq_allocator alloc(99); + + promise p1(allocator_arg, alloc); // { dg-excess-errors "" } + p1.set_value(5); + VERIFY( p1.get_future().get() == 5 ); +} + +int main() +{ + test01(); + return 0; +} 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 54347408c53..229ee3ff4bb 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 *-*-* } 608 } +// { dg-error "deleted function" "" { target *-*-* } 864 } 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 79d2e16639f..a40ab79b5b6 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 *-*-* } 592 } +// { dg-error "deleted function" "" { target *-*-* } 848 } diff --git a/libstdc++-v3/testsuite/30_threads/promise/cons/move.cc b/libstdc++-v3/testsuite/30_threads/promise/cons/move.cc index 8b1e1399801..5fc2cae44a4 100644 --- a/libstdc++-v3/testsuite/30_threads/promise/cons/move.cc +++ b/libstdc++-v3/testsuite/30_threads/promise/cons/move.cc @@ -44,7 +44,7 @@ void test01() } catch (std::future_error& e) { - VERIFY(e.code() == make_error_code(future_errc::future_already_retrieved)); + VERIFY(e.code() == make_error_code(future_errc::no_state)); } } diff --git a/libstdc++-v3/testsuite/30_threads/promise/cons/move_assign.cc b/libstdc++-v3/testsuite/30_threads/promise/cons/move_assign.cc index c5bda4d3560..5d96e8ffcd3 100644 --- a/libstdc++-v3/testsuite/30_threads/promise/cons/move_assign.cc +++ b/libstdc++-v3/testsuite/30_threads/promise/cons/move_assign.cc @@ -45,7 +45,7 @@ void test01() } catch (future_error& e) { - VERIFY(e.code() == make_error_code(future_errc::future_already_retrieved)); + VERIFY(e.code() == make_error_code(future_errc::no_state)); } } diff --git a/libstdc++-v3/testsuite/30_threads/promise/members/get_future.cc b/libstdc++-v3/testsuite/30_threads/promise/members/get_future.cc index 7e969908a99..b09e302ccd4 100644 --- a/libstdc++-v3/testsuite/30_threads/promise/members/get_future.cc +++ b/libstdc++-v3/testsuite/30_threads/promise/members/get_future.cc @@ -32,9 +32,9 @@ void test01() bool test __attribute__((unused)) = true; std::promise p1; - std::unique_future f1 = p1.get_future(); + std::future f1 = p1.get_future(); - VERIFY( !f1.is_ready() ); + VERIFY( f1.valid() ); int i1 = 0; diff --git a/libstdc++-v3/testsuite/30_threads/promise/members/set_exception.cc b/libstdc++-v3/testsuite/30_threads/promise/members/set_exception.cc index e5b8f60aa3a..4d2a1ec0247 100644 --- a/libstdc++-v3/testsuite/30_threads/promise/members/set_exception.cc +++ b/libstdc++-v3/testsuite/30_threads/promise/members/set_exception.cc @@ -29,17 +29,25 @@ void test01() { - bool test __attribute__((unused)) = true; + bool test = false; std::promise p1; - std::unique_future f1 = p1.get_future(); + std::future f1 = p1.get_future(); - VERIFY( !f1.is_ready() ); + VERIFY( f1.valid() ); p1.set_exception(std::copy_exception(0)); - VERIFY( f1.has_exception() ); - VERIFY( !f1.has_value() ); + try + { + f1.get(); + } + catch (int) + { + test = true; + } + VERIFY( test ); + VERIFY( !f1.valid() ); } int main() diff --git a/libstdc++-v3/testsuite/30_threads/promise/members/set_exception2.cc b/libstdc++-v3/testsuite/30_threads/promise/members/set_exception2.cc index 3bbe28d48da..872a4792fd0 100644 --- a/libstdc++-v3/testsuite/30_threads/promise/members/set_exception2.cc +++ b/libstdc++-v3/testsuite/30_threads/promise/members/set_exception2.cc @@ -32,7 +32,7 @@ void test01() bool test = false; std::promise p1; - std::unique_future f1 = p1.get_future(); + std::future f1 = p1.get_future(); p1.set_exception(std::copy_exception(0)); @@ -66,7 +66,7 @@ void test02() bool test = false; std::promise p1; - std::unique_future f1 = p1.get_future(); + std::future f1 = p1.get_future(); p1.set_value(2); @@ -82,8 +82,6 @@ void test02() test = true; } - VERIFY( f1.has_value() ); - VERIFY( !f1.has_exception() ); VERIFY( test ); } diff --git a/libstdc++-v3/testsuite/30_threads/promise/members/set_value.cc b/libstdc++-v3/testsuite/30_threads/promise/members/set_value.cc index 978ef1914b0..9d3f8ead308 100644 --- a/libstdc++-v3/testsuite/30_threads/promise/members/set_value.cc +++ b/libstdc++-v3/testsuite/30_threads/promise/members/set_value.cc @@ -33,9 +33,9 @@ void test01() bool test __attribute__((unused)) = true; std::promise p1; - std::unique_future f1 = p1.get_future(); + std::future f1 = p1.get_future(); - VERIFY( !f1.is_ready() ); + VERIFY( f1.valid() ); p1.set_value(0); @@ -50,15 +50,15 @@ void test02() using __gnu_test::rvalstruct; std::promise p1; - std::unique_future f1 = p1.get_future(); + std::future f1 = p1.get_future(); - VERIFY( !f1.is_ready() ); + VERIFY( f1.valid() ); p1.set_value(rvalstruct(1)); rvalstruct r1(f1.get()); - VERIFY( r1.valid ); + VERIFY( !f1.valid() ); VERIFY( r1.val == 1 ); } @@ -68,14 +68,15 @@ void test03() bool test __attribute__((unused)) = true; std::promise p1; - std::unique_future f1 = p1.get_future(); + std::future f1 = p1.get_future(); - VERIFY( !f1.is_ready() ); + VERIFY( f1.valid() ); int i1 = 0; p1.set_value(i1); int& i2 = f1.get(); + VERIFY( !f1.valid() ); VERIFY( &i1 == &i2 ); } @@ -84,14 +85,14 @@ void test04() bool test __attribute__((unused)) = true; std::promise p1; - std::unique_future f1 = p1.get_future(); + std::future f1 = p1.get_future(); - VERIFY( !f1.is_ready() ); + VERIFY( f1.valid() ); p1.set_value(); f1.get(); - VERIFY( f1.is_ready() ); + VERIFY( !f1.valid() ); } int main() diff --git a/libstdc++-v3/testsuite/30_threads/promise/members/set_value2.cc b/libstdc++-v3/testsuite/30_threads/promise/members/set_value2.cc index 58e2fe813e4..09c8a52fa1e 100644 --- a/libstdc++-v3/testsuite/30_threads/promise/members/set_value2.cc +++ b/libstdc++-v3/testsuite/30_threads/promise/members/set_value2.cc @@ -32,7 +32,7 @@ void test01() bool test = false; std::promise p1; - std::unique_future f1 = p1.get_future(); + std::future f1 = p1.get_future(); p1.set_value(1); @@ -48,7 +48,7 @@ void test01() test = true; } - VERIFY( f1.has_value() ); + VERIFY( f1.wait_for(std::chrono::milliseconds(1)) ); VERIFY( f1.get() == 1 ); VERIFY( test ); } @@ -58,7 +58,7 @@ void test02() bool test = false; std::promise p1; - std::unique_future f1 = p1.get_future(); + std::future f1 = p1.get_future(); p1.set_value(3); @@ -74,8 +74,7 @@ void test02() test = true; } - VERIFY( f1.has_value() ); - VERIFY( !f1.has_exception() ); + VERIFY( f1.wait_for(std::chrono::milliseconds(1)) ); VERIFY( f1.get() == 3 ); VERIFY( test ); } diff --git a/libstdc++-v3/testsuite/30_threads/promise/members/set_value3.cc b/libstdc++-v3/testsuite/30_threads/promise/members/set_value3.cc index 92581964e3c..b94b1b6eaa5 100644 --- a/libstdc++-v3/testsuite/30_threads/promise/members/set_value3.cc +++ b/libstdc++-v3/testsuite/30_threads/promise/members/set_value3.cc @@ -41,33 +41,33 @@ struct tester }; std::promise pglobal; -std::unique_future fglobal = pglobal.get_future(); +std::future fglobal = pglobal.get_future(); tester::tester(int) { bool test __attribute__((unused)) = true; - VERIFY (!fglobal.is_ready()); + VERIFY (!fglobal.wait_for(std::chrono::milliseconds(1))); } tester::tester(const tester&) { bool test __attribute__((unused)) = true; // if this copy happens while a mutex is locked next line could deadlock: - VERIFY (!fglobal.is_ready()); + VERIFY (!fglobal.wait_for(std::chrono::milliseconds(1))); } tester& tester::operator=(const tester&) { bool test __attribute__((unused)) = true; // if this copy happens while a mutex is locked next line could deadlock: - VERIFY (!fglobal.is_ready()); + VERIFY (!fglobal.wait_for(std::chrono::milliseconds(1))); return *this; } tester::~tester() { bool test __attribute__((unused)) = true; - VERIFY (fglobal.is_ready()); + VERIFY (fglobal.wait_for(std::chrono::milliseconds(1))); } void test01() @@ -76,7 +76,7 @@ void test01() pglobal.set_value( tester(1) ); - VERIFY( fglobal.is_ready() ); + VERIFY( fglobal.wait_for(std::chrono::milliseconds(1)) ); } int main() diff --git a/libstdc++-v3/testsuite/30_threads/promise/members/swap.cc b/libstdc++-v3/testsuite/30_threads/promise/members/swap.cc index 8bfbdfd6c8f..b27ee2be7b5 100644 --- a/libstdc++-v3/testsuite/30_threads/promise/members/swap.cc +++ b/libstdc++-v3/testsuite/30_threads/promise/members/swap.cc @@ -35,8 +35,8 @@ void test01() std::promise p2; p1.set_value(1); p1.swap(p2); - VERIFY( !p1.get_future().is_ready() ); - VERIFY( p2.get_future().is_ready() ); + VERIFY( !p1.get_future().wait_for(std::chrono::milliseconds(1)) ); + VERIFY( p2.get_future().wait_for(std::chrono::milliseconds(1)) ); } int main() diff --git a/libstdc++-v3/testsuite/30_threads/shared_future/cons/assign_neg.cc b/libstdc++-v3/testsuite/30_threads/shared_future/cons/assign.cc similarity index 74% rename from libstdc++-v3/testsuite/30_threads/shared_future/cons/assign_neg.cc rename to libstdc++-v3/testsuite/30_threads/shared_future/cons/assign.cc index 0f284cd0a26..434cf187c37 100644 --- a/libstdc++-v3/testsuite/30_threads/shared_future/cons/assign_neg.cc +++ b/libstdc++-v3/testsuite/30_threads/shared_future/cons/assign.cc @@ -1,10 +1,9 @@ -// { dg-do compile } // { dg-options "-std=gnu++0x" } // { dg-require-cstdint "" } // { dg-require-gthreads "" } // { dg-require-atomic-builtins "" } -// Copyright (C) 2009 Free Software Foundation, Inc. +// Copyright (C) 2010 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -23,16 +22,23 @@ #include +#include -extern std::shared_future& get(); +std::future get() { return std::promise().get_future(); } void test01() { // assign - std::shared_future& p1 = get(); - std::shared_future& p2 = get(); + std::shared_future p1; + std::shared_future p2 = get(); p1 = p2; + VERIFY( p1.valid() ); + VERIFY( p2.valid() ); +} + +int main() +{ + test01(); + return 0; } -// { dg-error "used here" "" { target *-*-* } 34 } -// { dg-error "deleted function" "" { target *-*-* } 493 } diff --git a/libstdc++-v3/testsuite/30_threads/shared_future/cons/copy.cc b/libstdc++-v3/testsuite/30_threads/shared_future/cons/copy.cc index b1940fae3c7..09af94edbe2 100644 --- a/libstdc++-v3/testsuite/30_threads/shared_future/cons/copy.cc +++ b/libstdc++-v3/testsuite/30_threads/shared_future/cons/copy.cc @@ -25,7 +25,7 @@ #include #include -extern std::unique_future&& get(); +extern std::future&& get(); void test01() { diff --git a/libstdc++-v3/testsuite/30_threads/shared_future/cons/default_neg.cc b/libstdc++-v3/testsuite/30_threads/shared_future/cons/default.cc similarity index 67% rename from libstdc++-v3/testsuite/30_threads/shared_future/cons/default_neg.cc rename to libstdc++-v3/testsuite/30_threads/shared_future/cons/default.cc index cc4aadfce6f..c247853de3a 100644 --- a/libstdc++-v3/testsuite/30_threads/shared_future/cons/default_neg.cc +++ b/libstdc++-v3/testsuite/30_threads/shared_future/cons/default.cc @@ -1,10 +1,9 @@ -// { dg-do compile } // { dg-options "-std=gnu++0x" } // { dg-require-cstdint "" } // { dg-require-gthreads "" } // { dg-require-atomic-builtins "" } -// Copyright (C) 2009 Free Software Foundation, Inc. +// Copyright (C) 2010 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -23,6 +22,7 @@ #include +#include #include void test01() @@ -30,11 +30,18 @@ void test01() using std::shared_future; using namespace __gnu_test; - shared_future p1; // { dg-error "22: error: no match" } - shared_future p2; // { dg-error "23: error: no match" } - shared_future p3; // { dg-error "23: error: no match" } - shared_future p4; // { dg-error "28: error: no match" } - shared_future p5; // { dg-error "33: error: no match" } + bool __attribute__((unused)) test = true; + + shared_future p1; + VERIFY( !p1.valid() ); + shared_future p2; + VERIFY( !p2.valid() ); + shared_future p3; + VERIFY( !p3.valid() ); + shared_future p4; + VERIFY( !p4.valid() ); + shared_future p5; + VERIFY( !p5.valid() ); } int main() @@ -42,4 +49,3 @@ int main() test01(); return 0; } -// { dg-excess-errors "note" } diff --git a/libstdc++-v3/testsuite/30_threads/shared_future/cons/move.cc b/libstdc++-v3/testsuite/30_threads/shared_future/cons/move.cc index 3494a10463f..bb9b62b1dcd 100644 --- a/libstdc++-v3/testsuite/30_threads/shared_future/cons/move.cc +++ b/libstdc++-v3/testsuite/30_threads/shared_future/cons/move.cc @@ -28,9 +28,9 @@ void test01() { - // construct from rvalue unique_future + // construct from rvalue future std::promise p1; - std::unique_future f1(p1.get_future()); + std::future f1(p1.get_future()); std::shared_future f2(std::move(f1)); } diff --git a/libstdc++-v3/testsuite/30_threads/shared_future/cons/move_assign.cc b/libstdc++-v3/testsuite/30_threads/shared_future/cons/move_assign.cc new file mode 100644 index 00000000000..147604956f9 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/shared_future/cons/move_assign.cc @@ -0,0 +1,43 @@ +// { dg-options "-std=gnu++0x" } +// { dg-require-cstdint "" } +// { dg-require-gthreads "" } +// { dg-require-atomic-builtins "" } + +// Copyright (C) 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + + +#include +#include + +std::future get() { return std::promise().get_future(); } + +void test01() +{ + // assign + std::shared_future p1; + std::shared_future p2 = get(); + p1 = std::move(p2); + VERIFY( p1.valid() ); + VERIFY( !p2.valid() ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/30_threads/shared_future/members/has_exception.cc b/libstdc++-v3/testsuite/30_threads/shared_future/members/has_exception.cc deleted file mode 100644 index 97d398025e5..00000000000 --- a/libstdc++-v3/testsuite/30_threads/shared_future/members/has_exception.cc +++ /dev/null @@ -1,70 +0,0 @@ -// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* alpha*-*-osf* mips-sgi-irix6* } } -// { dg-options " -std=gnu++0x -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* alpha*-*-osf* mips-sgi-irix6* } } -// { dg-options " -std=gnu++0x -pthreads" { target *-*-solaris* } } -// { dg-options " -std=gnu++0x " { target *-*-cygwin *-*-darwin* } } -// { dg-require-cstdint "" } -// { dg-require-gthreads "" } -// { dg-require-atomic-builtins "" } - -// Copyright (C) 2009 Free Software Foundation, Inc. -// -// This file is part of the GNU ISO C++ Library. This library is free -// software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the -// Free Software Foundation; either version 3, or (at your option) -// any later version. - -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License along -// with this library; see the file COPYING3. If not see -// . - - -#include -#include - -void test01() -{ - bool test __attribute__((unused)) = true; - - std::promise p1; - std::shared_future f1(p1.get_future()); - std::shared_future f2(f1); - - VERIFY( !f1.has_exception() ); - VERIFY( !f2.has_exception() ); - - p1.set_exception(std::copy_exception(1)); - - VERIFY( f1.has_exception() ); - VERIFY( f2.has_exception() ); -} - -void test02() -{ - std::promise p1; - bool test __attribute__((unused)) = true; - - std::shared_future f1(p1.get_future()); - std::shared_future f2(f1); - - VERIFY( !f1.has_exception() ); - VERIFY( !f2.has_exception() ); - - p1.set_value(1); - - VERIFY( !f1.has_exception() ); - VERIFY( !f2.has_exception() ); -} - -int main() -{ - test01(); - test02(); - - return 0; -} diff --git a/libstdc++-v3/testsuite/30_threads/shared_future/members/has_value.cc b/libstdc++-v3/testsuite/30_threads/shared_future/members/has_value.cc deleted file mode 100644 index 8903c825f88..00000000000 --- a/libstdc++-v3/testsuite/30_threads/shared_future/members/has_value.cc +++ /dev/null @@ -1,70 +0,0 @@ -// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* alpha*-*-osf* mips-sgi-irix6* } } -// { dg-options " -std=gnu++0x -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* alpha*-*-osf* mips-sgi-irix6* } } -// { dg-options " -std=gnu++0x -pthreads" { target *-*-solaris* } } -// { dg-options " -std=gnu++0x " { target *-*-cygwin *-*-darwin* } } -// { dg-require-cstdint "" } -// { dg-require-gthreads "" } -// { dg-require-atomic-builtins "" } - -// Copyright (C) 2009 Free Software Foundation, Inc. -// -// This file is part of the GNU ISO C++ Library. This library is free -// software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the -// Free Software Foundation; either version 3, or (at your option) -// any later version. - -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License along -// with this library; see the file COPYING3. If not see -// . - - -#include -#include - -void test01() -{ - bool test __attribute__((unused)) = true; - - std::promise p1; - std::shared_future f1(p1.get_future()); - std::shared_future f2(f1); - - VERIFY( !f1.has_value() ); - VERIFY( !f2.has_value() ); - - p1.set_value(1); - - VERIFY( f1.has_value() ); - VERIFY( f2.has_value() ); -} - -void test02() -{ - bool test __attribute__((unused)) = true; - - std::promise p1; - std::shared_future f1(p1.get_future()); - std::shared_future f2(f1); - - VERIFY( !f1.has_value() ); - VERIFY( !f2.has_value() ); - - p1.set_exception(std::copy_exception(1)); - - VERIFY( !f1.has_value() ); - VERIFY( !f2.has_value() ); -} - -int main() -{ - test01(); - test02(); - - return 0; -} diff --git a/libstdc++-v3/testsuite/30_threads/unique_future/members/has_value.cc b/libstdc++-v3/testsuite/30_threads/shared_future/members/valid.cc similarity index 77% rename from libstdc++-v3/testsuite/30_threads/unique_future/members/has_value.cc rename to libstdc++-v3/testsuite/30_threads/shared_future/members/valid.cc index f1f96f21ddc..c70ed38ffe3 100644 --- a/libstdc++-v3/testsuite/30_threads/unique_future/members/has_value.cc +++ b/libstdc++-v3/testsuite/30_threads/shared_future/members/valid.cc @@ -6,7 +6,7 @@ // { dg-require-gthreads "" } // { dg-require-atomic-builtins "" } -// Copyright (C) 2009 Free Software Foundation, Inc. +// Copyright (C) 2010 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -31,35 +31,31 @@ void test01() { bool test __attribute__((unused)) = true; - std::promise p1; - std::unique_future f1(p1.get_future()); + std::shared_future f0; - VERIFY( !f1.has_value() ); + VERIFY( !f0.valid() ); + + std::promise p1; + std::shared_future f1(p1.get_future()); + std::shared_future f2(f1); + + VERIFY( f1.valid() ); + VERIFY( f2.valid() ); p1.set_value(1); - VERIFY( f1.has_value() ); -} + VERIFY( f1.valid() ); + VERIFY( f2.valid() ); -void test02() -{ - bool test __attribute__((unused)) = true; + f1 = std::move(f0); - std::promise p1; - std::unique_future f1(p1.get_future()); - - VERIFY( !f1.has_value() ); - - p1.set_exception(std::copy_exception(1)); - - VERIFY( !f1.has_value() ); + VERIFY( !f0.valid() ); + VERIFY( !f1.valid() ); + VERIFY( f2.valid() ); } int main() { test01(); - test02(); - return 0; } - 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 69caf12edb4..ecdc27c3b8d 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 @@ -24,15 +24,15 @@ #include -extern std::unique_future& get(); +extern std::future& get(); void test01() { // assign - std::unique_future& p1 = get(); - std::unique_future& p2 = get(); + std::future& p1 = get(); + std::future& p2 = get(); p1 = p2; } // { dg-error "used here" "" { target *-*-* } 34 } -// { dg-error "deleted function" "" { target *-*-* } 419 } +// { dg-error "deleted function" "" { target *-*-* } 578 } 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 43e940cfa76..c76075da120 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 @@ -24,14 +24,14 @@ #include -extern std::unique_future& get(); +extern std::future& get(); void test01() { // copy - std::unique_future& p1 = get(); - std::unique_future p2(p1); + std::future& p1 = get(); + std::future p2(p1); } // { dg-error "used here" "" { target *-*-* } 33 } -// { dg-error "deleted function" "" { target *-*-* } 418 } +// { dg-error "deleted function" "" { target *-*-* } 577 } diff --git a/libstdc++-v3/testsuite/30_threads/unique_future/cons/default_neg.cc b/libstdc++-v3/testsuite/30_threads/unique_future/cons/default.cc similarity index 65% rename from libstdc++-v3/testsuite/30_threads/unique_future/cons/default_neg.cc rename to libstdc++-v3/testsuite/30_threads/unique_future/cons/default.cc index ba5066bfcab..5f301810d47 100644 --- a/libstdc++-v3/testsuite/30_threads/unique_future/cons/default_neg.cc +++ b/libstdc++-v3/testsuite/30_threads/unique_future/cons/default.cc @@ -1,10 +1,9 @@ -// { dg-do compile } // { dg-options "-std=gnu++0x" } // { dg-require-cstdint "" } // { dg-require-gthreads "" } // { dg-require-atomic-builtins "" } -// Copyright (C) 2009 Free Software Foundation, Inc. +// Copyright (C) 2010 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -23,18 +22,26 @@ #include +#include #include void test01() { - using std::unique_future; + using std::future; using namespace __gnu_test; - unique_future p1; // { dg-error "22: error: no match" } - unique_future p2; // { dg-error "23: error: no match" } - unique_future p3; // { dg-error "23: error: no match" } - unique_future p4; // { dg-error "28: error: no match" } - unique_future p5; // { dg-error "33: error: no match" } + bool __attribute__((unused)) test = true; + + future p1; + VERIFY( !p1.valid() ); + future p2; + VERIFY( !p2.valid() ); + future p3; + VERIFY( !p3.valid() ); + future p4; + VERIFY( !p4.valid() ); + future p5; + VERIFY( !p5.valid() ); } int main() @@ -42,4 +49,3 @@ int main() test01(); return 0; } -// { dg-excess-errors "note" } diff --git a/libstdc++-v3/testsuite/30_threads/unique_future/cons/move.cc b/libstdc++-v3/testsuite/30_threads/unique_future/cons/move.cc index 17eaa914e4e..26493141e10 100644 --- a/libstdc++-v3/testsuite/30_threads/unique_future/cons/move.cc +++ b/libstdc++-v3/testsuite/30_threads/unique_future/cons/move.cc @@ -30,8 +30,8 @@ void test01() { // move std::promise p1; - std::unique_future f1(p1.get_future()); - std::unique_future f2(std::move(f1)); + std::future f1(p1.get_future()); + std::future f2(std::move(f1)); } int main() diff --git a/libstdc++-v3/testsuite/30_threads/unique_future/cons/move_assign.cc b/libstdc++-v3/testsuite/30_threads/unique_future/cons/move_assign.cc new file mode 100644 index 00000000000..3208cf8d4eb --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/unique_future/cons/move_assign.cc @@ -0,0 +1,43 @@ +// { dg-options "-std=gnu++0x" } +// { dg-require-cstdint "" } +// { dg-require-gthreads "" } +// { dg-require-atomic-builtins "" } + +// Copyright (C) 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + + +#include +#include + +std::future get() { return std::promise().get_future(); } + +void test01() +{ + // assign + std::future p1; + std::future p2 = get(); + p1 = std::move(p2); + VERIFY( p1.valid() ); + VERIFY( !p2.valid() ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/30_threads/unique_future/members/get.cc b/libstdc++-v3/testsuite/30_threads/unique_future/members/get.cc index 5c9a4548491..a0e4a4326dc 100644 --- a/libstdc++-v3/testsuite/30_threads/unique_future/members/get.cc +++ b/libstdc++-v3/testsuite/30_threads/unique_future/members/get.cc @@ -34,10 +34,11 @@ void test01() bool test __attribute__((unused)) = true; std::promise p1; - std::unique_future f1(p1.get_future()); + std::future f1(p1.get_future()); p1.set_value(value); VERIFY( f1.get() == value ); + VERIFY( !f1.valid() ); } void test02() @@ -45,19 +46,21 @@ void test02() bool test __attribute__((unused)) = true; std::promise p1; - std::unique_future f1(p1.get_future()); + std::future f1(p1.get_future()); p1.set_value(value); VERIFY( &f1.get() == &value ); + VERIFY( !f1.valid() ); } void test03() { std::promise p1; - std::unique_future f1(p1.get_future()); + std::future f1(p1.get_future()); p1.set_value(); f1.get(); + VERIFY( !f1.valid() ); } int main() diff --git a/libstdc++-v3/testsuite/30_threads/unique_future/members/get2.cc b/libstdc++-v3/testsuite/30_threads/unique_future/members/get2.cc index e6317fed838..22ca15c3968 100644 --- a/libstdc++-v3/testsuite/30_threads/unique_future/members/get2.cc +++ b/libstdc++-v3/testsuite/30_threads/unique_future/members/get2.cc @@ -35,7 +35,7 @@ void test01() bool test __attribute__((unused)) = true; std::promise p1; - std::unique_future f1(p1.get_future()); + std::future f1(p1.get_future()); p1.set_exception(std::copy_exception(value)); try @@ -47,6 +47,7 @@ void test01() { VERIFY( e == value ); } + VERIFY( !f1.valid() ); } void test02() @@ -54,7 +55,7 @@ void test02() bool test __attribute__((unused)) = true; std::promise p1; - std::unique_future f1(p1.get_future()); + std::future f1(p1.get_future()); p1.set_exception(std::copy_exception(value)); try @@ -66,6 +67,7 @@ void test02() { VERIFY( e == value ); } + VERIFY( !f1.valid() ); } void test03() @@ -73,7 +75,7 @@ void test03() bool test __attribute__((unused)) = true; std::promise p1; - std::unique_future f1(p1.get_future()); + std::future f1(p1.get_future()); p1.set_exception(std::copy_exception(value)); try @@ -85,6 +87,7 @@ void test03() { VERIFY( e == value ); } + VERIFY( !f1.valid() ); } int main() diff --git a/libstdc++-v3/testsuite/30_threads/shared_future/members/is_ready.cc b/libstdc++-v3/testsuite/30_threads/unique_future/members/valid.cc similarity index 84% rename from libstdc++-v3/testsuite/30_threads/shared_future/members/is_ready.cc rename to libstdc++-v3/testsuite/30_threads/unique_future/members/valid.cc index eb2252a664b..df5b57f5dce 100644 --- a/libstdc++-v3/testsuite/30_threads/shared_future/members/is_ready.cc +++ b/libstdc++-v3/testsuite/30_threads/unique_future/members/valid.cc @@ -6,7 +6,7 @@ // { dg-require-gthreads "" } // { dg-require-atomic-builtins "" } -// Copyright (C) 2009 Free Software Foundation, Inc. +// Copyright (C) 2010 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -31,17 +31,22 @@ void test01() { bool test __attribute__((unused)) = true; - std::promise p1; - std::shared_future f1(p1.get_future()); - std::shared_future f2(f1); + std::future f0; + VERIFY( !f0.valid() ); - VERIFY( !f1.is_ready() ); - VERIFY( !f2.is_ready() ); + std::promise p1; + std::future f1(p1.get_future()); + + VERIFY( f1.valid() ); p1.set_value(1); - VERIFY( f1.is_ready() ); - VERIFY( f2.is_ready() ); + VERIFY( f1.valid() ); + + f1 = std::move(f0); + + VERIFY( !f1.valid() ); + VERIFY( !f0.valid() ); } int main() diff --git a/libstdc++-v3/testsuite/30_threads/unique_future/members/wait.cc b/libstdc++-v3/testsuite/30_threads/unique_future/members/wait.cc index b9c9402cf31..94a431f8183 100644 --- a/libstdc++-v3/testsuite/30_threads/unique_future/members/wait.cc +++ b/libstdc++-v3/testsuite/30_threads/unique_future/members/wait.cc @@ -31,7 +31,7 @@ #include -void wait(std::unique_future& f) +void wait(std::future& f) { f.wait(); } @@ -39,7 +39,7 @@ void wait(std::unique_future& f) void test01() { std::promise p1; - std::unique_future f1(p1.get_future()); + std::future f1(p1.get_future()); std::thread t1(wait, std::ref(f1)); diff --git a/libstdc++-v3/testsuite/30_threads/unique_future/members/wait_for.cc b/libstdc++-v3/testsuite/30_threads/unique_future/members/wait_for.cc index 065240097b1..0123caad34d 100644 --- a/libstdc++-v3/testsuite/30_threads/unique_future/members/wait_for.cc +++ b/libstdc++-v3/testsuite/30_threads/unique_future/members/wait_for.cc @@ -33,7 +33,7 @@ void test01() bool test __attribute__((unused)) = true; std::promise p1; - std::unique_future f1(p1.get_future()); + std::future f1(p1.get_future()); std::chrono::milliseconds delay(100); diff --git a/libstdc++-v3/testsuite/30_threads/unique_future/members/wait_until.cc b/libstdc++-v3/testsuite/30_threads/unique_future/members/wait_until.cc index 55bdcbcc76c..bea1e0ea707 100644 --- a/libstdc++-v3/testsuite/30_threads/unique_future/members/wait_until.cc +++ b/libstdc++-v3/testsuite/30_threads/unique_future/members/wait_until.cc @@ -38,7 +38,7 @@ void test01() bool test __attribute__((unused)) = true; std::promise p1; - std::unique_future f1(p1.get_future()); + std::future f1(p1.get_future()); auto when = make_time(10); VERIFY( !f1.wait_until(when) ); diff --git a/libstdc++-v3/testsuite/30_threads/unique_future/requirements/explicit_instantiation.cc b/libstdc++-v3/testsuite/30_threads/unique_future/requirements/explicit_instantiation.cc index 01e5c5924b2..5d761b1d3d2 100644 --- a/libstdc++-v3/testsuite/30_threads/unique_future/requirements/explicit_instantiation.cc +++ b/libstdc++-v3/testsuite/30_threads/unique_future/requirements/explicit_instantiation.cc @@ -26,9 +26,9 @@ #include using namespace __gnu_test; -using std::unique_future; -template class unique_future; -template class unique_future; -template class unique_future; -template class unique_future; -template class unique_future; +using std::future; +template class future; +template class future; +template class future; +template class future; +template class future;