From 58d9eeea636fe5358e06d6c3b06f12e96a4e16f5 Mon Sep 17 00:00:00 2001 From: Hui Date: Sat, 26 Oct 2024 21:20:11 +0100 Subject: [PATCH] [libc++][test] add test coverage for `flat_map::emplace_hint` --- .../flat.map.modifiers/emplace.pass.cpp | 88 ++++++++++++--- .../flat.map.modifiers/emplace_hint.pass.cpp | 106 ++++++++++++++++-- 2 files changed, 169 insertions(+), 25 deletions(-) diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/emplace.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/emplace.pass.cpp index 06631ac689f75..a54fcad639280 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/emplace.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/emplace.pass.cpp @@ -39,19 +39,81 @@ static_assert(!CanEmplace); static_assert(!CanEmplace); template -void test_simple() { +void test() { using Key = typename KeyContainer::value_type; using Value = typename ValueContainer::value_type; using M = std::flat_map, KeyContainer, ValueContainer>; using R = std::pair; - M m; - ASSERT_SAME_TYPE(decltype(m.emplace()), R); - R r = m.emplace(typename M::value_type(2, 3.5)); - assert(r.second); - assert(r.first == m.begin()); - assert(m.size() == 1); - assert(m.begin()->first == 2); - assert(m.begin()->second == 3.5); + { + // was empty + M m; + std::same_as decltype(auto) r = m.emplace(typename M::value_type(2, 3.5)); + assert(r.second); + assert(r.first == m.begin()); + assert(m.size() == 1); + assert(r.first->first == 2); + assert(r.first->second == 3.5); + } + { + // key does not exist and inserted at the begin + M m = {{3, 4.0}, {5, 3.0}, {6, 1.0}, {7, 0.0}}; + std::same_as decltype(auto) r = m.emplace(typename M::value_type(2, 2.0)); + assert(r.second); + assert(r.first == m.begin()); + assert(m.size() == 5); + assert(r.first->first == 2); + assert(r.first->second == 2.0); + } + { + // key does not exist and inserted in the middle + M m = {{0, 4.0}, {1, 3.0}, {3, 1.0}, {4, 0.0}}; + std::same_as decltype(auto) r = m.emplace(typename M::value_type(2, 2.0)); + assert(r.second); + assert(r.first == m.begin() + 2); + assert(m.size() == 5); + assert(r.first->first == 2); + assert(r.first->second == 2.0); + } + { + // key does not exist and inserted at the end + M m = {{0, 4.0}, {1, 3.0}}; + std::same_as decltype(auto) r = m.emplace(typename M::value_type(2, 2.0)); + assert(r.second); + assert(r.first == m.begin() + 2); + assert(m.size() == 3); + assert(r.first->first == 2); + assert(r.first->second == 2.0); + } + { + // key already exists and original at the begin + M m = {{2, 4.0}, {3, 3.0}, {5, 1.0}, {6, 0.0}}; + std::same_as decltype(auto) r = m.emplace(typename M::value_type(2, 2.0)); + assert(!r.second); + assert(r.first == m.begin()); + assert(m.size() == 4); + assert(r.first->first == 2); + assert(r.first->second == 4.0); + } + { + // key already exists and original in the middle + M m = {{0, 4.0}, {2, 3.0}, {3, 1.0}, {4, 0.0}}; + std::same_as decltype(auto) r = m.emplace(typename M::value_type(2, 2.0)); + assert(!r.second); + assert(r.first == m.begin() + 1); + assert(m.size() == 4); + assert(r.first->first == 2); + assert(r.first->second == 3.0); + } + { + // key already exists and original at the end + M m = {{0, 4.0}, {1, 3.0}, {2, 1.0}}; + std::same_as decltype(auto) r = m.emplace(typename M::value_type(2, 2.0)); + assert(!r.second); + assert(r.first == m.begin() + 2); + assert(m.size() == 3); + assert(r.first->first == 2); + assert(r.first->second == 1.0); + } } template @@ -82,10 +144,10 @@ void test_emplaceable() { } int main(int, char**) { - test_simple, std::vector>(); - test_simple, std::vector>(); - test_simple, MinSequenceContainer>(); - test_simple>, std::vector>>(); + test, std::vector>(); + test, std::vector>(); + test, MinSequenceContainer>(); + test>, std::vector>>(); test_emplaceable, std::vector>(); test_emplaceable, std::vector>(); diff --git a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/emplace_hint.pass.cpp b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/emplace_hint.pass.cpp index cfee6cac5806c..77c022a6de92b 100644 --- a/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/emplace_hint.pass.cpp +++ b/libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/emplace_hint.pass.cpp @@ -42,18 +42,100 @@ static_assert(!CanEmplaceHint); #endif template -void test_simple() { +void test() { using Key = typename KeyContainer::value_type; using Value = typename ValueContainer::value_type; using M = std::flat_map, KeyContainer, ValueContainer>; using R = M::iterator; - M m; - ASSERT_SAME_TYPE(decltype(m.emplace_hint(m.cbegin())), R); - R r = m.emplace_hint(m.end(), typename M::value_type(2, 3.5)); - assert(r == m.begin()); - assert(m.size() == 1); - assert(m.begin()->first == 2); - assert(m.begin()->second == 3.5); + { + // was empty + M m; + std::same_as decltype(auto) r = m.emplace_hint(m.end(), typename M::value_type(2, 3.5)); + assert(r == m.begin()); + assert(m.size() == 1); + assert(r->first == 2); + assert(r->second == 3.5); + } + { + // hints correct at the begin + M m = {{3, 3.0}, {4, 4.0}}; + auto hint = m.begin(); + std::same_as decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2, 2.0)); + assert(r == m.begin()); + assert(m.size() == 3); + assert(r->first == 2); + assert(r->second == 2.0); + } + { + // hints correct in the middle + M m = {{0, 0.0}, {1, 1.0}, {3, 3.0}, {4, 4.0}}; + auto hint = m.begin() + 2; + std::same_as decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2, 2.0)); + assert(r == m.begin() + 2); + assert(m.size() == 5); + assert(r->first == 2); + assert(r->second == 2.0); + } + { + // hints correct at the end + M m = {{0, 0.0}, {1, 1.0}}; + auto hint = m.end(); + std::same_as decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2, 2.0)); + assert(r == m.begin() + 2); + assert(m.size() == 3); + assert(r->first == 2); + assert(r->second == 2.0); + } + { + // hints correct but key already exists + M m = {{0, 0.0}, {1, 1.0}, {2, 1.9}, {3, 3.0}, {4, 4.0}}; + auto hint = m.begin() + 2; + std::same_as decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2, 2.0)); + assert(r == m.begin() + 2); + assert(m.size() == 5); + assert(r->first == 2); + assert(r->second == 1.9); + } + { + // hints incorrectly at the begin + M m = {{1, 1.0}, {4, 4.0}}; + auto hint = m.begin(); + std::same_as decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2, 2.0)); + assert(r == m.begin() + 1); + assert(m.size() == 3); + assert(r->first == 2); + assert(r->second == 2.0); + } + { + // hints incorrectly in the middle + M m = {{0, 0.0}, {1, 1.0}, {3, 3.0}, {4, 4.0}}; + auto hint = m.begin() + 1; + std::same_as decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2, 2.0)); + assert(r == m.begin() + 2); + assert(m.size() == 5); + assert(r->first == 2); + assert(r->second == 2.0); + } + { + // hints incorrectly at the end + M m = {{0, 0.0}, {3, 3.0}}; + auto hint = m.end(); + std::same_as decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2, 2.0)); + assert(r == m.begin() + 1); + assert(m.size() == 3); + assert(r->first == 2); + assert(r->second == 2.0); + } + { + // hints incorrect and key already exists + M m = {{0, 0.0}, {1, 1.0}, {2, 1.9}, {3, 3.0}, {4, 4.0}}; + auto hint = m.begin(); + std::same_as decltype(auto) r = m.emplace_hint(hint, typename M::value_type(2, 2.0)); + assert(r == m.begin() + 2); + assert(m.size() == 5); + assert(r->first == 2); + assert(r->second == 1.9); + } } template @@ -81,10 +163,10 @@ void test_emplaceable() { } int main(int, char**) { - test_simple, std::vector>(); - test_simple, std::vector>(); - test_simple, MinSequenceContainer>(); - test_simple>, std::vector>>(); + test, std::vector>(); + test, std::vector>(); + test, MinSequenceContainer>(); + test>, std::vector>>(); test_emplaceable, std::vector>(); test_emplaceable, std::vector>();