|
9 | 9 | #include "llvm/ADT/MapVector.h"
|
10 | 10 | #include "llvm/ADT/iterator_range.h"
|
11 | 11 | #include "gtest/gtest.h"
|
| 12 | +#include <memory> |
12 | 13 | #include <utility>
|
13 | 14 |
|
14 | 15 | using namespace llvm;
|
15 | 16 |
|
| 17 | +namespace { |
| 18 | +struct CountCopyAndMove { |
| 19 | + CountCopyAndMove() = default; |
| 20 | + CountCopyAndMove(const CountCopyAndMove &) { copy = 1; } |
| 21 | + CountCopyAndMove(CountCopyAndMove &&) { move = 1; } |
| 22 | + void operator=(const CountCopyAndMove &) { ++copy; } |
| 23 | + void operator=(CountCopyAndMove &&) { ++move; } |
| 24 | + int copy = 0; |
| 25 | + int move = 0; |
| 26 | +}; |
| 27 | + |
| 28 | +struct A : CountCopyAndMove { |
| 29 | + A(int v) : v(v) {} |
| 30 | + int v; |
| 31 | +}; |
| 32 | +} // namespace |
| 33 | + |
| 34 | +namespace llvm { |
| 35 | +template <> struct DenseMapInfo<A> { |
| 36 | + static inline A getEmptyKey() { return 0x7fffffff; } |
| 37 | + static inline A getTombstoneKey() { return -0x7fffffff - 1; } |
| 38 | + static unsigned getHashValue(const A &Val) { return (unsigned)(Val.v * 37U); } |
| 39 | + static bool isEqual(const A &LHS, const A &RHS) { return LHS.v == RHS.v; } |
| 40 | +}; |
| 41 | +} // namespace llvm |
| 42 | + |
| 43 | +namespace { |
16 | 44 | TEST(MapVectorTest, swap) {
|
17 | 45 | MapVector<int, int> MV1, MV2;
|
18 | 46 | std::pair<MapVector<int, int>::iterator, bool> R;
|
@@ -79,6 +107,87 @@ TEST(MapVectorTest, insert_pop) {
|
79 | 107 | EXPECT_EQ(MV[4], 7);
|
80 | 108 | }
|
81 | 109 |
|
| 110 | +TEST(MapVectorTest, try_emplace) { |
| 111 | + struct AAndU { |
| 112 | + A a; |
| 113 | + std::unique_ptr<int> b; |
| 114 | + AAndU(A a, std::unique_ptr<int> b) : a(a), b(std::move(b)) {} |
| 115 | + }; |
| 116 | + MapVector<A, AAndU> mv; |
| 117 | + |
| 118 | + A zero(0); |
| 119 | + auto try0 = mv.try_emplace(zero, zero, nullptr); |
| 120 | + EXPECT_TRUE(try0.second); |
| 121 | + EXPECT_EQ(0, try0.first->second.a.v); |
| 122 | + EXPECT_EQ(1, try0.first->second.a.copy); |
| 123 | + EXPECT_EQ(0, try0.first->second.a.move); |
| 124 | + |
| 125 | + auto try1 = mv.try_emplace(zero, zero, nullptr); |
| 126 | + EXPECT_FALSE(try1.second); |
| 127 | + EXPECT_EQ(0, try1.first->second.a.v); |
| 128 | + EXPECT_EQ(1, try1.first->second.a.copy); |
| 129 | + EXPECT_EQ(0, try1.first->second.a.move); |
| 130 | + |
| 131 | + EXPECT_EQ(try0.first, try1.first); |
| 132 | + EXPECT_EQ(1, try1.first->first.copy); |
| 133 | + EXPECT_EQ(0, try1.first->first.move); |
| 134 | + |
| 135 | + A two(2); |
| 136 | + auto try2 = mv.try_emplace(2, std::move(two), std::make_unique<int>(2)); |
| 137 | + EXPECT_TRUE(try2.second); |
| 138 | + EXPECT_EQ(2, try2.first->second.a.v); |
| 139 | + EXPECT_EQ(0, try2.first->second.a.move); |
| 140 | + |
| 141 | + std::unique_ptr<int> p(new int(3)); |
| 142 | + auto try3 = mv.try_emplace(std::move(two), 3, std::move(p)); |
| 143 | + EXPECT_FALSE(try3.second); |
| 144 | + EXPECT_EQ(2, try3.first->second.a.v); |
| 145 | + EXPECT_EQ(1, try3.first->second.a.copy); |
| 146 | + EXPECT_EQ(0, try3.first->second.a.move); |
| 147 | + |
| 148 | + EXPECT_EQ(try2.first, try3.first); |
| 149 | + EXPECT_EQ(0, try3.first->first.copy); |
| 150 | + EXPECT_EQ(1, try3.first->first.move); |
| 151 | + EXPECT_NE(nullptr, p); |
| 152 | +} |
| 153 | + |
| 154 | +TEST(MapVectorTest, insert_or_assign) { |
| 155 | + MapVector<A, A> mv; |
| 156 | + |
| 157 | + A zero(0); |
| 158 | + auto try0 = mv.insert_or_assign(zero, zero); |
| 159 | + EXPECT_TRUE(try0.second); |
| 160 | + EXPECT_EQ(0, try0.first->second.v); |
| 161 | + EXPECT_EQ(1, try0.first->second.copy); |
| 162 | + EXPECT_EQ(0, try0.first->second.move); |
| 163 | + |
| 164 | + auto try1 = mv.insert_or_assign(zero, zero); |
| 165 | + EXPECT_FALSE(try1.second); |
| 166 | + EXPECT_EQ(0, try1.first->second.v); |
| 167 | + EXPECT_EQ(2, try1.first->second.copy); |
| 168 | + EXPECT_EQ(0, try1.first->second.move); |
| 169 | + |
| 170 | + EXPECT_EQ(try0.first, try1.first); |
| 171 | + EXPECT_EQ(1, try1.first->first.copy); |
| 172 | + EXPECT_EQ(0, try1.first->first.move); |
| 173 | + |
| 174 | + A two(2); |
| 175 | + auto try2 = mv.try_emplace(2, std::move(two)); |
| 176 | + EXPECT_TRUE(try2.second); |
| 177 | + EXPECT_EQ(2, try2.first->second.v); |
| 178 | + EXPECT_EQ(1, try2.first->second.move); |
| 179 | + |
| 180 | + auto try3 = mv.insert_or_assign(std::move(two), 3); |
| 181 | + EXPECT_FALSE(try3.second); |
| 182 | + EXPECT_EQ(3, try3.first->second.v); |
| 183 | + EXPECT_EQ(0, try3.first->second.copy); |
| 184 | + EXPECT_EQ(2, try3.first->second.move); |
| 185 | + |
| 186 | + EXPECT_EQ(try2.first, try3.first); |
| 187 | + EXPECT_EQ(0, try3.first->first.copy); |
| 188 | + EXPECT_EQ(1, try3.first->first.move); |
| 189 | +} |
| 190 | + |
82 | 191 | TEST(MapVectorTest, erase) {
|
83 | 192 | MapVector<int, int> MV;
|
84 | 193 |
|
@@ -423,3 +532,4 @@ TEST(SmallMapVectorLargeTest, iteration_test) {
|
423 | 532 | count--;
|
424 | 533 | }
|
425 | 534 | }
|
| 535 | +} // namespace |
0 commit comments