1 //===- llvm/unittest/ADT/TinyPtrVectorTest.cpp ----------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // TinyPtrVector unit tests. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/ADT/TinyPtrVector.h" 15 #include "llvm/ADT/ArrayRef.h" 16 #include "llvm/ADT/STLExtras.h" 17 #include "llvm/Support/type_traits.h" 18 #include "gtest/gtest.h" 19 #include <algorithm> 20 #include <random> 21 #include <vector> 22 23 using namespace llvm; 24 25 namespace { 26 27 template <typename VectorT> 28 class TinyPtrVectorTest : public testing::Test { 29 protected: 30 typedef typename VectorT::value_type PtrT; 31 typedef typename std::remove_pointer<PtrT>::type ValueT; 32 33 VectorT V; 34 VectorT V2; 35 36 ValueT TestValues[1024]; 37 std::vector<PtrT> TestPtrs; 38 39 TinyPtrVectorTest() { 40 for (size_t i = 0, e = array_lengthof(TestValues); i != e; ++i) 41 TestPtrs.push_back(&TestValues[i]); 42 43 std::shuffle(TestPtrs.begin(), TestPtrs.end(), std::mt19937{}); 44 } 45 46 ArrayRef<PtrT> testArray(size_t N) { 47 return makeArrayRef(&TestPtrs[0], N); 48 } 49 50 void appendValues(VectorT &V, ArrayRef<PtrT> Values) { 51 for (size_t i = 0, e = Values.size(); i != e; ++i) 52 V.push_back(Values[i]); 53 } 54 55 void setVectors(ArrayRef<PtrT> Values1, ArrayRef<PtrT> Values2) { 56 V.clear(); 57 appendValues(V, Values1); 58 V2.clear(); 59 appendValues(V2, Values2); 60 } 61 62 void expectValues(const VectorT &V, ArrayRef<PtrT> Values) { 63 EXPECT_EQ(Values.empty(), V.empty()); 64 EXPECT_EQ(Values.size(), V.size()); 65 for (size_t i = 0, e = Values.size(); i != e; ++i) { 66 EXPECT_EQ(Values[i], V[i]); 67 EXPECT_EQ(Values[i], *std::next(V.begin(), i)); 68 } 69 EXPECT_EQ(V.end(), std::next(V.begin(), Values.size())); 70 } 71 }; 72 73 typedef ::testing::Types<TinyPtrVector<int*>, 74 TinyPtrVector<double*> 75 > TinyPtrVectorTestTypes; 76 TYPED_TEST_CASE(TinyPtrVectorTest, TinyPtrVectorTestTypes); 77 78 TYPED_TEST(TinyPtrVectorTest, EmptyTest) { 79 this->expectValues(this->V, this->testArray(0)); 80 } 81 82 TYPED_TEST(TinyPtrVectorTest, PushPopBack) { 83 this->V.push_back(this->TestPtrs[0]); 84 this->expectValues(this->V, this->testArray(1)); 85 this->V.push_back(this->TestPtrs[1]); 86 this->expectValues(this->V, this->testArray(2)); 87 this->V.push_back(this->TestPtrs[2]); 88 this->expectValues(this->V, this->testArray(3)); 89 this->V.push_back(this->TestPtrs[3]); 90 this->expectValues(this->V, this->testArray(4)); 91 this->V.push_back(this->TestPtrs[4]); 92 this->expectValues(this->V, this->testArray(5)); 93 94 // Pop and clobber a few values to keep things interesting. 95 this->V.pop_back(); 96 this->expectValues(this->V, this->testArray(4)); 97 this->V.pop_back(); 98 this->expectValues(this->V, this->testArray(3)); 99 this->TestPtrs[3] = &this->TestValues[42]; 100 this->TestPtrs[4] = &this->TestValues[43]; 101 this->V.push_back(this->TestPtrs[3]); 102 this->expectValues(this->V, this->testArray(4)); 103 this->V.push_back(this->TestPtrs[4]); 104 this->expectValues(this->V, this->testArray(5)); 105 106 this->V.pop_back(); 107 this->expectValues(this->V, this->testArray(4)); 108 this->V.pop_back(); 109 this->expectValues(this->V, this->testArray(3)); 110 this->V.pop_back(); 111 this->expectValues(this->V, this->testArray(2)); 112 this->V.pop_back(); 113 this->expectValues(this->V, this->testArray(1)); 114 this->V.pop_back(); 115 this->expectValues(this->V, this->testArray(0)); 116 117 this->appendValues(this->V, this->testArray(42)); 118 this->expectValues(this->V, this->testArray(42)); 119 } 120 121 TYPED_TEST(TinyPtrVectorTest, ClearTest) { 122 this->expectValues(this->V, this->testArray(0)); 123 this->V.clear(); 124 this->expectValues(this->V, this->testArray(0)); 125 126 this->appendValues(this->V, this->testArray(1)); 127 this->expectValues(this->V, this->testArray(1)); 128 this->V.clear(); 129 this->expectValues(this->V, this->testArray(0)); 130 131 this->appendValues(this->V, this->testArray(42)); 132 this->expectValues(this->V, this->testArray(42)); 133 this->V.clear(); 134 this->expectValues(this->V, this->testArray(0)); 135 } 136 137 TYPED_TEST(TinyPtrVectorTest, CopyAndMoveCtorTest) { 138 this->appendValues(this->V, this->testArray(42)); 139 TypeParam Copy(this->V); 140 this->expectValues(Copy, this->testArray(42)); 141 142 // This is a separate copy, and so it shouldn't destroy the original. 143 Copy.clear(); 144 this->expectValues(Copy, this->testArray(0)); 145 this->expectValues(this->V, this->testArray(42)); 146 147 TypeParam Copy2(this->V2); 148 this->appendValues(Copy2, this->testArray(42)); 149 this->expectValues(Copy2, this->testArray(42)); 150 this->expectValues(this->V2, this->testArray(0)); 151 152 TypeParam Move(std::move(Copy2)); 153 this->expectValues(Move, this->testArray(42)); 154 this->expectValues(Copy2, this->testArray(0)); 155 } 156 157 TYPED_TEST(TinyPtrVectorTest, CopyAndMoveTest) { 158 this->V = this->V2; 159 this->expectValues(this->V, this->testArray(0)); 160 this->expectValues(this->V2, this->testArray(0)); 161 this->V = std::move(this->V2); 162 this->expectValues(this->V, this->testArray(0)); 163 164 this->setVectors(this->testArray(1), this->testArray(0)); 165 this->V = this->V2; 166 this->expectValues(this->V, this->testArray(0)); 167 this->expectValues(this->V2, this->testArray(0)); 168 this->setVectors(this->testArray(1), this->testArray(0)); 169 this->V = std::move(this->V2); 170 this->expectValues(this->V, this->testArray(0)); 171 172 this->setVectors(this->testArray(2), this->testArray(0)); 173 this->V = this->V2; 174 this->expectValues(this->V, this->testArray(0)); 175 this->expectValues(this->V2, this->testArray(0)); 176 this->setVectors(this->testArray(2), this->testArray(0)); 177 this->V = std::move(this->V2); 178 this->expectValues(this->V, this->testArray(0)); 179 180 this->setVectors(this->testArray(42), this->testArray(0)); 181 this->V = this->V2; 182 this->expectValues(this->V, this->testArray(0)); 183 this->expectValues(this->V2, this->testArray(0)); 184 this->setVectors(this->testArray(42), this->testArray(0)); 185 this->V = std::move(this->V2); 186 this->expectValues(this->V, this->testArray(0)); 187 188 this->setVectors(this->testArray(0), this->testArray(1)); 189 this->V = this->V2; 190 this->expectValues(this->V, this->testArray(1)); 191 this->expectValues(this->V2, this->testArray(1)); 192 this->setVectors(this->testArray(0), this->testArray(1)); 193 this->V = std::move(this->V2); 194 this->expectValues(this->V, this->testArray(1)); 195 196 this->setVectors(this->testArray(0), this->testArray(2)); 197 this->V = this->V2; 198 this->expectValues(this->V, this->testArray(2)); 199 this->expectValues(this->V2, this->testArray(2)); 200 this->setVectors(this->testArray(0), this->testArray(2)); 201 this->V = std::move(this->V2); 202 this->expectValues(this->V, this->testArray(2)); 203 204 this->setVectors(this->testArray(0), this->testArray(42)); 205 this->V = this->V2; 206 this->expectValues(this->V, this->testArray(42)); 207 this->expectValues(this->V2, this->testArray(42)); 208 this->setVectors(this->testArray(0), this->testArray(42)); 209 this->V = std::move(this->V2); 210 this->expectValues(this->V, this->testArray(42)); 211 212 this->setVectors(this->testArray(1), this->testArray(1)); 213 this->V = this->V2; 214 this->expectValues(this->V, this->testArray(1)); 215 this->expectValues(this->V2, this->testArray(1)); 216 this->V = std::move(this->V2); 217 this->expectValues(this->V, this->testArray(1)); 218 219 this->setVectors(this->testArray(1), this->testArray(2)); 220 this->V = this->V2; 221 this->expectValues(this->V, this->testArray(2)); 222 this->expectValues(this->V2, this->testArray(2)); 223 this->setVectors(this->testArray(1), this->testArray(2)); 224 this->V = std::move(this->V2); 225 this->expectValues(this->V, this->testArray(2)); 226 227 this->setVectors(this->testArray(1), this->testArray(42)); 228 this->V = this->V2; 229 this->expectValues(this->V, this->testArray(42)); 230 this->expectValues(this->V2, this->testArray(42)); 231 this->setVectors(this->testArray(1), this->testArray(42)); 232 this->V = std::move(this->V2); 233 this->expectValues(this->V, this->testArray(42)); 234 235 this->setVectors(this->testArray(2), this->testArray(1)); 236 this->V = this->V2; 237 this->expectValues(this->V, this->testArray(1)); 238 this->expectValues(this->V2, this->testArray(1)); 239 this->setVectors(this->testArray(2), this->testArray(1)); 240 this->V = std::move(this->V2); 241 this->expectValues(this->V, this->testArray(1)); 242 243 this->setVectors(this->testArray(2), this->testArray(2)); 244 this->V = this->V2; 245 this->expectValues(this->V, this->testArray(2)); 246 this->expectValues(this->V2, this->testArray(2)); 247 this->setVectors(this->testArray(2), this->testArray(2)); 248 this->V = std::move(this->V2); 249 this->expectValues(this->V, this->testArray(2)); 250 251 this->setVectors(this->testArray(2), this->testArray(42)); 252 this->V = this->V2; 253 this->expectValues(this->V, this->testArray(42)); 254 this->expectValues(this->V2, this->testArray(42)); 255 this->setVectors(this->testArray(2), this->testArray(42)); 256 this->V = std::move(this->V2); 257 this->expectValues(this->V, this->testArray(42)); 258 259 this->setVectors(this->testArray(42), this->testArray(1)); 260 this->V = this->V2; 261 this->expectValues(this->V, this->testArray(1)); 262 this->expectValues(this->V2, this->testArray(1)); 263 this->setVectors(this->testArray(42), this->testArray(1)); 264 this->V = std::move(this->V2); 265 this->expectValues(this->V, this->testArray(1)); 266 267 this->setVectors(this->testArray(42), this->testArray(2)); 268 this->V = this->V2; 269 this->expectValues(this->V, this->testArray(2)); 270 this->expectValues(this->V2, this->testArray(2)); 271 this->setVectors(this->testArray(42), this->testArray(2)); 272 this->V = std::move(this->V2); 273 this->expectValues(this->V, this->testArray(2)); 274 275 this->setVectors(this->testArray(42), this->testArray(42)); 276 this->V = this->V2; 277 this->expectValues(this->V, this->testArray(42)); 278 this->expectValues(this->V2, this->testArray(42)); 279 this->setVectors(this->testArray(42), this->testArray(42)); 280 this->V = std::move(this->V2); 281 this->expectValues(this->V, this->testArray(42)); 282 } 283 284 TYPED_TEST(TinyPtrVectorTest, EraseTest) { 285 this->appendValues(this->V, this->testArray(1)); 286 this->expectValues(this->V, this->testArray(1)); 287 this->V.erase(this->V.begin()); 288 this->expectValues(this->V, this->testArray(0)); 289 290 this->appendValues(this->V, this->testArray(42)); 291 this->expectValues(this->V, this->testArray(42)); 292 this->V.erase(this->V.begin()); 293 this->TestPtrs.erase(this->TestPtrs.begin()); 294 this->expectValues(this->V, this->testArray(41)); 295 this->V.erase(std::next(this->V.begin(), 1)); 296 this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 1)); 297 this->expectValues(this->V, this->testArray(40)); 298 this->V.erase(std::next(this->V.begin(), 2)); 299 this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 2)); 300 this->expectValues(this->V, this->testArray(39)); 301 this->V.erase(std::next(this->V.begin(), 5)); 302 this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 5)); 303 this->expectValues(this->V, this->testArray(38)); 304 this->V.erase(std::next(this->V.begin(), 13)); 305 this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 13)); 306 this->expectValues(this->V, this->testArray(37)); 307 308 typename TypeParam::iterator I = this->V.begin(); 309 do { 310 I = this->V.erase(I); 311 } while (I != this->V.end()); 312 this->expectValues(this->V, this->testArray(0)); 313 } 314 315 TYPED_TEST(TinyPtrVectorTest, EraseRangeTest) { 316 this->appendValues(this->V, this->testArray(1)); 317 this->expectValues(this->V, this->testArray(1)); 318 this->V.erase(this->V.begin(), this->V.begin()); 319 this->expectValues(this->V, this->testArray(1)); 320 this->V.erase(this->V.end(), this->V.end()); 321 this->expectValues(this->V, this->testArray(1)); 322 this->V.erase(this->V.begin(), this->V.end()); 323 this->expectValues(this->V, this->testArray(0)); 324 325 this->appendValues(this->V, this->testArray(42)); 326 this->expectValues(this->V, this->testArray(42)); 327 this->V.erase(this->V.begin(), std::next(this->V.begin(), 1)); 328 this->TestPtrs.erase(this->TestPtrs.begin(), 329 std::next(this->TestPtrs.begin(), 1)); 330 this->expectValues(this->V, this->testArray(41)); 331 this->V.erase(std::next(this->V.begin(), 1), std::next(this->V.begin(), 2)); 332 this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 1), 333 std::next(this->TestPtrs.begin(), 2)); 334 this->expectValues(this->V, this->testArray(40)); 335 this->V.erase(std::next(this->V.begin(), 2), std::next(this->V.begin(), 4)); 336 this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 2), 337 std::next(this->TestPtrs.begin(), 4)); 338 this->expectValues(this->V, this->testArray(38)); 339 this->V.erase(std::next(this->V.begin(), 5), std::next(this->V.begin(), 10)); 340 this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 5), 341 std::next(this->TestPtrs.begin(), 10)); 342 this->expectValues(this->V, this->testArray(33)); 343 this->V.erase(std::next(this->V.begin(), 13), std::next(this->V.begin(), 26)); 344 this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 13), 345 std::next(this->TestPtrs.begin(), 26)); 346 this->expectValues(this->V, this->testArray(20)); 347 this->V.erase(std::next(this->V.begin(), 7), this->V.end()); 348 this->expectValues(this->V, this->testArray(7)); 349 this->V.erase(this->V.begin(), this->V.end()); 350 this->expectValues(this->V, this->testArray(0)); 351 } 352 353 TYPED_TEST(TinyPtrVectorTest, Insert) { 354 this->V.insert(this->V.end(), this->TestPtrs[0]); 355 this->expectValues(this->V, this->testArray(1)); 356 this->V.clear(); 357 this->appendValues(this->V, this->testArray(4)); 358 this->expectValues(this->V, this->testArray(4)); 359 this->V.insert(this->V.end(), this->TestPtrs[4]); 360 this->expectValues(this->V, this->testArray(5)); 361 this->V.insert(this->V.begin(), this->TestPtrs[42]); 362 this->TestPtrs.insert(this->TestPtrs.begin(), this->TestPtrs[42]); 363 this->expectValues(this->V, this->testArray(6)); 364 this->V.insert(std::next(this->V.begin(), 3), this->TestPtrs[43]); 365 this->TestPtrs.insert(std::next(this->TestPtrs.begin(), 3), 366 this->TestPtrs[43]); 367 this->expectValues(this->V, this->testArray(7)); 368 } 369 370 TYPED_TEST(TinyPtrVectorTest, InsertRange) { 371 this->V.insert(this->V.end(), this->TestPtrs.begin(), this->TestPtrs.begin()); 372 this->expectValues(this->V, this->testArray(0)); 373 this->V.insert(this->V.begin(), this->TestPtrs.begin(), 374 this->TestPtrs.begin()); 375 this->expectValues(this->V, this->testArray(0)); 376 this->V.insert(this->V.end(), this->TestPtrs.end(), this->TestPtrs.end()); 377 this->expectValues(this->V, this->testArray(0)); 378 this->V.insert(this->V.end(), this->TestPtrs.begin(), 379 std::next(this->TestPtrs.begin())); 380 this->expectValues(this->V, this->testArray(1)); 381 this->V.clear(); 382 this->V.insert(this->V.end(), this->TestPtrs.begin(), 383 std::next(this->TestPtrs.begin(), 2)); 384 this->expectValues(this->V, this->testArray(2)); 385 this->V.clear(); 386 this->V.insert(this->V.end(), this->TestPtrs.begin(), 387 std::next(this->TestPtrs.begin(), 42)); 388 this->expectValues(this->V, this->testArray(42)); 389 this->V.clear(); 390 this->V.insert(this->V.end(), 391 std::next(this->TestPtrs.begin(), 5), 392 std::next(this->TestPtrs.begin(), 13)); 393 this->V.insert(this->V.begin(), 394 std::next(this->TestPtrs.begin(), 0), 395 std::next(this->TestPtrs.begin(), 3)); 396 this->V.insert(std::next(this->V.begin(), 2), 397 std::next(this->TestPtrs.begin(), 2), 398 std::next(this->TestPtrs.begin(), 4)); 399 this->V.erase(std::next(this->V.begin(), 4)); 400 this->V.insert(std::next(this->V.begin(), 4), 401 std::next(this->TestPtrs.begin(), 4), 402 std::next(this->TestPtrs.begin(), 5)); 403 this->expectValues(this->V, this->testArray(13)); 404 } 405 406 } 407 408 TEST(TinyPtrVectorTest, SingleEltCtorTest) { 409 int v = 55; 410 TinyPtrVector<int *> V(&v); 411 412 EXPECT_TRUE(V.size() == 1); 413 EXPECT_FALSE(V.empty()); 414 EXPECT_TRUE(V.front() == &v); 415 } 416 417 TEST(TinyPtrVectorTest, ArrayRefCtorTest) { 418 int data_array[128]; 419 std::vector<int *> data; 420 421 for (unsigned i = 0, e = 128; i != e; ++i) { 422 data_array[i] = 324 - int(i); 423 data.push_back(&data_array[i]); 424 } 425 426 TinyPtrVector<int *> V(data); 427 EXPECT_TRUE(V.size() == 128); 428 EXPECT_FALSE(V.empty()); 429 for (unsigned i = 0, e = 128; i != e; ++i) { 430 EXPECT_TRUE(V[i] == data[i]); 431 } 432 } 433 434 TEST(TinyPtrVectorTest, MutableArrayRefTest) { 435 int data_array[128]; 436 std::vector<int *> data; 437 438 for (unsigned i = 0, e = 128; i != e; ++i) { 439 data_array[i] = 324 - int(i); 440 data.push_back(&data_array[i]); 441 } 442 443 TinyPtrVector<int *> V(data); 444 EXPECT_TRUE(V.size() == 128); 445 EXPECT_FALSE(V.empty()); 446 447 MutableArrayRef<int *> mut_array = V; 448 for (unsigned i = 0, e = 128; i != e; ++i) { 449 EXPECT_TRUE(mut_array[i] == data[i]); 450 mut_array[i] = 324 + mut_array[i]; 451 EXPECT_TRUE(mut_array[i] == (324 + data[i])); 452 } 453 } 454