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