From d283baedeac851b940357e63bc7c2fbe9d7d7440 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20Michal?= Date: Wed, 12 Nov 2025 14:49:35 +0100 Subject: [PATCH 01/16] Add tests. --- tests/std/test.lst | 1 + .../P3016R6_inconsistent_begin_end/env.lst | 4 ++ .../P3016R6_inconsistent_begin_end/test.cpp | 65 +++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 tests/std/tests/P3016R6_inconsistent_begin_end/env.lst create mode 100644 tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp diff --git a/tests/std/test.lst b/tests/std/test.lst index c502981b96d..41a9aa8da45 100644 --- a/tests/std/test.lst +++ b/tests/std/test.lst @@ -720,6 +720,7 @@ tests\P2693R1_text_formatting_header_stacktrace tests\P2693R1_text_formatting_header_thread tests\P2693R1_text_formatting_stacktrace tests\P2693R1_text_formatting_thread_id +tests\P3016R6_inconsistent_begin_end tests\P3107R5_enabled_specializations tests\P3349R1_contiguous_iterators_to_pointers tests\P3503R3_packaged_task_promise_with_allocator diff --git a/tests/std/tests/P3016R6_inconsistent_begin_end/env.lst b/tests/std/tests/P3016R6_inconsistent_begin_end/env.lst new file mode 100644 index 00000000000..642f530ffad --- /dev/null +++ b/tests/std/tests/P3016R6_inconsistent_begin_end/env.lst @@ -0,0 +1,4 @@ +# Copyright (c) Microsoft Corporation. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +RUNALL_INCLUDE ..\usual_latest_matrix.lst diff --git a/tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp b/tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp new file mode 100644 index 00000000000..8e5080a6fb7 --- /dev/null +++ b/tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp @@ -0,0 +1,65 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include +#include +#include + +namespace my { + + template + void begin(std::initializer_list); + + template + void end(std::initializer_list); + + template + void empty(std::initializer_list); + + template + void data(std::initializer_list); +} + + +int main() { + { + // Check that free functions in std can't be invoked with braced-initializer-list. + // If they could be invoked, the following expressions would be ambiguous between std:: and my:: + using namespace std; + using namespace my; + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + static_assert(std::is_same_v); + } + + { + // Check that free functions in std still can be invoked on std::initializer_list + std::initializer_list il = {1, 2, 3}; + + using namespace std; + (void) begin(il); + (void) cbegin(il); + (void) end(il); + (void) cend(il); + (void) size(il); + (void) empty(il); + (void) data(il); + } + + { + // Check that free functions in std can be invoked on std::valarray + std::valarray v{1}; + + using namespace std; + (void) begin(v); + (void) cbegin(v); // Did not compile before P3016R6 + (void) end(v); + (void) cend(v); // Did not compile before P3016R6 + (void) size(v); + // There are no members 'empty' and 'data' of valarray + // (void) empty(il); + // (void) data(il); + } +} From 498ee1cef4e1d6e9e9dfb86bc74fc064a80dc901 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20Michal?= Date: Wed, 12 Nov 2025 14:55:04 +0100 Subject: [PATCH 02/16] Remove free function overloads for std::initializer_list --- stl/inc/initializer_list | 17 ++++++++--------- stl/inc/xutility | 10 ---------- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/stl/inc/initializer_list b/stl/inc/initializer_list index b5d6ae7370e..852c8c32149 100644 --- a/stl/inc/initializer_list +++ b/stl/inc/initializer_list @@ -51,20 +51,19 @@ public: return static_cast(_Last - _First); } + _NODISCARD constexpr bool empty() const noexcept { + return size() == 0; + } + + _NODISCARD constexpr const _Elem* data() const noexcept { + return begin(); + } + private: const _Elem* _First; const _Elem* _Last; }; -_EXPORT_STD template -_NODISCARD constexpr const _Elem* begin(initializer_list<_Elem> _Ilist) noexcept { - return _Ilist.begin(); -} - -_EXPORT_STD template -_NODISCARD constexpr const _Elem* end(initializer_list<_Elem> _Ilist) noexcept { - return _Ilist.end(); -} _STD_END // TRANSITION, non-_Ugly attribute tokens diff --git a/stl/inc/xutility b/stl/inc/xutility index bbaf4357d91..7815db74d9b 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -2283,11 +2283,6 @@ _NODISCARD_EMPTY_NON_MEMBER constexpr bool empty(const _Ty (&)[_Size]) noexcept return false; } -_EXPORT_STD template -_NODISCARD_EMPTY_NON_MEMBER constexpr bool empty(initializer_list<_Elem> _Ilist) noexcept { - return _Ilist.size() == 0; -} - _EXPORT_STD template _NODISCARD constexpr auto data(_Container& _Cont) noexcept(noexcept(_Cont.data())) /* strengthened */ -> decltype(_Cont.data()) { @@ -2305,11 +2300,6 @@ _NODISCARD constexpr _Ty* data(_Ty (&_Array)[_Size]) noexcept { return _Array; } -_EXPORT_STD template -_NODISCARD constexpr const _Elem* data(initializer_list<_Elem> _Ilist) noexcept { - return _Ilist.begin(); -} - #if _HAS_CXX20 #if _HAS_CXX23 _EXPORT_STD template From 497704e913a3e17cffdea7a0f470db0d94f4d2af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20Michal?= Date: Wed, 12 Nov 2025 14:55:35 +0100 Subject: [PATCH 03/16] Change begin/end for valarray from friend free functions to members. --- stl/inc/valarray | 50 +++++++++++++++++------------------------------- 1 file changed, 18 insertions(+), 32 deletions(-) diff --git a/stl/inc/valarray b/stl/inc/valarray index a6a0909d9a8..bef247d8aa7 100644 --- a/stl/inc/valarray +++ b/stl/inc/valarray @@ -59,19 +59,9 @@ class valarray { // store array with various indexing options public: friend _Tidy_deallocate_guard; - template - friend _Ty2* begin(valarray<_Ty2>& _Array) noexcept /* strengthened */; - - template - friend const _Ty2* begin(const valarray<_Ty2>& _Array) noexcept /* strengthened */; - - template - friend _Ty2* end(valarray<_Ty2>& _Array) noexcept /* strengthened */; - - template - friend const _Ty2* end(const valarray<_Ty2>& _Array) noexcept /* strengthened */; - using value_type = _Ty; + using iterator = _Ty*; + using const_iterator = const _Ty*; valarray() = default; // construct empty valarray @@ -411,6 +401,22 @@ public: return _Mysize; } + _NODISCARD iterator begin() noexcept /* strengthened */ { + return _Myptr; + } + + _NODISCARD const_iterator begin() const noexcept /* strengthened */ { + return _Myptr; + } + + _NODISCARD iterator end() noexcept /* strengthened */ { + return _Myptr + _Mysize; + } + + _NODISCARD const_iterator end() const noexcept /* strengthened */ { + return _Myptr + _Mysize; + } + _NODISCARD const _Ty& operator[](size_t _Off) const noexcept /* strengthened */ { #if _MSVC_STL_HARDENING_VALARRAY || _ITERATOR_DEBUG_LEVEL != 0 _STL_VERIFY(_Off < _Mysize, "valarray subscript out of range"); @@ -612,26 +618,6 @@ void swap(valarray<_Ty>& _Left, valarray<_Ty>& _Right) noexcept { _Left.swap(_Right); } -_EXPORT_STD template -_NODISCARD _Ty* begin(valarray<_Ty>& _Array) noexcept /* strengthened */ { - return _Array._Myptr; -} - -_EXPORT_STD template -_NODISCARD const _Ty* begin(const valarray<_Ty>& _Array) noexcept /* strengthened */ { - return _Array._Myptr; -} - -_EXPORT_STD template -_NODISCARD _Ty* end(valarray<_Ty>& _Array) noexcept /* strengthened */ { - return _Array._Myptr + _Array.size(); -} - -_EXPORT_STD template -_NODISCARD const _Ty* end(const valarray<_Ty>& _Array) noexcept /* strengthened */ { - return _Array._Myptr + _Array.size(); -} - _EXPORT_STD template _NODISCARD valarray<_Ty> operator*(const valarray<_Ty>& _Left, const typename valarray<_Ty>::value_type& _Right) { const size_t _Size = _Left.size(); From 0887c8d7f62e74decc6e9e787f1a6e54a7c9c496 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20Michal?= Date: Wed, 12 Nov 2025 14:56:07 +0100 Subject: [PATCH 04/16] Add feature test macros __cpp_lib_initializer_list and __cpp_lib_valarray --- stl/inc/yvals_core.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index 0ccf71729ed..ca87e407b8a 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -80,6 +80,7 @@ // (__cpp_lib_freestanding_algorithm and __cpp_lib_freestanding_array only) // P2937R0 Freestanding Library: Remove strtok // P2968R2 Make std::ignore A First-Class Object +// P3016R6 Resolve Inconsistencies In begin/end For valarray And Braced Initializer Lists // P3223R2 Making istream::ignore() Less Surprising // P3323R1 Forbid atomic, Specify atomic_ref // (for atomic) @@ -1833,6 +1834,11 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect #define __cpp_lib_unreachable 202202L #endif // _HAS_CXX23 +// C++26 +#define __cpp_lib_initializer_list 202511L +#define __cpp_lib_valarray 202511L + + // macros with language mode sensitivity #if _HAS_CXX20 #define __cpp_lib_array_constexpr 201811L // P1032R1 Miscellaneous constexpr From 9a56b7e4ab1aca2c0f3c4ee295a9a54221f068be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20Michal?= Date: Wed, 12 Nov 2025 15:21:53 +0100 Subject: [PATCH 05/16] Remove extra whitespace. --- stl/inc/yvals_core.h | 1 - 1 file changed, 1 deletion(-) diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index ca87e407b8a..e299b61b6a4 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -1838,7 +1838,6 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect #define __cpp_lib_initializer_list 202511L #define __cpp_lib_valarray 202511L - // macros with language mode sensitivity #if _HAS_CXX20 #define __cpp_lib_array_constexpr 201811L // P1032R1 Miscellaneous constexpr From ecc409ad93a7f80be86164011a9412fe194b3a07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20Michal?= Date: Wed, 12 Nov 2025 15:32:39 +0100 Subject: [PATCH 06/16] Fix incorrect formatting. --- stl/inc/valarray | 4 ++-- .../P3016R6_inconsistent_begin_end/test.cpp | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/stl/inc/valarray b/stl/inc/valarray index bef247d8aa7..73a6a0e8fa8 100644 --- a/stl/inc/valarray +++ b/stl/inc/valarray @@ -59,8 +59,8 @@ class valarray { // store array with various indexing options public: friend _Tidy_deallocate_guard; - using value_type = _Ty; - using iterator = _Ty*; + using value_type = _Ty; + using iterator = _Ty*; using const_iterator = const _Ty*; valarray() = default; // construct empty valarray diff --git a/tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp b/tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp index 8e5080a6fb7..9d99422f908 100644 --- a/tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp +++ b/tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp @@ -1,25 +1,25 @@ // Copyright (c) Microsoft Corporation. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include #include +#include #include #include namespace my { - - template + + template void begin(std::initializer_list); - template + template void end(std::initializer_list); - template + template void empty(std::initializer_list); - template + template void data(std::initializer_list); -} +} // namespace my int main() { @@ -33,8 +33,8 @@ int main() { static_assert(std::is_same_v); static_assert(std::is_same_v); } - - { + + { // Check that free functions in std still can be invoked on std::initializer_list std::initializer_list il = {1, 2, 3}; From b9c607a2a5648fba205dfaae624b76f2f5d093f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20Michal?= Date: Wed, 12 Nov 2025 18:59:29 +0100 Subject: [PATCH 07/16] Update tests to unconditionally support P3016R6. Only check that begin(initializer_list) is constexpr in C++17 onwards (tests/Dev11_1074023_constexpr). Mark libc++ std/language.support/support.initlist/support.initlist.range/begin_end.pass.cpp as known FAIL. --- tests/libcxx/expected_results.txt | 3 +++ tests/std/tests/Dev11_1074023_constexpr/test.cpp | 2 ++ 2 files changed, 5 insertions(+) diff --git a/tests/libcxx/expected_results.txt b/tests/libcxx/expected_results.txt index 343abccc27a..156412a9bc1 100644 --- a/tests/libcxx/expected_results.txt +++ b/tests/libcxx/expected_results.txt @@ -142,6 +142,9 @@ std/language.support/support.limits/support.limits.general/mdspan.version.compil # libc++ has not implemented P2937R0: "Freestanding Library: Remove strtok" std/language.support/support.limits/support.limits.general/cstring.version.compile.pass.cpp FAIL +# libc++ has not implemented P3016R6: "Resolve Inconsistencies In begin/end For valarray And Braced Initializer Lists" +std/language.support/support.initlist/support.initlist.range/begin_end.pass.cpp FAIL + # libc++ has not implemented P3323R1: "Forbid atomic, Specify atomic_ref" std/atomics/atomics.ref/member_types.compile.pass.cpp FAIL diff --git a/tests/std/tests/Dev11_1074023_constexpr/test.cpp b/tests/std/tests/Dev11_1074023_constexpr/test.cpp index d9b87f87247..47092a0a47e 100644 --- a/tests/std/tests/Dev11_1074023_constexpr/test.cpp +++ b/tests/std/tests/Dev11_1074023_constexpr/test.cpp @@ -53,7 +53,9 @@ constexpr auto int64_max = numeric_limits::max(); constexpr initializer_list il; STATIC_ASSERT(il.size() == 0); STATIC_ASSERT(il.begin() == il.end()); +#if _HAS_CXX17 STATIC_ASSERT(begin(il) == end(il)); +#endif // _HAS_CXX17 // TRANSITION, // constexpr error_category() noexcept; From 1f660da4f4e45f158faab11ac0706364db6cf671 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20Michal?= Date: Thu, 13 Nov 2025 13:25:25 +0100 Subject: [PATCH 08/16] Correct placement of feature test macros in yvals_core.h --- stl/inc/yvals_core.h | 6 ++---- .../VSO_0157762_feature_test_macros/test.compile.pass.cpp | 4 ++++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index e299b61b6a4..97dc0808a70 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -1609,6 +1609,7 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect #define __cpp_lib_freestanding_tuple 202306L #define __cpp_lib_freestanding_utility 202306L #define __cpp_lib_generic_associative_lookup 201304L +#define __cpp_lib_initializer_list 202511L #define __cpp_lib_integer_sequence 201304L #define __cpp_lib_integral_constant_callable 201304L #define __cpp_lib_is_final 201402L @@ -1626,6 +1627,7 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect #define __cpp_lib_transformation_trait_aliases 201304L #define __cpp_lib_tuple_element_t 201402L #define __cpp_lib_tuples_by_type 201304L +#define __cpp_lib_valarray 202511L // C++17 #define __cpp_lib_addressof_constexpr 201603L @@ -1834,10 +1836,6 @@ _EMIT_STL_ERROR(STL1004, "C++98 unexpected() is incompatible with C++23 unexpect #define __cpp_lib_unreachable 202202L #endif // _HAS_CXX23 -// C++26 -#define __cpp_lib_initializer_list 202511L -#define __cpp_lib_valarray 202511L - // macros with language mode sensitivity #if _HAS_CXX20 #define __cpp_lib_array_constexpr 201811L // P1032R1 Miscellaneous constexpr diff --git a/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp b/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp index fe5fbd82a9a..67578b87396 100644 --- a/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp +++ b/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp @@ -1048,3 +1048,7 @@ STATIC_ASSERT(__cpp_lib_variant == 202102L); #endif STATIC_ASSERT(__cpp_lib_void_t == 201411L); + +STATIC_ASSERT(__cpp_lib_initializer_list == 202511L); + +STATIC_ASSERT(__cpp_lib_valarray == 202511L); From dcf8058dcfdb86a10af7f7ae2fe71f9cb1b8d714 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojt=C4=9Bch=20Michal?= Date: Thu, 13 Nov 2025 13:29:04 +0100 Subject: [PATCH 09/16] Add constexpr tests for std::initializer_list and iteration over braced-init-list --- .../P3016R6_inconsistent_begin_end/env.lst | 2 +- .../P3016R6_inconsistent_begin_end/test.cpp | 96 ++++++++++++------- 2 files changed, 60 insertions(+), 38 deletions(-) diff --git a/tests/std/tests/P3016R6_inconsistent_begin_end/env.lst b/tests/std/tests/P3016R6_inconsistent_begin_end/env.lst index 642f530ffad..19f025bd0e6 100644 --- a/tests/std/tests/P3016R6_inconsistent_begin_end/env.lst +++ b/tests/std/tests/P3016R6_inconsistent_begin_end/env.lst @@ -1,4 +1,4 @@ # Copyright (c) Microsoft Corporation. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -RUNALL_INCLUDE ..\usual_latest_matrix.lst +RUNALL_INCLUDE ..\usual_matrix.lst diff --git a/tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp b/tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp index 9d99422f908..ab63fa58fe5 100644 --- a/tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp +++ b/tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp @@ -6,6 +6,8 @@ #include #include +#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) + namespace my { template @@ -21,45 +23,65 @@ namespace my { void data(std::initializer_list); } // namespace my +_CONSTEXPR17 bool test_initializer_list() { + // Check that free functions in std still can be invoked on std::initializer_list + std::initializer_list il = {1, 2, 3}; -int main() { - { - // Check that free functions in std can't be invoked with braced-initializer-list. - // If they could be invoked, the following expressions would be ambiguous between std:: and my:: - using namespace std; - using namespace my; - static_assert(std::is_same_v); - static_assert(std::is_same_v); - static_assert(std::is_same_v); - static_assert(std::is_same_v); - } + using namespace std; + (void) begin(il); + (void) cbegin(il); + (void) end(il); + (void) cend(il); + (void) size(il); + (void) empty(il); + (void) data(il); - { - // Check that free functions in std still can be invoked on std::initializer_list - std::initializer_list il = {1, 2, 3}; - - using namespace std; - (void) begin(il); - (void) cbegin(il); - (void) end(il); - (void) cend(il); - (void) size(il); - (void) empty(il); - (void) data(il); - } + return true; +} + +bool test_valarray() { + // Check that free functions in std can be invoked on std::valarray + std::valarray v{1}; - { - // Check that free functions in std can be invoked on std::valarray - std::valarray v{1}; - - using namespace std; - (void) begin(v); - (void) cbegin(v); // Did not compile before P3016R6 - (void) end(v); - (void) cend(v); // Did not compile before P3016R6 - (void) size(v); - // There are no members 'empty' and 'data' of valarray - // (void) empty(il); - // (void) data(il); + using namespace std; + (void) begin(v); + (void) cbegin(v); // Did not compile before P3016R6 + (void) end(v); + (void) cend(v); // Did not compile before P3016R6 + (void) size(v); + // There are no members 'empty' and 'data' of valarray + // (void) empty(il); + // (void) data(il); + + return true; +} + +constexpr bool test_braced_init_list_iteration() { + int sum = 0; + for (int n : {1, 2, 3, 4}) { + sum += n; } + return sum == 10; +} + + +int main() { + // Check that free functions in std can't be invoked with braced-initializer-list. + // If they could be invoked, the following expressions would be ambiguous between std:: and my:: + using namespace std; + using namespace my; + STATIC_ASSERT(std::is_same_v); + STATIC_ASSERT(std::is_same_v); + STATIC_ASSERT(std::is_same_v); + STATIC_ASSERT(std::is_same_v); + + test_initializer_list(); + test_valarray(); + test_braced_init_list_iteration(); + +#if _HAS_CXX17 + STATIC_ASSERT(test_initializer_list()); +#endif // _HAS_CXX17 + // STATIC_ASSERT(test_valarray()); // valarray is not literal + STATIC_ASSERT(test_braced_init_list_iteration()); } From 1b6624a12b507966c0b7e14b40b3c1781251c225 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 7 Jan 2026 02:45:24 -0800 Subject: [PATCH 10/16] Sort VSO_0157762_feature_test_macros. --- .../VSO_0157762_feature_test_macros/test.compile.pass.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp b/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp index f96f65a4dd3..aaf81e98164 100644 --- a/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp +++ b/tests/std/tests/VSO_0157762_feature_test_macros/test.compile.pass.cpp @@ -491,6 +491,8 @@ STATIC_ASSERT(__cpp_lib_hypot == 201603L); STATIC_ASSERT(__cpp_lib_incomplete_container_elements == 201505L); +STATIC_ASSERT(__cpp_lib_initializer_list == 202511L); + #if _HAS_CXX20 STATIC_ASSERT(__cpp_lib_int_pow2 == 202002L); #elif defined(__cpp_lib_int_pow2) @@ -1037,6 +1039,8 @@ STATIC_ASSERT(__cpp_lib_unwrap_ref == 201811L); #error __cpp_lib_unwrap_ref is defined #endif +STATIC_ASSERT(__cpp_lib_valarray == 202511L); + #if _HAS_CXX20 STATIC_ASSERT(__cpp_lib_variant == 202106L); #elif _HAS_CXX17 @@ -1046,7 +1050,3 @@ STATIC_ASSERT(__cpp_lib_variant == 202102L); #endif STATIC_ASSERT(__cpp_lib_void_t == 201411L); - -STATIC_ASSERT(__cpp_lib_initializer_list == 202511L); - -STATIC_ASSERT(__cpp_lib_valarray == 202511L); From 714e09480b31aaa8d0a3ddfa4489184ebec03b55 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 7 Jan 2026 03:00:22 -0800 Subject: [PATCH 11/16] Micro-optimize initializer_list empty/data. --- stl/inc/initializer_list | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stl/inc/initializer_list b/stl/inc/initializer_list index 852c8c32149..9a6279a4a2f 100644 --- a/stl/inc/initializer_list +++ b/stl/inc/initializer_list @@ -52,11 +52,11 @@ public: } _NODISCARD constexpr bool empty() const noexcept { - return size() == 0; + return _First == _Last; } _NODISCARD constexpr const _Elem* data() const noexcept { - return begin(); + return _First; } private: From 13b95c8177f9b34dcda24514aca670a6f0983cda Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 7 Jan 2026 03:21:38 -0800 Subject: [PATCH 12/16] Remove "strengthened" comments. --- stl/inc/xutility | 48 ++++++++++++++++++------------------------------ 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index 98351888992..25501b2fcee 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -2142,26 +2142,23 @@ constexpr bool disable_sized_sentinel_for, reverse_ite #endif // _HAS_CXX20 _EXPORT_STD template -_NODISCARD _CONSTEXPR17 auto begin(_Container& _Cont) noexcept(noexcept(_Cont.begin())) /* strengthened */ - -> decltype(_Cont.begin()) { +_NODISCARD _CONSTEXPR17 auto begin(_Container& _Cont) noexcept(noexcept(_Cont.begin())) -> decltype(_Cont.begin()) { return _Cont.begin(); } _EXPORT_STD template -_NODISCARD _CONSTEXPR17 auto begin(const _Container& _Cont) noexcept(noexcept(_Cont.begin())) /* strengthened */ +_NODISCARD _CONSTEXPR17 auto begin(const _Container& _Cont) noexcept(noexcept(_Cont.begin())) -> decltype(_Cont.begin()) { return _Cont.begin(); } _EXPORT_STD template -_NODISCARD _CONSTEXPR17 auto end(_Container& _Cont) noexcept(noexcept(_Cont.end())) /* strengthened */ - -> decltype(_Cont.end()) { +_NODISCARD _CONSTEXPR17 auto end(_Container& _Cont) noexcept(noexcept(_Cont.end())) -> decltype(_Cont.end()) { return _Cont.end(); } _EXPORT_STD template -_NODISCARD _CONSTEXPR17 auto end(const _Container& _Cont) noexcept(noexcept(_Cont.end())) /* strengthened */ - -> decltype(_Cont.end()) { +_NODISCARD _CONSTEXPR17 auto end(const _Container& _Cont) noexcept(noexcept(_Cont.end())) -> decltype(_Cont.end()) { return _Cont.end(); } @@ -2188,66 +2185,60 @@ _NODISCARD constexpr auto cend(const _Container& _Cont) noexcept(noexcept(_STD e } _EXPORT_STD template -_NODISCARD _CONSTEXPR17 auto rbegin(_Container& _Cont) noexcept(noexcept(_Cont.rbegin())) /* strengthened */ - -> decltype(_Cont.rbegin()) { +_NODISCARD _CONSTEXPR17 auto rbegin(_Container& _Cont) noexcept(noexcept(_Cont.rbegin())) -> decltype(_Cont.rbegin()) { return _Cont.rbegin(); } _EXPORT_STD template -_NODISCARD _CONSTEXPR17 auto rbegin(const _Container& _Cont) noexcept(noexcept(_Cont.rbegin())) /* strengthened */ +_NODISCARD _CONSTEXPR17 auto rbegin(const _Container& _Cont) noexcept(noexcept(_Cont.rbegin())) -> decltype(_Cont.rbegin()) { return _Cont.rbegin(); } _EXPORT_STD template -_NODISCARD _CONSTEXPR17 auto rend(_Container& _Cont) noexcept(noexcept(_Cont.rend())) /* strengthened */ - -> decltype(_Cont.rend()) { +_NODISCARD _CONSTEXPR17 auto rend(_Container& _Cont) noexcept(noexcept(_Cont.rend())) -> decltype(_Cont.rend()) { return _Cont.rend(); } _EXPORT_STD template -_NODISCARD _CONSTEXPR17 auto rend(const _Container& _Cont) noexcept(noexcept(_Cont.rend())) /* strengthened */ - -> decltype(_Cont.rend()) { +_NODISCARD _CONSTEXPR17 auto rend(const _Container& _Cont) noexcept(noexcept(_Cont.rend())) -> decltype(_Cont.rend()) { return _Cont.rend(); } _EXPORT_STD template -_NODISCARD _CONSTEXPR17 reverse_iterator<_Ty*> rbegin(_Ty (&_Array)[_Size]) noexcept /* strengthened */ { +_NODISCARD _CONSTEXPR17 reverse_iterator<_Ty*> rbegin(_Ty (&_Array)[_Size]) noexcept { return reverse_iterator<_Ty*>(_Array + _Size); } _EXPORT_STD template -_NODISCARD _CONSTEXPR17 reverse_iterator<_Ty*> rend(_Ty (&_Array)[_Size]) noexcept /* strengthened */ { +_NODISCARD _CONSTEXPR17 reverse_iterator<_Ty*> rend(_Ty (&_Array)[_Size]) noexcept { return reverse_iterator<_Ty*>(_Array); } _EXPORT_STD template -_NODISCARD _CONSTEXPR17 reverse_iterator rbegin(initializer_list<_Elem> _Ilist) noexcept -/* strengthened */ { +_NODISCARD _CONSTEXPR17 reverse_iterator rbegin(initializer_list<_Elem> _Ilist) noexcept { return reverse_iterator(_Ilist.end()); } _EXPORT_STD template -_NODISCARD _CONSTEXPR17 reverse_iterator rend(initializer_list<_Elem> _Ilist) noexcept -/* strengthened */ { +_NODISCARD _CONSTEXPR17 reverse_iterator rend(initializer_list<_Elem> _Ilist) noexcept { return reverse_iterator(_Ilist.begin()); } _EXPORT_STD template -_NODISCARD _CONSTEXPR17 auto crbegin(const _Container& _Cont) noexcept(noexcept(_STD rbegin(_Cont))) /* strengthened */ +_NODISCARD _CONSTEXPR17 auto crbegin(const _Container& _Cont) noexcept(noexcept(_STD rbegin(_Cont))) -> decltype(_STD rbegin(_Cont)) { return _STD rbegin(_Cont); } _EXPORT_STD template -_NODISCARD _CONSTEXPR17 auto crend(const _Container& _Cont) noexcept(noexcept(_STD rend(_Cont))) /* strengthened */ +_NODISCARD _CONSTEXPR17 auto crend(const _Container& _Cont) noexcept(noexcept(_STD rend(_Cont))) -> decltype(_STD rend(_Cont)) { return _STD rend(_Cont); } _EXPORT_STD template -_NODISCARD constexpr auto size(const _Container& _Cont) noexcept(noexcept(_Cont.size())) /* strengthened */ - -> decltype(_Cont.size()) { +_NODISCARD constexpr auto size(const _Container& _Cont) noexcept(noexcept(_Cont.size())) -> decltype(_Cont.size()) { return _Cont.size(); } @@ -2272,8 +2263,7 @@ _NODISCARD constexpr ptrdiff_t ssize(const _Ty (&)[_Size]) noexcept { #endif // _HAS_CXX20 _EXPORT_STD template -_NODISCARD_EMPTY_NON_MEMBER constexpr auto empty(const _Container& _Cont) - noexcept(noexcept(_Cont.empty())) /* strengthened */ +_NODISCARD_EMPTY_NON_MEMBER constexpr auto empty(const _Container& _Cont) noexcept(noexcept(_Cont.empty())) -> decltype(_Cont.empty()) { return _Cont.empty(); } @@ -2284,14 +2274,12 @@ _NODISCARD_EMPTY_NON_MEMBER constexpr bool empty(const _Ty (&)[_Size]) noexcept } _EXPORT_STD template -_NODISCARD constexpr auto data(_Container& _Cont) noexcept(noexcept(_Cont.data())) /* strengthened */ - -> decltype(_Cont.data()) { +_NODISCARD constexpr auto data(_Container& _Cont) noexcept(noexcept(_Cont.data())) -> decltype(_Cont.data()) { return _Cont.data(); } _EXPORT_STD template -_NODISCARD constexpr auto data(const _Container& _Cont) noexcept(noexcept(_Cont.data())) /* strengthened */ - -> decltype(_Cont.data()) { +_NODISCARD constexpr auto data(const _Container& _Cont) noexcept(noexcept(_Cont.data())) -> decltype(_Cont.data()) { return _Cont.data(); } From fbf64639385ee565cf215a2cee27d4c57f78f0a5 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 7 Jan 2026 03:21:58 -0800 Subject: [PATCH 13/16] Simplify `ssize()` to match N5032 and remove its "strengthened" comment. `make_signed_t` requires non-bool integral/enum types, so the `static_cast` can't possibly throw. --- stl/inc/xutility | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index 25501b2fcee..b88e899ea2b 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -2249,8 +2249,7 @@ _NODISCARD constexpr size_t size(const _Ty (&)[_Size]) noexcept { #if _HAS_CXX20 _EXPORT_STD template -_NODISCARD constexpr auto ssize(const _Container& _Cont) noexcept(noexcept( - static_cast>>(_Cont.size()))) /* strengthened */ +_NODISCARD constexpr auto ssize(const _Container& _Cont) noexcept(noexcept(_Cont.size())) -> common_type_t> { using _Common = common_type_t>; return static_cast<_Common>(_Cont.size()); From 6578f060da7b2d27712ef1d293cc827504a36fbf Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 7 Jan 2026 03:33:06 -0800 Subject: [PATCH 14/16] `typename` => `class` in test code. --- tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp b/tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp index ab63fa58fe5..01bd47872c4 100644 --- a/tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp +++ b/tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp @@ -10,16 +10,16 @@ namespace my { - template + template void begin(std::initializer_list); - template + template void end(std::initializer_list); - template + template void empty(std::initializer_list); - template + template void data(std::initializer_list); } // namespace my From 897baa7c9ab2680cf411ddc49cd9b99643d4607e Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 7 Jan 2026 03:38:10 -0800 Subject: [PATCH 15/16] Adjust newlines. --- tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp b/tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp index 01bd47872c4..2677a13054b 100644 --- a/tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp +++ b/tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp @@ -9,7 +9,6 @@ #define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) namespace my { - template void begin(std::initializer_list); @@ -64,7 +63,6 @@ constexpr bool test_braced_init_list_iteration() { return sum == 10; } - int main() { // Check that free functions in std can't be invoked with braced-initializer-list. // If they could be invoked, the following expressions would be ambiguous between std:: and my:: From 019075f01d50789630943d46b13e3d4e4e70c2f9 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Wed, 7 Jan 2026 03:41:48 -0800 Subject: [PATCH 16/16] Avoid commented-out test code. --- tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp b/tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp index 2677a13054b..2b666b769b0 100644 --- a/tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp +++ b/tests/std/tests/P3016R6_inconsistent_begin_end/test.cpp @@ -38,6 +38,7 @@ _CONSTEXPR17 bool test_initializer_list() { return true; } +// test_valarray() is not constexpr because valarray is not a literal type bool test_valarray() { // Check that free functions in std can be invoked on std::valarray std::valarray v{1}; @@ -49,8 +50,6 @@ bool test_valarray() { (void) cend(v); // Did not compile before P3016R6 (void) size(v); // There are no members 'empty' and 'data' of valarray - // (void) empty(il); - // (void) data(il); return true; } @@ -80,6 +79,5 @@ int main() { #if _HAS_CXX17 STATIC_ASSERT(test_initializer_list()); #endif // _HAS_CXX17 - // STATIC_ASSERT(test_valarray()); // valarray is not literal STATIC_ASSERT(test_braced_init_list_iteration()); }