From a73d2fa852c5104c458f2877a0fc361ab8507660 Mon Sep 17 00:00:00 2001 From: Nina Dinka Ranns Date: Tue, 14 May 2019 15:48:27 +0000 Subject: [PATCH] nonesuch is insufficiently useless (lwg2996) 2019-05-14 Nina Dinka Ranns nonesuch is insufficiently useless (lwg2996) * include/std/type_traits (struct __nonesuch): Added private base class to make __nonesuch not an aggregate and removed deleted default constructor. * include/bits/stl_pair.h (struct __nonesuch_no_braces): Removed. (operator=(const pair&)): Use __nonesuch instead of __nonesuch_no_braces. (operator=(pair&&)): Likewise * include/std/tuple (operator=(const tuple&)): Use __nonesuch instead of __nonesuch_no_braces. (operator=(tuple&&)): Likewise * include/experimental/type_traits (struct nonesuch): Added private base class to make nonesuch not an aggregate and removed deleted default constructor. * testsuite/20_util/nonesuch/nonesuch.cc: New. * testsuite/experimental/type_traits/nonesuch.cc: New. From-SVN: r271175 --- libstdc++-v3/ChangeLog | 19 +++++++++ libstdc++-v3/include/bits/stl_pair.h | 11 +---- libstdc++-v3/include/experimental/type_traits | 4 +- libstdc++-v3/include/std/tuple | 8 ++-- libstdc++-v3/include/std/type_traits | 4 +- .../testsuite/20_util/nonesuch/nonesuch.cc | 39 ++++++++++++++++++ .../experimental/type_traits/nonesuch.cc | 40 +++++++++++++++++++ 7 files changed, 108 insertions(+), 17 deletions(-) create mode 100644 libstdc++-v3/testsuite/20_util/nonesuch/nonesuch.cc create mode 100644 libstdc++-v3/testsuite/experimental/type_traits/nonesuch.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index c2466cefaa5..5a21ebcb022 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,22 @@ +2019-05-14 Nina Dinka Ranns + + nonesuch is insufficiently useless (lwg2996) + * include/std/type_traits (struct __nonesuch): Added private base + class to make __nonesuch not an aggregate and removed deleted default + constructor. + * include/bits/stl_pair.h (struct __nonesuch_no_braces): Removed. + (operator=(const pair&)): Use __nonesuch instead of + __nonesuch_no_braces. + (operator=(pair&&)): Likewise + * include/std/tuple (operator=(const tuple&)): Use __nonesuch instead + of __nonesuch_no_braces. + (operator=(tuple&&)): Likewise + * include/experimental/type_traits (struct nonesuch): Added private + base class to make nonesuch not an aggregate and removed deleted + default constructor. + * testsuite/20_util/nonesuch/nonesuch.cc: New. + * testsuite/experimental/type_traits/nonesuch.cc: New. + 2019-05-14 Jonathan Wakely * include/bits/std_function.h (_Simple_type_wrapper): Remove. diff --git a/libstdc++-v3/include/bits/stl_pair.h b/libstdc++-v3/include/bits/stl_pair.h index f99b774c21e..c04f169bb6c 100644 --- a/libstdc++-v3/include/bits/stl_pair.h +++ b/libstdc++-v3/include/bits/stl_pair.h @@ -180,13 +180,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return false; } }; - - // PR libstdc++/79141, a utility type for preventing - // initialization of an argument of a disabled assignment - // operator from a pair of empty braces. - struct __nonesuch_no_braces : std::__nonesuch { - explicit __nonesuch_no_braces(const __nonesuch&) = delete; - }; #endif // C++11 template class __pair_base @@ -393,7 +386,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator=(typename conditional< __and_, is_copy_assignable<_T2>>::value, - const pair&, const __nonesuch_no_braces&>::type __p) + const pair&, const __nonesuch&>::type __p) { first = __p.first; second = __p.second; @@ -404,7 +397,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator=(typename conditional< __and_, is_move_assignable<_T2>>::value, - pair&&, __nonesuch_no_braces&&>::type __p) + pair&&, __nonesuch&&>::type __p) noexcept(__and_, is_nothrow_move_assignable<_T2>>::value) { diff --git a/libstdc++-v3/include/experimental/type_traits b/libstdc++-v3/include/experimental/type_traits index 09743c5e92b..c2b2dcc2739 100644 --- a/libstdc++-v3/include/experimental/type_traits +++ b/libstdc++-v3/include/experimental/type_traits @@ -227,9 +227,9 @@ inline namespace fundamentals_v2 template using void_t = void; -struct nonesuch +struct __nonesuchbase {}; +struct nonesuch : private __nonesuchbase { - nonesuch() = delete; ~nonesuch() = delete; nonesuch(nonesuch const&) = delete; void operator=(nonesuch const&) = delete; diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index 956e031ae9d..a28111749f0 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -832,7 +832,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION tuple& operator=(typename conditional<__assignable(), const tuple&, - const __nonesuch_no_braces&>::type __in) + const __nonesuch&>::type __in) noexcept(__nothrow_assignable()) { this->_M_assign(__in); @@ -842,7 +842,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION tuple& operator=(typename conditional<__assignable<_Elements...>(), tuple&&, - __nonesuch_no_braces&&>::type __in) + __nonesuch&&>::type __in) noexcept(__nothrow_assignable<_Elements...>()) { this->_M_assign(std::move(__in)); @@ -1243,7 +1243,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION tuple& operator=(typename conditional<__assignable(), const tuple&, - const __nonesuch_no_braces&>::type __in) + const __nonesuch&>::type __in) noexcept(__nothrow_assignable()) { this->_M_assign(__in); @@ -1253,7 +1253,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION tuple& operator=(typename conditional<__assignable<_T1, _T2>(), tuple&&, - __nonesuch_no_braces&&>::type __in) + __nonesuch&&>::type __in) noexcept(__nothrow_assignable<_T1, _T2>()) { this->_M_assign(std::move(__in)); diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index f68d366269d..b1c3e943e79 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -2792,8 +2792,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __call_is_nothrow_<_Fn, _Args...>>::type { }; - struct __nonesuch { - __nonesuch() = delete; + struct __nonesuchbase {}; + struct __nonesuch : private __nonesuchbase { ~__nonesuch() = delete; __nonesuch(__nonesuch const&) = delete; void operator=(__nonesuch const&) = delete; diff --git a/libstdc++-v3/testsuite/20_util/nonesuch/nonesuch.cc b/libstdc++-v3/testsuite/20_util/nonesuch/nonesuch.cc new file mode 100644 index 00000000000..100d7e3b752 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/nonesuch/nonesuch.cc @@ -0,0 +1,39 @@ +// 2019-05-14 Nina Dinka Ranns +// Copyright (C) 2019 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++14 } } + +#include +// Example taken from LWG2960 + +using std::__nonesuch; +struct such {}; +void f(const such&){}; +void f(const std::__nonesuch&); + +int main(){ + static_assert(!std::is_default_constructible<__nonesuch>::value, + "__nonesuch is default constructible"); + static_assert(!std::is_copy_constructible<__nonesuch>::value, + "__nonesuch is copy constructible"); + static_assert(!std::is_assignable<__nonesuch, __nonesuch>::value, + "__nonesuch is assignable"); + static_assert(!std::is_destructible<__nonesuch>::value, + "__nonesuch is destructible"); + f({}); +} diff --git a/libstdc++-v3/testsuite/experimental/type_traits/nonesuch.cc b/libstdc++-v3/testsuite/experimental/type_traits/nonesuch.cc new file mode 100644 index 00000000000..2e624026b15 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/type_traits/nonesuch.cc @@ -0,0 +1,40 @@ +// 2019-05-14 Nina Dinka Ranns +// Copyright (C) 2019 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++14 } } + +#include +// Example taken from LWG2960 + +using std::experimental::nonesuch; + +struct such {}; +void f(const such&){}; +void f(const nonesuch&); + +int main(){ + static_assert(!std::is_default_constructible::value, + "nonesuch is default constructible"); + static_assert(!std::is_copy_constructible::value, + "nonesuch is copy constructible"); + static_assert(!std::is_assignable::value, + "nonesuch is assignable"); + static_assert(!std::is_destructible::value, + "nonesuch is destructible"); + f({}); +} -- 2.30.2