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/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 diff --git a/tests/std/tests/Dev10_860410_bitset_ctors/test.cpp b/tests/std/tests/Dev10_860410_bitset_ctors/test.cpp index 8121cab24df..68fabe95b36 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*, 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>); +} + +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"