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 std::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], *std::next(V.begin(), i));
     76     }
     77     EXPECT_EQ(V.end(), std::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   TypeParam Move(std::move(Copy2));
    161   this->expectValues(Move, this->testArray(42));
    162   this->expectValues(Copy2, this->testArray(0));
    163 }
    164 
    165 TYPED_TEST(TinyPtrVectorTest, CopyAndMoveTest) {
    166   this->V = this->V2;
    167   this->expectValues(this->V, this->testArray(0));
    168   this->expectValues(this->V2, this->testArray(0));
    169   this->V = std::move(this->V2);
    170   this->expectValues(this->V, this->testArray(0));
    171 
    172   this->setVectors(this->testArray(1), 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(1), this->testArray(0));
    177   this->V = std::move(this->V2);
    178   this->expectValues(this->V, this->testArray(0));
    179 
    180   this->setVectors(this->testArray(2), 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(2), this->testArray(0));
    185   this->V = std::move(this->V2);
    186   this->expectValues(this->V, this->testArray(0));
    187 
    188   this->setVectors(this->testArray(42), this->testArray(0));
    189   this->V = this->V2;
    190   this->expectValues(this->V, this->testArray(0));
    191   this->expectValues(this->V2, this->testArray(0));
    192   this->setVectors(this->testArray(42), this->testArray(0));
    193   this->V = std::move(this->V2);
    194   this->expectValues(this->V, this->testArray(0));
    195 
    196   this->setVectors(this->testArray(0), this->testArray(1));
    197   this->V = this->V2;
    198   this->expectValues(this->V, this->testArray(1));
    199   this->expectValues(this->V2, this->testArray(1));
    200   this->setVectors(this->testArray(0), this->testArray(1));
    201   this->V = std::move(this->V2);
    202   this->expectValues(this->V, this->testArray(1));
    203 
    204   this->setVectors(this->testArray(0), this->testArray(2));
    205   this->V = this->V2;
    206   this->expectValues(this->V, this->testArray(2));
    207   this->expectValues(this->V2, this->testArray(2));
    208   this->setVectors(this->testArray(0), this->testArray(2));
    209   this->V = std::move(this->V2);
    210   this->expectValues(this->V, this->testArray(2));
    211 
    212   this->setVectors(this->testArray(0), this->testArray(42));
    213   this->V = this->V2;
    214   this->expectValues(this->V, this->testArray(42));
    215   this->expectValues(this->V2, this->testArray(42));
    216   this->setVectors(this->testArray(0), this->testArray(42));
    217   this->V = std::move(this->V2);
    218   this->expectValues(this->V, this->testArray(42));
    219 
    220   this->setVectors(this->testArray(1), this->testArray(1));
    221   this->V = this->V2;
    222   this->expectValues(this->V, this->testArray(1));
    223   this->expectValues(this->V2, this->testArray(1));
    224   this->V = std::move(this->V2);
    225   this->expectValues(this->V, this->testArray(1));
    226 
    227   this->setVectors(this->testArray(1), this->testArray(2));
    228   this->V = this->V2;
    229   this->expectValues(this->V, this->testArray(2));
    230   this->expectValues(this->V2, this->testArray(2));
    231   this->setVectors(this->testArray(1), this->testArray(2));
    232   this->V = std::move(this->V2);
    233   this->expectValues(this->V, this->testArray(2));
    234 
    235   this->setVectors(this->testArray(1), this->testArray(42));
    236   this->V = this->V2;
    237   this->expectValues(this->V, this->testArray(42));
    238   this->expectValues(this->V2, this->testArray(42));
    239   this->setVectors(this->testArray(1), this->testArray(42));
    240   this->V = std::move(this->V2);
    241   this->expectValues(this->V, this->testArray(42));
    242 
    243   this->setVectors(this->testArray(2), this->testArray(1));
    244   this->V = this->V2;
    245   this->expectValues(this->V, this->testArray(1));
    246   this->expectValues(this->V2, this->testArray(1));
    247   this->setVectors(this->testArray(2), this->testArray(1));
    248   this->V = std::move(this->V2);
    249   this->expectValues(this->V, this->testArray(1));
    250 
    251   this->setVectors(this->testArray(2), this->testArray(2));
    252   this->V = this->V2;
    253   this->expectValues(this->V, this->testArray(2));
    254   this->expectValues(this->V2, this->testArray(2));
    255   this->setVectors(this->testArray(2), this->testArray(2));
    256   this->V = std::move(this->V2);
    257   this->expectValues(this->V, this->testArray(2));
    258 
    259   this->setVectors(this->testArray(2), this->testArray(42));
    260   this->V = this->V2;
    261   this->expectValues(this->V, this->testArray(42));
    262   this->expectValues(this->V2, this->testArray(42));
    263   this->setVectors(this->testArray(2), this->testArray(42));
    264   this->V = std::move(this->V2);
    265   this->expectValues(this->V, this->testArray(42));
    266 
    267   this->setVectors(this->testArray(42), this->testArray(1));
    268   this->V = this->V2;
    269   this->expectValues(this->V, this->testArray(1));
    270   this->expectValues(this->V2, this->testArray(1));
    271   this->setVectors(this->testArray(42), this->testArray(1));
    272   this->V = std::move(this->V2);
    273   this->expectValues(this->V, this->testArray(1));
    274 
    275   this->setVectors(this->testArray(42), 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   this->setVectors(this->testArray(42), this->testArray(2));
    280   this->V = std::move(this->V2);
    281   this->expectValues(this->V, this->testArray(2));
    282 
    283   this->setVectors(this->testArray(42), this->testArray(42));
    284   this->V = this->V2;
    285   this->expectValues(this->V, this->testArray(42));
    286   this->expectValues(this->V2, this->testArray(42));
    287   this->setVectors(this->testArray(42), this->testArray(42));
    288   this->V = std::move(this->V2);
    289   this->expectValues(this->V, this->testArray(42));
    290 }
    291 
    292 TYPED_TEST(TinyPtrVectorTest, EraseTest) {
    293   this->appendValues(this->V, this->testArray(1));
    294   this->expectValues(this->V, this->testArray(1));
    295   this->V.erase(this->V.begin());
    296   this->expectValues(this->V, this->testArray(0));
    297 
    298   this->appendValues(this->V, this->testArray(42));
    299   this->expectValues(this->V, this->testArray(42));
    300   this->V.erase(this->V.begin());
    301   this->TestPtrs.erase(this->TestPtrs.begin());
    302   this->expectValues(this->V, this->testArray(41));
    303   this->V.erase(std::next(this->V.begin(), 1));
    304   this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 1));
    305   this->expectValues(this->V, this->testArray(40));
    306   this->V.erase(std::next(this->V.begin(), 2));
    307   this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 2));
    308   this->expectValues(this->V, this->testArray(39));
    309   this->V.erase(std::next(this->V.begin(), 5));
    310   this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 5));
    311   this->expectValues(this->V, this->testArray(38));
    312   this->V.erase(std::next(this->V.begin(), 13));
    313   this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 13));
    314   this->expectValues(this->V, this->testArray(37));
    315 
    316   typename TypeParam::iterator I = this->V.begin();
    317   do {
    318     I = this->V.erase(I);
    319   } while (I != this->V.end());
    320   this->expectValues(this->V, this->testArray(0));
    321 }
    322 
    323 TYPED_TEST(TinyPtrVectorTest, EraseRangeTest) {
    324   this->appendValues(this->V, this->testArray(1));
    325   this->expectValues(this->V, this->testArray(1));
    326   this->V.erase(this->V.begin(), this->V.begin());
    327   this->expectValues(this->V, this->testArray(1));
    328   this->V.erase(this->V.end(), this->V.end());
    329   this->expectValues(this->V, this->testArray(1));
    330   this->V.erase(this->V.begin(), this->V.end());
    331   this->expectValues(this->V, this->testArray(0));
    332 
    333   this->appendValues(this->V, this->testArray(42));
    334   this->expectValues(this->V, this->testArray(42));
    335   this->V.erase(this->V.begin(), std::next(this->V.begin(), 1));
    336   this->TestPtrs.erase(this->TestPtrs.begin(),
    337                        std::next(this->TestPtrs.begin(), 1));
    338   this->expectValues(this->V, this->testArray(41));
    339   this->V.erase(std::next(this->V.begin(), 1), std::next(this->V.begin(), 2));
    340   this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 1),
    341                        std::next(this->TestPtrs.begin(), 2));
    342   this->expectValues(this->V, this->testArray(40));
    343   this->V.erase(std::next(this->V.begin(), 2), std::next(this->V.begin(), 4));
    344   this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 2),
    345                        std::next(this->TestPtrs.begin(), 4));
    346   this->expectValues(this->V, this->testArray(38));
    347   this->V.erase(std::next(this->V.begin(), 5), std::next(this->V.begin(), 10));
    348   this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 5),
    349                        std::next(this->TestPtrs.begin(), 10));
    350   this->expectValues(this->V, this->testArray(33));
    351   this->V.erase(std::next(this->V.begin(), 13), std::next(this->V.begin(), 26));
    352   this->TestPtrs.erase(std::next(this->TestPtrs.begin(), 13),
    353                        std::next(this->TestPtrs.begin(), 26));
    354   this->expectValues(this->V, this->testArray(20));
    355   this->V.erase(std::next(this->V.begin(), 7), this->V.end());
    356   this->expectValues(this->V, this->testArray(7));
    357   this->V.erase(this->V.begin(), this->V.end());
    358   this->expectValues(this->V, this->testArray(0));
    359 }
    360 
    361 TYPED_TEST(TinyPtrVectorTest, Insert) {
    362   this->V.insert(this->V.end(), this->TestPtrs[0]);
    363   this->expectValues(this->V, this->testArray(1));
    364   this->V.clear();
    365   this->appendValues(this->V, this->testArray(4));
    366   this->expectValues(this->V, this->testArray(4));
    367   this->V.insert(this->V.end(), this->TestPtrs[4]);
    368   this->expectValues(this->V, this->testArray(5));
    369   this->V.insert(this->V.begin(), this->TestPtrs[42]);
    370   this->TestPtrs.insert(this->TestPtrs.begin(), this->TestPtrs[42]);
    371   this->expectValues(this->V, this->testArray(6));
    372   this->V.insert(std::next(this->V.begin(), 3), this->TestPtrs[43]);
    373   this->TestPtrs.insert(std::next(this->TestPtrs.begin(), 3),
    374                         this->TestPtrs[43]);
    375   this->expectValues(this->V, this->testArray(7));
    376 }
    377 
    378 TYPED_TEST(TinyPtrVectorTest, InsertRange) {
    379   this->V.insert(this->V.end(), this->TestPtrs.begin(), this->TestPtrs.begin());
    380   this->expectValues(this->V, this->testArray(0));
    381   this->V.insert(this->V.begin(), this->TestPtrs.begin(),
    382                  this->TestPtrs.begin());
    383   this->expectValues(this->V, this->testArray(0));
    384   this->V.insert(this->V.end(), this->TestPtrs.end(), this->TestPtrs.end());
    385   this->expectValues(this->V, this->testArray(0));
    386   this->V.insert(this->V.end(), this->TestPtrs.begin(),
    387                  std::next(this->TestPtrs.begin()));
    388   this->expectValues(this->V, this->testArray(1));
    389   this->V.clear();
    390   this->V.insert(this->V.end(), this->TestPtrs.begin(),
    391                  std::next(this->TestPtrs.begin(), 2));
    392   this->expectValues(this->V, this->testArray(2));
    393   this->V.clear();
    394   this->V.insert(this->V.end(), this->TestPtrs.begin(),
    395                  std::next(this->TestPtrs.begin(), 42));
    396   this->expectValues(this->V, this->testArray(42));
    397   this->V.clear();
    398   this->V.insert(this->V.end(),
    399                  std::next(this->TestPtrs.begin(), 5),
    400                  std::next(this->TestPtrs.begin(), 13));
    401   this->V.insert(this->V.begin(),
    402                  std::next(this->TestPtrs.begin(), 0),
    403                  std::next(this->TestPtrs.begin(), 3));
    404   this->V.insert(std::next(this->V.begin(), 2),
    405                  std::next(this->TestPtrs.begin(), 2),
    406                  std::next(this->TestPtrs.begin(), 4));
    407   this->V.erase(std::next(this->V.begin(), 4));
    408   this->V.insert(std::next(this->V.begin(), 4),
    409                  std::next(this->TestPtrs.begin(), 4),
    410                  std::next(this->TestPtrs.begin(), 5));
    411   this->expectValues(this->V, this->testArray(13));
    412 }
    413 
    414 }
    415