* include/std/future (_State_baseV2::_M_set_result): Pass pointers to
authorredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 7 Aug 2014 20:13:52 +0000 (20:13 +0000)
committerredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 7 Aug 2014 20:13:52 +0000 (20:13 +0000)
_M_do_set.
(_State_baseV2::_M_do_set): Change parameters to pointers.
(_State_baseV2::_Setter): Change _M_arg from reference to pointer.
(_State_baseV2::__setter): Initialize _Setter with pointers.
(_State_baseV2::__setter(promise<void>*)): Remove overload.
(promise::set_value, promise::set_exception): Pass setter directly
to _M_set_result.
(_State_baseV2::_Task_setter): Add template parameter for callable
type and replace std::function member with pointer to that type.
Change _M_result member from reference to pointer.
(_State_baseV2::_S_task_setter): Change parameter to lvalue reference
and initialize _Task_setter with pointers.
(__location_invariant): Specialize for _Setter and _Task_setter.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@213737 138bc75d-0d04-0410-961f-82ee72b054a4

libstdc++-v3/ChangeLog
libstdc++-v3/include/std/future

index 6dfddd0..00a76a8 100644 (file)
        * testsuite/23_containers/list/requirements/dr438/insert_neg.cc:
        Likewise.
 
+       * include/std/future (_State_baseV2::_M_set_result): Pass pointers to
+       _M_do_set.
+       (_State_baseV2::_M_do_set): Change parameters to pointers.
+       (_State_baseV2::_Setter): Change _M_arg from reference to pointer.
+       (_State_baseV2::__setter): Initialize _Setter with pointers.
+       (_State_baseV2::__setter(promise<void>*)): Remove overload.
+       (promise::set_value, promise::set_exception): Pass setter directly
+       to _M_set_result.
+       (_State_baseV2::_Task_setter): Add template parameter for callable
+       type and replace std::function member with pointer to that type.
+       Change _M_result member from reference to pointer.
+       (_State_baseV2::_S_task_setter): Change parameter to lvalue reference
+       and initialize _Task_setter with pointers.
+       (__location_invariant): Specialize for _Setter and _Task_setter.
+
 2014-08-02  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/15339
index be2ed96..c3aaaec 100644 (file)
@@ -358,7 +358,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
         // all calls to this function are serialized,
         // side-effects of invoking __res only happen once
        call_once(_M_once, &_State_baseV2::_M_do_set, this,
-                 ref(__res), ref(__lock));
+                 std::__addressof(__res), std::__addressof(__lock));
        if (__lock.owns_lock())
          _M_cond.notify_all();
        else if (!__ignore_failure)
@@ -396,19 +396,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
         struct _Setter<_Res, _Arg&>
         {
           // check this is only used by promise<R>::set_value(const R&)
-          // or promise<R>::set_value(R&)
+          // or promise<R&>::set_value(R&)
           static_assert(is_same<_Res, _Arg&>::value  // promise<R&>
-              || is_same<const _Res, _Arg>::value,  // promise<R>
+              || is_same<const _Res, _Arg>::value,   // promise<R>
               "Invalid specialisation");
 
           typename promise<_Res>::_Ptr_type operator()()
           {
             _State_baseV2::_S_check(_M_promise->_M_future);
-            _M_promise->_M_storage->_M_set(_M_arg);
+            _M_promise->_M_storage->_M_set(*_M_arg);
             return std::move(_M_promise->_M_storage);
           }
           promise<_Res>*    _M_promise;
-          _Arg&             _M_arg;
+          _Arg*             _M_arg;
         };
 
       // set rvalues
@@ -418,11 +418,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
           typename promise<_Res>::_Ptr_type operator()()
           {
             _State_baseV2::_S_check(_M_promise->_M_future);
-            _M_promise->_M_storage->_M_set(std::move(_M_arg));
+            _M_promise->_M_storage->_M_set(std::move(*_M_arg));
             return std::move(_M_promise->_M_storage);
           }
           promise<_Res>*    _M_promise;
-          _Res&             _M_arg;
+          _Res*             _M_arg;
         };
 
       struct __exception_ptr_tag { };
@@ -434,31 +434,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
           typename promise<_Res>::_Ptr_type operator()()
           {
             _State_baseV2::_S_check(_M_promise->_M_future);
-            _M_promise->_M_storage->_M_error = _M_ex;
+            _M_promise->_M_storage->_M_error = *_M_ex;
             return std::move(_M_promise->_M_storage);
           }
 
           promise<_Res>*   _M_promise;
-          exception_ptr&    _M_ex;
+          exception_ptr*    _M_ex;
         };
 
       template<typename _Res, typename _Arg>
         static _Setter<_Res, _Arg&&>
         __setter(promise<_Res>* __prom, _Arg&& __arg)
         {
-          return _Setter<_Res, _Arg&&>{ __prom, __arg };
+          return _Setter<_Res, _Arg&&>{ __prom, &__arg };
         }
 
       template<typename _Res>
         static _Setter<_Res, __exception_ptr_tag>
         __setter(exception_ptr& __ex, promise<_Res>* __prom)
         {
-          return _Setter<_Res, __exception_ptr_tag>{ __prom, __ex };
+          return _Setter<_Res, __exception_ptr_tag>{ __prom, &__ex };
         }
 
-      static _Setter<void, void>
-      __setter(promise<void>* __prom);
-
       template<typename _Tp>
         static void
         _S_check(const shared_ptr<_Tp>& __p)
@@ -469,10 +466,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     private:
       void
-      _M_do_set(function<_Ptr_type()>& __f, unique_lock<mutex>& __lock)
+      _M_do_set(function<_Ptr_type()>* __f, unique_lock<mutex>* __lock)
       {
-        _Ptr_type __res = __f(); // do not hold lock while running setter
-       __lock.lock();
+        _Ptr_type __res = (*__f)(); // do not hold lock while running setter
+       __lock->lock();
         _M_result.swap(__res);
       }
 
@@ -514,15 +511,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static std::shared_ptr<_State_base>
       _S_make_async_state(_BoundFn&& __fn);
 
-    template<typename _Res_ptr,
+    template<typename _Res_ptr, typename _Fn,
             typename _Res = typename _Res_ptr::element_type::result_type>
       struct _Task_setter;
 
     template<typename _Res_ptr, typename _BoundFn>
-      static _Task_setter<_Res_ptr>
-      _S_task_setter(_Res_ptr& __ptr, _BoundFn&& __call)
+      static _Task_setter<_Res_ptr, _BoundFn>
+      _S_task_setter(_Res_ptr& __ptr, _BoundFn& __call)
       {
-       return _Task_setter<_Res_ptr>{ __ptr, std::ref(__call) };
+       return { std::__addressof(__ptr), std::__addressof(__call) };
       }
   };
 
@@ -554,6 +551,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       void _M_destroy() { delete this; }
     };
 
+  // Allow _Setter objects to be stored locally in std::function
+  template<typename _Res, typename _Arg>
+    struct __is_location_invariant
+    <__future_base::_State_base::_Setter<_Res, _Arg>>
+    : true_type { };
+
+  // Allow _Task_setter objects to be stored locally in std::function
+  template<typename _Res_ptr, typename _Fn, typename _Res>
+    struct __is_location_invariant
+    <__future_base::_Task_setter<_Res_ptr, _Fn, _Res>>
+    : true_type { };
+
 #ifndef _GLIBCXX_ASYNC_ABI_COMPAT
 
   /// Common implementation for future and shared_future.
@@ -994,24 +1003,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       // Setting the result
       void
       set_value(const _Res& __r)
-      {
-        auto __setter = _State::__setter(this, __r);
-        _M_future->_M_set_result(std::move(__setter));
-      }
+      { _M_future->_M_set_result(_State::__setter(this, __r)); }
 
       void
       set_value(_Res&& __r)
-      {
-        auto __setter = _State::__setter(this, std::move(__r));
-        _M_future->_M_set_result(std::move(__setter));
-      }
+      { _M_future->_M_set_result(_State::__setter(this, std::move(__r))); }
 
       void
       set_exception(exception_ptr __p)
-      {
-        auto __setter = _State::__setter(__p, this);
-        _M_future->_M_set_result(std::move(__setter));
-      }
+      { _M_future->_M_set_result(_State::__setter(__p, this)); }
     };
 
   template<typename _Res>
@@ -1092,17 +1092,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       // Setting the result
       void
       set_value(_Res& __r)
-      {
-        auto __setter = _State::__setter(this, __r);
-        _M_future->_M_set_result(std::move(__setter));
-      }
+      { _M_future->_M_set_result(_State::__setter(this, __r)); }
 
       void
       set_exception(exception_ptr __p)
-      {
-        auto __setter = _State::__setter(__p, this);
-        _M_future->_M_set_result(std::move(__setter));
-      }
+      { _M_future->_M_set_result(_State::__setter(__p, this)); }
     };
 
   /// Explicit specialization for promise<void>
@@ -1177,10 +1171,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       void
       set_exception(exception_ptr __p)
-      {
-        auto __setter = _State::__setter(__p, this);
-        _M_future->_M_set_result(std::move(__setter));
-      }
+      { _M_future->_M_set_result(_State::__setter(__p, this)); }
     };
 
   // set void
@@ -1196,28 +1187,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       promise<void>*    _M_promise;
     };
 
-  inline __future_base::_State_base::_Setter<void, void>
-  __future_base::_State_base::__setter(promise<void>* __prom)
-  {
-    return _Setter<void, void>{ __prom };
-  }
-
   inline void
   promise<void>::set_value()
-  {
-    auto __setter = _State::__setter(this);
-    _M_future->_M_set_result(std::move(__setter));
-  }
-
+  { _M_future->_M_set_result(_State::_Setter<void, void>{ this }); }
 
-  template<typename _Ptr_type, typename _Res>
+  template<typename _Ptr_type, typename _Fn, typename _Res>
     struct __future_base::_Task_setter
     {
       _Ptr_type operator()()
       {
        __try
          {
-           _M_result->_M_set(_M_fn());
+           (*_M_result)->_M_set((*_M_fn)());
          }
        __catch(const __cxxabiv1::__forced_unwind&)
          {
@@ -1225,22 +1206,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          }
        __catch(...)
          {
-           _M_result->_M_error = current_exception();
+           (*_M_result)->_M_error = current_exception();
          }
-       return std::move(_M_result);
+       return std::move(*_M_result);
       }
-      _Ptr_type&                _M_result;
-      std::function<_Res()>     _M_fn;
+      _Ptr_type*       _M_result;
+      _Fn*             _M_fn;
     };
 
-  template<typename _Ptr_type>
-    struct __future_base::_Task_setter<_Ptr_type, void>
+  template<typename _Ptr_type, typename _Fn>
+    struct __future_base::_Task_setter<_Ptr_type, _Fn, void>
     {
       _Ptr_type operator()()
       {
        __try
          {
-           _M_fn();
+           (*_M_fn)();
          }
        __catch(const __cxxabiv1::__forced_unwind&)
          {
@@ -1248,12 +1229,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          }
        __catch(...)
          {
-           _M_result->_M_error = current_exception();
+           (*_M_result)->_M_error = current_exception();
          }
-       return std::move(_M_result);
+       return std::move(*_M_result);
       }
-      _Ptr_type&                _M_result;
-      std::function<void()>     _M_fn;
+      _Ptr_type*       _M_result;
+      _Fn*             _M_fn;
     };
 
   template<typename _Res, typename... _Args>
@@ -1294,8 +1275,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        // bound arguments decay so wrap lvalue references
        auto __boundfn = std::__bind_simple(std::ref(_M_impl._M_fn),
            _S_maybe_wrap_ref(std::forward<_Args>(__args))...);
-       auto __setter = _S_task_setter(this->_M_result, std::move(__boundfn));
-       this->_M_set_result(std::move(__setter));
+       this->_M_set_result(_S_task_setter(this->_M_result, __boundfn));
       }
 
       virtual shared_ptr<_Task_state_base<_Res(_Args...)>>