[libcxx-commits] [libcxx] [libc++][test] add test coverage for `flat_map::emplace_hint` (PR #113773)

via libcxx-commits libcxx-commits at lists.llvm.org
Sat Oct 26 13:21:18 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: Hui (huixie90)

<details>
<summary>Changes</summary>



---
Full diff: https://github.com/llvm/llvm-project/pull/113773.diff


2 Files Affected:

- (modified) libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/emplace.pass.cpp (+75-13) 
- (modified) libcxx/test/std/containers/container.adaptors/flat.map/flat.map.modifiers/emplace_hint.pass.cpp (+94-12) 


``````````diff
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 06631ac689f75d..a54fcad639280b 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<Map, Emplaceable>);
 static_assert(!CanEmplace<Map, int, double>);
 
 template <class KeyContainer, class ValueContainer>
-void test_simple() {
+void test() {
   using Key   = typename KeyContainer::value_type;
   using Value = typename ValueContainer::value_type;
   using M     = std::flat_map<Key, Value, std::less<Key>, KeyContainer, ValueContainer>;
   using R     = std::pair<typename M::iterator, bool>;
-  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<R> 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<R> 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<R> 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<R> 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<R> 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<R> 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<R> 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 <class KeyContainer, class ValueContainer>
@@ -82,10 +144,10 @@ void test_emplaceable() {
 }
 
 int main(int, char**) {
-  test_simple<std::vector<int>, std::vector<double>>();
-  test_simple<std::deque<int>, std::vector<double>>();
-  test_simple<MinSequenceContainer<int>, MinSequenceContainer<double>>();
-  test_simple<std::vector<int, min_allocator<int>>, std::vector<double, min_allocator<double>>>();
+  test<std::vector<int>, std::vector<double>>();
+  test<std::deque<int>, std::vector<double>>();
+  test<MinSequenceContainer<int>, MinSequenceContainer<double>>();
+  test<std::vector<int, min_allocator<int>>, std::vector<double, min_allocator<double>>>();
 
   test_emplaceable<std::vector<int>, std::vector<Emplaceable>>();
   test_emplaceable<std::deque<int>, std::vector<Emplaceable>>();
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 cfee6cac5806cc..77c022a6de92bc 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<Map, int, double>);
 #endif
 
 template <class KeyContainer, class ValueContainer>
-void test_simple() {
+void test() {
   using Key   = typename KeyContainer::value_type;
   using Value = typename ValueContainer::value_type;
   using M     = std::flat_map<Key, Value, std::less<Key>, 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<R> 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<R> 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<R> 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<R> 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<R> 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<R> 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<R> 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<R> 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<R> 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 <class KeyContainer, class ValueContainer>
@@ -81,10 +163,10 @@ void test_emplaceable() {
 }
 
 int main(int, char**) {
-  test_simple<std::vector<int>, std::vector<double>>();
-  test_simple<std::deque<int>, std::vector<double>>();
-  test_simple<MinSequenceContainer<int>, MinSequenceContainer<double>>();
-  test_simple<std::vector<int, min_allocator<int>>, std::vector<double, min_allocator<double>>>();
+  test<std::vector<int>, std::vector<double>>();
+  test<std::deque<int>, std::vector<double>>();
+  test<MinSequenceContainer<int>, MinSequenceContainer<double>>();
+  test<std::vector<int, min_allocator<int>>, std::vector<double, min_allocator<double>>>();
 
   test_emplaceable<std::vector<int>, std::vector<Emplaceable>>();
   test_emplaceable<std::deque<int>, std::vector<Emplaceable>>();

``````````

</details>


https://github.com/llvm/llvm-project/pull/113773


More information about the libcxx-commits mailing list