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:
parent
6805e400e9
commit
7d2035fafe
4 changed files with 79 additions and 20 deletions
|
@ -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):
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include <functional>
|
||||
|
||||
struct A {
|
||||
void foo(int n) { }
|
||||
void foo(int) { }
|
||||
};
|
||||
|
||||
void
|
||||
|
|
|
@ -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));
|
||||
}
|
Loading…
Add table
Reference in a new issue