This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[v3 PATCH] nonesuch is insufficiently useless (lwg2996)
- From: Nina Dinka Ranns <dinka dot ranns at gmail dot com>
- To: gcc-patches List <gcc-patches at gcc dot gnu dot org>, "libstdc++" <libstdc++ at gcc dot gnu dot org>
- Date: Tue, 14 May 2019 15:43:23 +0100
- Subject: [v3 PATCH] nonesuch is insufficiently useless (lwg2996)
Tested on Linux x86_64
nonesuch is insufficiently useless (lwg2996)
2019-05-14 Nina Dinka Ranns <dinka.ranns@gmail.com>
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
Index: libstdc++-v3/include/bits/stl_pair.h
===================================================================
--- libstdc++-v3/include/bits/stl_pair.h (revision 270630)
+++ libstdc++-v3/include/bits/stl_pair.h (working copy)
@@ -178,13 +178,6 @@
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<typename _U1, typename _U2> class __pair_base
@@ -378,7 +371,7 @@
operator=(typename conditional<
__and_<is_copy_assignable<_T1>,
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;
@@ -389,7 +382,7 @@
operator=(typename conditional<
__and_<is_move_assignable<_T1>,
is_move_assignable<_T2>>::value,
- pair&&, __nonesuch_no_braces&&>::type __p)
+ pair&&, __nonesuch&&>::type __p)
noexcept(__and_<is_nothrow_move_assignable<_T1>,
is_nothrow_move_assignable<_T2>>::value)
{
Index: libstdc++-v3/include/experimental/type_traits
===================================================================
--- libstdc++-v3/include/experimental/type_traits (revision 270630)
+++ libstdc++-v3/include/experimental/type_traits (working copy)
@@ -226,9 +226,9 @@
template<typename...> 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;
Index: libstdc++-v3/include/std/tuple
===================================================================
--- libstdc++-v3/include/std/tuple (revision 270630)
+++ libstdc++-v3/include/std/tuple (working copy)
@@ -816,7 +816,7 @@
tuple&
operator=(typename conditional<__assignable<const _Elements&...>(),
const tuple&,
- const __nonesuch_no_braces&>::type __in)
+ const __nonesuch&>::type __in)
noexcept(__nothrow_assignable<const _Elements&...>())
{
this->_M_assign(__in);
@@ -826,7 +826,7 @@
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));
@@ -1204,7 +1204,7 @@
tuple&
operator=(typename conditional<__assignable<const _T1&, const _T2&>(),
const tuple&,
- const __nonesuch_no_braces&>::type __in)
+ const __nonesuch&>::type __in)
noexcept(__nothrow_assignable<const _T1&, const _T2&>())
{
this->_M_assign(__in);
@@ -1214,7 +1214,7 @@
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));
Index: libstdc++-v3/include/std/type_traits
===================================================================
--- libstdc++-v3/include/std/type_traits (revision 270630)
+++ libstdc++-v3/include/std/type_traits (working copy)
@@ -2769,8 +2769,8 @@
__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;
Index: libstdc++-v3/testsuite/20_util/nonesuch/nonesuch.cc
===================================================================
--- libstdc++-v3/testsuite/20_util/nonesuch/nonesuch.cc (nonexistent)
+++ libstdc++-v3/testsuite/20_util/nonesuch/nonesuch.cc (working copy)
@@ -0,0 +1,39 @@
+// 2019-05-14 Nina Dinka Ranns <dinka.ranns@gmail.com>
+// 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
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++14 } }
+
+#include <type_traits>
+// 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({});
+}
Index: libstdc++-v3/testsuite/experimental/type_traits/nonesuch.cc
===================================================================
--- libstdc++-v3/testsuite/experimental/type_traits/nonesuch.cc (nonexistent)
+++ libstdc++-v3/testsuite/experimental/type_traits/nonesuch.cc (working copy)
@@ -0,0 +1,40 @@
+// 2019-05-14 Nina Dinka Ranns <dinka.ranns@gmail.com>
+// 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
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++14 } }
+
+#include <experimental/type_traits>
+// 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<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({});
+}