Simplify std::__invoke_impl definitions

* include/std/functional (_Unwrap): Rename to __inv_unwrap.
	(__invfwd): Adjust.
	(__invoke_impl): Remove unused template parameters.
	* testsuite/20_util/function_objects/invoke/59768.cc: Remove unused
	parameter.
	* testsuite/20_util/function_objects/invoke/ref_ext.cc: Copy 59768.cc
	and test __invoke extension for C++11.

From-SVN: r239120
This commit is contained in:
Jonathan Wakely 2016-08-04 12:09:29 +01:00 committed by Jonathan Wakely
parent 6805e400e9
commit 7d2035fafe
4 changed files with 79 additions and 20 deletions

View file

@ -1,3 +1,13 @@
2016-08-04 Jonathan Wakely <jwakely@redhat.com>
* include/std/functional (_Unwrap): Rename to __inv_unwrap.
(__invfwd): Adjust.
(__invoke_impl): Remove unused template parameters.
* testsuite/20_util/function_objects/invoke/59768.cc: Remove unused
parameter.
* testsuite/20_util/function_objects/invoke/ref_ext.cc: Copy 59768.cc
and test __invoke extension for C++11.
2016-08-03 Jonathan Wakely <jwakely@redhat.com>
* include/bits/shared_ptr_base.h (__cpp_lib_enable_shared_from_this):

View file

@ -185,31 +185,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ };
template<typename _Tp, typename _Up = typename decay<_Tp>::type>
struct _Unwrap
struct __inv_unwrap
{
using type = _Tp&&;
// Equivalent to std::forward<_Tp>
static constexpr _Tp&&
_S_fwd(_Tp& __t) noexcept { return static_cast<_Tp&&>(__t); }
using type = _Tp;
};
template<typename _Tp, typename _Up>
struct _Unwrap<_Tp, reference_wrapper<_Up>>
struct __inv_unwrap<_Tp, reference_wrapper<_Up>>
{
using type = _Up&;
// Get an lvalue-reference from a reference_wrapper.
static _Up&
_S_fwd(const _Tp& __t) noexcept { __t.get(); }
};
// Used by __invoke_impl instead of std::forward<_Tp> so that a
// reference_wrapper is converted to an lvalue-reference.
template<typename _Tp>
inline typename _Unwrap<_Tp>::type
template<typename _Tp, typename _Up = typename __inv_unwrap<_Tp>::type>
inline _Up&&
__invfwd(typename remove_reference<_Tp>::type& __t) noexcept
{ return _Unwrap<_Tp>::_S_fwd(__t); }
{ return static_cast<_Up&&>(__t); }
template<typename _Res, typename _Fn, typename... _Args>
inline _Res
@ -235,16 +227,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return ((*std::forward<_Tp>(__t)).*__f)(std::forward<_Args>(__args)...);
}
template<typename _Res, typename _MemFun, typename _Tp, typename... _Args>
template<typename _Res, typename _MemPtr, typename _Tp>
inline _Res
__invoke_impl(__invoke_memobj_ref, _MemFun&& __f, _Tp&& __t)
__invoke_impl(__invoke_memobj_ref, _MemPtr&& __f, _Tp&& __t)
noexcept(noexcept(__invfwd<_Tp>(__t).*__f))
{ return __invfwd<_Tp>(__t).*__f; }
template<typename _Res, typename _MemFun, typename _Tp, typename... _Args>
template<typename _Res, typename _MemPtr, typename _Tp>
inline _Res
__invoke_impl(__invoke_memobj_deref, _MemFun&& __f, _Tp&& __t,
_Args&&... __args)
__invoke_impl(__invoke_memobj_deref, _MemPtr&& __f, _Tp&& __t)
noexcept(noexcept((*std::forward<_Tp>(__t)).*__f))
{ return (*std::forward<_Tp>(__t)).*__f; }

View file

@ -21,7 +21,7 @@
#include <functional>
struct A {
void foo(int n) { }
void foo(int) { }
};
void

View file

@ -0,0 +1,58 @@
// Copyright (C) 2015-2016 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/>.
// { dg-do compile { target c++11 } }
#include <functional>
struct A {
void foo(int) { }
};
void
test01()
{
// PR libstdc++/59768
A a;
auto ref = std::ref(a);
std::__invoke(&A::foo, ref, 100); // lvalue
std::__invoke(&A::foo, std::move(ref), 100); // rvalue
const auto refc = std::ref(a);
std::__invoke(&A::foo, refc, 100); // const lvalue
std::__invoke(&A::foo, std::move(refc), 100); // const rvalue
}
struct B {
int bar = 0;
};
void
test02()
{
B b;
// Invocation through a reference_wrapper means the object is an lvalue.
int* ptr [[gnu::unused]];
auto ref = std::ref(b);
ptr = &std::__invoke(&B::bar, ref);
ptr = &std::__invoke(&B::bar, std::move(ref));
const int* cptr [[gnu::unused]];
auto cref = std::cref(b);
cptr = &std::__invoke(&B::bar, cref);
cptr = &std::__invoke(&B::bar, std::move(cref));
}