Files
llvm/libcxx/test/std/containers/associative/map/map.cons/copy_alloc.pass.cpp
Nikolas Klauser 1cac2be874 [libc++] Optimize copy construction and assignment of __tree (#151304)
```
----------------------------------------------------------------------------------------------------------
Benchmark                                                                              old             new
----------------------------------------------------------------------------------------------------------
std::map<int, int>::ctor(const&)/0                                                 15.5 ns         14.9 ns
std::map<int, int>::ctor(const&)/32                                                 474 ns          321 ns
std::map<int, int>::ctor(const&)/1024                                             24591 ns        11101 ns
std::map<int, int>::ctor(const&)/8192                                            236153 ns        98868 ns
std::map<std::string, int>::ctor(const&)/0                                         15.2 ns         14.9 ns
std::map<std::string, int>::ctor(const&)/32                                        2673 ns         2340 ns
std::map<std::string, int>::ctor(const&)/1024                                    115354 ns        86088 ns
std::map<std::string, int>::ctor(const&)/8192                                   1298510 ns       626876 ns
std::map<int, int>::operator=(const&) (into cleared Container)/0                   16.5 ns         16.1 ns
std::map<int, int>::operator=(const&) (into cleared Container)/32                   548 ns          323 ns
std::map<int, int>::operator=(const&) (into cleared Container)/1024               28418 ns        11026 ns
std::map<int, int>::operator=(const&) (into cleared Container)/8192              281827 ns        97113 ns
std::map<int, int>::operator=(const&) (into populated Container)/0                 2.42 ns         1.85 ns
std::map<int, int>::operator=(const&) (into populated Container)/32                 369 ns         73.0 ns
std::map<int, int>::operator=(const&) (into populated Container)/1024             24078 ns         2322 ns
std::map<int, int>::operator=(const&) (into populated Container)/8192            266537 ns        22963 ns
std::map<std::string, int>::operator=(const&) (into cleared Container)/0           16.6 ns         16.2 ns
std::map<std::string, int>::operator=(const&) (into cleared Container)/32          2614 ns         1622 ns
std::map<std::string, int>::operator=(const&) (into cleared Container)/1024      116826 ns        63281 ns
std::map<std::string, int>::operator=(const&) (into cleared Container)/8192     1316655 ns       649177 ns
std::map<std::string, int>::operator=(const&) (into populated Container)/0         2.42 ns         1.89 ns
std::map<std::string, int>::operator=(const&) (into populated Container)/32        1264 ns          581 ns
std::map<std::string, int>::operator=(const&) (into populated Container)/1024    238826 ns        39943 ns
std::map<std::string, int>::operator=(const&) (into populated Container)/8192   2412327 ns       379456 ns
```

Fixes #77658
Fixes #62571
2025-08-05 09:49:40 +02:00

112 lines
3.6 KiB
C++

//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// <map>
// class map
// map(const map& m, const allocator_type& a);
#include <cassert>
#include <map>
#include "test_macros.h"
#include "../../../test_compare.h"
#include "test_allocator.h"
#include "min_allocator.h"
template <class Alloc>
void test_alloc(const Alloc& new_alloc) {
{ // Simple check
using V = std::pair<const int, int>;
using Map = std::map<int, int, std::less<int>, Alloc>;
V arr[] = {V(1, 1), V(2, 3), V(3, 6)};
const Map orig(begin(arr), end(arr));
Map copy(orig, new_alloc);
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());
assert(copy.get_allocator() == new_alloc);
// 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 Map = std::map<int, int, std::less<int>, Alloc>;
const Map orig;
Map 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>;
using Map = std::map<int, int, std::less<int>, Alloc>;
V arr[] = {V(1, 1), V(2, 3), V(3, 6), V(4, 7), V(5, 0)};
const Map orig(begin(arr), end(arr));
Map 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());
}
}
void test() {
test_alloc(std::allocator<std::pair<const int, int> >());
test_alloc(test_allocator<std::pair<const int, int> >(25)); // Make sure that the new allocator is actually used
test_alloc(min_allocator<std::pair<const int, int> >()); // Make sure that fancy pointers work
{ // Ensure that the comparator is copied
using V = std::pair<const int, int>;
using Map = std::map<int, int, test_less<int> >;
V arr[] = {V(1, 1), V(2, 3), V(3, 6)};
const Map orig(begin(arr), end(arr), test_less<int>(3));
Map copy(orig, std::allocator<V>());
assert(copy.size() == 3);
assert(copy.key_comp() == test_less<int>(3));
// Check that orig is still what is expected
assert(orig.size() == 3);
assert(orig.key_comp() == test_less<int>(3));
}
}
int main(int, char**) {
test();
return 0;
}