summaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>2009-11-03 00:47:48 +0000
committerbkoz <bkoz@138bc75d-0d04-0410-961f-82ee72b054a4>2009-11-03 00:47:48 +0000
commit53200162d9ee14633f53f14e03aa565941551dc6 (patch)
treec654e0ab06b931548a732abc1309e98b6cc75d0a /libstdc++-v3
parentc356a43c60fe4a7dac807259e42aa6f358d82f10 (diff)
downloadgcc-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')
-rw-r--r--libstdc++-v3/ChangeLog21
-rw-r--r--libstdc++-v3/include/std/future700
-rw-r--r--libstdc++-v3/testsuite/30_threads/packaged_task/cons/assign_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/30_threads/packaged_task/cons/copy_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/30_threads/promise/cons/assign_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/30_threads/promise/cons/copy_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/30_threads/shared_future/cons/assign_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/30_threads/unique_future/cons/assign_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/30_threads/unique_future/cons/copy_neg.cc2
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 }