From 9f77586dbc1cf8e96047e45b3ccc283d26437239 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Fri, 14 Nov 2025 21:03:25 +0800 Subject: [PATCH 1/3] Implement LWG-4294 --- stl/inc/bitset | 4 +- .../tests/Dev10_860410_bitset_ctors/test.cpp | 95 +++++++++++++++++++ 2 files changed, 98 insertions(+), 1 deletion(-) diff --git a/stl/inc/bitset b/stl/inc/bitset index 13ed3252884..9b8a247a6d1 100644 --- a/stl/inc/bitset +++ b/stl/inc/bitset @@ -237,7 +237,9 @@ public: _Construct<_Traits>(_Str.data() + _Pos, _Count, _Elem0, _Elem1); } - template + template >, is_trivially_copyable<_Elem>, + is_standard_layout<_Elem>, is_trivially_default_constructible<_Elem>>, + int> = 0> _CONSTEXPR23 explicit bitset(const _Elem* _Ntcts, typename basic_string<_Elem>::size_type _Count = basic_string<_Elem>::npos, _Elem _Elem0 = static_cast<_Elem>('0'), _Elem _Elem1 = static_cast<_Elem>('1')) { diff --git a/tests/std/tests/Dev10_860410_bitset_ctors/test.cpp b/tests/std/tests/Dev10_860410_bitset_ctors/test.cpp index 8121cab24df..0a283e3fd46 100644 --- a/tests/std/tests/Dev10_860410_bitset_ctors/test.cpp +++ b/tests/std/tests/Dev10_860410_bitset_ctors/test.cpp @@ -7,6 +7,7 @@ #include #include #include +#include using namespace std; @@ -31,6 +32,100 @@ namespace lwg_4140 { } } // namespace lwg_4140 +// Also test LWG-4294 "bitset(const CharT*) constructor needs to be constrained". + +template +void test_ntcts_constructibility_single() { // COMPILE-ONLY + STATIC_ASSERT(is_constructible_v, Elem*> == Expected); + STATIC_ASSERT(is_constructible_v, const Elem*> == Expected); + // the constructor is explicit + STATIC_ASSERT(!is_convertible_v>); + STATIC_ASSERT(!is_convertible_v>); +} + +template +void test_ntcts_constructibility_for_lengths() { // COMPILE-ONLY + test_ntcts_constructibility_single<0, Elem, Expected>(); + test_ntcts_constructibility_single<1, Elem, Expected>(); + test_ntcts_constructibility_single<8, Elem, Expected>(); + test_ntcts_constructibility_single<16, Elem, Expected>(); + test_ntcts_constructibility_single<32, Elem, Expected>(); + test_ntcts_constructibility_single<48, Elem, Expected>(); + test_ntcts_constructibility_single<64, Elem, Expected>(); + test_ntcts_constructibility_single<96, Elem, Expected>(); +} + +void test_ntcts_constructibility() { // COMPILE-ONLY + // test encoded character types (expected usages) + test_ntcts_constructibility_for_lengths(); +#ifdef __cpp_char8_t + test_ntcts_constructibility_for_lengths(); +#endif // __cpp_char8_t + test_ntcts_constructibility_for_lengths(); + test_ntcts_constructibility_for_lengths(); + test_ntcts_constructibility_for_lengths(); + + enum unscoped_enum {}; + enum class scoped_enum {}; + + struct pod_class { + int n1; + }; + struct missing_trivial_default_ctor { + int n2 = 42; + }; + struct missing_standard_layout : pod_class { + int n3; + }; + struct missing_trivially_copyable { + missing_trivially_copyable() = default; + missing_trivially_copyable(const missing_trivially_copyable&) = default; + missing_trivially_copyable(missing_trivially_copyable&&) = default; + missing_trivially_copyable& operator=(const missing_trivially_copyable&) = default; + constexpr missing_trivially_copyable& operator=(missing_trivially_copyable&&) noexcept { + return *this; + } + ~missing_trivially_copyable() = default; + }; + + // test scalar types + test_ntcts_constructibility_for_lengths(); + test_ntcts_constructibility_for_lengths(); + test_ntcts_constructibility_for_lengths(); + test_ntcts_constructibility_for_lengths(); + test_ntcts_constructibility_for_lengths(); + test_ntcts_constructibility_for_lengths(); + test_ntcts_constructibility_for_lengths(); + + // test POD array types + test_ntcts_constructibility_for_lengths(); + test_ntcts_constructibility_for_lengths(); +#ifdef __cpp_char8_t + test_ntcts_constructibility_for_lengths(); + test_ntcts_constructibility_for_lengths(); +#endif // __cpp_char8_t + test_ntcts_constructibility_for_lengths(); + test_ntcts_constructibility_for_lengths(); + test_ntcts_constructibility_for_lengths(); + test_ntcts_constructibility_for_lengths(); + test_ntcts_constructibility_for_lengths(); + test_ntcts_constructibility_for_lengths(); + test_ntcts_constructibility_for_lengths(); + test_ntcts_constructibility_for_lengths(); + test_ntcts_constructibility_for_lengths(); + test_ntcts_constructibility_for_lengths(); + + // test class types + test_ntcts_constructibility_for_lengths(); + test_ntcts_constructibility_for_lengths(); + test_ntcts_constructibility_for_lengths(); + test_ntcts_constructibility_for_lengths(); + + // test worse class types + test_ntcts_constructibility_for_lengths(); + test_ntcts_constructibility_for_lengths(); +} + const char parsedStr[] = "1000110111110011110111111111111111010111110111100101010100001001" "1111111111111111111111111111111111111111111111111111111111111111" "0111111111111111111111111111111111111111111111111111111111111111" From 847fe01d2ed99341b7bb7c09b0e73fe27a79e2fc Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Fri, 14 Nov 2025 22:34:04 +0800 Subject: [PATCH 2/3] Fix test cases --- tests/std/tests/Dev10_860410_bitset_ctors/test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/std/tests/Dev10_860410_bitset_ctors/test.cpp b/tests/std/tests/Dev10_860410_bitset_ctors/test.cpp index 0a283e3fd46..68fabe95b36 100644 --- a/tests/std/tests/Dev10_860410_bitset_ctors/test.cpp +++ b/tests/std/tests/Dev10_860410_bitset_ctors/test.cpp @@ -36,8 +36,8 @@ namespace lwg_4140 { template void test_ntcts_constructibility_single() { // COMPILE-ONLY - STATIC_ASSERT(is_constructible_v, Elem*> == Expected); - STATIC_ASSERT(is_constructible_v, const Elem*> == Expected); + STATIC_ASSERT(is_constructible_v, Elem*, size_t, Elem, Elem> == Expected); + STATIC_ASSERT(is_constructible_v, const Elem*, size_t, Elem, Elem> == Expected); // the constructor is explicit STATIC_ASSERT(!is_convertible_v>); STATIC_ASSERT(!is_convertible_v>); From 6658d4d28df65853037d0f7c20c159a0040d305b Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Sat, 15 Nov 2025 07:42:23 +0800 Subject: [PATCH 3/3] Unblock one libcxx test --- tests/libcxx/expected_results.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index 343abccc27a..329cbb8881f 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -77,9 +77,6 @@ std/input.output/iostreams.base/ios.base/ios.base.storage/pword.pass.cpp SKIPPED # LWG-3197 "std::prev should not require BidirectionalIterator" (New) std/iterators/iterator.primitives/iterator.operations/prev.pass.cpp FAIL -# Testing nonstandard behavior -std/utilities/template.bitset/bitset.cons/string_ctor.pass.cpp FAIL - # Tests with undefined behavior under N4842 [basic.start.term]/6 (detached threads) std/thread/futures/futures.task/futures.task.members/dtor.pass.cpp SKIPPED std/thread/futures/futures.unique_future/wait_until.pass.cpp SKIPPED