Commit 8232dc64 by Paolo Carlini Committed by Paolo Carlini

functional (_Bind<_Functor(_Bound_args...)>::__call): Rename const version to…

functional (_Bind<_Functor(_Bound_args...)>::__call): Rename const version to __call_c and remove _Sfinae template parameter.

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.

From-SVN: r155978
parent fc35a90d
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> 2010-01-16 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
PR libstdc++/35942 PR libstdc++/35942
......
// <functional> -*- C++ -*- // <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. // Free Software Foundation, Inc.
// //
// This file is part of the GNU ISO C++ Library. This library is free // This file is part of the GNU ISO C++ Library. This library is free
...@@ -112,8 +112,7 @@ namespace std ...@@ -112,8 +112,7 @@ namespace std
template<typename _Functor> template<typename _Functor>
struct _Weak_result_type_impl struct _Weak_result_type_impl
: _Maybe_get_result_type<_Has_result_type<_Functor>::value, _Functor> : _Maybe_get_result_type<_Has_result_type<_Functor>::value, _Functor>
{ { };
};
/// Retrieve the result type for a function type. /// Retrieve the result type for a function type.
template<typename _Res, typename... _ArgTypes> template<typename _Res, typename... _ArgTypes>
...@@ -171,8 +170,7 @@ namespace std ...@@ -171,8 +170,7 @@ namespace std
template<typename _Functor> template<typename _Functor>
struct _Weak_result_type struct _Weak_result_type
: _Weak_result_type_impl<typename remove_cv<_Functor>::type> : _Weak_result_type_impl<typename remove_cv<_Functor>::type>
{ { };
};
template<typename _Signature> template<typename _Signature>
class result_of; class result_of;
...@@ -859,8 +857,7 @@ namespace std ...@@ -859,8 +857,7 @@ namespace std
struct _Build_index_tuple<_Num, _Index_tuple<_Indexes...> > struct _Build_index_tuple<_Num, _Index_tuple<_Indexes...> >
: _Build_index_tuple<_Num - 1, : _Build_index_tuple<_Num - 1,
_Index_tuple<_Indexes..., sizeof...(_Indexes)> > _Index_tuple<_Indexes..., sizeof...(_Indexes)> >
{ { };
};
template<int... _Indexes> template<int... _Indexes>
struct _Build_index_tuple<0, _Index_tuple<_Indexes...> > struct _Build_index_tuple<0, _Index_tuple<_Indexes...> >
...@@ -902,8 +899,7 @@ namespace std ...@@ -902,8 +899,7 @@ namespace std
struct _Safe_tuple_element struct _Safe_tuple_element
: _Safe_tuple_element_impl<__i, _Tuple, : _Safe_tuple_element_impl<__i, _Tuple,
(__i >= 0 && __i < tuple_size<_Tuple>::value)> (__i >= 0 && __i < tuple_size<_Tuple>::value)>
{ { };
};
/** /**
* Maps an argument to bind() into an actual argument to the bound * Maps an argument to bind() into an actual argument to the bound
...@@ -937,7 +933,7 @@ namespace std ...@@ -937,7 +933,7 @@ namespace std
*/ */
template<typename _CVRef, typename _Tuple> template<typename _CVRef, typename _Tuple>
result_type result_type
operator()(_CVRef& __arg, const _Tuple&) const volatile operator()(_CVRef& __arg, _Tuple&&) const volatile
{ return __arg.get(); } { return __arg.get(); }
}; };
...@@ -962,12 +958,12 @@ namespace std ...@@ -962,12 +958,12 @@ namespace std
template<typename _CVArg, typename... _Args> template<typename _CVArg, typename... _Args>
typename result_of<_CVArg(_Args...)>::type typename result_of<_CVArg(_Args...)>::type
operator()(_CVArg& __arg, operator()(_CVArg& __arg,
tuple<_Args...>& __tuple) const volatile tuple<_Args...>&& __tuple) const volatile
{ {
// Construct an index tuple and forward to __call // Construct an index tuple and forward to __call
typedef typename _Build_index_tuple<sizeof...(_Args)>::__type typedef typename _Build_index_tuple<sizeof...(_Args)>::__type
_Indexes; _Indexes;
return this->__call(__arg, __tuple, _Indexes()); return this->__call(__arg, std::move(__tuple), _Indexes());
} }
private: private:
...@@ -975,7 +971,7 @@ namespace std ...@@ -975,7 +971,7 @@ namespace std
// of the arguments in the tuple. // of the arguments in the tuple.
template<typename _CVArg, typename... _Args, int... _Indexes> template<typename _CVArg, typename... _Args, int... _Indexes>
typename result_of<_CVArg(_Args...)>::type typename result_of<_CVArg(_Args...)>::type
__call(_CVArg& __arg, tuple<_Args...>& __tuple, __call(_CVArg& __arg, tuple<_Args...>&& __tuple,
const _Index_tuple<_Indexes...>&) const volatile const _Index_tuple<_Indexes...>&) const volatile
{ {
return __arg(std::forward<_Args>(get<_Indexes>(__tuple))...); return __arg(std::forward<_Args>(get<_Indexes>(__tuple))...);
...@@ -1009,7 +1005,7 @@ namespace std ...@@ -1009,7 +1005,7 @@ namespace std
template<typename _Tuple> template<typename _Tuple>
typename result<_Mu(_Arg, _Tuple)>::type 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>( return std::forward<typename result<_Mu(_Arg, _Tuple)>::type>(
::std::get<(is_placeholder<_Arg>::value - 1)>(__tuple)); ::std::get<(is_placeholder<_Arg>::value - 1)>(__tuple));
...@@ -1036,7 +1032,7 @@ namespace std ...@@ -1036,7 +1032,7 @@ namespace std
// Pick up the cv-qualifiers of the argument // Pick up the cv-qualifiers of the argument
template<typename _CVArg, typename _Tuple> template<typename _CVArg, typename _Tuple>
_CVArg&& _CVArg&&
operator()(_CVArg&& __arg, const _Tuple&) const volatile operator()(_CVArg&& __arg, _Tuple&&) const volatile
{ return std::forward<_CVArg>(__arg); } { return std::forward<_CVArg>(__arg); }
}; };
...@@ -1096,137 +1092,114 @@ namespace std ...@@ -1096,137 +1092,114 @@ namespace std
tuple<_Bound_args...> _M_bound_args; tuple<_Bound_args...> _M_bound_args;
// Call unqualified // Call unqualified
template<typename... _Args, int... _Indexes, typename _Sfinae template<typename... _Args, int... _Indexes>
= decltype( std::declval<_Functor>()(
_Mu<_Bound_args>()( std::declval<_Bound_args&>(),
std::declval<tuple<_Args...>&>() )... ) )>
typename result_of< typename result_of<
_Functor(typename result_of<_Mu<_Bound_args> _Functor(typename result_of<_Mu<_Bound_args>
(_Bound_args&, tuple<_Args...>&)>::type...) (_Bound_args&, tuple<_Args...>&&)>::type...)
>::type >::type
__call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>) __call(tuple<_Args...>&& __args, _Index_tuple<_Indexes...>)
{ {
return _M_f(_Mu<_Bound_args>() return _M_f(_Mu<_Bound_args>()
(get<_Indexes>(_M_bound_args), __args)...); (get<_Indexes>(_M_bound_args), std::move(__args))...);
} }
// Call as const // Call as const
template<typename... _Args, int... _Indexes, typename _Sfinae template<typename... _Args, int... _Indexes>
= decltype( std::declval<const _Functor>()(
_Mu<_Bound_args>()( std::declval<const _Bound_args&>(),
std::declval<tuple<_Args...>&>() )... ) )>
typename result_of< typename result_of<
const _Functor(typename result_of<_Mu<_Bound_args> const _Functor(typename result_of<_Mu<_Bound_args>
(const _Bound_args&, tuple<_Args...>&) (const _Bound_args&, tuple<_Args...>&&)
>::type...)>::type >::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>() return _M_f(_Mu<_Bound_args>()
(get<_Indexes>(_M_bound_args), __args)...); (get<_Indexes>(_M_bound_args), std::move(__args))...);
} }
#if 0 #if 0
// Call as volatile // Call as volatile
template<typename... _Args, int... _Indexes, typename _Sfinae template<typename... _Args, int... _Indexes>
= decltype( std::declval<volatile _Functor>()(
_Mu<_Bound_args>()( std::declval<volatile _Bound_args&>(),
std::declval<tuple<_Args...>&>() )... ) )>
typename result_of< typename result_of<
volatile _Functor(typename result_of<_Mu<_Bound_args> volatile _Functor(typename result_of<_Mu<_Bound_args>
(volatile _Bound_args&, tuple<_Args...>&) (volatile _Bound_args&, tuple<_Args...>&&)
>::type...)>::type >::type...)>::type
__call(tuple<_Args...>&& __args, __call_v(tuple<_Args...>&& __args,
_Index_tuple<_Indexes...>) volatile _Index_tuple<_Indexes...>) volatile
{ {
return _M_f(_Mu<_Bound_args>() return _M_f(_Mu<_Bound_args>()
(get<_Indexes>(_M_bound_args), __args)...); (get<_Indexes>(_M_bound_args), std::move(__args))...);
} }
// Call as const volatile // Call as const volatile
template<typename... _Args, int... _Indexes, typename _Sfinae template<typename... _Args, int... _Indexes>
= decltype( std::declval<const volatile _Functor>()(
_Mu<_Bound_args>()( std::declval<const volatile _Bound_args&>(),
std::declval<tuple<_Args...>&>() )... ) )>
typename result_of< typename result_of<
const volatile _Functor(typename result_of<_Mu<_Bound_args> const volatile _Functor(typename result_of<_Mu<_Bound_args>
(const volatile _Bound_args&, (const volatile _Bound_args&,
tuple<_Args...>&) tuple<_Args...>&&)
>::type...)>::type >::type...)>::type
__call(tuple<_Args...>&& __args, __call_c_v(tuple<_Args...>&& __args,
_Index_tuple<_Indexes...>) const volatile _Index_tuple<_Indexes...>) const volatile
{ {
return _M_f(_Mu<_Bound_args>() return _M_f(_Mu<_Bound_args>()
(get<_Indexes>(_M_bound_args), __args)...); (get<_Indexes>(_M_bound_args), std::move(__args))...);
} }
#endif #endif
public: public:
explicit _Bind(_Functor __f, _Bound_args... __bound_args) explicit _Bind(_Functor __f, _Bound_args... __bound_args)
: _M_f(std::forward<_Functor>(__f)), : _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 // Call unqualified
template<typename... _Args, typename _Sfinae template<typename... _Args, typename _Result
= decltype( std::declval<_Functor>()( = decltype( std::declval<_Functor>()(
_Mu<_Bound_args>()( std::declval<_Bound_args&>(), _Mu<_Bound_args>()( std::declval<_Bound_args&>(),
std::declval<tuple<_Args...>&>() )... ) )> std::declval<tuple<_Args...>&&>() )... ) )>
typename result_of< _Result
_Functor(typename result_of<_Mu<_Bound_args>
(_Bound_args&, tuple<_Args...>&)>::type...)
>::type
operator()(_Args&&... __args) operator()(_Args&&... __args)
{ {
return this->__call(tuple<_Args...>(std::forward<_Args>(__args)...), return this->__call(tuple<_Args...>(std::forward<_Args>(__args)...),
_Bound_indexes()); _Bound_indexes());
} }
// Call as const // Call as const
template<typename... _Args, typename _Sfinae template<typename... _Args, typename _Result
= decltype( std::declval<const _Functor>()( = decltype( std::declval<const _Functor>()(
_Mu<_Bound_args>()( std::declval<const _Bound_args&>(), _Mu<_Bound_args>()( std::declval<const _Bound_args&>(),
std::declval<tuple<_Args...>&>() )... ) )> std::declval<tuple<_Args...>&&>() )... ) )>
typename result_of< _Result
const _Functor(typename result_of<_Mu<_Bound_args>
(const _Bound_args&, tuple<_Args...>&)>::type...)
>::type
operator()(_Args&&... __args) const operator()(_Args&&... __args) const
{ {
return this->__call(tuple<_Args...>(std::forward<_Args>(__args)...), return this->__call_c(tuple<_Args...>
_Bound_indexes()); (std::forward<_Args>(__args)...),
_Bound_indexes());
} }
#if 0 #if 0
// Call as volatile // Call as volatile
template<typename... _Args, typename _Sfinae template<typename... _Args, typename _Result
= decltype( std::declval<volatile _Functor>()( = decltype( std::declval<volatile _Functor>()(
_Mu<_Bound_args>()( std::declval<volatile _Bound_args&>(), _Mu<_Bound_args>()( std::declval<volatile _Bound_args&>(),
std::declval<tuple<_Args...>&>() )... ) )> std::declval<tuple<_Args...>&&>() )... ) )>
typename result_of< _Result
volatile _Functor(typename result_of<_Mu<_Bound_args>
(volatile _Bound_args&, tuple<_Args...>&)>::type...)
>::type
operator()(_Args&&... __args) volatile operator()(_Args&&... __args) volatile
{ {
return this->__call(tuple<_Args...>(std::forward<_Args>(__args)...), return this->__call_v(tuple<_Args...>
_Bound_indexes()); (std::forward<_Args>(__args)...),
_Bound_indexes());
} }
// Call as const volatile // Call as const volatile
template<typename... _Args, typename _Sfinae template<typename... _Args, typename _Result
= decltype( std::declval<const volatile _Functor>()( = decltype( std::declval<const volatile _Functor>()(
_Mu<_Bound_args>()( std::declval<const volatile _Bound_args&>(), _Mu<_Bound_args>()( std::declval<const volatile _Bound_args&>(),
std::declval<tuple<_Args...>&>() )... ) )> std::declval<tuple<_Args...>&&>() )... ) )>
typename result_of< _Result
const volatile _Functor(typename result_of<_Mu<_Bound_args>
(const volatile _Bound_args&,
tuple<_Args...>&)>::type...)
>::type
operator()(_Args&&... __args) const volatile operator()(_Args&&... __args) const volatile
{ {
return this->__call(tuple<_Args...>(std::forward<_Args>(__args)...), return this->__call_c_v(tuple<_Args...>
_Bound_indexes()); (std::forward<_Args>(__args)...),
_Bound_indexes());
} }
#endif #endif
}; };
...@@ -1258,7 +1231,7 @@ namespace std ...@@ -1258,7 +1231,7 @@ namespace std
typename __disable_if_void<_Res>::type = 0) typename __disable_if_void<_Res>::type = 0)
{ {
return _M_f(_Mu<_Bound_args>() return _M_f(_Mu<_Bound_args>()
(get<_Indexes>(_M_bound_args), __args)...); (get<_Indexes>(_M_bound_args), std::move(__args))...);
} }
// Call unqualified, return void // Call unqualified, return void
...@@ -1268,7 +1241,7 @@ namespace std ...@@ -1268,7 +1241,7 @@ namespace std
typename __enable_if_void<_Res>::type = 0) typename __enable_if_void<_Res>::type = 0)
{ {
_M_f(_Mu<_Bound_args>() _M_f(_Mu<_Bound_args>()
(get<_Indexes>(_M_bound_args), __args)...); (get<_Indexes>(_M_bound_args), std::move(__args))...);
} }
// Call as const // Call as const
...@@ -1278,7 +1251,7 @@ namespace std ...@@ -1278,7 +1251,7 @@ namespace std
typename __disable_if_void<_Res>::type = 0) const typename __disable_if_void<_Res>::type = 0) const
{ {
return _M_f(_Mu<_Bound_args>() 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 // Call as const, return void
...@@ -1288,7 +1261,7 @@ namespace std ...@@ -1288,7 +1261,7 @@ namespace std
typename __enable_if_void<_Res>::type = 0) const typename __enable_if_void<_Res>::type = 0) const
{ {
_M_f(_Mu<_Bound_args>() _M_f(_Mu<_Bound_args>()
(get<_Indexes>(_M_bound_args), __args)...); (get<_Indexes>(_M_bound_args), std::move(__args))...);
} }
// Call as volatile // Call as volatile
...@@ -1298,7 +1271,7 @@ namespace std ...@@ -1298,7 +1271,7 @@ namespace std
typename __disable_if_void<_Res>::type = 0) volatile typename __disable_if_void<_Res>::type = 0) volatile
{ {
return _M_f(_Mu<_Bound_args>() 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 // Call as volatile, return void
...@@ -1308,7 +1281,7 @@ namespace std ...@@ -1308,7 +1281,7 @@ namespace std
typename __enable_if_void<_Res>::type = 0) volatile typename __enable_if_void<_Res>::type = 0) volatile
{ {
_M_f(_Mu<_Bound_args>() _M_f(_Mu<_Bound_args>()
(get<_Indexes>(_M_bound_args), __args)...); (get<_Indexes>(_M_bound_args), std::move(__args))...);
} }
// Call as const volatile // Call as const volatile
...@@ -1318,7 +1291,7 @@ namespace std ...@@ -1318,7 +1291,7 @@ namespace std
typename __disable_if_void<_Res>::type = 0) const volatile typename __disable_if_void<_Res>::type = 0) const volatile
{ {
return _M_f(_Mu<_Bound_args>() 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 // Call as const volatile, return void
...@@ -1329,7 +1302,7 @@ namespace std ...@@ -1329,7 +1302,7 @@ namespace std
typename __enable_if_void<_Res>::type = 0) const volatile typename __enable_if_void<_Res>::type = 0) const volatile
{ {
_M_f(_Mu<_Bound_args>() _M_f(_Mu<_Bound_args>()
(get<_Indexes>(_M_bound_args), __args)...); (get<_Indexes>(_M_bound_args), std::move(__args))...);
} }
public: public:
...@@ -1338,7 +1311,7 @@ namespace std ...@@ -1338,7 +1311,7 @@ namespace std
explicit explicit
_Bind_result(_Functor __f, _Bound_args... __bound_args) _Bind_result(_Functor __f, _Bound_args... __bound_args)
: _M_f(std::forward<_Functor>(__f)), : _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 // Call unqualified
...@@ -1447,11 +1420,9 @@ namespace std ...@@ -1447,11 +1420,9 @@ namespace std
*/ */
template<typename _Tp> template<typename _Tp>
struct __is_location_invariant struct __is_location_invariant
: integral_constant<bool, : integral_constant<bool, (is_pointer<_Tp>::value
(is_pointer<_Tp>::value || is_member_pointer<_Tp>::value)>
|| is_member_pointer<_Tp>::value)> { };
{
};
class _Undefined_class; class _Undefined_class;
...@@ -1503,8 +1474,7 @@ namespace std ...@@ -1503,8 +1474,7 @@ namespace std
template<typename _Tp> template<typename _Tp>
struct __is_location_invariant<_Simple_type_wrapper<_Tp> > struct __is_location_invariant<_Simple_type_wrapper<_Tp> >
: __is_location_invariant<_Tp> : __is_location_invariant<_Tp>
{ { };
};
// Converts a reference to a function object into a callable // Converts a reference to a function object into a callable
// function object. // function object.
......
// 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;
}
...@@ -28,6 +28,8 @@ int inc(int& i) { return ++i; } ...@@ -28,6 +28,8 @@ int inc(int& i) { return ++i; }
void test01() void test01()
{ {
bool test __attribute__((unused)) = true;
int counter = 0; int counter = 0;
std::bind(&inc, _1)(counter); std::bind(&inc, _1)(counter);
VERIFY(counter == 1 ); VERIFY(counter == 1 );
...@@ -45,6 +47,8 @@ struct Inc ...@@ -45,6 +47,8 @@ struct Inc
void test02() void test02()
{ {
bool test __attribute__((unused)) = true;
int counter = 0; int counter = 0;
std::bind(Inc(), _1)(counter); std::bind(Inc(), _1)(counter);
VERIFY(counter == 1 ); VERIFY(counter == 1 );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment