public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
From: Jonathan Wakely <redi@gcc.gnu.org>
To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org
Subject: [gcc r11-1598] libstdc++: Implement P1972R2 changes to std::variant (PR 95832)
Date: Tue, 23 Jun 2020 09:27:54 +0000 (GMT)	[thread overview]
Message-ID: <20200623092754.793C13952DA7@sourceware.org> (raw)

https://gcc.gnu.org/g:c98fc4eb3afeda6ad8220d0d79bc1247a92c7c65

commit r11-1598-gc98fc4eb3afeda6ad8220d0d79bc1247a92c7c65
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Tue Jun 23 10:24:49 2020 +0100

    libstdc++: Implement P1972R2 changes to std::variant (PR 95832)
    
    G++ implements P1972R2 since r11-1597-0ca22d027ecc and so we no longer
    need the P0608R3 special case to prevent narrowing conversions to bool.
    
    Since non-GNU compilers don't necessarily implment P1972R2 yet, this
    may cause a regression for those compilers. There is no feature-test
    macro we can use to detect it though, so we'll have to live with it.
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/95832
            * include/std/variant (__detail::__variant::_Build_FUN): Remove
            partial specialization to prevent narrowing conversions to bool.
            * testsuite/20_util/variant/compile.cc: Test non-narrowing
            conversions to bool.
            * testsuite/20_util/variant/run.cc: Likewise.

Diff:
---
 libstdc++-v3/include/std/variant                  | 21 ++++-----------
 libstdc++-v3/testsuite/20_util/variant/compile.cc |  8 ++++++
 libstdc++-v3/testsuite/20_util/variant/run.cc     | 31 +++++++++++++++++++++++
 3 files changed, 44 insertions(+), 16 deletions(-)

diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index 258a5fb18bd..6eeb3c80ec2 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -164,7 +164,7 @@ namespace __detail
 {
 namespace __variant
 {
-  // Returns the first appearence of _Tp in _Types.
+  // Returns the first appearance of _Tp in _Types.
   // Returns sizeof...(_Types) if _Tp is not in _Types.
   template<typename _Tp, typename... _Types>
     struct __index_of : std::integral_constant<size_t, 0> {};
@@ -733,10 +733,8 @@ namespace __variant
   // Helper used to check for valid conversions that don't involve narrowing.
   template<typename _Ti> struct _Arr { _Ti _M_x[1]; };
 
-  // Build an imaginary function FUN(Ti) for each alternative type Ti
-  template<size_t _Ind, typename _Tp, typename _Ti,
-	   bool _Ti_is_cv_bool = is_same_v<remove_cv_t<_Ti>, bool>,
-	   typename = void>
+  // "Build an imaginary function FUN(Ti) for each alternative type Ti"
+  template<size_t _Ind, typename _Tp, typename _Ti, typename = void>
     struct _Build_FUN
     {
       // This function means 'using _Build_FUN<I, T, Ti>::_S_fun;' is valid,
@@ -744,24 +742,15 @@ namespace __variant
       void _S_fun();
     };
 
-  // ... for which Ti x[] = {std::forward<T>(t)}; is well-formed,
+  // "... for which Ti x[] = {std::forward<T>(t)}; is well-formed."
   template<size_t _Ind, typename _Tp, typename _Ti>
-    struct _Build_FUN<_Ind, _Tp, _Ti, false,
+    struct _Build_FUN<_Ind, _Tp, _Ti,
 		      void_t<decltype(_Arr<_Ti>{{std::declval<_Tp>()}})>>
     {
       // This is the FUN function for type _Ti, with index _Ind
       static integral_constant<size_t, _Ind> _S_fun(_Ti);
     };
 
-  // ... and if Ti is cv bool, remove_cvref_t<T> is bool.
-  template<size_t _Ind, typename _Tp, typename _Ti>
-    struct _Build_FUN<_Ind, _Tp, _Ti, true,
-		      enable_if_t<is_same_v<__remove_cvref_t<_Tp>, bool>>>
-    {
-      // This is the FUN function for when _Ti is cv bool, with index _Ind
-      static integral_constant<size_t, _Ind> _S_fun(_Ti);
-    };
-
   template<typename _Tp, typename _Variant,
 	   typename = make_index_sequence<variant_size_v<_Variant>>>
     struct _Build_FUNs;
diff --git a/libstdc++-v3/testsuite/20_util/variant/compile.cc b/libstdc++-v3/testsuite/20_util/variant/compile.cc
index a53071c8867..b2b60d1cf10 100644
--- a/libstdc++-v3/testsuite/20_util/variant/compile.cc
+++ b/libstdc++-v3/testsuite/20_util/variant/compile.cc
@@ -155,6 +155,14 @@ void arbitrary_ctor()
   static_assert(!is_constructible_v<variant<int>, unsigned>);
   static_assert(!is_constructible_v<variant<bool>, int>);
   static_assert(!is_constructible_v<variant<bool>, void*>);
+
+  // P1957R2 Converting from T* to bool should be considered narrowing
+  struct ConvertibleToBool
+  {
+    operator bool() const { return true; }
+  };
+  static_assert(is_constructible_v<variant<bool>, ConvertibleToBool>);
+  static_assert(is_constructible_v<variant<bool, int>, ConvertibleToBool>);
 }
 
 struct none { none() = delete; };
diff --git a/libstdc++-v3/testsuite/20_util/variant/run.cc b/libstdc++-v3/testsuite/20_util/variant/run.cc
index 3e2228a4666..0ac5de25289 100644
--- a/libstdc++-v3/testsuite/20_util/variant/run.cc
+++ b/libstdc++-v3/testsuite/20_util/variant/run.cc
@@ -139,6 +139,20 @@ void arbitrary_ctor()
     variant<float, big_int> v3 = 0;
     VERIFY(v3.index() == 1);
   }
+
+  {
+    // P1957R2 Converting from T* to bool should be considered narrowing
+    struct ConvertibleToBool
+    {
+      operator bool() const { return true; }
+    };
+    variant<bool> v1 = ConvertibleToBool();
+    VERIFY(std::get<0>(v1) == true);
+    variant<bool, int> v2 = ConvertibleToBool();
+    VERIFY(std::get<0>(v2) == true);
+    variant<int, bool> v3 = ConvertibleToBool();
+    VERIFY(std::get<1>(v3) == true);
+  }
 }
 
 struct ThrowingMoveCtorThrowsCopyCtor
@@ -226,6 +240,23 @@ void arbitrary_assign()
     v3 = 0;
     VERIFY(v3.index() == 1);
   }
+
+  {
+    // P1957R2 Converting from T* to bool should be considered narrowing
+    struct ConvertibleToBool
+    {
+      operator bool() const { return true; }
+    };
+    variant<bool> v1;
+    v1 = ConvertibleToBool();
+    VERIFY(std::get<0>(v1) == true);
+    variant<bool, int> v2;
+    v2 = ConvertibleToBool();
+    VERIFY(std::get<0>(v2) == true);
+    variant<int, bool> v3;
+    v3 = ConvertibleToBool();
+    VERIFY(std::get<1>(v3) == true);
+  }
 }
 
 void dtor()


                 reply	other threads:[~2020-06-23  9:27 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200623092754.793C13952DA7@sourceware.org \
    --to=redi@gcc.gnu.org \
    --cc=gcc-cvs@gcc.gnu.org \
    --cc=libstdc++-cvs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).