]> 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 d9d446bc2f6513a2ddc38096d3e04231b414d69d..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
@@ -1417,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));
       }
@@ -1426,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));
@@ -1445,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;
@@ -1462,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...)>
@@ -1478,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())
@@ -1516,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);
@@ -1580,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.
@@ -1634,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.
@@ -1708,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;
@@ -1741,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,
@@ -1750,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