From 7d2035fafe935fd7552a2b764807fe1e0274f2be Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Thu, 4 Aug 2016 12:09:29 +0100 Subject: [PATCH] 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 --- libstdc++-v3/ChangeLog | 10 ++++ libstdc++-v3/include/std/functional | 29 ++++------ .../20_util/function_objects/invoke/59768.cc | 2 +- .../function_objects/invoke/ref_ext.cc | 58 +++++++++++++++++++ 4 files changed, 79 insertions(+), 20 deletions(-) create mode 100644 libstdc++-v3/testsuite/20_util/function_objects/invoke/ref_ext.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index d1162310bf6..b124d757ff3 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,13 @@ +2016-08-04 Jonathan Wakely + + * 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 * include/bits/shared_ptr_base.h (__cpp_lib_enable_shared_from_this): diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index 700505e8f24..d635ef53769 100644 --- a/libstdc++-v3/include/std/functional +++ b/libstdc++-v3/include/std/functional @@ -185,31 +185,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { }; template::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 - 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 - inline typename _Unwrap<_Tp>::type + template::type> + inline _Up&& __invfwd(typename remove_reference<_Tp>::type& __t) noexcept - { return _Unwrap<_Tp>::_S_fwd(__t); } + { return static_cast<_Up&&>(__t); } template inline _Res @@ -235,16 +227,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return ((*std::forward<_Tp>(__t)).*__f)(std::forward<_Args>(__args)...); } - template + template 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 + template 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; } diff --git a/libstdc++-v3/testsuite/20_util/function_objects/invoke/59768.cc b/libstdc++-v3/testsuite/20_util/function_objects/invoke/59768.cc index 2a519eaf64d..6aaae222e52 100644 --- a/libstdc++-v3/testsuite/20_util/function_objects/invoke/59768.cc +++ b/libstdc++-v3/testsuite/20_util/function_objects/invoke/59768.cc @@ -21,7 +21,7 @@ #include struct A { - void foo(int n) { } + void foo(int) { } }; void diff --git a/libstdc++-v3/testsuite/20_util/function_objects/invoke/ref_ext.cc b/libstdc++-v3/testsuite/20_util/function_objects/invoke/ref_ext.cc new file mode 100644 index 00000000000..d7e57668779 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/function_objects/invoke/ref_ext.cc @@ -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 +// . + +// { dg-do compile { target c++11 } } + +#include + +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)); +} -- 2.30.2