2010-01-16 Paolo Carlini <paolo.carlini@oracle.com>
authorpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 17 Jan 2010 13:29:41 +0000 (13:29 +0000)
committerpaolo <paolo@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 17 Jan 2010 13:29:41 +0000 (13:29 +0000)
* include/std/functional (_Bind<_Functor(_Bound_args...)>::__call):
Rename const version to __call_c and remove _Sfinae template
parameter.
(_Bind<_Functor(_Bound_args...)>::operator()): Adjust.

* include/std/functional: Pass everywhere temporary tuple<_Args...>
arguments by rvalue reference.

* testsuite/20_util/bind/cv_quals.cc: New.

* testsuite/20_util/bind/ref2.cc: Add missing test variables.

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

libstdc++-v3/ChangeLog
libstdc++-v3/include/std/functional
libstdc++-v3/testsuite/20_util/bind/cv_quals.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/bind/ref2.cc

index cd65c4f..0e25c9e 100644 (file)
@@ -1,3 +1,17 @@
+2010-01-16  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       * include/std/functional (_Bind<_Functor(_Bound_args...)>::__call):
+       Rename const version to __call_c and remove _Sfinae template
+       parameter.
+       (_Bind<_Functor(_Bound_args...)>::operator()): Adjust.
+
+       * include/std/functional: Pass everywhere temporary tuple<_Args...>
+       arguments by rvalue reference.
+
+       * testsuite/20_util/bind/cv_quals.cc: New.
+
+       * testsuite/20_util/bind/ref2.cc: Add missing test variables.
+
 2010-01-16  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
 
        PR libstdc++/35942
index 34b85ab..5444f3d 100644 (file)
@@ -1,6 +1,6 @@
 // <functional> -*- C++ -*-
 
-// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
 // Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
@@ -112,8 +112,7 @@ namespace std
   template<typename _Functor>
     struct _Weak_result_type_impl
     : _Maybe_get_result_type<_Has_result_type<_Functor>::value, _Functor>
-    {
-    };
+    { };
 
   /// Retrieve the result type for a function type.
   template<typename _Res, typename... _ArgTypes> 
@@ -171,8 +170,7 @@ namespace std
   template<typename _Functor>
     struct _Weak_result_type
     : _Weak_result_type_impl<typename remove_cv<_Functor>::type>
-    {
-    };
+    { };
 
   template<typename _Signature>
     class result_of;
@@ -859,8 +857,7 @@ namespace std
     struct _Build_index_tuple<_Num, _Index_tuple<_Indexes...> >
     : _Build_index_tuple<_Num - 1, 
                          _Index_tuple<_Indexes..., sizeof...(_Indexes)> >
-    {
-    };
+    { };
 
   template<int... _Indexes>
     struct _Build_index_tuple<0, _Index_tuple<_Indexes...> >
@@ -902,8 +899,7 @@ namespace std
    struct _Safe_tuple_element
    : _Safe_tuple_element_impl<__i, _Tuple, 
                               (__i >= 0 && __i < tuple_size<_Tuple>::value)>
-   {
-   };
+   { };
 
   /**
    *  Maps an argument to bind() into an actual argument to the bound
@@ -937,7 +933,7 @@ namespace std
        */
       template<typename _CVRef, typename _Tuple>
         result_type
-        operator()(_CVRef& __arg, const _Tuple&) const volatile
+        operator()(_CVRef& __arg, _Tuple&&) const volatile
         { return __arg.get(); }
     };
 
@@ -962,12 +958,12 @@ namespace std
       template<typename _CVArg, typename... _Args>
         typename result_of<_CVArg(_Args...)>::type
         operator()(_CVArg& __arg,
-                  tuple<_Args...>& __tuple) const volatile
+                  tuple<_Args...>&& __tuple) const volatile
         {
          // Construct an index tuple and forward to __call
          typedef typename _Build_index_tuple<sizeof...(_Args)>::__type
            _Indexes;
-         return this->__call(__arg, __tuple, _Indexes());
+         return this->__call(__arg, std::move(__tuple), _Indexes());
        }
 
     private:
@@ -975,7 +971,7 @@ namespace std
       // of the arguments in the tuple. 
       template<typename _CVArg, typename... _Args, int... _Indexes>
         typename result_of<_CVArg(_Args...)>::type
-        __call(_CVArg& __arg, tuple<_Args...>& __tuple,
+        __call(_CVArg& __arg, tuple<_Args...>&& __tuple,
               const _Index_tuple<_Indexes...>&) const volatile
         {
          return __arg(std::forward<_Args>(get<_Indexes>(__tuple))...);
@@ -1009,7 +1005,7 @@ namespace std
 
       template<typename _Tuple>
         typename result<_Mu(_Arg, _Tuple)>::type
-        operator()(const volatile _Arg&, _Tuple& __tuple) const volatile
+        operator()(const volatile _Arg&, _Tuple&& __tuple) const volatile
         {
          return std::forward<typename result<_Mu(_Arg, _Tuple)>::type>(
               ::std::get<(is_placeholder<_Arg>::value - 1)>(__tuple));
@@ -1036,7 +1032,7 @@ namespace std
       // Pick up the cv-qualifiers of the argument
       template<typename _CVArg, typename _Tuple>
         _CVArg&&
-        operator()(_CVArg&& __arg, const _Tuple&) const volatile
+        operator()(_CVArg&& __arg, _Tuple&&) const volatile
         { return std::forward<_CVArg>(__arg); }
     };
 
@@ -1096,137 +1092,114 @@ namespace std
       tuple<_Bound_args...> _M_bound_args;
 
       // Call unqualified
-      template<typename... _Args, int... _Indexes, typename _Sfinae
-        = decltype( std::declval<_Functor>()(
-              _Mu<_Bound_args>()( std::declval<_Bound_args&>(),
-                                  std::declval<tuple<_Args...>&>() )... ) )>
+      template<typename... _Args, int... _Indexes>
         typename result_of<
                    _Functor(typename result_of<_Mu<_Bound_args> 
-                            (_Bound_args&, tuple<_Args...>&)>::type...)
+                            (_Bound_args&, tuple<_Args...>&&)>::type...)
                  >::type
         __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>)
         {
           return _M_f(_Mu<_Bound_args>()
-                      (get<_Indexes>(_M_bound_args), __args)...);
+                      (get<_Indexes>(_M_bound_args), std::move(__args))...);
         }
 
       // Call as const
-      template<typename... _Args, int... _Indexes, typename _Sfinae
-        = decltype( std::declval<const _Functor>()(
-              _Mu<_Bound_args>()( std::declval<const _Bound_args&>(),
-                                  std::declval<tuple<_Args...>&>() )... ) )>
+      template<typename... _Args, int... _Indexes>
         typename result_of<
                    const _Functor(typename result_of<_Mu<_Bound_args> 
-                                    (const _Bound_args&, tuple<_Args...>&)
+                                    (const _Bound_args&, tuple<_Args...>&&)
                                   >::type...)>::type
-        __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const
+        __call_c(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) const
         {
           return _M_f(_Mu<_Bound_args>()
-                      (get<_Indexes>(_M_bound_args), __args)...);
+                      (get<_Indexes>(_M_bound_args), std::move(__args))...);
         }
 
 #if 0
       // Call as volatile
-      template<typename... _Args, int... _Indexes, typename _Sfinae
-        = decltype( std::declval<volatile _Functor>()(
-              _Mu<_Bound_args>()( std::declval<volatile _Bound_args&>(),
-                                  std::declval<tuple<_Args...>&>() )... ) )>
+      template<typename... _Args, int... _Indexes>
         typename result_of<
                    volatile _Functor(typename result_of<_Mu<_Bound_args> 
-                                    (volatile _Bound_args&, tuple<_Args...>&)
+                                    (volatile _Bound_args&, tuple<_Args...>&&)
                                   >::type...)>::type
-        __call(tuple<_Args...>&& __args, 
-               _Index_tuple<_Indexes...>) volatile
+        __call_v(tuple<_Args...>&& __args, 
+                _Index_tuple<_Indexes...>) volatile
         {
           return _M_f(_Mu<_Bound_args>()
-                      (get<_Indexes>(_M_bound_args), __args)...);
+                      (get<_Indexes>(_M_bound_args), std::move(__args))...);
         }
 
       // Call as const volatile
-      template<typename... _Args, int... _Indexes, typename _Sfinae
-        = decltype( std::declval<const volatile _Functor>()(
-              _Mu<_Bound_args>()( std::declval<const volatile _Bound_args&>(),
-                                  std::declval<tuple<_Args...>&>() )... ) )>
+      template<typename... _Args, int... _Indexes>
         typename result_of<
                    const volatile _Functor(typename result_of<_Mu<_Bound_args> 
                                     (const volatile _Bound_args&, 
-                                     tuple<_Args...>&)
+                                     tuple<_Args...>&&)
                                   >::type...)>::type
-        __call(tuple<_Args...>&& __args, 
-               _Index_tuple<_Indexes...>) const volatile
+        __call_c_v(tuple<_Args...>&& __args, 
+                  _Index_tuple<_Indexes...>) const volatile
         {
           return _M_f(_Mu<_Bound_args>()
-                      (get<_Indexes>(_M_bound_args), __args)...);
+                      (get<_Indexes>(_M_bound_args), std::move(__args))...);
         }
 #endif
 
      public:
       explicit _Bind(_Functor __f, _Bound_args... __bound_args)
       : _M_f(std::forward<_Functor>(__f)),
-      _M_bound_args(std::forward<_Bound_args>(__bound_args)...)
+       _M_bound_args(std::forward<_Bound_args>(__bound_args)...)
       { }
 
       // Call unqualified
-      template<typename... _Args, typename _Sfinae
+      template<typename... _Args, typename _Result
         = decltype( std::declval<_Functor>()(
               _Mu<_Bound_args>()( std::declval<_Bound_args&>(),
-                                  std::declval<tuple<_Args...>&>() )... ) )>
-        typename result_of<
-                   _Functor(typename result_of<_Mu<_Bound_args> 
-                            (_Bound_args&, tuple<_Args...>&)>::type...)
-                 >::type
+                                 std::declval<tuple<_Args...>&&>() )... ) )>
+        _Result
         operator()(_Args&&... __args)
         {
           return this->__call(tuple<_Args...>(std::forward<_Args>(__args)...),
-                              _Bound_indexes());
+                             _Bound_indexes());
         }
 
       // Call as const
-      template<typename... _Args, typename _Sfinae
+      template<typename... _Args, typename _Result
         = decltype( std::declval<const _Functor>()(
-              _Mu<_Bound_args>()( std::declval<const _Bound_args&>(),
-                                  std::declval<tuple<_Args...>&>() )... ) )>
-        typename result_of<
-                   const _Functor(typename result_of<_Mu<_Bound_args> 
-                            (const _Bound_args&, tuple<_Args...>&)>::type...)
-                 >::type
+             _Mu<_Bound_args>()( std::declval<const _Bound_args&>(),
+                                 std::declval<tuple<_Args...>&&>() )... ) )>
+        _Result
         operator()(_Args&&... __args) const
         {
-          return this->__call(tuple<_Args...>(std::forward<_Args>(__args)...),
-                              _Bound_indexes());
+          return this->__call_c(tuple<_Args...>
+                               (std::forward<_Args>(__args)...),
+                               _Bound_indexes());
         }
 
 #if 0
       // Call as volatile
-      template<typename... _Args, typename _Sfinae
+      template<typename... _Args, typename _Result
         = decltype( std::declval<volatile _Functor>()(
               _Mu<_Bound_args>()( std::declval<volatile _Bound_args&>(),
-                                  std::declval<tuple<_Args...>&>() )... ) )>
-        typename result_of<
-                   volatile _Functor(typename result_of<_Mu<_Bound_args> 
-                            (volatile _Bound_args&, tuple<_Args...>&)>::type...)
-                 >::type
+                                  std::declval<tuple<_Args...>&&>() )... ) )>
+        _Result
         operator()(_Args&&... __args) volatile
         {
-          return this->__call(tuple<_Args...>(std::forward<_Args>(__args)...),
-                              _Bound_indexes());
+          return this->__call_v(tuple<_Args...>
+                               (std::forward<_Args>(__args)...),
+                               _Bound_indexes());
         }
 
-
       // Call as const volatile
-      template<typename... _Args, typename _Sfinae
+      template<typename... _Args, typename _Result
         = decltype( std::declval<const volatile _Functor>()(
               _Mu<_Bound_args>()( std::declval<const volatile _Bound_args&>(),
-                                  std::declval<tuple<_Args...>&>() )... ) )>
-        typename result_of<
-                   const volatile _Functor(typename result_of<_Mu<_Bound_args> 
-                            (const volatile _Bound_args&, 
-                             tuple<_Args...>&)>::type...)
-                 >::type
+                                  std::declval<tuple<_Args...>&&>() )... ) )>
+        _Result
         operator()(_Args&&... __args) const volatile
         {
-          return this->__call(tuple<_Args...>(std::forward<_Args>(__args)...),
-                              _Bound_indexes());
+          return this->__call_c_v(tuple<_Args...>
+                                 (std::forward<_Args>(__args)...),
+                                 _Bound_indexes());
         }
 #endif
     };
@@ -1258,7 +1231,7 @@ namespace std
             typename __disable_if_void<_Res>::type = 0)
         {
           return _M_f(_Mu<_Bound_args>()
-                      (get<_Indexes>(_M_bound_args), __args)...);
+                      (get<_Indexes>(_M_bound_args), std::move(__args))...);
         }
 
       // Call unqualified, return void
@@ -1268,7 +1241,7 @@ namespace std
             typename __enable_if_void<_Res>::type = 0)
         {
           _M_f(_Mu<_Bound_args>()
-                      (get<_Indexes>(_M_bound_args), __args)...);
+              (get<_Indexes>(_M_bound_args), std::move(__args))...);
         }
 
       // Call as const
@@ -1278,7 +1251,7 @@ namespace std
             typename __disable_if_void<_Res>::type = 0) const
         {
           return _M_f(_Mu<_Bound_args>()
-                      (get<_Indexes>(_M_bound_args), __args)...);
+                      (get<_Indexes>(_M_bound_args), std::move(__args))...);
         }
 
       // Call as const, return void
@@ -1288,7 +1261,7 @@ namespace std
             typename __enable_if_void<_Res>::type = 0) const
         {
           _M_f(_Mu<_Bound_args>()
-                      (get<_Indexes>(_M_bound_args), __args)...);
+              (get<_Indexes>(_M_bound_args),  std::move(__args))...);
         }
 
       // Call as volatile
@@ -1298,7 +1271,7 @@ namespace std
             typename __disable_if_void<_Res>::type = 0) volatile
         {
           return _M_f(_Mu<_Bound_args>()
-                      (get<_Indexes>(_M_bound_args), __args)...);
+                      (get<_Indexes>(_M_bound_args), std::move(__args))...);
         }
 
       // Call as volatile, return void
@@ -1308,7 +1281,7 @@ namespace std
             typename __enable_if_void<_Res>::type = 0) volatile
         {
           _M_f(_Mu<_Bound_args>()
-                      (get<_Indexes>(_M_bound_args), __args)...);
+              (get<_Indexes>(_M_bound_args), std::move(__args))...);
         }
 
       // Call as const volatile
@@ -1318,7 +1291,7 @@ namespace std
             typename __disable_if_void<_Res>::type = 0) const volatile
         {
           return _M_f(_Mu<_Bound_args>()
-                      (get<_Indexes>(_M_bound_args), __args)...);
+                      (get<_Indexes>(_M_bound_args), std::move(__args))...);
         }
 
       // Call as const volatile, return void
@@ -1329,7 +1302,7 @@ namespace std
             typename __enable_if_void<_Res>::type = 0) const volatile
         {
           _M_f(_Mu<_Bound_args>()
-                      (get<_Indexes>(_M_bound_args), __args)...);
+              (get<_Indexes>(_M_bound_args), std::move(__args))...);
         }
 
     public:
@@ -1338,7 +1311,7 @@ namespace std
       explicit
       _Bind_result(_Functor __f, _Bound_args... __bound_args)
       : _M_f(std::forward<_Functor>(__f)),
-      _M_bound_args(std::forward<_Bound_args>(__bound_args)...)
+       _M_bound_args(std::forward<_Bound_args>(__bound_args)...)
       { }
 
       // Call unqualified
@@ -1447,11 +1420,9 @@ namespace std
    */
   template<typename _Tp>
     struct __is_location_invariant
-    : integral_constant<bool,
-                        (is_pointer<_Tp>::value
-                         || is_member_pointer<_Tp>::value)>
-    {
-    };
+    : integral_constant<bool, (is_pointer<_Tp>::value
+                              || is_member_pointer<_Tp>::value)>
+    { };
 
   class _Undefined_class;
 
@@ -1503,8 +1474,7 @@ namespace std
   template<typename _Tp>
     struct __is_location_invariant<_Simple_type_wrapper<_Tp> >
     : __is_location_invariant<_Tp>
-    {
-    };
+    { };
 
   // Converts a reference to a function object into a callable
   // function object.
diff --git a/libstdc++-v3/testsuite/20_util/bind/cv_quals.cc b/libstdc++-v3/testsuite/20_util/bind/cv_quals.cc
new file mode 100644 (file)
index 0000000..b42fe9a
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright (C) 2010 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/>.
+
+// 20.7.11 Function template bind
+
+// { dg-options "-std=gnu++0x" }
+
+#include <functional>
+#include <testsuite_hooks.h>
+
+struct X
+{
+  int operator()() { return 0; }
+  int operator()() const { return 1; }
+  // int operator()() volatile { return 2; }
+  // int operator()() const volatile { return 3; }
+};
+
+void test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  auto b0 = std::bind(X());
+  VERIFY( b0() == 0 );
+
+  const auto b1 = std::bind(X());
+  VERIFY( b1() == 1 );
+
+  // volatile auto b2 = std::bind(X());
+  // VERIFY( b2() == 2 );
+
+  // const volatile auto b3 = std::bind(X());
+  // VERIFY( b3() == 3 );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}
index bf6456c..6149431 100644 (file)
@@ -28,6 +28,8 @@ int inc(int& i) { return ++i; }
 
 void test01()
 {
+  bool test __attribute__((unused)) = true;
+
   int counter = 0;
   std::bind(&inc, _1)(counter);
   VERIFY(counter == 1 );
@@ -45,6 +47,8 @@ struct Inc
 
 void test02()
 {
+  bool test __attribute__((unused)) = true;
+
   int counter = 0;
   std::bind(Inc(), _1)(counter);
   VERIFY(counter == 1 );