[v3] nonesuch is insufficiently useless (lwg2996)

Message ID CAAcHv8f--x_f86VJRQ6ZykjwfzAt6TAuP3J4+iUC6Mj0PUTHrg@mail.gmail.com
State New
Headers show
Series
  • [v3] nonesuch is insufficiently useless (lwg2996)
Related show

Commit Message

Nina Dinka Ranns May 14, 2019, 2:43 p.m.
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

Comments

Jonathan Wakely May 14, 2019, 3:50 p.m. | #1
On 14/05/19 15:43 +0100, Nina Dinka Ranns wrote:
>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


Thanks!

Tested and committed, again with some changelog edits, and some whitespace
before the opening braces here ...

>@@ -2769,8 +2769,8 @@

>              __call_is_nothrow_<_Fn, _Args...>>::type

>     { };

> 

>-  struct __nonesuch {

>-    __nonesuch() = delete;

>+  struct __nonesuchbase{};

>+  struct __nonesuch : private __nonesuchbase{
Nina Dinka Ranns May 14, 2019, 4:11 p.m. | #2
That was fast :)
I’ll check the changelog for future reference.
Thanks,
Nina

On Tue, 14 May 2019 at 16:50, Jonathan Wakely <jwakely@redhat.com> wrote:

> On 14/05/19 15:43 +0100, Nina Dinka Ranns wrote:

> >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

>

> Thanks!

>

> Tested and committed, again with some changelog edits, and some whitespace

> before the opening braces here ...

>

> >@@ -2769,8 +2769,8 @@

> >              __call_is_nothrow_<_Fn, _Args...>>::type

> >     { };

> >

> >-  struct __nonesuch {

> >-    __nonesuch() = delete;

> >+  struct __nonesuchbase{};

> >+  struct __nonesuch : private __nonesuchbase{

>

>

>

Patch

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({});
+}