]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - libstdc++-v3/include/std/future
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / include / std / future
index 6351d7ef49452d56e37280526dc4763402c4baac..59aa981261b2e2aa27e5212ebd5953dcadb9aa44 100644 (file)
@@ -1,6 +1,6 @@
 // <future> -*- C++ -*-
 
-// Copyright (C) 2009-2017 Free Software Foundation, Inc.
+// Copyright (C) 2009-2020 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
@@ -181,8 +181,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // _GLIBCXX_RESOLVE_LIB_DEFECTS
   // 2021. Further incorrect usages of result_of
   template<typename _Fn, typename... _Args>
-    using __async_result_of = typename result_of<
-      typename decay<_Fn>::type(typename decay<_Args>::type...)>::type;
+    using __async_result_of = typename __invoke_result<
+      typename decay<_Fn>::type, typename decay<_Args>::type...>::type;
 
   template<typename _Fn, typename... _Args>
     future<__async_result_of<_Fn, _Args...>>
@@ -192,7 +192,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     future<__async_result_of<_Fn, _Args...>>
     async(_Fn&& __fn, _Args&&... __args);
 
-#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
+#if defined(_GLIBCXX_HAS_GTHREADS)
 
   /// Base class and enclosing scope.
   struct __future_base
@@ -471,7 +471,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          // Used by std::promise to copy construct the result.
           typename promise<_Res>::_Ptr_type operator()() const
           {
-            _State_baseV2::_S_check(_M_promise->_M_future);
             _M_promise->_M_storage->_M_set(*_M_arg);
             return std::move(_M_promise->_M_storage);
           }
@@ -486,7 +485,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          // Used by std::promise to move construct the result.
           typename promise<_Res>::_Ptr_type operator()() const
           {
-            _State_baseV2::_S_check(_M_promise->_M_future);
             _M_promise->_M_storage->_M_set(std::move(*_M_arg));
             return std::move(_M_promise->_M_storage);
           }
@@ -494,6 +492,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
           _Res*             _M_arg;
         };
 
+      // set void
+      template<typename _Res>
+       struct _Setter<_Res, void>
+       {
+         static_assert(is_void<_Res>::value, "Only used for promise<void>");
+
+         typename promise<_Res>::_Ptr_type operator()() const
+         { return std::move(_M_promise->_M_storage); }
+
+         promise<_Res>*    _M_promise;
+       };
+
       struct __exception_ptr_tag { };
 
       // set exceptions
@@ -503,7 +513,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          // Used by std::promise to store an exception as the result.
           typename promise<_Res>::_Ptr_type operator()() const
           {
-            _State_baseV2::_S_check(_M_promise->_M_future);
             _M_promise->_M_storage->_M_error = *_M_ex;
             return std::move(_M_promise->_M_storage);
           }
@@ -516,6 +525,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
         static _Setter<_Res, _Arg&&>
         __setter(promise<_Res>* __prom, _Arg&& __arg)
         {
+         _S_check(__prom->_M_future);
           return _Setter<_Res, _Arg&&>{ __prom, std::__addressof(__arg) };
         }
 
@@ -523,9 +533,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
         static _Setter<_Res, __exception_ptr_tag>
         __setter(exception_ptr& __ex, promise<_Res>* __prom)
         {
+         _S_check(__prom->_M_future);
           return _Setter<_Res, __exception_ptr_tag>{ __prom, &__ex };
         }
 
+      template<typename _Res>
+       static _Setter<_Res, void>
+       __setter(promise<_Res>* __prom)
+       {
+         _S_check(__prom->_M_future);
+         return _Setter<_Res, void>{ __prom };
+       }
+
       template<typename _Tp>
         static void
         _S_check(const shared_ptr<_Tp>& __p)
@@ -877,7 +896,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       constexpr shared_future() noexcept : _Base_type() { }
 
       /// Copy constructor
-      shared_future(const shared_future& __sf) : _Base_type(__sf) { }
+      shared_future(const shared_future& __sf) noexcept : _Base_type(__sf) { }
 
       /// Construct from a future rvalue
       shared_future(future<_Res>&& __uf) noexcept
@@ -889,7 +908,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       : _Base_type(std::move(__sf))
       { }
 
-      shared_future& operator=(const shared_future& __sf)
+      shared_future& operator=(const shared_future& __sf) noexcept
       {
         shared_future(__sf)._M_swap(*this);
         return *this;
@@ -1027,6 +1046,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       typedef __future_base::_Result<_Res>     _Res_type;
       typedef __future_base::_Ptr<_Res_type>   _Ptr_type;
       template<typename, typename> friend class _State::_Setter;
+      friend _State;
 
       shared_ptr<_State>                        _M_future;
       _Ptr_type                                 _M_storage;
@@ -1137,6 +1157,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       typedef __future_base::_Result<_Res&>    _Res_type;
       typedef __future_base::_Ptr<_Res_type>   _Ptr_type;
       template<typename, typename> friend class _State::_Setter;
+      friend _State;
 
       shared_ptr<_State>                        _M_future;
       _Ptr_type                                 _M_storage;
@@ -1226,6 +1247,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       typedef __future_base::_Result<void>     _Res_type;
       typedef __future_base::_Ptr<_Res_type>   _Ptr_type;
       template<typename, typename> friend class _State::_Setter;
+      friend _State;
 
       shared_ptr<_State>                        _M_future;
       _Ptr_type                                 _M_storage;
@@ -1286,14 +1308,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { return future<void>(_M_future); }
 
       // Setting the result
-      void set_value();
+      void
+      set_value()
+      { _M_future->_M_set_result(_State::__setter(this)); }
 
       void
       set_exception(exception_ptr __p)
       { _M_future->_M_set_result(_State::__setter(__p, this)); }
 
       void
-      set_value_at_thread_exit();
+      set_value_at_thread_exit()
+      { _M_future->_M_set_delayed_result(_State::__setter(this), _M_future); }
 
       void
       set_exception_at_thread_exit(exception_ptr __p)
@@ -1303,30 +1328,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     };
 
-  // set void
-  template<>
-    struct __future_base::_State_base::_Setter<void, void>
-    {
-      promise<void>::_Ptr_type operator()() const
-      {
-        _State_base::_S_check(_M_promise->_M_future);
-        return std::move(_M_promise->_M_storage);
-      }
-
-      promise<void>*    _M_promise;
-    };
-
-  inline void
-  promise<void>::set_value()
-  { _M_future->_M_set_result(_State::_Setter<void, void>{ this }); }
-
-  inline void
-  promise<void>::set_value_at_thread_exit()
-  {
-    _M_future->_M_set_delayed_result(_State::_Setter<void, void>{this},
-                                    _M_future);
-  }
-
   template<typename _Ptr_type, typename _Fn, typename _Res>
     struct __future_base::_Task_setter
     {
@@ -1416,8 +1417,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       virtual void
       _M_run(_Args&&... __args)
       {
-       auto __boundfn = [&] () -> typename result_of<_Fn(_Args&&...)>::type {
-           return std::__invoke(_M_impl._M_fn, std::forward<_Args>(__args)...);
+       auto __boundfn = [&] () -> _Res {
+           return std::__invoke_r<_Res>(_M_impl._M_fn,
+                                        std::forward<_Args>(__args)...);
        };
        this->_M_set_result(_S_task_setter(this->_M_result, __boundfn));
       }
@@ -1425,8 +1427,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       virtual void
       _M_run_delayed(_Args&&... __args, weak_ptr<_State_base> __self)
       {
-       auto __boundfn = [&] () -> typename result_of<_Fn(_Args&&...)>::type {
-           return std::__invoke(_M_impl._M_fn, std::forward<_Args>(__args)...);
+       auto __boundfn = [&] () -> _Res {
+           return std::__invoke_r<_Res>(_M_impl._M_fn,
+                                        std::forward<_Args>(__args)...);
        };
        this->_M_set_delayed_result(_S_task_setter(this->_M_result, __boundfn),
                                    std::move(__self));
@@ -1444,9 +1447,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       } _M_impl;
     };
 
-  template<typename _Signature, typename _Fn, typename _Alloc>
+  template<typename _Signature, typename _Fn,
+          typename _Alloc = std::allocator<int>>
     static shared_ptr<__future_base::_Task_state_base<_Signature>>
-    __create_task_state(_Fn&& __fn, const _Alloc& __a)
+    __create_task_state(_Fn&& __fn, const _Alloc& __a = _Alloc())
     {
       typedef typename decay<_Fn>::type _Fn2;
       typedef __future_base::_Task_state<_Fn2, _Alloc, _Signature> _State;
@@ -1461,15 +1465,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                                                 static_cast<_Alloc&>(_M_impl));
     }
 
-  template<typename _Task, typename _Fn, bool
-          = is_same<_Task, typename decay<_Fn>::type>::value>
-    struct __constrain_pkgdtask
-    { typedef void __type; };
-
-  template<typename _Task, typename _Fn>
-    struct __constrain_pkgdtask<_Task, _Fn, true>
-    { };
-
   /// packaged_task
   template<typename _Res, typename... _ArgTypes>
     class packaged_task<_Res(_ArgTypes...)>
@@ -1477,34 +1472,50 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       typedef __future_base::_Task_state_base<_Res(_ArgTypes...)> _State_type;
       shared_ptr<_State_type>                   _M_state;
 
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 3039. Unnecessary decay in thread and packaged_task
+      template<typename _Fn, typename _Fn2 = __remove_cvref_t<_Fn>>
+       using __not_same
+         = typename enable_if<!is_same<packaged_task, _Fn2>::value>::type;
+
     public:
       // Construction and destruction
       packaged_task() noexcept { }
 
-      // _GLIBCXX_RESOLVE_LIB_DEFECTS
-      // 2095.  missing constructors needed for uses-allocator construction
-      template<typename _Allocator>
-       packaged_task(allocator_arg_t, const _Allocator& __a) noexcept
-       { }
-
-      template<typename _Fn, typename = typename
-              __constrain_pkgdtask<packaged_task, _Fn>::__type>
+      template<typename _Fn, typename = __not_same<_Fn>>
        explicit
        packaged_task(_Fn&& __fn)
-       : packaged_task(allocator_arg, std::allocator<int>(),
-                       std::forward<_Fn>(__fn))
+       : _M_state(
+           __create_task_state<_Res(_ArgTypes...)>(std::forward<_Fn>(__fn)))
        { }
 
+#if __cplusplus < 201703L
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
-      // 2097.  packaged_task constructors should be constrained
+      // 2097. packaged_task constructors should be constrained
       // 2407. [this constructor should not be] explicit
-      template<typename _Fn, typename _Alloc, typename = typename
-              __constrain_pkgdtask<packaged_task, _Fn>::__type>
+      // 2921. packaged_task and type-erased allocators
+      template<typename _Fn, typename _Alloc, typename = __not_same<_Fn>>
        packaged_task(allocator_arg_t, const _Alloc& __a, _Fn&& __fn)
        : _M_state(__create_task_state<_Res(_ArgTypes...)>(
-                   std::forward<_Fn>(__fn), __a))
+                  std::forward<_Fn>(__fn), __a))
+       { }
+
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 2095.  missing constructors needed for uses-allocator construction
+      template<typename _Allocator>
+       packaged_task(allocator_arg_t, const _Allocator& __a) noexcept
        { }
 
+      template<typename _Allocator>
+       packaged_task(allocator_arg_t, const _Allocator&,
+                     const packaged_task&) = delete;
+
+      template<typename _Allocator>
+       packaged_task(allocator_arg_t, const _Allocator&,
+                     packaged_task&& __other) noexcept
+       { this->swap(__other); }
+#endif
+
       ~packaged_task()
       {
         if (static_cast<bool>(_M_state) && !_M_state.unique())
@@ -1515,19 +1526,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       packaged_task(const packaged_task&) = delete;
       packaged_task& operator=(const packaged_task&) = delete;
 
-      template<typename _Allocator>
-       packaged_task(allocator_arg_t, const _Allocator&,
-                     const packaged_task&) = delete;
-
       // Move support
       packaged_task(packaged_task&& __other) noexcept
       { this->swap(__other); }
 
-      template<typename _Allocator>
-       packaged_task(allocator_arg_t, const _Allocator&,
-                     packaged_task&& __other) noexcept
-       { this->swap(__other); }
-
       packaged_task& operator=(packaged_task&& __other) noexcept
       {
        packaged_task(std::move(__other)).swap(*this);
@@ -1579,10 +1581,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
         packaged_task<_Res(_ArgTypes...)>& __y) noexcept
     { __x.swap(__y); }
 
+#if __cplusplus < 201703L
+  // _GLIBCXX_RESOLVE_LIB_DEFECTS
+  // 2976. Dangling uses_allocator specialization for packaged_task
   template<typename _Res, typename _Alloc>
     struct uses_allocator<packaged_task<_Res>, _Alloc>
     : public true_type { };
-
+#endif
 
   // Shared state created by std::async().
   // Holds a deferred function and storage for its result.
@@ -1633,11 +1638,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     //
     // [futures.async]:
     //
-    //  a call to a waiting function on an asynchronous return object that
+    // - a call to a waiting function on an asynchronous return object that
     // shares the shared state created by this async call shall block until
     // the associated thread has completed, as if joined, or else time out.
     //
-    //  the associated thread completion synchronizes with the return from
+    // - the associated thread completion synchronizes with the return from
     // the first function that successfully detects the ready status of the
     // shared state or with the return from the last function that releases
     // the shared state, whichever happens first.
@@ -1707,7 +1712,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   /// async
   template<typename _Fn, typename... _Args>
-    future<__async_result_of<_Fn, _Args...>>
+    _GLIBCXX_NODISCARD future<__async_result_of<_Fn, _Args...>>
     async(launch __policy, _Fn&& __fn, _Args&&... __args)
     {
       std::shared_ptr<__future_base::_State_base> __state;
@@ -1740,7 +1745,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   /// async, potential overload
   template<typename _Fn, typename... _Args>
-    inline future<__async_result_of<_Fn, _Args...>>
+    _GLIBCXX_NODISCARD inline future<__async_result_of<_Fn, _Args...>>
     async(_Fn&& __fn, _Args&&... __args)
     {
       return std::async(launch::async|launch::deferred,
@@ -1749,7 +1754,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 
 #endif // _GLIBCXX_ASYNC_ABI_COMPAT
-#endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1
+#endif // _GLIBCXX_HAS_GTHREADS
 
   // @} group futures
 _GLIBCXX_END_NAMESPACE_VERSION