Commit faa00511 by Jonathan Wakely Committed by Jonathan Wakely

future (launch): Update enumerators and define operators required for bitmask type.

2011-05-28  Jonathan Wakely  <jwakely.gcc@gmail.com>

	* include/std/future (launch): Update enumerators and define
	operators required for bitmask type. Remove trailing whitespace.
	* src/future.cc: Remove trailing whitespace.
	* testsuite/30_threads/async/any.cc: Adjust.
	* testsuite/30_threads/async/sync.cc: Adjust.
	* testsuite/30_threads/async/launch.cc: New.

From-SVN: r174374
parent 6ffe882a
2011-05-28 Jonathan Wakely <jwakely.gcc@gmail.com> 2011-05-28 Jonathan Wakely <jwakely.gcc@gmail.com>
* include/std/future (launch): Update enumerators and define
operators required for bitmask type. Remove trailing whitespace.
* src/future.cc: Remove trailing whitespace.
* testsuite/30_threads/async/any.cc: Adjust.
* testsuite/30_threads/async/sync.cc: Adjust.
* testsuite/30_threads/async/launch.cc: New.
2011-05-28 Jonathan Wakely <jwakely.gcc@gmail.com>
* include/std/future: Use noexcept. * include/std/future: Use noexcept.
* src/future.cc: Likewise. * src/future.cc: Likewise.
......
...@@ -75,12 +75,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -75,12 +75,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
future_category() noexcept; future_category() noexcept;
/// Overload for make_error_code. /// Overload for make_error_code.
inline error_code inline error_code
make_error_code(future_errc __errc) noexcept make_error_code(future_errc __errc) noexcept
{ return error_code(static_cast<int>(__errc), future_category()); } { return error_code(static_cast<int>(__errc), future_category()); }
/// Overload for make_error_condition. /// Overload for make_error_condition.
inline error_condition inline error_condition
make_error_condition(future_errc __errc) noexcept make_error_condition(future_errc __errc) noexcept
{ return error_condition(static_cast<int>(__errc), future_category()); } { return error_condition(static_cast<int>(__errc), future_category()); }
...@@ -99,10 +99,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -99,10 +99,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
virtual ~future_error() noexcept; virtual ~future_error() noexcept;
virtual const char* virtual const char*
what() const noexcept; what() const noexcept;
const error_code& const error_code&
code() const noexcept { return _M_code; } code() const noexcept { return _M_code; }
}; };
...@@ -116,22 +116,51 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -116,22 +116,51 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Res> template<typename _Res>
class atomic_future; class atomic_future;
template<typename _Signature> template<typename _Signature>
class packaged_task; class packaged_task;
template<typename _Res> template<typename _Res>
class promise; class promise;
/// Launch code for futures /// Launch code for futures
enum class launch enum class launch
{ {
any, async = 1,
async, deferred = 2
sync
}; };
inline constexpr launch operator&(launch __x, launch __y)
{
return static_cast<launch>(
static_cast<int>(__x) & static_cast<int>(__y));
}
inline constexpr launch operator|(launch __x, launch __y)
{
return static_cast<launch>(
static_cast<int>(__x) | static_cast<int>(__y));
}
inline constexpr launch operator^(launch __x, launch __y)
{
return static_cast<launch>(
static_cast<int>(__x) ^ static_cast<int>(__y));
}
inline constexpr launch operator~(launch __x)
{ return static_cast<launch>(~static_cast<int>(__x)); }
inline launch& operator&=(launch& __x, launch __y)
{ return __x = __x & __y; }
inline launch& operator|=(launch& __x, launch __y)
{ return __x = __x | __y; }
inline launch& operator^=(launch& __x, launch __y)
{ return __x = __x ^ __y; }
/// Status code for futures /// Status code for futures
enum class future_status enum class future_status
{ {
ready, ready,
timeout, timeout,
...@@ -206,7 +235,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -206,7 +235,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
} }
// Return lvalue, future will add const or rvalue-reference // Return lvalue, future will add const or rvalue-reference
_Res& _Res&
_M_value() noexcept { return *static_cast<_Res*>(_M_addr()); } _M_value() noexcept { return *static_cast<_Res*>(_M_addr()); }
void void
...@@ -484,7 +513,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -484,7 +513,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
private: private:
_Res* _M_value_ptr; _Res* _M_value_ptr;
void _M_destroy() { delete this; } void _M_destroy() { delete this; }
}; };
...@@ -513,10 +542,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -513,10 +542,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__basic_future(const __basic_future&) = delete; __basic_future(const __basic_future&) = delete;
__basic_future& operator=(const __basic_future&) = delete; __basic_future& operator=(const __basic_future&) = delete;
bool bool
valid() const noexcept { return static_cast<bool>(_M_state); } valid() const noexcept { return static_cast<bool>(_M_state); }
void void
wait() const wait() const
{ {
_State_base::_S_check(_M_state); _State_base::_S_check(_M_state);
...@@ -629,7 +658,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -629,7 +658,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
shared_future<_Res> share(); shared_future<_Res> share();
}; };
/// Partial specialization for future<R&> /// Partial specialization for future<R&>
template<typename _Res> template<typename _Res>
class future<_Res&> : public __basic_future<_Res&> class future<_Res&> : public __basic_future<_Res&>
...@@ -663,7 +692,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -663,7 +692,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
} }
/// Retrieving the value /// Retrieving the value
_Res& _Res&
get() get()
{ {
typename _Base_type::_Reset __reset(*this); typename _Base_type::_Reset __reset(*this);
...@@ -706,7 +735,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -706,7 +735,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
} }
/// Retrieving the value /// Retrieving the value
void void
get() get()
{ {
typename _Base_type::_Reset __reset(*this); typename _Base_type::_Reset __reset(*this);
...@@ -760,7 +789,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -760,7 +789,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return __rs; return __rs;
} }
}; };
/// Partial specialization for shared_future<R&> /// Partial specialization for shared_future<R&>
template<typename _Res> template<typename _Res>
class shared_future<_Res&> : public __basic_future<_Res&> class shared_future<_Res&> : public __basic_future<_Res&>
...@@ -796,7 +825,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -796,7 +825,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
} }
/// Retrieving the value /// Retrieving the value
_Res& _Res&
get() { return this->_M_get_result()._M_get(); } get() { return this->_M_get_result()._M_get(); }
}; };
...@@ -835,7 +864,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -835,7 +864,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
} }
// Retrieving the value // Retrieving the value
void void
get() { this->_M_get_result(); } get() { this->_M_get_result(); }
}; };
...@@ -880,7 +909,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -880,7 +909,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef __future_base::_Result<_Res> _Res_type; typedef __future_base::_Result<_Res> _Res_type;
typedef typename __future_base::_Ptr<_Res_type>::type _Ptr_type; typedef typename __future_base::_Ptr<_Res_type>::type _Ptr_type;
template<typename, typename> friend class _State::_Setter; template<typename, typename> friend class _State::_Setter;
shared_ptr<_State> _M_future; shared_ptr<_State> _M_future;
_Ptr_type _M_storage; _Ptr_type _M_storage;
...@@ -983,7 +1012,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -983,7 +1012,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ } { }
promise(promise&& __rhs) noexcept promise(promise&& __rhs) noexcept
: _M_future(std::move(__rhs._M_future)), : _M_future(std::move(__rhs._M_future)),
_M_storage(std::move(__rhs._M_storage)) _M_storage(std::move(__rhs._M_storage))
{ } { }
...@@ -1175,7 +1204,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -1175,7 +1204,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}; };
template<typename _Res, typename... _Args> template<typename _Res, typename... _Args>
struct __future_base::_Task_state<_Res(_Args...)> struct __future_base::_Task_state<_Res(_Args...)>
: __future_base::_State_base : __future_base::_State_base
{ {
typedef _Res _Res_type; typedef _Res _Res_type;
...@@ -1334,7 +1363,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -1334,7 +1363,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
public: public:
typedef _Res _Res_type; typedef _Res _Res_type;
explicit explicit
_Async_state(std::function<_Res()>&& __fn) _Async_state(std::function<_Res()>&& __fn)
: _M_result(new _Result<_Res>()), _M_fn(std::move(__fn)), : _M_result(new _Result<_Res>()), _M_fn(std::move(__fn)),
_M_thread(mem_fn(&_Async_state::_M_do_run), this) _M_thread(mem_fn(&_Async_state::_M_do_run), this)
...@@ -1356,14 +1385,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -1356,14 +1385,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
thread _M_thread; thread _M_thread;
}; };
/// async /// async
template<typename _Fn, typename... _Args> template<typename _Fn, typename... _Args>
future<typename result_of<_Fn(_Args...)>::type> future<typename result_of<_Fn(_Args...)>::type>
async(launch __policy, _Fn&& __fn, _Args&&... __args) async(launch __policy, _Fn&& __fn, _Args&&... __args)
{ {
typedef typename result_of<_Fn(_Args...)>::type result_type; typedef typename result_of<_Fn(_Args...)>::type result_type;
std::shared_ptr<__future_base::_State_base> __state; std::shared_ptr<__future_base::_State_base> __state;
if (__policy == launch::async) if ((__policy & (launch::async|launch::deferred)) == launch::async)
{ {
typedef typename __future_base::_Async_state<result_type> _State; typedef typename __future_base::_Async_state<result_type> _State;
__state = std::make_shared<_State>(std::bind<result_type>( __state = std::make_shared<_State>(std::bind<result_type>(
...@@ -1384,7 +1413,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -1384,7 +1413,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__async_sfinae_helper<typename decay<_Fn>::type, _Fn, _Args...>::type __async_sfinae_helper<typename decay<_Fn>::type, _Fn, _Args...>::type
async(_Fn&& __fn, _Args&&... __args) async(_Fn&& __fn, _Args&&... __args)
{ {
return async(launch::any, std::forward<_Fn>(__fn), return async(launch::async|launch::deferred, std::forward<_Fn>(__fn),
std::forward<_Args>(__args)...); std::forward<_Args>(__args)...);
} }
......
...@@ -76,7 +76,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -76,7 +76,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
future_error::~future_error() noexcept { } future_error::~future_error() noexcept { }
const char* const char*
future_error::what() const noexcept { return _M_code.message().c_str(); } future_error::what() const noexcept { return _M_code.message().c_str(); }
#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) \ #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) \
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
// { dg-require-gthreads "" } // { dg-require-gthreads "" }
// { dg-require-atomic-builtins "" } // { dg-require-atomic-builtins "" }
// Copyright (C) 2010 Free Software Foundation, Inc. // Copyright (C) 2010, 2011 Free Software Foundation, Inc.
// //
// This file is part of the GNU ISO C++ Library. This library is free // 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 // software; you can redistribute it and/or modify it under the
...@@ -41,7 +41,7 @@ void test01() ...@@ -41,7 +41,7 @@ void test01()
int a = 1; int a = 1;
int b = 10; int b = 10;
int c = 100; int c = 100;
future<int> f1 = async(launch::any, sum(), a, ref(b), cref(c)); future<int> f1 = async(launch::async|launch::deferred, sum(), a, ref(b), cref(c));
future<int> f2 = async(sum(), a, ref(b), cref(c)); future<int> f2 = async(sum(), a, ref(b), cref(c));
VERIFY( f1.valid() ); VERIFY( f1.valid() );
......
// { 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) 2011 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
// <http://www.gnu.org/licenses/>.
#include <future>
#include <testsuite_hooks.h>
void test01()
{
bool test __attribute__((unused)) = true;
using std::launch;
const launch none{};
const launch both = launch::async|launch::deferred;
const launch all = ~none;
VERIFY( (none & both) == none );
VERIFY( (none | both) == both );
VERIFY( (none ^ both) == both );
VERIFY( (none & all) == none );
VERIFY( (none | all) == all );
VERIFY( (none ^ all) == all );
VERIFY( (both & all) == both );
VERIFY( (both | all) == all );
VERIFY( (both ^ all) == ~both );
VERIFY( (none & launch::async) == none );
VERIFY( (none & launch::deferred) == none );
VERIFY( (none | launch::async) == launch::async );
VERIFY( (none | launch::deferred) == launch::deferred );
VERIFY( (none ^ launch::async) == launch::async );
VERIFY( (none ^ launch::deferred) == launch::deferred );
VERIFY( (none & none) == none );
VERIFY( (none | none) == none );
VERIFY( (none ^ none) == none );
VERIFY( (both & both) == both );
VERIFY( (both | both) == both );
VERIFY( (both ^ both) == none );
VERIFY( (all & all) == all );
VERIFY( (all | all) == all );
VERIFY( (all ^ all) == none );
launch l = none;
l &= none;
VERIFY( l == none );
l |= none;
VERIFY( l == none );
l ^= none;
VERIFY( l == none );
l &= both;
VERIFY( l == none );
l |= both;
VERIFY( l == both );
l ^= both;
VERIFY( l == none );
}
int main()
{
test01();
return 0;
}
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
// { dg-require-gthreads "" } // { dg-require-gthreads "" }
// { dg-require-atomic-builtins "" } // { dg-require-atomic-builtins "" }
// Copyright (C) 2010 Free Software Foundation, Inc. // Copyright (C) 2010, 2011 Free Software Foundation, Inc.
// //
// This file is part of the GNU ISO C++ Library. This library is free // 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 // software; you can redistribute it and/or modify it under the
...@@ -41,7 +41,7 @@ void test01() ...@@ -41,7 +41,7 @@ void test01()
int a = 1; int a = 1;
int b = 10; int b = 10;
int c = 100; int c = 100;
future<int> f1 = async(launch::sync, sum(), a, ref(b), cref(c)); future<int> f1 = async(launch::deferred, sum(), a, ref(b), cref(c));
VERIFY( f1.valid() ); VERIFY( f1.valid() );
VERIFY( f1.get() == 111 ); VERIFY( f1.get() == 111 );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment