Skip to content

Commit a941e8c

Browse files
author
Bogdan Graur
committed
Adds back special-case for booleans in std::variant gated by
_LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT.
1 parent 9be9f62 commit a941e8c

File tree

6 files changed

+49
-3
lines changed

6 files changed

+49
-3
lines changed

libcxx/docs/Status/Cxx20Papers.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@
173173
"`P1868R2 <https://wg21.link/P1868R2>`__","LWG","width: clarifying units of width and precision in std::format","Prague","|Complete|","14.0"
174174
"`P1937R2 <https://wg21.link/P1937R2>`__","CWG","Fixing inconsistencies between constexpr and consteval functions","Prague","* *",""
175175
"`P1956R1 <https://wg21.link/P1956R1>`__","LWG","On the names of low-level bit manipulation functions","Prague","|Complete|","12.0"
176-
"`P1957R2 <https://wg21.link/P1957R2>`__","CWG","Converting from ``T*``\ to bool should be considered narrowing (re: US 212)","Prague","|Complete|","18.0"
176+
"`P1957R2 <https://wg21.link/P1957R2>`__","CWG","Converting from ``T*``\ to bool should be considered narrowing (re: US 212)","Prague","* *",""
177177
"`P1963R0 <https://wg21.link/P1963R0>`__","LWG","Fixing US 313","Prague","* *","",""
178178
"`P1964R2 <https://wg21.link/P1964R2>`__","LWG","Wording for boolean-testable","Prague","|Complete|","13.0"
179179
"`P1970R2 <https://wg21.link/P1970R2>`__","LWG","Consistency for size() functions: Add ranges::ssize","Prague","|Complete|","15.0","|ranges|"

libcxx/include/variant

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,6 +1252,24 @@ struct __overload {
12521252
auto operator()(_Tp, _Up&&) const -> __check_for_narrowing<_Tp, _Up>;
12531253
};
12541254

1255+
#ifdef _LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT
1256+
template <class _Tp, size_t>
1257+
struct __overload_bool {
1258+
template <class _Up, class _Ap = __remove_cvref_t<_Up>>
1259+
auto operator()(bool, _Up&&) const
1260+
-> enable_if_t<is_same_v<_Ap, bool>, __type_identity<_Tp>>;
1261+
};
1262+
1263+
template <size_t _Idx>
1264+
struct __overload<bool, _Idx> : __overload_bool<bool, _Idx> {};
1265+
template <size_t _Idx>
1266+
struct __overload<bool const, _Idx> : __overload_bool<bool const, _Idx> {};
1267+
template <size_t _Idx>
1268+
struct __overload<bool volatile, _Idx> : __overload_bool<bool volatile, _Idx> {};
1269+
template <size_t _Idx>
1270+
struct __overload<bool const volatile, _Idx> : __overload_bool<bool const volatile, _Idx> {};
1271+
#endif
1272+
12551273
template <class ..._Bases>
12561274
struct __all_overloads : _Bases... {
12571275
void operator()() const;

libcxx/test/std/utilities/variant/variant.variant/variant.assign/T.pass.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,13 @@ void test_T_assignment_sfinae() {
146146
};
147147
static_assert(!std::is_assignable<V, X>::value,
148148
"no boolean conversion in operator=");
149+
#if defined(_LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT)
150+
static_assert(!std::is_assignable<V, std::false_type>::value,
151+
"no converted to bool in operator=");
152+
#else
149153
static_assert(std::is_assignable<V, std::false_type>::value,
150154
"converted to bool in operator=");
155+
#endif
151156
}
152157
{
153158
struct X {};
@@ -296,21 +301,25 @@ void test_T_assignment_performs_assignment() {
296301
#endif // TEST_HAS_NO_EXCEPTIONS
297302
}
298303

304+
#if !defined(_LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT)
299305
void test_T_assignment_vector_bool() {
300306
std::vector<bool> vec = {true};
301307
std::variant<bool, int> v;
302308
v = vec[0];
303309
assert(v.index() == 0);
304310
assert(std::get<0>(v) == true);
305311
}
312+
#endif
306313

307314
int main(int, char**) {
308315
test_T_assignment_basic();
309316
test_T_assignment_performs_construction();
310317
test_T_assignment_performs_assignment();
311318
test_T_assignment_noexcept();
312319
test_T_assignment_sfinae();
320+
#if !defined(_LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT)
313321
test_T_assignment_vector_bool();
322+
#endif
314323

315324
return 0;
316325
}

libcxx/test/std/utilities/variant/variant.variant/variant.assign/conv.pass.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,13 @@ int main(int, char**)
3333

3434
static_assert(!std::is_assignable<std::variant<int, bool>, decltype("meow")>::value, "");
3535
static_assert(!std::is_assignable<std::variant<int, const bool>, decltype("meow")>::value, "");
36-
36+
#if defined(_LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT)
37+
static_assert(!std::is_assignable<std::variant<int, const volatile bool>, decltype("meow")>::value, "");
38+
static_assert(!std::is_assignable<std::variant<bool>, std::true_type>::value, "");
39+
#else
3740
static_assert(std::is_assignable<std::variant<bool>, std::true_type>::value, "");
41+
#endif
42+
3843
static_assert(!std::is_assignable<std::variant<bool>, std::unique_ptr<char> >::value, "");
3944
static_assert(!std::is_assignable<std::variant<bool>, decltype(nullptr)>::value, "");
4045

libcxx/test/std/utilities/variant/variant.variant/variant.ctor/T.pass.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,13 @@ void test_T_ctor_sfinae() {
8080
};
8181
static_assert(!std::is_constructible<V, X>::value,
8282
"no boolean conversion in constructor");
83+
#if defined(_LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT)
84+
static_assert(!std::is_constructible<V, std::false_type>::value,
85+
"no converted to bool in constructor");
86+
#else
8387
static_assert(std::is_constructible<V, std::false_type>::value,
8488
"converted to bool in constructor");
89+
#endif
8590
}
8691
{
8792
struct X {};
@@ -199,19 +204,23 @@ void test_construction_with_repeated_types() {
199204
static_assert(std::is_constructible<V, Bar>::value, "");
200205
}
201206

207+
#if !defined(_LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT)
202208
void test_vector_bool() {
203209
std::vector<bool> vec = {true};
204210
std::variant<bool, int> v = vec[0];
205211
assert(v.index() == 0);
206212
assert(std::get<0>(v) == true);
207213
}
214+
#endif
208215

209216
int main(int, char**) {
210217
test_T_ctor_basic();
211218
test_T_ctor_noexcept();
212219
test_T_ctor_sfinae();
213220
test_no_narrowing_check_for_class_types();
214221
test_construction_with_repeated_types();
222+
#if !defined(_LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT)
215223
test_vector_bool();
224+
#endif
216225
return 0;
217226
}

libcxx/test/std/utilities/variant/variant.variant/variant.ctor/conv.pass.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,13 @@ int main(int, char**)
3232

3333
static_assert(!std::is_constructible<std::variant<int, bool>, decltype("meow")>::value, "");
3434
static_assert(!std::is_constructible<std::variant<int, const bool>, decltype("meow")>::value, "");
35-
35+
#if defined(_LIBCPP_ENABLE_NARROWING_CONVERSIONS_IN_VARIANT)
36+
static_assert(!std::is_constructible<std::variant<int, const volatile bool>, decltype("meow")>::value, "");
37+
static_assert(!std::is_constructible<std::variant<bool>, std::true_type>::value, "");
38+
#else
3639
static_assert(std::is_constructible<std::variant<bool>, std::true_type>::value, "");
40+
#endif
41+
3742
static_assert(!std::is_constructible<std::variant<bool>, std::unique_ptr<char> >::value, "");
3843
static_assert(!std::is_constructible<std::variant<bool>, decltype(nullptr)>::value, "");
3944

0 commit comments

Comments
 (0)