[v3] update std::launch enum
Jonathan Wakely
jwakely.gcc@gmail.com
Sat May 28 08:18:00 GMT 2011
This updates the std::launch enum to match the FDIS.
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.
I considered keeping the old enumerators "sync" (with the value of
deferred) and "any" (with the value "async|deferred") for backward
compatibility but decided against it.
Tested x86_64-linux, committed to trunk.
-------------- next part --------------
Index: include/std/future
===================================================================
--- include/std/future (revision 174368)
+++ include/std/future (working copy)
@@ -75,12 +75,12 @@
future_category() noexcept;
/// Overload for make_error_code.
- inline error_code
+ inline error_code
make_error_code(future_errc __errc) noexcept
{ return error_code(static_cast<int>(__errc), future_category()); }
/// Overload for make_error_condition.
- inline error_condition
+ inline error_condition
make_error_condition(future_errc __errc) noexcept
{ return error_condition(static_cast<int>(__errc), future_category()); }
@@ -99,10 +99,10 @@
virtual ~future_error() noexcept;
- virtual const char*
+ virtual const char*
what() const noexcept;
- const error_code&
+ const error_code&
code() const noexcept { return _M_code; }
};
@@ -116,22 +116,51 @@
template<typename _Res>
class atomic_future;
- template<typename _Signature>
+ template<typename _Signature>
class packaged_task;
template<typename _Res>
class promise;
/// Launch code for futures
- enum class launch
- {
- any,
- async,
- sync
+ enum class launch
+ {
+ async = 1,
+ deferred = 2
};
+ 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
- enum class future_status
+ enum class future_status
{
ready,
timeout,
@@ -206,7 +235,7 @@
}
// Return lvalue, future will add const or rvalue-reference
- _Res&
+ _Res&
_M_value() noexcept { return *static_cast<_Res*>(_M_addr()); }
void
@@ -484,7 +513,7 @@
private:
_Res* _M_value_ptr;
-
+
void _M_destroy() { delete this; }
};
@@ -513,10 +542,10 @@
__basic_future(const __basic_future&) = delete;
__basic_future& operator=(const __basic_future&) = delete;
- bool
+ bool
valid() const noexcept { return static_cast<bool>(_M_state); }
- void
+ void
wait() const
{
_State_base::_S_check(_M_state);
@@ -629,7 +658,7 @@
shared_future<_Res> share();
};
-
+
/// Partial specialization for future<R&>
template<typename _Res>
class future<_Res&> : public __basic_future<_Res&>
@@ -663,7 +692,7 @@
}
/// Retrieving the value
- _Res&
+ _Res&
get()
{
typename _Base_type::_Reset __reset(*this);
@@ -706,7 +735,7 @@
}
/// Retrieving the value
- void
+ void
get()
{
typename _Base_type::_Reset __reset(*this);
@@ -760,7 +789,7 @@
return __rs;
}
};
-
+
/// Partial specialization for shared_future<R&>
template<typename _Res>
class shared_future<_Res&> : public __basic_future<_Res&>
@@ -796,7 +825,7 @@
}
/// Retrieving the value
- _Res&
+ _Res&
get() { return this->_M_get_result()._M_get(); }
};
@@ -835,7 +864,7 @@
}
// Retrieving the value
- void
+ void
get() { this->_M_get_result(); }
};
@@ -880,7 +909,7 @@
typedef __future_base::_Result<_Res> _Res_type;
typedef typename __future_base::_Ptr<_Res_type>::type _Ptr_type;
template<typename, typename> friend class _State::_Setter;
-
+
shared_ptr<_State> _M_future;
_Ptr_type _M_storage;
@@ -983,7 +1012,7 @@
{ }
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))
{ }
@@ -1175,7 +1204,7 @@
};
template<typename _Res, typename... _Args>
- struct __future_base::_Task_state<_Res(_Args...)>
+ struct __future_base::_Task_state<_Res(_Args...)>
: __future_base::_State_base
{
typedef _Res _Res_type;
@@ -1334,7 +1363,7 @@
public:
typedef _Res _Res_type;
- explicit
+ 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)
@@ -1356,14 +1385,14 @@
thread _M_thread;
};
- /// async
+ /// async
template<typename _Fn, typename... _Args>
future<typename result_of<_Fn(_Args...)>::type>
async(launch __policy, _Fn&& __fn, _Args&&... __args)
{
typedef typename result_of<_Fn(_Args...)>::type result_type;
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;
__state = std::make_shared<_State>(std::bind<result_type>(
@@ -1384,7 +1413,7 @@
__async_sfinae_helper<typename decay<_Fn>::type, _Fn, _Args...>::type
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)...);
}
Index: src/future.cc
===================================================================
--- src/future.cc (revision 174368)
+++ src/future.cc (working copy)
@@ -76,7 +76,7 @@
future_error::~future_error() noexcept { }
- const char*
+ const char*
future_error::what() const noexcept { return _M_code.message().c_str(); }
#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) \
Index: testsuite/30_threads/async/sync.cc
===================================================================
--- testsuite/30_threads/async/sync.cc (revision 174358)
+++ testsuite/30_threads/async/sync.cc (working copy)
@@ -6,7 +6,7 @@
// { dg-require-gthreads "" }
// { 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
// software; you can redistribute it and/or modify it under the
@@ -41,7 +41,7 @@
int a = 1;
int b = 10;
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.get() == 111 );
Index: testsuite/30_threads/async/any.cc
===================================================================
--- testsuite/30_threads/async/any.cc (revision 174358)
+++ testsuite/30_threads/async/any.cc (working copy)
@@ -6,7 +6,7 @@
// { dg-require-gthreads "" }
// { 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
// software; you can redistribute it and/or modify it under the
@@ -41,7 +41,7 @@
int a = 1;
int b = 10;
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));
VERIFY( f1.valid() );
Index: testsuite/30_threads/async/launch.cc
===================================================================
--- testsuite/30_threads/async/launch.cc (revision 0)
+++ testsuite/30_threads/async/launch.cc (revision 0)
@@ -0,0 +1,94 @@
+// { 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;
+}
More information about the Gcc-patches
mailing list