From 13564f8d5208edb6c471fd28635a49a7e94155f3 Mon Sep 17 00:00:00 2001 From: paolo Date: Sun, 17 Jan 2010 13:29:41 +0000 Subject: [PATCH] 2010-01-16 Paolo Carlini * 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 | 14 +++ libstdc++-v3/include/std/functional | 160 ++++++++++-------------- libstdc++-v3/testsuite/20_util/bind/cv_quals.cc | 54 ++++++++ libstdc++-v3/testsuite/20_util/bind/ref2.cc | 4 + 4 files changed, 137 insertions(+), 95 deletions(-) create mode 100644 libstdc++-v3/testsuite/20_util/bind/cv_quals.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index cd65c4fa4c8..0e25c9e2ae5 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,17 @@ +2010-01-16 Paolo Carlini + + * 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 PR libstdc++/35942 diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index 34b85ab9597..5444f3d1f1c 100644 --- a/libstdc++-v3/include/std/functional +++ b/libstdc++-v3/include/std/functional @@ -1,6 +1,6 @@ // -*- 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 struct _Weak_result_type_impl : _Maybe_get_result_type<_Has_result_type<_Functor>::value, _Functor> - { - }; + { }; /// Retrieve the result type for a function type. template @@ -171,8 +170,7 @@ namespace std template struct _Weak_result_type : _Weak_result_type_impl::type> - { - }; + { }; template 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 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 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 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::__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 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 result<_Mu(_Arg, _Tuple)>::type - operator()(const volatile _Arg&, _Tuple& __tuple) const volatile + operator()(const volatile _Arg&, _Tuple&& __tuple) const volatile { return std::forward::type>( ::std::get<(is_placeholder<_Arg>::value - 1)>(__tuple)); @@ -1036,7 +1032,7 @@ namespace std // Pick up the cv-qualifiers of the argument template _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()( - _Mu<_Bound_args>()( std::declval<_Bound_args&>(), - std::declval&>() )... ) )> + template 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()( - _Mu<_Bound_args>()( std::declval(), - std::declval&>() )... ) )> + template 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()( - _Mu<_Bound_args>()( std::declval(), - std::declval&>() )... ) )> + template 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()( - _Mu<_Bound_args>()( std::declval(), - std::declval&>() )... ) )> + template 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()( _Mu<_Bound_args>()( std::declval<_Bound_args&>(), - std::declval&>() )... ) )> - typename result_of< - _Functor(typename result_of<_Mu<_Bound_args> - (_Bound_args&, tuple<_Args...>&)>::type...) - >::type + std::declval&&>() )... ) )> + _Result operator()(_Args&&... __args) { return this->__call(tuple<_Args...>(std::forward<_Args>(__args)...), - _Bound_indexes()); + _Bound_indexes()); } // Call as const - template()( - _Mu<_Bound_args>()( std::declval(), - std::declval&>() )... ) )> - typename result_of< - const _Functor(typename result_of<_Mu<_Bound_args> - (const _Bound_args&, tuple<_Args...>&)>::type...) - >::type + _Mu<_Bound_args>()( std::declval(), + std::declval&&>() )... ) )> + _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()( _Mu<_Bound_args>()( std::declval(), - std::declval&>() )... ) )> - typename result_of< - volatile _Functor(typename result_of<_Mu<_Bound_args> - (volatile _Bound_args&, tuple<_Args...>&)>::type...) - >::type + std::declval&&>() )... ) )> + _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()( _Mu<_Bound_args>()( std::declval(), - std::declval&>() )... ) )> - typename result_of< - const volatile _Functor(typename result_of<_Mu<_Bound_args> - (const volatile _Bound_args&, - tuple<_Args...>&)>::type...) - >::type + std::declval&&>() )... ) )> + _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 struct __is_location_invariant - : integral_constant::value - || is_member_pointer<_Tp>::value)> - { - }; + : integral_constant::value + || is_member_pointer<_Tp>::value)> + { }; class _Undefined_class; @@ -1503,8 +1474,7 @@ namespace std template 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 index 00000000000..b42fe9a6159 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/bind/cv_quals.cc @@ -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 +// . + +// 20.7.11 Function template bind + +// { dg-options "-std=gnu++0x" } + +#include +#include + +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; +} diff --git a/libstdc++-v3/testsuite/20_util/bind/ref2.cc b/libstdc++-v3/testsuite/20_util/bind/ref2.cc index bf6456c38b5..61494315756 100644 --- a/libstdc++-v3/testsuite/20_util/bind/ref2.cc +++ b/libstdc++-v3/testsuite/20_util/bind/ref2.cc @@ -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 ); -- 2.11.0