[libcxx-commits] [libcxx] [libc++] Optimize copy construction and assignment of __tree (PR #151304)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Thu Jul 31 06:38:43 PDT 2025


================
@@ -12,116 +12,119 @@
 
 // map(const map& m);
 
-#include <map>
 #include <cassert>
+#include <map>
 
-#include "test_macros.h"
+#include "min_allocator.h"
 #include "../../../test_compare.h"
 #include "test_allocator.h"
-#include "min_allocator.h"
 
-int main(int, char**) {
-  {
-    typedef std::pair<const int, double> V;
-    V ar[] = {
-        V(1, 1),
-        V(1, 1.5),
-        V(1, 2),
-        V(2, 1),
-        V(2, 1.5),
-        V(2, 2),
-        V(3, 1),
-        V(3, 1.5),
-        V(3, 2),
-    };
-    typedef test_less<int> C;
-    typedef test_allocator<V> A;
-    std::map<int, double, C, A> mo(ar, ar + sizeof(ar) / sizeof(ar[0]), C(5), A(7));
-    std::map<int, double, C, A> m = mo;
-    assert(m.get_allocator() == A(7));
-    assert(m.key_comp() == C(5));
-    assert(m.size() == 3);
-    assert(std::distance(m.begin(), m.end()) == 3);
-    assert(*m.begin() == V(1, 1));
-    assert(*std::next(m.begin()) == V(2, 1));
-    assert(*std::next(m.begin(), 2) == V(3, 1));
-
-    assert(mo.get_allocator() == A(7));
-    assert(mo.key_comp() == C(5));
-    assert(mo.size() == 3);
-    assert(std::distance(mo.begin(), mo.end()) == 3);
-    assert(*mo.begin() == V(1, 1));
-    assert(*std::next(mo.begin()) == V(2, 1));
-    assert(*std::next(mo.begin(), 2) == V(3, 1));
+template <template <class> class Alloc>
+void test_alloc() {
+  { // Simple check
+    using V = std::pair<const int, int>;
+    V arr[] = {V(1, 1), V(2, 3), V(3, 6)};
+    std::map<int, int, std::less<int>, Alloc<V>> orig(begin(arr), end(arr));
+    std::map<int, int, std::less<int>, Alloc<V>> copy = orig;
+    assert(copy.size() == 3);
+    assert(*std::next(copy.begin(), 0) == V(1, 1));
+    assert(*std::next(copy.begin(), 1) == V(2, 3));
+    assert(*std::next(copy.begin(), 2) == V(3, 6));
+    assert(std::next(copy.begin(), 3) == copy.end());
+
+    // Check that orig is still what is expected
+    assert(orig.size() == 3);
+    assert(*std::next(orig.begin(), 0) == V(1, 1));
+    assert(*std::next(orig.begin(), 1) == V(2, 3));
+    assert(*std::next(orig.begin(), 2) == V(3, 6));
+    assert(std::next(orig.begin(), 3) == orig.end());
+  }
+
+  { // copy empty map
+    using V = std::pair<const int, int>;
+    std::map<int, int, std::less<int>, Alloc<V>> orig;
+    std::map<int, int, std::less<int>, Alloc<V>> copy = orig;
+    assert(copy.size() == 0);
+    assert(copy.begin() == copy.end());
+
+    // Check that orig is still what is expected
+    assert(orig.size() == 0);
+    assert(orig.begin() == orig.end());
+  }
+
+  { // only some leaf nodes exist
+    using V = std::pair<const int, int>;
+    V arr[] = {V(1, 1), V(2, 3), V(3, 6), V(4, 7), V(5, 0)};
+    std::map<int, int, std::less<int>, Alloc<V>> orig(begin(arr), end(arr));
+    std::map<int, int, std::less<int>, Alloc<V>> copy = orig;
+    assert(copy.size() == 5);
+    assert(*std::next(copy.begin(), 0) == V(1, 1));
+    assert(*std::next(copy.begin(), 1) == V(2, 3));
+    assert(*std::next(copy.begin(), 2) == V(3, 6));
+    assert(*std::next(copy.begin(), 3) == V(4, 7));
+    assert(*std::next(copy.begin(), 4) == V(5, 0));
+    assert(std::next(copy.begin(), 5) == copy.end());
+
+    // Check that orig is still what is expected
+    assert(orig.size() == 5);
+    assert(*std::next(orig.begin(), 0) == V(1, 1));
+    assert(*std::next(orig.begin(), 1) == V(2, 3));
+    assert(*std::next(orig.begin(), 2) == V(3, 6));
+    assert(*std::next(orig.begin(), 3) == V(4, 7));
+    assert(*std::next(orig.begin(), 4) == V(5, 0));
+    assert(std::next(orig.begin(), 5) == orig.end());
----------------
ldionne wrote:

Can we add another case with a larger (more realistic) number of elements? It can be something simple like numbers from 1 to 50.

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


More information about the libcxx-commits mailing list