From e68046f1f1225b0bb3150375dfa25f09d77461ff Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 23 Jan 2026 10:05:04 -0800 Subject: [PATCH 01/17] Update citations. --- stl/inc/flat_map | 14 +++++++------- stl/inc/flat_set | 10 +++++----- tests/std/tests/P0429R9_flat_map/test.cpp | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/stl/inc/flat_map b/stl/inc/flat_map index 503a6573f7c..da82fc49d6d 100644 --- a/stl/inc/flat_map +++ b/stl/inc/flat_map @@ -330,22 +330,22 @@ public: static_assert(is_same_v, "key_type and key_container_type::value_type must be the same. " - "(N5014 [flat.map.overview]/8, [flat.multimap.overview]/8)"); + "(N5032 [flat.map.overview]/8, [flat.multimap.overview]/8)"); static_assert(is_same_v, "mapped_type and mapped_container_type::value_type must be the same. " - "(N5014 [flat.map.overview]/8, [flat.multimap.overview]/8)"); + "(N5032 [flat.map.overview]/8, [flat.multimap.overview]/8)"); static_assert(!_Is_vector_bool, "key_container_type cannot be vector because it is not a sequence container. " - "(N5014 [flat.map.overview]/7, [flat.multimap.overview]/7)"); + "(N5032 [flat.map.overview]/7, [flat.multimap.overview]/7)"); static_assert(!_Is_vector_bool, "mapped_container_type cannot be vector because it is not a sequence container. " - "(N5014 [flat.map.overview]/7, [flat.multimap.overview]/7)"); + "(N5032 [flat.map.overview]/7, [flat.multimap.overview]/7)"); static_assert(random_access_iterator, "key_container_type must support random-access iterators in order to be adapted. " - "(N5014 [flat.map.overview]/7, [flat.multimap.overview]/7)"); + "(N5032 [flat.map.overview]/7, [flat.multimap.overview]/7)"); static_assert(random_access_iterator, "mapped_container_type must support random-access iterators in order to be adapted. " - "(N5014 [flat.map.overview]/7, [flat.multimap.overview]/7)"); + "(N5032 [flat.map.overview]/7, [flat.multimap.overview]/7)"); class value_compare { public: @@ -748,7 +748,7 @@ public: _NODISCARD containers extract() && noexcept( is_nothrow_move_constructible_v && is_nothrow_move_constructible_v) /* strengthened */ { - // always clears the container (N5014 [flat.map.modifiers]/34 and [flat.multimap.overview]/4) + // always clears the container (N5032 [flat.map.modifiers]/35 and [flat.multimap.overview]/4) _Clear_guard _Always_clear{this}; return _STD move(_Data); } diff --git a/stl/inc/flat_set b/stl/inc/flat_set index bf910f4cf3c..60d723304e9 100644 --- a/stl/inc/flat_set +++ b/stl/inc/flat_set @@ -87,13 +87,13 @@ private: public: static_assert(same_as<_Kty, typename _Container::value_type>, "key_type and container_type::value_type must be the same. " - "(N5014 [flat.set.overview]/8, [flat.multiset.overview]/8)"); + "(N5032 [flat.set.overview]/8, [flat.multiset.overview]/8)"); static_assert(!_Is_vector_bool<_Container>, "vector cannot be adapted because it is not a sequence container. " - "(N5014 [flat.set.overview]/7, [flat.multiset.overview]/7)"); + "(N5032 [flat.set.overview]/7, [flat.multiset.overview]/7)"); static_assert(random_access_iterator, "Sequence containers must support random-access iterators in order to be adapted. " - "(N5014 [flat.set.overview]/7, [flat.multiset.overview]/7)"); + "(N5032 [flat.set.overview]/7, [flat.multiset.overview]/7)"); using key_type = _Kty; using value_type = _Kty; @@ -365,7 +365,7 @@ public: _NODISCARD container_type extract() && noexcept( is_nothrow_move_constructible_v) /* strengthened */ { - // always clears the container (N5014 [flat.set.modifiers]/14 and [flat.multiset.modifiers]/10) + // always clears the container (N5032 [flat.set.modifiers]/16 and [flat.multiset.modifiers]/15) _Clear_guard _Always_clear{this}; return _STD move(_Mycont); } @@ -664,7 +664,7 @@ private: template _NODISCARD size_type _Erase_if(_Pred _Predicate) { - // Maintain invariants when an exception is thrown (N5014 [flat.set.erasure]/5, [flat.multiset.erasure]/5) + // Maintain invariants when an exception is thrown (N5032 [flat.set.erasure]/5, [flat.multiset.erasure]/5) _Clear_guard _Guard{this}; const auto _Erased_count = _STD _Erase_remove_if(_Mycont, _Predicate); _Guard._Target = nullptr; diff --git a/tests/std/tests/P0429R9_flat_map/test.cpp b/tests/std/tests/P0429R9_flat_map/test.cpp index 7be0b081067..932d91c326a 100644 --- a/tests/std/tests/P0429R9_flat_map/test.cpp +++ b/tests/std/tests/P0429R9_flat_map/test.cpp @@ -447,7 +447,7 @@ void test_construction() { assert(check_key_content(fmmap, {0, 1, 2, 2, 3, 4})); assert(check_value_content( - fmmap, {44, 2324, 635462, 7, 433, 5})); // guaranteed by N4971 [flat.multimap.cons]/6 + fmmap, {44, 2324, 635462, 7, 433, 5})); // guaranteed by N5032 [flat.multimap.cons]/3 assert(fmmap == fmmap1); } { @@ -964,7 +964,7 @@ void test_insert() { assert(it5->second == 'q'); assert(check_key_content(fmm, {10, 10, 70, 70, 90})); - // N4981 [associative.reqmts.general]/68 and /72 specify the values of the result to be {'m', 'n', 'p', 'q', 'w'}. + // N5032 [associative.reqmts.general]/68 and /72 specify the values of the result to be {'m', 'n', 'p', 'q', 'w'}. assert(check_value_content(fmm, {'m', 'n', 'p', 'q', 'w'})); } From 58c081e1b1f3465bc39823d75a4c991fa9bae741 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 23 Jan 2026 12:18:10 -0800 Subject: [PATCH 02/17] We can use `_STD is_sorted_until`. --- stl/inc/flat_map | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stl/inc/flat_map b/stl/inc/flat_map index da82fc49d6d..9f9c0fd3640 100644 --- a/stl/inc/flat_map +++ b/stl/inc/flat_map @@ -1104,7 +1104,8 @@ private: } // O(N) if already sorted. - const auto _Num_sorted = _RANGES is_sorted_until(_Data.keys, _Pass_key_comp()) - _Data.keys.begin(); + const auto _Num_sorted = + _STD is_sorted_until(_Data.keys.begin(), _Data.keys.end(), _Pass_key_comp()) - _Data.keys.begin(); auto _View = _View_to_mutate(); const auto _Begin_unsorted_values = _View.begin() + _Num_sorted; From 5b1e95ba85049140bf63c2699cfbaad1ad6f961e Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 23 Jan 2026 12:42:28 -0800 Subject: [PATCH 03/17] P0429R9_flat_map_ms_specific: Simplify `flat_map_unique_if` with `conditional_t`. --- .../test.compile.pass.cpp | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/tests/std/tests/P0429R9_flat_map_ms_specific/test.compile.pass.cpp b/tests/std/tests/P0429R9_flat_map_ms_specific/test.compile.pass.cpp index fd39e6a478c..0426beb99ff 100644 --- a/tests/std/tests/P0429R9_flat_map_ms_specific/test.compile.pass.cpp +++ b/tests/std/tests/P0429R9_flat_map_ms_specific/test.compile.pass.cpp @@ -35,21 +35,9 @@ struct MyAllocator { } }; -template -struct flat_map_unique_if_impl; -template <> -struct flat_map_unique_if_impl { - template - using type = flat_map; -}; -template <> -struct flat_map_unique_if_impl { - template - using type = flat_multimap; -}; - template -using flat_map_unique_if = flat_map_unique_if_impl::template type; +using flat_map_unique_if = conditional_t, + flat_multimap>; template constexpr bool has_different_nested_types = !is_same_v From d53bddd3c180e7bbda844814d210242ed11cc3f7 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 23 Jan 2026 12:43:19 -0800 Subject: [PATCH 04/17] P0429R9_flat_map_ms_specific: Simplify `test_scary_ness_one()` by moving the `Cont` alias up. --- .../test.compile.pass.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/tests/std/tests/P0429R9_flat_map_ms_specific/test.compile.pass.cpp b/tests/std/tests/P0429R9_flat_map_ms_specific/test.compile.pass.cpp index 0426beb99ff..03f1dc2c165 100644 --- a/tests/std/tests/P0429R9_flat_map_ms_specific/test.compile.pass.cpp +++ b/tests/std/tests/P0429R9_flat_map_ms_specific/test.compile.pass.cpp @@ -45,17 +45,16 @@ constexpr bool has_different_nested_types = !is_same_v void test_scary_ness_one() { - using Iter = flat_map::iterator; - using OtherIter = - flat_map_unique_if, vector>::iterator; + using Cont = flat_map_unique_if, vector>; + + using Iter = flat_map::iterator; + using OtherIter = Cont::iterator; static_assert(is_same_v); - using ConstIter = flat_map::const_iterator; - using OtherConstIter = - flat_map_unique_if, vector>::const_iterator; + using ConstIter = flat_map::const_iterator; + using OtherConstIter = Cont::const_iterator; static_assert(is_same_v); - using Cont = flat_map_unique_if, vector>; using OtherCont1 = flat_map_unique_if, vector>; using OtherCont2 = flat_map_unique_if, deque>; using OtherCont3 = flat_map_unique_if, deque>; From c1075cf81bf6ebd4da38cea9dd6e48e2d06f08f0 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 23 Jan 2026 13:11:07 -0800 Subject: [PATCH 05/17] Include `` for `stderr`. --- tests/std/tests/P0429R9_flat_map/test.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/std/tests/P0429R9_flat_map/test.cpp b/tests/std/tests/P0429R9_flat_map/test.cpp index 932d91c326a..a9751abaf10 100644 --- a/tests/std/tests/P0429R9_flat_map/test.cpp +++ b/tests/std/tests/P0429R9_flat_map/test.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include From 998cea57f980c7b223241bcf44e9e58480631d23 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 23 Jan 2026 13:11:24 -0800 Subject: [PATCH 06/17] Use `is_specialization_v` which the test just defined. --- tests/std/tests/P0429R9_flat_map/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/std/tests/P0429R9_flat_map/test.cpp b/tests/std/tests/P0429R9_flat_map/test.cpp index a9751abaf10..de93272f24a 100644 --- a/tests/std/tests/P0429R9_flat_map/test.cpp +++ b/tests/std/tests/P0429R9_flat_map/test.cpp @@ -46,7 +46,7 @@ void assert_all_requirements(const T& s) { assert_noexcept_requirements(s); assert_noexcept_requirements(const_cast(s)); - assert_is_sorted_maybe_unique<_Is_specialization_v>(s); + assert_is_sorted_maybe_unique>(s); } template From 58d9448720c768baa19c081766dd9b443abb8002 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 23 Jan 2026 13:11:37 -0800 Subject: [PATCH 07/17] Consolidate `println` calls. --- tests/std/tests/P0429R9_flat_map/test.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/std/tests/P0429R9_flat_map/test.cpp b/tests/std/tests/P0429R9_flat_map/test.cpp index de93272f24a..95b165b51d1 100644 --- a/tests/std/tests/P0429R9_flat_map/test.cpp +++ b/tests/std/tests/P0429R9_flat_map/test.cpp @@ -64,8 +64,7 @@ template [[nodiscard]] bool check_content(const T& obj, const type_identity_t& expected) { assert_all_requirements(obj); if (!ranges::equal(obj, expected)) { - println(stderr, "Unexpected content!\nExpected {}", expected); - println(stderr, "Actual {}", obj); + println(stderr, "Unexpected content!\nExpected {}\nActual {}", expected, obj); return false; } return true; From 83c30fbb5b43b6ebfbd14b7c8fd5db3063c525a3 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 23 Jan 2026 13:11:52 -0800 Subject: [PATCH 08/17] Avoid quasi-shadowing `ranges::subrange`. --- tests/std/tests/P0429R9_flat_map/test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/std/tests/P0429R9_flat_map/test.cpp b/tests/std/tests/P0429R9_flat_map/test.cpp index 95b165b51d1..31b98932725 100644 --- a/tests/std/tests/P0429R9_flat_map/test.cpp +++ b/tests/std/tests/P0429R9_flat_map/test.cpp @@ -108,8 +108,8 @@ template assert(ranges::adjacent_find(subranges, is_gap_or_overlap) == subranges.end()); } - return ranges::all_of(subranges, [&expected, &actual](const subrange_t& subrange) { - const auto& [first_index, last_index, type] = subrange; + return ranges::all_of(subranges, [&expected, &actual](const subrange_t& sr) { + const auto& [first_index, last_index, type] = sr; const ranges::subrange actual_subrange{actual.begin() + first_index, actual.begin() + last_index + 1}; const ranges::subrange expected_subrange{expected.begin() + first_index, expected.begin() + last_index + 1}; From fc8a27bc3412a4a8dc91616477c3e566e8cfbf1d Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 23 Jan 2026 13:22:45 -0800 Subject: [PATCH 09/17] Fix MyAllocator, then fix recently added tests. --- tests/std/tests/P0429R9_flat_map/test.cpp | 33 ++++++++++++----------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/tests/std/tests/P0429R9_flat_map/test.cpp b/tests/std/tests/P0429R9_flat_map/test.cpp index 31b98932725..349a072742b 100644 --- a/tests/std/tests/P0429R9_flat_map/test.cpp +++ b/tests/std/tests/P0429R9_flat_map/test.cpp @@ -122,28 +122,31 @@ template } template -class MyAllocator : public allocator { +class MyAllocator { public: using value_type = T; - using allocator::allocator; - static size_t getActiveAllocationCount() { - return s_allocations.load(); - } + MyAllocator() = default; + template + MyAllocator(const MyAllocator&) noexcept {} - T* allocate(size_t n) { - ++s_allocations; - return allocator::allocate(n); + [[nodiscard]] static size_t getActiveAllocationCount() { + return s_allocations.load(); } - T* allocate_at_least(size_t n) { + [[nodiscard]] T* allocate(size_t n) { ++s_allocations; - return allocator::allocate_at_least(n); + return allocator{}.allocate(n); } void deallocate(T* p, size_t n) noexcept { --s_allocations; - allocator::deallocate(p, n); + allocator{}.deallocate(p, n); + } + + template + [[nodiscard]] friend constexpr bool operator==(const MyAllocator&, const MyAllocator&) noexcept { + return true; } private: @@ -283,9 +286,9 @@ void test_construction() { // and flat_map(const key_comp&, const alloc&) { MyAllocatorCounter allocation_counter; - flat_map fmap(MyAllocator{}); + flat_map_my_allocator fmap(MyAllocator{}); assert(!allocation_counter.check_then_reset()); - flat_map fmap1(less{}, MyAllocator{}); + flat_map_my_allocator fmap1(less{}, MyAllocator{}); assert(!allocation_counter.check_then_reset()); assert(check_key_content(fmap, {})); @@ -294,9 +297,9 @@ void test_construction() { } { MyAllocatorCounter allocation_counter; - flat_multimap fmmap(MyAllocator{}); + flat_multimap_my_allocator fmmap(MyAllocator{}); assert(!allocation_counter.check_then_reset()); - flat_multimap fmmap1(less{}, MyAllocator{}); + flat_multimap_my_allocator fmmap1(less{}, MyAllocator{}); assert(!allocation_counter.check_then_reset()); assert(check_key_content(fmmap, {})); From eb72090e017ac279bb7a88c0474b59a9c60adad9 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 23 Jan 2026 13:36:06 -0800 Subject: [PATCH 10/17] Cosmetic: Move `size_t N` to be first. --- tests/std/tests/P0429R9_flat_map/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/std/tests/P0429R9_flat_map/test.cpp b/tests/std/tests/P0429R9_flat_map/test.cpp index 349a072742b..8d910f39da4 100644 --- a/tests/std/tests/P0429R9_flat_map/test.cpp +++ b/tests/std/tests/P0429R9_flat_map/test.cpp @@ -167,7 +167,7 @@ struct almost_pair { }; namespace std { - template + template struct tuple_element> { using type = conditional_t; }; From 79d6cbd22c5b3801ba96d3904959858ce76f1097 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 23 Jan 2026 13:36:29 -0800 Subject: [PATCH 11/17] Fix tuple_element to be 0-based. --- tests/std/tests/P0429R9_flat_map/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/std/tests/P0429R9_flat_map/test.cpp b/tests/std/tests/P0429R9_flat_map/test.cpp index 8d910f39da4..bbc76294ca9 100644 --- a/tests/std/tests/P0429R9_flat_map/test.cpp +++ b/tests/std/tests/P0429R9_flat_map/test.cpp @@ -169,7 +169,7 @@ struct almost_pair { namespace std { template struct tuple_element> { - using type = conditional_t; + using type = conditional_t; }; } // namespace std From 377c3902a5eb19c9744659e7c879112b85f0c5ad Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 23 Jan 2026 13:38:23 -0800 Subject: [PATCH 12/17] Avoid unnecessary `U&&`; `constructible_from` uses `declval`. --- tests/std/tests/P0429R9_flat_map/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/std/tests/P0429R9_flat_map/test.cpp b/tests/std/tests/P0429R9_flat_map/test.cpp index bbc76294ca9..8b203d2874b 100644 --- a/tests/std/tests/P0429R9_flat_map/test.cpp +++ b/tests/std/tests/P0429R9_flat_map/test.cpp @@ -181,7 +181,7 @@ class Packaged { public: Packaged() : value() {} template - requires constructible_from + requires constructible_from Packaged(U&& u) : value(forward(u)) {} T get() const { From 0c72eb34927eaf5917c9d162b17c9e36df041c10 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 23 Jan 2026 13:52:30 -0800 Subject: [PATCH 13/17] Use `less{}` for consistency --- tests/std/tests/P0429R9_flat_map/test.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/std/tests/P0429R9_flat_map/test.cpp b/tests/std/tests/P0429R9_flat_map/test.cpp index 8b203d2874b..e3a0c9ee9fe 100644 --- a/tests/std/tests/P0429R9_flat_map/test.cpp +++ b/tests/std/tests/P0429R9_flat_map/test.cpp @@ -263,10 +263,9 @@ void test_construction() { { // Test flat_map() and flat_map(const key_compare&) - const less compare; { flat_map fmap; - flat_map fmap1(compare); + flat_map fmap1(less{}); assert(check_key_content(fmap, {})); assert(check_value_content(fmap, {})); @@ -274,7 +273,7 @@ void test_construction() { } { flat_multimap fmmap; - flat_multimap fmmap1(compare); + flat_multimap fmmap1(less{}); assert(check_key_content(fmmap, {})); assert(check_value_content(fmmap, {})); From e7c6bb5d64a7aef42c9cf10a9191eff3d53d2f35 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 23 Jan 2026 14:01:17 -0800 Subject: [PATCH 14/17] Adjust comment spacing. --- tests/std/tests/P0429R9_flat_map/test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/std/tests/P0429R9_flat_map/test.cpp b/tests/std/tests/P0429R9_flat_map/test.cpp index e3a0c9ee9fe..c82614b3bdc 100644 --- a/tests/std/tests/P0429R9_flat_map/test.cpp +++ b/tests/std/tests/P0429R9_flat_map/test.cpp @@ -463,7 +463,7 @@ void test_construction() { } { // Test flat_map(_Sorted_t, const key_cont&, const mapped_cont&, const key_comp&, const alloc&) - // and flat_map(_Sorted_t, const key_cont&, const mapped_cont&, const alloc&) + // and flat_map(_Sorted_t, const key_cont&, const mapped_cont&, const alloc&) { KeyCont> keys = {0, 1, 2, 3, 4}; MappedCont> vals = {44, 2324, 635462, 433, 5}; @@ -624,7 +624,7 @@ void test_construction() { } { // Test flat_map(_Sorted_t, iter, iter, const key_comp&, const alloc&) - // and flat_map(_Sorted_t, iter, iter, const alloc&) + // and flat_map(_Sorted_t, iter, iter, const alloc&) { almost_pair value_types[]{{0, 44}, {1, 2324}, {2, 635462}, {3, 433}, {4, 5}}; From f53322235d9cfd64b6e43b0a90762f2a66624b26 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 23 Jan 2026 14:01:31 -0800 Subject: [PATCH 15/17] Improve test_erase_if() scoping. --- tests/std/tests/P0429R9_flat_map/test.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/std/tests/P0429R9_flat_map/test.cpp b/tests/std/tests/P0429R9_flat_map/test.cpp index c82614b3bdc..230fa19f674 100644 --- a/tests/std/tests/P0429R9_flat_map/test.cpp +++ b/tests/std/tests/P0429R9_flat_map/test.cpp @@ -873,16 +873,18 @@ void test_construction() { template