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