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 struct __index_of : std::integral_constant {}; @@ -733,10 +733,8 @@ namespace __variant // Helper used to check for valid conversions that don't involve narrowing. template struct _Arr { _Ti _M_x[1]; }; - // Build an imaginary function FUN(Ti) for each alternative type Ti - template, bool>, - typename = void> + // "Build an imaginary function FUN(Ti) for each alternative type Ti" + template struct _Build_FUN { // This function means 'using _Build_FUN::_S_fun;' is valid, @@ -744,24 +742,15 @@ namespace __variant void _S_fun(); }; - // ... for which Ti x[] = {std::forward(t)}; is well-formed, + // "... for which Ti x[] = {std::forward(t)}; is well-formed." template - struct _Build_FUN<_Ind, _Tp, _Ti, false, + struct _Build_FUN<_Ind, _Tp, _Ti, void_t{{std::declval<_Tp>()}})>> { // This is the FUN function for type _Ti, with index _Ind static integral_constant _S_fun(_Ti); }; - // ... and if Ti is cv bool, remove_cvref_t is bool. - template - struct _Build_FUN<_Ind, _Tp, _Ti, true, - enable_if_t, bool>>> - { - // This is the FUN function for when _Ti is cv bool, with index _Ind - static integral_constant _S_fun(_Ti); - }; - template>> 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, unsigned>); static_assert(!is_constructible_v, int>); static_assert(!is_constructible_v, void*>); + + // P1957R2 Converting from T* to bool should be considered narrowing + struct ConvertibleToBool + { + operator bool() const { return true; } + }; + static_assert(is_constructible_v, ConvertibleToBool>); + static_assert(is_constructible_v, 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 v3 = 0; VERIFY(v3.index() == 1); } + + { + // P1957R2 Converting from T* to bool should be considered narrowing + struct ConvertibleToBool + { + operator bool() const { return true; } + }; + variant v1 = ConvertibleToBool(); + VERIFY(std::get<0>(v1) == true); + variant v2 = ConvertibleToBool(); + VERIFY(std::get<0>(v2) == true); + variant 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 v1; + v1 = ConvertibleToBool(); + VERIFY(std::get<0>(v1) == true); + variant v2; + v2 = ConvertibleToBool(); + VERIFY(std::get<0>(v2) == true); + variant v3; + v3 = ConvertibleToBool(); + VERIFY(std::get<1>(v3) == true); + } } void dtor()