diff --git a/tests/std/tests/P0429R9_flat_map/test.cpp b/tests/std/tests/P0429R9_flat_map/test.cpp index ca4a2989ef..fe24005a90 100644 --- a/tests/std/tests/P0429R9_flat_map/test.cpp +++ b/tests/std/tests/P0429R9_flat_map/test.cpp @@ -1417,6 +1417,356 @@ void test_non_strict_weak_order_compare() { } } +void test_operator_subscript() { + { + flat_map fm; + + fm[10] = 'm'; + assert(fm[10] == 'm'); + assert(fm.size() == 1); + + fm[70] = 'e'; + assert(fm[70] == 'e'); + assert(fm.size() == 2); + + fm[10] = 'z'; + assert(fm[10] == 'z'); + assert(fm.size() == 2); + + int key = 30; + fm[move(key)] = 'r'; + assert(fm[30] == 'r'); + assert(fm.size() == 3); + + [[maybe_unused]] char& ref = fm[99]; + assert(fm[99] == '\0'); + assert(fm.size() == 4); + + assert(check_key_content(fm, {10, 30, 70, 99})); + assert(check_value_content(fm, {'z', 'r', 'e', '\0'})); + } + + { + flat_map fm; + fm[1] = "hello"; + assert(fm[1] == "hello"); + assert(fm[2].empty()); + assert(fm.size() == 2); + + assert(check_key_content(fm, {1, 2})); + assert(check_value_content(fm, {string{"hello"}, string{}})); + } + + { + flat_map, char, TransparentPackagedCompare> fm; + fm[5] = 'a'; + assert(fm.size() == 1); + + fm[5] = 'b'; + assert(fm.size() == 1); + assert(fm.begin()->second == 'b'); + + fm[10] = 'c'; + assert(fm.size() == 2); + assert(fm.find(10)->second == 'c'); + + assert(check_key_content(fm, {Packaged(5), Packaged(10)})); + assert(check_value_content(fm, {'b', 'c'})); + } +} + +void test_at() { + { + flat_map fm{{10, 'm'}, {20, 'o'}, {70, 'e'}, {90, 'w'}}; + + assert(fm.at(10) == 'm'); + assert(fm.at(20) == 'o'); + assert(fm.at(70) == 'e'); + assert(fm.at(90) == 'w'); + + fm.at(10) = 'x'; + assert(fm.at(10) == 'x'); + assert(fm.size() == 4); + } + + { + const flat_map fm{{10, 'm'}, {20, 'o'}, {70, 'e'}, {90, 'w'}}; + + assert(fm.at(10) == 'm'); + assert(fm.at(20) == 'o'); + assert(fm.at(70) == 'e'); + assert(fm.at(90) == 'w'); + } + + { + flat_map fm{{10, 'm'}, {20, 'o'}}; + bool caught = false; + try { + (void) fm.at(42); + } catch (const out_of_range&) { + caught = true; + } + assert(caught); + } + + { + const flat_map fm{{10, 'm'}, {20, 'o'}}; + bool caught = false; + try { + (void) fm.at(42); + } catch (const out_of_range&) { + caught = true; + } + assert(caught); + } + + { + flat_map fm; + bool caught = false; + try { + (void) fm.at(0); + } catch (const out_of_range&) { + caught = true; + } + assert(caught); + } + + { + flat_map, char, TransparentPackagedCompare> fm; + fm.emplace(Packaged(5), 'a'); + fm.emplace(Packaged(10), 'b'); + + assert(fm.at(5) == 'a'); + assert(fm.at(10) == 'b'); + fm.at(5) = 'z'; + assert(fm.at(5) == 'z'); + + const auto& cfm = fm; + assert(cfm.at(5) == 'z'); + assert(cfm.at(10) == 'b'); + + bool caught = false; + try { + (void) fm.at(99); + } catch (const out_of_range&) { + caught = true; + } + assert(caught); + + bool caught_const = false; + try { + (void) cfm.at(99); + } catch (const out_of_range&) { + caught_const = true; + } + assert(caught_const); + } +} + +void test_emplace() { + { + flat_map fm; + + const auto [it1, inserted1] = fm.emplace(10, 'm'); + assert(it1->first == 10); + assert(it1->second == 'm'); + assert(inserted1); + + const auto [it2, inserted2] = fm.emplace(70, 'e'); + assert(it2->first == 70); + assert(it2->second == 'e'); + assert(inserted2); + + const auto [it3, inserted3] = fm.emplace(20, 'o'); + assert(it3->first == 20); + assert(it3->second == 'o'); + assert(inserted3); + + const auto [it4, inserted4] = fm.emplace(10, 'X'); + assert(it4->first == 10); + assert(it4->second == 'm'); + assert(!inserted4); + + assert(check_key_content(fm, {10, 20, 70})); + assert(check_value_content(fm, {'m', 'o', 'e'})); + } + + { + flat_map fm; + + const auto [it1, inserted1] = fm.emplace(pair{5, 'a'}); + assert(it1->first == 5); + assert(it1->second == 'a'); + assert(inserted1); + + const auto [it2, inserted2] = fm.emplace(pair{5, 'b'}); + assert(it2->first == 5); + assert(it2->second == 'a'); + assert(!inserted2); + } + + { + flat_map fm{{1, 'a'}, {5, 'e'}, {10, 'j'}}; + + const auto it1 = fm.emplace_hint(fm.end(), 20, 't'); + assert(it1->first == 20); + assert(it1->second == 't'); + + const auto it2 = fm.emplace_hint(fm.begin(), 0, 'z'); + assert(it2->first == 0); + assert(it2->second == 'z'); + + const auto it3 = fm.emplace_hint(fm.find(5), 5, 'X'); + assert(it3->first == 5); + assert(it3->second == 'e'); + + assert(check_key_content(fm, {0, 1, 5, 10, 20})); + assert(check_value_content(fm, {'z', 'a', 'e', 'j', 't'})); + } +} + +void test_try_emplace() { + { + flat_map fm; + + const auto [it1, ins1] = fm.try_emplace(10, "hello"); + assert(it1->first == 10); + assert(it1->second == "hello"); + assert(ins1); + + const auto [it2, ins2] = fm.try_emplace(20, size_t{3}, 'x'); + assert(it2->first == 20); + assert(it2->second == "xxx"); + assert(ins2); + + const auto [it3, ins3] = fm.try_emplace(10, "world"); + assert(it3->first == 10); + assert(it3->second == "hello"); + assert(!ins3); + + assert(fm.size() == 2); + } + + { + flat_map fm; + + int key1 = 10; + const auto [it1, ins1] = fm.try_emplace(move(key1), 'm'); + assert(it1->first == 10); + assert(it1->second == 'm'); + assert(ins1); + + int key2 = 10; + const auto [it2, ins2] = fm.try_emplace(move(key2), 'X'); + assert(it2->first == 10); + assert(it2->second == 'm'); + assert(!ins2); + } + + { + flat_map fm{{1, 'a'}, {5, 'e'}, {10, 'j'}}; + + const auto it1 = fm.try_emplace(fm.end(), 20, 't'); + assert(it1->first == 20); + assert(it1->second == 't'); + + const auto it2 = fm.try_emplace(fm.begin(), 0, 'z'); + assert(it2->first == 0); + assert(it2->second == 'z'); + + const auto it3 = fm.try_emplace(fm.find(5), 5, 'X'); + assert(it3->first == 5); + assert(it3->second == 'e'); + + assert(check_key_content(fm, {0, 1, 5, 10, 20})); + assert(check_value_content(fm, {'z', 'a', 'e', 'j', 't'})); + } + + { + flat_map fm{{1, 'a'}, {5, 'e'}, {10, 'j'}}; + + const auto it1 = fm.try_emplace(fm.begin(), 20, 't'); + assert(it1->first == 20); + assert(it1->second == 't'); + + assert(check_key_content(fm, {1, 5, 10, 20})); + assert(check_value_content(fm, {'a', 'e', 'j', 't'})); + } + + { + flat_map, char, TransparentPackagedCompare> fm; + + const auto [it1, ins1] = fm.try_emplace(5, 'a'); + assert(ins1); + assert(it1->first == Packaged(5)); + assert(it1->second == 'a'); + + const auto [it2, ins2] = fm.try_emplace(10, 'b'); + assert(ins2); + + const auto [it3, ins3] = fm.try_emplace(5, 'X'); + assert(!ins3); + assert(it3->second == 'a'); + + assert(fm.size() == 2); + } + + { + flat_map, char, TransparentPackagedCompare> fm; + fm.try_emplace(5, 'a'); + fm.try_emplace(10, 'b'); + + const auto it = fm.try_emplace(fm.end(), 20, 'c'); + assert(it->first == Packaged(20)); + assert(it->second == 'c'); + assert(fm.size() == 3); + } +} + +void test_replace() { + { + flat_map fm{{1, 'a'}, {2, 'b'}, {3, 'c'}}; + + vector new_keys = {10, 20, 30, 40}; + vector new_vals = {'w', 'x', 'y', 'z'}; + fm.replace(move(new_keys), move(new_vals)); + + assert(check_key_content(fm, {10, 20, 30, 40})); + assert(check_value_content(fm, {'w', 'x', 'y', 'z'})); + } + + { + flat_map fm{{1, 'a'}, {2, 'b'}}; + + fm.replace(vector{}, vector{}); + + assert(fm.empty()); + } + + { + flat_map fm; + + vector new_keys = {42}; + vector new_vals = {'x'}; + fm.replace(move(new_keys), move(new_vals)); + + assert(fm.size() == 1); + assert(fm.begin()->first == 42); + assert(fm.begin()->second == 'x'); + } + + { + flat_map fm{{1, 'a'}, {2, 'b'}, {3, 'c'}}; + + auto extracted = move(fm).extract(); + assert(fm.empty()); + + fm.replace(move(extracted.keys), move(extracted.values)); + assert(check_key_content(fm, {1, 2, 3})); + assert(check_value_content(fm, {'a', 'b', 'c'})); + } +} + void run_normal_tests() { test_key_mapped_cont_combinations(); test_key_mapped_cont_combinations(); @@ -1434,6 +1784,12 @@ void run_normal_tests() { test_lookup_call_on_temporaries(); test_non_strict_weak_order_compare(); + + test_operator_subscript(); + test_at(); + test_emplace(); + test_try_emplace(); + test_replace(); } enum class cont_type { multi, unique };