From 54e205f87ed4be20f05165fe4a027dec2a360eab Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Mon, 26 Jan 2026 04:14:28 -0800 Subject: [PATCH 01/25] Drop `using namespace ranges;`, qualify `ranges::input_range` and `ranges::range_reference_t`. --- tests/std/tests/P1222R4_flat_set/test.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/std/tests/P1222R4_flat_set/test.cpp b/tests/std/tests/P1222R4_flat_set/test.cpp index f18ebbaf78e..d9374a8df9f 100644 --- a/tests/std/tests/P1222R4_flat_set/test.cpp +++ b/tests/std/tests/P1222R4_flat_set/test.cpp @@ -24,12 +24,11 @@ #define TEST_ASSERT(...) assert((__VA_ARGS__)) using namespace std; -using namespace ranges; enum class iterator_pair_construction : bool { no_allocator, with_allocator }; template -concept container_compatible_range = input_range && convertible_to, T>; +concept container_compatible_range = ranges::input_range && convertible_to, T>; template , iterator_pair_construction Choice = iterator_pair_construction::with_allocator> From 5ad5748ee847554b97ebb566e31fc0db0f96dfb5 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Mon, 26 Jan 2026 04:18:30 -0800 Subject: [PATCH 02/25] Drop `std::` for `less`, `greater`, `move`, `copy`. --- tests/std/tests/P1222R4_flat_set/test.cpp | 86 +++++++++++------------ 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/tests/std/tests/P1222R4_flat_set/test.cpp b/tests/std/tests/P1222R4_flat_set/test.cpp index d9374a8df9f..abb77fbecad 100644 --- a/tests/std/tests/P1222R4_flat_set/test.cpp +++ b/tests/std/tests/P1222R4_flat_set/test.cpp @@ -67,7 +67,7 @@ class alternative_vector : private vector { // not allocator-aware, bu constexpr alternative_vector(allocator_arg_t, const type_identity_t& a, const alternative_vector& other) : base_type(other, a) {} constexpr alternative_vector(allocator_arg_t, const type_identity_t& a, alternative_vector&& other) - : base_type(std::move(other), a) {} + : base_type(move(other), a) {} constexpr explicit alternative_vector(initializer_list il) : base_type(il) {} alternative_vector(const alternative_vector&) = default; @@ -171,8 +171,8 @@ void assert_all_requirements_and_equals( template void test_constructors() { - using lt = std::less; - using gt = std::greater; + using lt = less; + using gt = greater; { // Test flat_set() @@ -208,21 +208,21 @@ void test_constructors() { a = {1, 7, 7, 7, 2, 100, -1}; assert_all_requirements_and_equals(a, {-1, 1, 2, 7, 100}); assert_all_requirements_and_equals(flat_set(a, allocator{}), {-1, 1, 2, 7, 100}); - assert_all_requirements_and_equals(flat_set(std::move(a), allocator{}), {-1, 1, 2, 7, 100}); + assert_all_requirements_and_equals(flat_set(move(a), allocator{}), {-1, 1, 2, 7, 100}); flat_multiset b{}; b = {1, 7, 7, 7, 2, 100, -1}; assert_all_requirements_and_equals(b, {-1, 1, 2, 7, 7, 7, 100}); assert_all_requirements_and_equals(flat_multiset(b, allocator{}), {-1, 1, 2, 7, 7, 7, 100}); - assert_all_requirements_and_equals(flat_multiset(std::move(b), allocator{}), {-1, 1, 2, 7, 7, 7, 100}); + assert_all_requirements_and_equals(flat_multiset(move(b), allocator{}), {-1, 1, 2, 7, 7, 7, 100}); } template void test_allocator_extended_constructors() { using vec = alternative_vector, Choice>; constexpr allocator ator; - constexpr std::less comp; + constexpr less comp; { - using fs = flat_set, vec>; + using fs = flat_set, vec>; fs s{3, 7, 1, 85, 222, 1}; fs s_expected{1, 3, 7, 85, 222}; @@ -233,7 +233,7 @@ void test_allocator_extended_constructors() { TEST_ASSERT(fs{s, ator} == s_expected); TEST_ASSERT(fs{s_expected, ator} == s_expected); - TEST_ASSERT(fs{std::move(s), ator} == s_expected); + TEST_ASSERT(fs{move(s), ator} == s_expected); TEST_ASSERT(fs{fs{s_expected}, ator} == s_expected); TEST_ASSERT(fs{v_raw, ator} == s_expected); @@ -257,7 +257,7 @@ void test_allocator_extended_constructors() { } } { - using fms = flat_multiset, vec>; + using fms = flat_multiset, vec>; fms s{3, 7, 1, 85, 222, 1}; fms s_expected{1, 1, 3, 7, 85, 222}; @@ -268,7 +268,7 @@ void test_allocator_extended_constructors() { TEST_ASSERT(fms{s, ator} == s_expected); TEST_ASSERT(fms{s_expected, ator} == s_expected); - TEST_ASSERT(fms{std::move(s), ator} == s_expected); + TEST_ASSERT(fms{move(s), ator} == s_expected); TEST_ASSERT(fms{fms{s_expected}, ator} == s_expected); TEST_ASSERT(fms{v_raw, ator} == s_expected); @@ -311,7 +311,7 @@ void test_always_reversible() { using base::base; }; - Set, not_reversible> fs({1, 2, 3}); + Set, not_reversible> fs({1, 2, 3}); assert_all_requirements_and_equals(fs, {3, 2, 1}); assert(fs.rbegin() + 3 == fs.rend()); assert(fs.crend() - fs.crbegin() == 3); @@ -319,7 +319,7 @@ void test_always_reversible() { template void test_insert_1() { - using lt = std::less; + using lt = less; const vector vec{0, 1, 2}; { @@ -374,7 +374,7 @@ void test_insert_1() { template void test_insert_2() { - using lt = std::less; + using lt = less; const int val = 1; { @@ -403,7 +403,7 @@ void test_insert_2() { } // TRANSITION, too simple - using gt = std::greater; + using gt = greater; { flat_set a{0, 5}; assert_all_requirements_and_equals(a, {5, 0}); @@ -417,7 +417,7 @@ void test_insert_2() { // Test that hint to emplace/insert is respected, when possible; check returned iterator template void test_insert_hint_is_respected() { - using lt = std::less; + using lt = less; { flat_multiset a{-1, -1, 1, 1}; @@ -621,7 +621,7 @@ void test_insert_upper_bound() { template void test_spaceship_operator() { static constexpr bool multi = _Is_specialization_v; - static constexpr bool invert = is_same_v>; + static constexpr bool invert = is_same_v>; T a{3, 2, 2, 1}; T b{1, 2, 3}; @@ -659,7 +659,7 @@ void test_non_static_comparer() { a.insert_range(vector{7, 7, 3, 3, 2}); assert_all_requirements_and_equals(a, {9, 7, 5, 3, 2, -1}); - a = std::move(aBackup); + a = move(aBackup); assert_all_requirements_and_equals(a, {1, 2, 3}); a.insert(-100); @@ -696,9 +696,9 @@ void test_extract_1() { }; will_throw = false; - Set, test_exception> fs{4, 3, 2, 1}; + Set, test_exception> fs{4, 3, 2, 1}; assert_all_requirements_and_equals(fs, {1, 2, 3, 4}); - auto extr = std::move(fs).extract(); + auto extr = move(fs).extract(); assert(ranges::equal(extr, vector{1, 2, 3, 4})); assert_all_requirements_and_equals(fs, {}); // assert empty @@ -706,7 +706,7 @@ void test_extract_1() { assert_all_requirements_and_equals(fs, {1, 2, 3, 4}); try { will_throw = true; - (void) std::move(fs).extract(); + (void) move(fs).extract(); } catch (...) { will_throw = false; assert_all_requirements_and_equals(fs, {}); // assert empty @@ -736,9 +736,9 @@ void test_extract_2() { } }; - Set, always_copy> fs{4, 3, 2, 1}; + Set, always_copy> fs{4, 3, 2, 1}; assert_all_requirements_and_equals(fs, {1, 2, 3, 4}); - auto extr = std::move(fs).extract(); + auto extr = move(fs).extract(); assert(ranges::equal(extr, vector{1, 2, 3, 4})); assert_all_requirements_and_equals(fs, {}); // assert empty } @@ -798,7 +798,7 @@ void test_invariant_robustness() { // this copy-assignment cannot provide strong-guarantee for `this`: odd_container& operator=(const odd_container& other) { resize(other.size()); - std::copy(other.begin(), other.end(), begin()); + copy(other.begin(), other.end(), begin()); return *this; } @@ -807,7 +807,7 @@ void test_invariant_robustness() { odd_container(odd_container&& other) { reserve(other.size()); for (auto& e : other) { - push_back(std::move(e)); + push_back(move(e)); } } @@ -815,7 +815,7 @@ void test_invariant_robustness() { // elements of `other` in moved-from state: odd_container& operator=(odd_container&& other) { resize(other.size()); - std::move(other.begin(), other.end(), begin()); + move(other.begin(), other.end(), begin()); return *this; } }; @@ -846,7 +846,7 @@ void test_invariant_robustness() { { copy_limit = unlimited; SetT fs1{0, 1, 2, 3, 4}; - SetT fs2{std::move(fs1)}; + SetT fs2{move(fs1)}; assert_all_requirements(fs1); assert(ranges::equal(fs2, vector{0, 1, 2, 3, 4}, {}, &odd_key::key)); @@ -854,7 +854,7 @@ void test_invariant_robustness() { bool caught = false; try { copy_limit = 2; - SetT fs3{std::move(fs2)}; // will throw after moving 2 odd_key. + SetT fs3{move(fs2)}; // will throw after moving 2 odd_key. } catch (...) { copy_limit = unlimited; assert_all_requirements(fs2); @@ -868,7 +868,7 @@ void test_invariant_robustness() { SetT fs1{0, 1, 2, 3, 4}; SetT fs2; SetT fs3{5, 6, 7, 8, 9}; - fs2 = std::move(fs1); + fs2 = move(fs1); assert_all_requirements(fs1); assert(ranges::equal(fs2, vector{0, 1, 2, 3, 4}, {}, &odd_key::key)); @@ -877,7 +877,7 @@ void test_invariant_robustness() { bool caught = false; try { copy_limit = 2; - fs2 = std::move(fs3); // will throw after moving 2 odd_key. + fs2 = move(fs3); // will throw after moving 2 odd_key. } catch (...) { copy_limit = unlimited; assert_all_requirements(fs2); @@ -912,14 +912,14 @@ template struct holder { T t; operator T() && { - return std::move(t); + return move(t); } }; static_assert(is_convertible_v::const_iterator>, flat_set::const_iterator>); void test_erase_2() { - using C = flat_set>; + using C = flat_set>; C fs{0, 1, 2, 3}; assert_all_requirements_and_equals(fs, {0, 1, 2, 3}); // this should be allowed per P2077R3: @@ -953,16 +953,16 @@ namespace detail { static_assert(same_as().erase(declval()))>); // erase key_type - static_assert(can_erase_key>, int>); - static_assert(can_erase_key>, int>); + static_assert(can_erase_key>, int>); + static_assert(can_erase_key>, int>); static_assert(can_erase_key, int>); // erase wrapped key_type - static_assert(!can_erase_key>, holder>); - static_assert(can_erase_key>, holder>); + static_assert(!can_erase_key>, holder>); + static_assert(can_erase_key>, holder>); static_assert(can_erase_key, holder>); // erase wrapped iterator - the member function template returning size_type must not be selected - static_assert(can_erase_iterator_holder>>); - static_assert(can_erase_iterator_holder>>); + static_assert(can_erase_iterator_holder>>); + static_assert(can_erase_iterator_holder>>); static_assert(can_erase_iterator_holder>); } // namespace detail @@ -1244,12 +1244,12 @@ void test_non_strict_weak_order_compare() { void run_normal_tests() { test_spaceship_operator>(); test_spaceship_operator>(); - test_spaceship_operator>>(); - test_spaceship_operator>>(); - test_spaceship_operator, deque>>(); - test_spaceship_operator, deque>>(); - test_spaceship_operator, deque>>(); - test_spaceship_operator, deque>>(); + test_spaceship_operator>>(); + test_spaceship_operator>>(); + test_spaceship_operator, deque>>(); + test_spaceship_operator, deque>>(); + test_spaceship_operator, deque>>(); + test_spaceship_operator, deque>>(); test_constructors>(); test_constructors>(); From 180e07834fe5de0a16db1ab71a925ae2a74943e0 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Mon, 26 Jan 2026 04:20:10 -0800 Subject: [PATCH 03/25] Use `ranges::equal` and `println()`. This is more consistent with the flat_map test and improves the output from: ``` running normal tests...Expected: {1, 3, 7, 85, 223, } Got: {1, 3, 7, 85, 222, } ``` to: ``` running normal tests...Unexpected content! Expected [1, 3, 7, 85, 223] Actual {1, 3, 7, 85, 222} ``` --- tests/std/tests/P1222R4_flat_set/test.cpp | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/tests/std/tests/P1222R4_flat_set/test.cpp b/tests/std/tests/P1222R4_flat_set/test.cpp index abb77fbecad..ccee35f4097 100644 --- a/tests/std/tests/P1222R4_flat_set/test.cpp +++ b/tests/std/tests/P1222R4_flat_set/test.cpp @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -146,17 +145,8 @@ template void assert_all_requirements_and_equals(const T& s, const initializer_list& il) { assert_all_requirements(s); - if (!std::equal(s.begin(), s.end(), il.begin(), il.end())) { - cout << "Expected: {"; - for (auto&& e : il) { - cout << e << ", "; - } - cout << "}" << endl; - cout << "Got: {"; - for (auto&& e : s) { - cout << e << ", "; - } - cout << "}" << endl; + if (!ranges::equal(s, il)) { + println("Unexpected content!\nExpected {}\nActual {}", il, s); assert(false); } } From 1397a42f660e1539f45965fb173690403ff3f4cd Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Mon, 26 Jan 2026 04:47:51 -0800 Subject: [PATCH 04/25] `INT_MAX` => `(numeric_limits::max)()` --- tests/std/tests/P1222R4_flat_set/test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/std/tests/P1222R4_flat_set/test.cpp b/tests/std/tests/P1222R4_flat_set/test.cpp index ccee35f4097..708a89ee21d 100644 --- a/tests/std/tests/P1222R4_flat_set/test.cpp +++ b/tests/std/tests/P1222R4_flat_set/test.cpp @@ -3,12 +3,12 @@ #include #include -#include #include #include #include #include #include +#include #include #include #include @@ -735,7 +735,7 @@ void test_extract_2() { void test_invariant_robustness() { static int copy_limit = 2; - constexpr int unlimited = INT_MAX; + constexpr int unlimited = (numeric_limits::max)(); struct odd_key { static void countdown() { From aa5983624779128d84330d4643b133a883e2cd81 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Mon, 26 Jan 2026 04:58:41 -0800 Subject: [PATCH 05/25] Cite N5032 [associative.reqmts.general] instead of P2077R3 Heterogeneous Erasure Overloads For Associative Containers. --- tests/std/tests/P1222R4_flat_set/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/std/tests/P1222R4_flat_set/test.cpp b/tests/std/tests/P1222R4_flat_set/test.cpp index 708a89ee21d..e1d57b6c6c2 100644 --- a/tests/std/tests/P1222R4_flat_set/test.cpp +++ b/tests/std/tests/P1222R4_flat_set/test.cpp @@ -912,7 +912,7 @@ void test_erase_2() { using C = flat_set>; C fs{0, 1, 2, 3}; assert_all_requirements_and_equals(fs, {0, 1, 2, 3}); - // this should be allowed per P2077R3: + // this should be allowed per N5032 [associative.reqmts.general]/7.23.2 and /122-125: fs.erase(holder{fs.cbegin()}); assert_all_requirements_and_equals(fs, {1, 2, 3}); fs.erase(holder{fs.begin()}); From cab2c030129a6a7774e1a56634793ad9f2d971a2 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Mon, 26 Jan 2026 08:43:27 -0800 Subject: [PATCH 06/25] Drop extra newlines. --- tests/std/tests/P1222R4_flat_set/test.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/std/tests/P1222R4_flat_set/test.cpp b/tests/std/tests/P1222R4_flat_set/test.cpp index e1d57b6c6c2..7395038dcfd 100644 --- a/tests/std/tests/P1222R4_flat_set/test.cpp +++ b/tests/std/tests/P1222R4_flat_set/test.cpp @@ -462,7 +462,6 @@ void test_insert_hint_is_respected() { } } - struct key_comparer { const auto& extract_key(const auto& obj) const { if constexpr (requires { obj.key; }) { @@ -956,7 +955,6 @@ namespace detail { static_assert(can_erase_iterator_holder>); } // namespace detail - template void test_erase_if() { constexpr int erased_result[]{1, 3}; From 2b636754140d86ab114d0fa9f534baa406bff070 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Mon, 26 Jan 2026 08:49:41 -0800 Subject: [PATCH 07/25] Run tests in definition order. --- tests/std/tests/P1222R4_flat_set/test.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/std/tests/P1222R4_flat_set/test.cpp b/tests/std/tests/P1222R4_flat_set/test.cpp index 7395038dcfd..e59eadd32a7 100644 --- a/tests/std/tests/P1222R4_flat_set/test.cpp +++ b/tests/std/tests/P1222R4_flat_set/test.cpp @@ -1230,15 +1230,6 @@ void test_non_strict_weak_order_compare() { } void run_normal_tests() { - test_spaceship_operator>(); - test_spaceship_operator>(); - test_spaceship_operator>>(); - test_spaceship_operator>>(); - test_spaceship_operator, deque>>(); - test_spaceship_operator, deque>>(); - test_spaceship_operator, deque>>(); - test_spaceship_operator, deque>>(); - test_constructors>(); test_constructors>(); test_allocator_extended_constructors(); @@ -1253,11 +1244,20 @@ void run_normal_tests() { test_insert_2>(); test_insert_hint_is_respected>(); test_insert_hint_is_respected>(); + test_comparer_application(); test_insert_transparent(); test_insert_using_invalid_hint(); test_insert_upper_bound(); - test_comparer_application(); + test_spaceship_operator>(); + test_spaceship_operator>(); + test_spaceship_operator>>(); + test_spaceship_operator>>(); + test_spaceship_operator, deque>>(); + test_spaceship_operator, deque>>(); + test_spaceship_operator, deque>>(); + test_spaceship_operator, deque>>(); + test_non_static_comparer(); test_extract_1(); @@ -1265,9 +1265,9 @@ void run_normal_tests() { test_extract_2(); test_extract_2(); + test_invariant_robustness(); test_erase_1(); test_erase_2(); - test_invariant_robustness(); test_erase_if>(); test_erase_if>(); From 283b596a5161fdc0ff756b31a5705c8e29378587 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Mon, 26 Jan 2026 06:30:29 -0800 Subject: [PATCH 08/25] Overhaul `test_constructors()` to actually test all normal constructors. Update 2-arg `assert_all_requirements_and_equals()` to accept other ranges. Drop 3-arg `assert_all_requirements_and_equals()`. --- tests/std/tests/P1222R4_flat_set/test.cpp | 120 ++++++++++++++-------- 1 file changed, 75 insertions(+), 45 deletions(-) diff --git a/tests/std/tests/P1222R4_flat_set/test.cpp b/tests/std/tests/P1222R4_flat_set/test.cpp index e59eadd32a7..641017e7bda 100644 --- a/tests/std/tests/P1222R4_flat_set/test.cpp +++ b/tests/std/tests/P1222R4_flat_set/test.cpp @@ -141,69 +141,99 @@ void assert_all_requirements(const T& s) { assert_is_sorted_maybe_unique<_Is_specialization_v>(s); } -template -void assert_all_requirements_and_equals(const T& s, const initializer_list& il) { +template > +void assert_all_requirements_and_equals(const T& s, const U& correct) { assert_all_requirements(s); - if (!ranges::equal(s, il)) { - println("Unexpected content!\nExpected {}\nActual {}", il, s); + if (!ranges::equal(s, correct)) { + println("Unexpected content!\nExpected {}\nActual {}", correct, s); assert(false); } } -template -void assert_all_requirements_and_equals( - const T& first, const U& second, const initializer_list& il) { - assert_all_requirements_and_equals(first, il); - assert_all_requirements_and_equals(second, il); - assert(first == second); -} - template void test_constructors() { using lt = less; using gt = greater; + // Test flat_set() + // and flat_set(const key_compare&) + assert_all_requirements_and_equals(flat_set(), {}); + assert_all_requirements_and_equals(flat_multiset(), {}); + assert_all_requirements_and_equals(flat_set(lt{}), {}); + assert_all_requirements_and_equals(flat_multiset(lt{}), {}); + { - // Test flat_set() - // and flat_set(const key_compare&) - const lt comp; - { - flat_set fs; - flat_set fs1(comp); - assert_all_requirements_and_equals(fs, fs1, {}); - } - { - flat_multiset fms; - flat_multiset fms1(comp); - assert_all_requirements_and_equals(fms, fms1, {}); - } - } - { - // Test flat_set(const container) + // Test flat_set(container_type, const key_compare& = key_compare()) + flat_set fs1(C{3, 7, 1, 85, 222, 1}); + flat_multiset fms1(C{3, 7, 1, 85, 7, 222, 1}); + flat_set fs2(C{1, 2, 3, 3}, gt{}); + flat_multiset fms2(C{1, 1, 2, 3}, gt{}); + assert_all_requirements_and_equals(fs1, {1, 3, 7, 85, 222}); + assert_all_requirements_and_equals(fms1, {1, 1, 3, 7, 7, 85, 222}); + assert_all_requirements_and_equals(fs2, {3, 2, 1}); + assert_all_requirements_and_equals(fms2, {3, 2, 1, 1}); + + // Test flat_set(const flat_set&) + // and flat_set(flat_set&&) + flat_set fs3(fs1); + flat_multiset fms3(fms1); + flat_set fs4(move(fs2)); + flat_multiset fms4(move(fms2)); + assert_all_requirements_and_equals(fs3, {1, 3, 7, 85, 222}); + assert_all_requirements_and_equals(fms3, {1, 1, 3, 7, 7, 85, 222}); + assert_all_requirements_and_equals(fs4, {3, 2, 1}); + assert_all_requirements_and_equals(fms4, {3, 2, 1, 1}); } - assert_all_requirements_and_equals(flat_set(C{3, 7, 1, 85, 222, 1}), {1, 3, 7, 85, 222}); - assert_all_requirements_and_equals(flat_multiset(C{3, 7, 1, 85, 7, 222, 1}), {1, 1, 3, 7, 7, 85, 222}); - assert_all_requirements_and_equals(flat_set(C{1, 2, 3, 3}, gt{}), {3, 2, 1}); - assert_all_requirements_and_equals(flat_multiset(C{1, 1, 2, 3}, gt{}), {3, 2, 1, 1}); + // Test flat_set(sorted_unique_t, container_type, const key_compare& = key_compare()) + assert_all_requirements_and_equals(flat_set(sorted_unique, C{1, 200, 30000}), {1, 200, 30000}); + assert_all_requirements_and_equals(flat_multiset(sorted_equivalent, C{-1, 3, 3}), {-1, 3, 3}); assert_all_requirements_and_equals(flat_set(sorted_unique, C{30000, 200, 1}, gt{}), {30000, 200, 1}); assert_all_requirements_and_equals(flat_multiset(sorted_equivalent, C{3, 3, -1}, gt{}), {3, 3, -1}); - assert_all_requirements_and_equals(flat_set({30000, 200, 1}, gt{}), {30000, 200, 1}); - assert_all_requirements_and_equals(flat_multiset({3, 3, -1}, gt{}), {3, 3, -1}); + + const int arr[] = {2, 7, 18, 28, 18, 28, 45, 90, 45, 23}; + + // Test flat_set(InIt, InIt, const key_compare& = key_compare()) + assert_all_requirements_and_equals(flat_set(begin(arr), end(arr)), {2, 7, 18, 23, 28, 45, 90}); + assert_all_requirements_and_equals( + flat_multiset(begin(arr), end(arr)), {2, 7, 18, 18, 23, 28, 28, 45, 45, 90}); + assert_all_requirements_and_equals(flat_set(begin(arr), end(arr), gt{}), {90, 45, 28, 23, 18, 7, 2}); + assert_all_requirements_and_equals( + flat_multiset(begin(arr), end(arr), gt{}), {90, 45, 45, 28, 28, 23, 18, 18, 7, 2}); + + { + // Test flat_set(sorted_unique_t, InIt, InIt, const key_compare& = key_compare()) + const int ua[] = {10, 20, 30}; // unique ascending + const int ea[] = {40, 50, 50, 60, 60, 60}; // equivalent ascending + const int ud[] = {66, 55, 44}; // unique descending + const int ed[] = {33, 22, 22, 11, 11, 11}; // equivalent descending + assert_all_requirements_and_equals(flat_set(sorted_unique, begin(ua), end(ua)), ua); + assert_all_requirements_and_equals(flat_multiset(sorted_equivalent, begin(ea), end(ea)), ea); + assert_all_requirements_and_equals(flat_set(sorted_unique, begin(ud), end(ud), gt{}), ud); + assert_all_requirements_and_equals(flat_multiset(sorted_equivalent, begin(ed), end(ed), gt{}), ed); + } + + // Test flat_set(from_range_t, R&&) + // and flat_set(from_range_t, R&&, const key_compare&) + assert_all_requirements_and_equals(flat_set(from_range, arr), {2, 7, 18, 23, 28, 45, 90}); + assert_all_requirements_and_equals( + flat_multiset(from_range, arr), {2, 7, 18, 18, 23, 28, 28, 45, 45, 90}); + assert_all_requirements_and_equals(flat_set(from_range, arr, gt{}), {90, 45, 28, 23, 18, 7, 2}); + assert_all_requirements_and_equals( + flat_multiset(from_range, arr, gt{}), {90, 45, 45, 28, 28, 23, 18, 18, 7, 2}); + + // Test flat_set(initializer_list, const key_compare& = key_compare()) + assert_all_requirements_and_equals(flat_set({3, 7, 1, 85, 222, 1}), {1, 3, 7, 85, 222}); + assert_all_requirements_and_equals(flat_multiset({3, 7, 1, 85, 7, 222, 1}), {1, 1, 3, 7, 7, 85, 222}); + assert_all_requirements_and_equals(flat_set({1, 2, 3, 3}, gt{}), {3, 2, 1}); + assert_all_requirements_and_equals(flat_multiset({1, 1, 2, 3}, gt{}), {3, 2, 1, 1}); + + // Test flat_set(sorted_unique_t, initializer_list, const key_compare& = key_compare()) + assert_all_requirements_and_equals(flat_set(sorted_unique, {1, 200, 30000}), {1, 200, 30000}); + assert_all_requirements_and_equals(flat_multiset(sorted_equivalent, {-1, 3, 3}), {-1, 3, 3}); assert_all_requirements_and_equals(flat_set(sorted_unique, {30000, 200, 1}, gt{}), {30000, 200, 1}); assert_all_requirements_and_equals(flat_multiset(sorted_equivalent, {3, 3, -1}, gt{}), {3, 3, -1}); - - flat_set a{}; - a = {1, 7, 7, 7, 2, 100, -1}; - assert_all_requirements_and_equals(a, {-1, 1, 2, 7, 100}); - assert_all_requirements_and_equals(flat_set(a, allocator{}), {-1, 1, 2, 7, 100}); - assert_all_requirements_and_equals(flat_set(move(a), allocator{}), {-1, 1, 2, 7, 100}); - flat_multiset b{}; - b = {1, 7, 7, 7, 2, 100, -1}; - assert_all_requirements_and_equals(b, {-1, 1, 2, 7, 7, 7, 100}); - assert_all_requirements_and_equals(flat_multiset(b, allocator{}), {-1, 1, 2, 7, 7, 7, 100}); - assert_all_requirements_and_equals(flat_multiset(move(b), allocator{}), {-1, 1, 2, 7, 7, 7, 100}); } template From f0eb53a00a08f4a0c2787aa9afbbba44f2494923 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Mon, 26 Jan 2026 10:57:50 -0800 Subject: [PATCH 09/25] Test construction from just an allocator. --- tests/std/tests/P1222R4_flat_set/test.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/std/tests/P1222R4_flat_set/test.cpp b/tests/std/tests/P1222R4_flat_set/test.cpp index 641017e7bda..9d6b00f1ed6 100644 --- a/tests/std/tests/P1222R4_flat_set/test.cpp +++ b/tests/std/tests/P1222R4_flat_set/test.cpp @@ -249,6 +249,7 @@ void test_allocator_extended_constructors() { vec v_raw{3, 7, 1, 85, 222, 1}; vec v_sorted_unique{1, 3, 7, 85, 222}; + TEST_ASSERT(fs{ator} == fs{}); TEST_ASSERT(fs{comp, ator} == fs{}); TEST_ASSERT(fs{s, ator} == s_expected); @@ -284,6 +285,7 @@ void test_allocator_extended_constructors() { vec v_raw{3, 7, 1, 85, 222, 1}; vec v_sorted_eq{1, 1, 3, 7, 85, 222}; + TEST_ASSERT(fms{ator} == fms{}); TEST_ASSERT(fms{comp, ator} == fms{}); TEST_ASSERT(fms{s, ator} == s_expected); From 8a6ca1748721a4bc5ba6fe4db2c5f567cd65ed11 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 27 Jan 2026 02:39:54 -0800 Subject: [PATCH 10/25] Expand `test_insert_2()`, fixing "TRANSITION, too simple". --- tests/std/tests/P1222R4_flat_set/test.cpp | 29 +++++++++++++++++------ 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/tests/std/tests/P1222R4_flat_set/test.cpp b/tests/std/tests/P1222R4_flat_set/test.cpp index 9d6b00f1ed6..756b806c92f 100644 --- a/tests/std/tests/P1222R4_flat_set/test.cpp +++ b/tests/std/tests/P1222R4_flat_set/test.cpp @@ -424,15 +424,30 @@ void test_insert_2() { assert_all_requirements_and_equals(a, {0, 0, 0, 1, 5, 6}); } - // TRANSITION, too simple using gt = greater; { - flat_set a{0, 5}; - assert_all_requirements_and_equals(a, {5, 0}); - a.insert(a.begin(), 3); - assert_all_requirements_and_equals(a, {5, 3, 0}); - a.insert(a.end(), 4); - assert_all_requirements_and_equals(a, {5, 4, 3, 0}); + flat_set a{5, 7, 9}; + assert_all_requirements_and_equals(a, {9, 7, 5}); + a.emplace_hint(a.end()); + assert_all_requirements_and_equals(a, {9, 7, 5, 0}); + a.emplace_hint(a.begin() + 1, 8); + assert_all_requirements_and_equals(a, {9, 8, 7, 5, 0}); + a.insert(a.begin() + 3, 6); + assert_all_requirements_and_equals(a, {9, 8, 7, 6, 5, 0}); + a.insert(a.end() - 1, val); + assert_all_requirements_and_equals(a, {9, 8, 7, 6, 5, 1, 0}); + } + { + flat_multiset a{3, 1, 4, 1, 5, 9}; + assert_all_requirements_and_equals(a, {9, 5, 4, 3, 1, 1}); + a.emplace_hint(a.end()); + assert_all_requirements_and_equals(a, {9, 5, 4, 3, 1, 1, 0}); + a.emplace_hint(a.begin() + 2, 4); + assert_all_requirements_and_equals(a, {9, 5, 4, 4, 3, 1, 1, 0}); + a.insert(a.begin() + 1, 6); + assert_all_requirements_and_equals(a, {9, 6, 5, 4, 4, 3, 1, 1, 0}); + a.insert(a.end() - 3, val); + assert_all_requirements_and_equals(a, {9, 6, 5, 4, 4, 3, 1, 1, 1, 0}); } } From ca727a3c5d5ca6c03e5cfadad61d28459d43941c Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Tue, 27 Jan 2026 03:14:03 -0800 Subject: [PATCH 11/25] Extract identical key_comparer to test_container_requirements.hpp. --- .../std/include/test_container_requirements.hpp | 16 ++++++++++++++++ tests/std/tests/P0429R9_flat_map/test.cpp | 16 ---------------- tests/std/tests/P1222R4_flat_set/test.cpp | 16 ---------------- 3 files changed, 16 insertions(+), 32 deletions(-) diff --git a/tests/std/include/test_container_requirements.hpp b/tests/std/include/test_container_requirements.hpp index cebe64d3ab1..664b88e7eaf 100644 --- a/tests/std/include/test_container_requirements.hpp +++ b/tests/std/include/test_container_requirements.hpp @@ -187,3 +187,19 @@ void assert_three_way_comparability() { static_assert(std::three_way_comparable); } } + +struct key_comparer { + const auto& extract_key(const auto& obj) const { + if constexpr (requires { obj.key; }) { + return obj.key; + } else { + return obj; + } + } + + bool operator()(const auto& lhs, const auto& rhs) const { + return extract_key(lhs) < extract_key(rhs); + } + + using is_transparent = int; +}; diff --git a/tests/std/tests/P0429R9_flat_map/test.cpp b/tests/std/tests/P0429R9_flat_map/test.cpp index fbd797b28be..0ded4ac821e 100644 --- a/tests/std/tests/P0429R9_flat_map/test.cpp +++ b/tests/std/tests/P0429R9_flat_map/test.cpp @@ -233,22 +233,6 @@ struct MyAllocatorCounter { size_t activeAllocations; }; -struct key_comparer { - const auto& extract_key(const auto& obj) const { - if constexpr (requires { obj.key; }) { - return obj.key; - } else { - return obj; - } - } - - bool operator()(const auto& lhs, const auto& rhs) const { - return extract_key(lhs) < extract_key(rhs); - } - - using is_transparent = int; -}; - template