future (launch): Update enumerators and define operators required for bitmask type.
authorJonathan Wakely <jwakely.gcc@gmail.com>
Sat, 28 May 2011 00:24:11 +0000 (00:24 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Sat, 28 May 2011 00:24:11 +0000 (01:24 +0100)
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

libstdc++-v3/ChangeLog
libstdc++-v3/include/std/future
libstdc++-v3/src/future.cc
libstdc++-v3/testsuite/30_threads/async/any.cc
libstdc++-v3/testsuite/30_threads/async/launch.cc [new file with mode: 0644]
libstdc++-v3/testsuite/30_threads/async/sync.cc

index 6d27f0aa5e3d96e27a1f5fc38c5d25d4f61f4395..71b9adeecc2b2431a4501d611b24bed88c6e53b0 100644 (file)
@@ -1,3 +1,12 @@
+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.
index 479904c5cf997792b5fc81481d72e255556e7212..2b3e982200d6e2cecc62e4d9993248467ffe2049 100644 (file)
@@ -75,12 +75,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   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 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     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 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   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 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        }
 
        // 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 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     private:
       _Res*                    _M_value_ptr;
-      
+
       void _M_destroy() { delete this; }
     };
 
@@ -513,10 +542,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       __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 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       shared_future<_Res> share();
     };
+
   /// Partial specialization for future<R&>
   template<typename _Res>
     class future<_Res&> : public __basic_future<_Res&>
@@ -663,7 +692,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 
       /// Retrieving the value
-      _Res& 
+      _Res&
       get()
       {
         typename _Base_type::_Reset __reset(*this);
@@ -706,7 +735,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 
       /// Retrieving the value
-      void 
+      void
       get()
       {
         typename _Base_type::_Reset __reset(*this);
@@ -760,7 +789,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        return __rs;
       }
     };
+
   /// Partial specialization for shared_future<R&>
   template<typename _Res>
     class shared_future<_Res&> : public __basic_future<_Res&>
@@ -796,7 +825,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 
       /// Retrieving the value
-      _Res& 
+      _Res&
       get() { return this->_M_get_result()._M_get(); }
     };
 
@@ -835,7 +864,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 
       // Retrieving the value
-      void 
+      void
       get() { this->_M_get_result(); }
     };
 
@@ -880,7 +909,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       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 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { }
 
       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 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     };
 
   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 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     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 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       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 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     __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 ad941f95ad2d98000ef992d5b20e59d782c9aaea..94ae6f170d52f3d96fcd4217941d7f94ce7cdc98 100644 (file)
@@ -76,7 +76,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   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 40c103f960142535d01121ec27dbde052b2bd638..fe4deeb52b96bb48e115ca06198a8fdbd59a1f8d 100644 (file)
@@ -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 @@ void test01()
   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() );
diff --git a/libstdc++-v3/testsuite/30_threads/async/launch.cc b/libstdc++-v3/testsuite/30_threads/async/launch.cc
new file mode 100644 (file)
index 0000000..78fa2f7
--- /dev/null
@@ -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;
+}
index f1d137737736e42b7595fe4efadf24c5cce1ae28..1daf01238a2322a3911f3b5ec8bfa2d291dc9350 100644 (file)
@@ -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 @@ void test01()
   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 );