diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2018-06-15 15:19:47 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2018-06-15 15:19:47 +0100 |
commit | 7f93abd805763ef3827fce9194b0adcd2419a45c (patch) | |
tree | fb00df793c897b007fc7ff9c3344d546a10c0f2b | |
parent | d1ac60d5759dc63e4f03311d6c85cda8c9d12133 (diff) | |
download | gcc-7f93abd805763ef3827fce9194b0adcd2419a45c.zip gcc-7f93abd805763ef3827fce9194b0adcd2419a45c.tar.gz gcc-7f93abd805763ef3827fce9194b0adcd2419a45c.tar.bz2 |
LWG 2993 reference_wrapper<T> conversion from T&&
* doc/xml/manual/intro.xml: Document LWG 2993 change.
* include/bits/refwrap.h (reference_wrapper(_Tp&)): Remove.
(reference_wrapper(_Tp&&)): Remove.
(reference_wrapper<_Up>(_Up&&)): Define new constructor as constrained
template.
(reference_wrapper): Add deduction guide.
* testsuite/20_util/reference_wrapper/deduction.cc: New.
* testsuite/20_util/reference_wrapper/lwg2993.cc: New.
From-SVN: r261632
-rw-r--r-- | libstdc++-v3/ChangeLog | 10 | ||||
-rw-r--r-- | libstdc++-v3/doc/xml/manual/intro.xml | 8 | ||||
-rw-r--r-- | libstdc++-v3/include/bits/refwrap.h | 25 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/reference_wrapper/deduction.cc | 45 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/20_util/reference_wrapper/lwg2993.cc | 55 |
5 files changed, 138 insertions, 5 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index aafffa5..31c8f36 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,15 @@ 2018-06-15 Jonathan Wakely <jwakely@redhat.com> + LWG 2993 reference_wrapper<T> conversion from T&& + * doc/xml/manual/intro.xml: Document LWG 2993 change. + * include/bits/refwrap.h (reference_wrapper(_Tp&)): Remove. + (reference_wrapper(_Tp&&)): Remove. + (reference_wrapper<_Up>(_Up&&)): Define new constructor as constrained + template. + (reference_wrapper): Add deduction guide. + * testsuite/20_util/reference_wrapper/deduction.cc: New. + * testsuite/20_util/reference_wrapper/lwg2993.cc: New. + LWG 3039 Unnecessary decay in thread and packaged_task * include/std/future (__constrain_pkgdtask): Replace with ... (packaged_task::__not_same): New alias template, using diff --git a/libstdc++-v3/doc/xml/manual/intro.xml b/libstdc++-v3/doc/xml/manual/intro.xml index b0fc131..90d4390 100644 --- a/libstdc++-v3/doc/xml/manual/intro.xml +++ b/libstdc++-v3/doc/xml/manual/intro.xml @@ -1160,6 +1160,14 @@ requirements of the license of GCC. <listitem><para>Add noexcept. </para></listitem></varlistentry> + <varlistentry xml:id="manual.bugs.dr2993"><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="&DR;#2993">2993</link>: + <emphasis><code>reference_wrapper<T></code> conversion from <code>T&&</code> + </emphasis> + </term> + <listitem><para>Replaced the constructors with a constrained template, + to prevent participation in overload resolution when not valid. + </para></listitem></varlistentry> + <varlistentry xml:id="manual.bugs.dr3074"><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="&DR;#3074">3074</link>: <emphasis>Non-member functions for <code>valarray</code> should only deduce from the <code>valarray</code> </emphasis> diff --git a/libstdc++-v3/include/bits/refwrap.h b/libstdc++-v3/include/bits/refwrap.h index c1d4670..2fdf231 100644 --- a/libstdc++-v3/include/bits/refwrap.h +++ b/libstdc++-v3/include/bits/refwrap.h @@ -291,14 +291,25 @@ _GLIBCXX_MEM_FN_TRAITS(&& noexcept, false_type, true_type) { _Tp* _M_data; + static _Tp* _S_fun(_Tp& __r) noexcept { return std::__addressof(__r); } + static void _S_fun(_Tp&&) = delete; + + template<typename _Up, typename _Up2 = __remove_cvref_t<_Up>> + using __not_same + = typename enable_if<!is_same<reference_wrapper, _Up2>::value>::type; + public: typedef _Tp type; - reference_wrapper(_Tp& __indata) noexcept - : _M_data(std::__addressof(__indata)) - { } - - reference_wrapper(_Tp&&) = delete; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2993. reference_wrapper<T> conversion from T&& + // 3041. Unnecessary decay in reference_wrapper + template<typename _Up, typename = __not_same<_Up>, typename + = decltype(reference_wrapper::_S_fun(std::declval<_Up>()))> + reference_wrapper(_Up&& __uref) + noexcept(noexcept(reference_wrapper::_S_fun(std::declval<_Up>()))) + : _M_data(reference_wrapper::_S_fun(std::forward<_Up>(__uref))) + { } reference_wrapper(const reference_wrapper&) = default; @@ -320,6 +331,10 @@ _GLIBCXX_MEM_FN_TRAITS(&& noexcept, false_type, true_type) } }; +#if __cpp_deduction_guides + template<typename _Tp> + reference_wrapper(_Tp&) -> reference_wrapper<_Tp>; +#endif /// Denotes a reference should be taken to a variable. template<typename _Tp> diff --git a/libstdc++-v3/testsuite/20_util/reference_wrapper/deduction.cc b/libstdc++-v3/testsuite/20_util/reference_wrapper/deduction.cc new file mode 100644 index 0000000..cc5b260 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/reference_wrapper/deduction.cc @@ -0,0 +1,45 @@ +// Copyright (C) 2018 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-options "-std=gnu++17" } +// { dg-do compile { target c++17 } } + +#include <functional> + +void +test01() +{ + int i = 0; + std::reference_wrapper rw0(i); + [[maybe_unused]] std::reference_wrapper<int>* p0 = &rw0; + [[maybe_unused]] int& r0 = rw0; + + std::reference_wrapper rw1(rw0); + [[maybe_unused]] std::reference_wrapper<int>* p1 = &rw1; + [[maybe_unused]] int& r1 = rw1; +} + +void +test02() +{ + const int i = 0; + std::reference_wrapper rw0(i); + [[maybe_unused]] std::reference_wrapper<const int>* p0 = &rw0; + + std::reference_wrapper rw1(rw0); + [[maybe_unused]] std::reference_wrapper<const int>* p1 = &rw1; +} diff --git a/libstdc++-v3/testsuite/20_util/reference_wrapper/lwg2993.cc b/libstdc++-v3/testsuite/20_util/reference_wrapper/lwg2993.cc new file mode 100644 index 0000000..0a33948 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/reference_wrapper/lwg2993.cc @@ -0,0 +1,55 @@ +// Copyright (C) 2018 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> + +// LWG 2993. reference_wrapper<T> conversion from T&& + +static_assert(std::is_convertible<std::reference_wrapper<int>, + std::reference_wrapper<const int>>::value, + "LWG 2993 enables qualification conversions"); + +// The comments below are taken from the issue discussion and describe the +// behaviour before the resolution of LWG 2993. There should be no errors now. + +struct convertible_from_int { convertible_from_int(int) { } }; + +void +test01() +{ + + void meow(std::reference_wrapper<int>); //#1 + void meow(convertible_from_int); //#2 + // error, ambiguous; would unambiguously call #2 if #1 instead took int& + meow(0); +} + +void +test02() +{ + std::reference_wrapper<int> purr(); + + // error, ambiguous: ICS exists from int prvalue to + // reference_wrapper<int> and from reference_wrapper<int> to int + auto x = true ? purr() : 0; + + // error: no member 'type' because the conditional + // expression is ill-formed + using t = std::common_type_t<std::reference_wrapper<int>, int>; +} |