Home | History | Annotate | Download | only in ADT
      1 //===- unittests/ADT/BumpPtrListTest.cpp - BumpPtrList unit tests ---------===//
      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 #include "llvm/ADT/AllocatorList.h"
     11 #include "llvm/ADT/STLExtras.h"
     12 #include "gtest/gtest.h"
     13 
     14 using namespace llvm;
     15 
     16 namespace {
     17 
     18 struct CountsDestructors {
     19   static unsigned NumCalls;
     20   ~CountsDestructors() { ++NumCalls; }
     21 };
     22 unsigned CountsDestructors::NumCalls = 0;
     23 
     24 struct MoveOnly {
     25   int V;
     26   explicit MoveOnly(int V) : V(V) {}
     27   MoveOnly() = delete;
     28   MoveOnly(MoveOnly &&X) { V = X.V; }
     29   MoveOnly(const MoveOnly &X) = delete;
     30   MoveOnly &operator=(MoveOnly &&X) = delete;
     31   MoveOnly &operator=(const MoveOnly &X) = delete;
     32 };
     33 
     34 struct EmplaceOnly {
     35   int V1, V2;
     36   explicit EmplaceOnly(int V1, int V2) : V1(V1), V2(V2) {}
     37   EmplaceOnly() = delete;
     38   EmplaceOnly(EmplaceOnly &&X) = delete;
     39   EmplaceOnly(const EmplaceOnly &X) = delete;
     40   EmplaceOnly &operator=(EmplaceOnly &&X) = delete;
     41   EmplaceOnly &operator=(const EmplaceOnly &X) = delete;
     42 };
     43 
     44 TEST(BumpPtrListTest, DefaultConstructor) {
     45   BumpPtrList<int> L;
     46   EXPECT_TRUE(L.empty());
     47 }
     48 
     49 TEST(BumpPtrListTest, pushPopBack) {
     50   // Build a list with push_back.
     51   BumpPtrList<int> L;
     52   int Ns[] = {1, 3, 9, 5, 7};
     53   for (const int N : Ns)
     54     L.push_back(N);
     55 
     56   // Use iterators to check contents.
     57   auto I = L.begin();
     58   for (int N : Ns)
     59     EXPECT_EQ(N, *I++);
     60   EXPECT_EQ(I, L.end());
     61 
     62   // Unbuild the list with pop_back.
     63   for (int N : llvm::reverse(Ns)) {
     64     EXPECT_EQ(N, L.back());
     65     L.pop_back();
     66   }
     67   EXPECT_TRUE(L.empty());
     68 }
     69 
     70 TEST(BumpPtrListTest, pushPopFront) {
     71   // Build a list with push_front.
     72   BumpPtrList<int> L;
     73   int Ns[] = {1, 3, 9, 5, 7};
     74   for (const int N : Ns)
     75     L.push_front(N);
     76 
     77   // Use reverse iterators to check contents.
     78   auto I = L.rbegin();
     79   for (int N : Ns)
     80     EXPECT_EQ(N, *I++);
     81   EXPECT_EQ(I, L.rend());
     82 
     83   // Unbuild the list with pop_front.
     84   for (int N : llvm::reverse(Ns)) {
     85     EXPECT_EQ(N, L.front());
     86     L.pop_front();
     87   }
     88   EXPECT_TRUE(L.empty());
     89 }
     90 
     91 TEST(BumpPtrListTest, pushBackMoveOnly) {
     92   BumpPtrList<MoveOnly> L;
     93   int Ns[] = {1, 3, 9, 5, 7};
     94   for (const int N : Ns) {
     95     L.push_back(MoveOnly(N));
     96     EXPECT_EQ(N, L.back().V);
     97   }
     98   // Instantiate with MoveOnly.
     99   while (!L.empty())
    100     L.pop_back();
    101 }
    102 
    103 TEST(BumpPtrListTest, pushFrontMoveOnly) {
    104   BumpPtrList<MoveOnly> L;
    105   int Ns[] = {1, 3, 9, 5, 7};
    106   for (const int N : Ns) {
    107     L.push_front(MoveOnly(N));
    108     EXPECT_EQ(N, L.front().V);
    109   }
    110   // Instantiate with MoveOnly.
    111   while (!L.empty())
    112     L.pop_front();
    113 }
    114 
    115 TEST(BumpPtrListTest, emplaceBack) {
    116   BumpPtrList<EmplaceOnly> L;
    117   int N1s[] = {1, 3, 9, 5, 7};
    118   int N2s[] = {7, 3, 1, 8, 2};
    119   for (int I = 0; I != 5; ++I) {
    120     L.emplace_back(N1s[I], N2s[I]);
    121     EXPECT_EQ(N1s[I], L.back().V1);
    122     EXPECT_EQ(N2s[I], L.back().V2);
    123   }
    124   // Instantiate with EmplaceOnly.
    125   while (!L.empty())
    126     L.pop_back();
    127 }
    128 
    129 TEST(BumpPtrListTest, emplaceFront) {
    130   BumpPtrList<EmplaceOnly> L;
    131   int N1s[] = {1, 3, 9, 5, 7};
    132   int N2s[] = {7, 3, 1, 8, 2};
    133   for (int I = 0; I != 5; ++I) {
    134     L.emplace_front(N1s[I], N2s[I]);
    135     EXPECT_EQ(N1s[I], L.front().V1);
    136     EXPECT_EQ(N2s[I], L.front().V2);
    137   }
    138   // Instantiate with EmplaceOnly.
    139   while (!L.empty())
    140     L.pop_front();
    141 }
    142 
    143 TEST(BumpPtrListTest, swap) {
    144   // Build two lists with different lifetimes and swap them.
    145   int N1s[] = {1, 3, 5, 7, 9};
    146   int N2s[] = {2, 4, 6, 8, 10};
    147 
    148   BumpPtrList<int> L1;
    149   L1.insert(L1.end(), std::begin(N1s), std::end(N1s));
    150   {
    151     BumpPtrList<int> L2;
    152     L2.insert(L2.end(), std::begin(N2s), std::end(N2s));
    153 
    154     // Swap the lists.
    155     L1.swap(L2);
    156 
    157     // Check L2's contents before it goes out of scope.
    158     auto I = L2.begin();
    159     for (int N : N1s)
    160       EXPECT_EQ(N, *I++);
    161     EXPECT_EQ(I, L2.end());
    162   }
    163 
    164   // Check L1's contents now that L2 is out of scope (with its allocation
    165   // blocks).
    166   auto I = L1.begin();
    167   for (int N : N2s)
    168     EXPECT_EQ(N, *I++);
    169   EXPECT_EQ(I, L1.end());
    170 }
    171 
    172 TEST(BumpPtrListTest, clear) {
    173   CountsDestructors::NumCalls = 0;
    174   CountsDestructors N;
    175   BumpPtrList<CountsDestructors> L;
    176   L.push_back(N);
    177   L.push_back(N);
    178   L.push_back(N);
    179   EXPECT_EQ(3u, L.size());
    180   EXPECT_EQ(0u, CountsDestructors::NumCalls);
    181   L.pop_back();
    182   EXPECT_EQ(1u, CountsDestructors::NumCalls);
    183   L.clear();
    184   EXPECT_EQ(3u, CountsDestructors::NumCalls);
    185 }
    186 
    187 TEST(BumpPtrListTest, move) {
    188   BumpPtrList<int> L1, L2;
    189   L1.push_back(1);
    190   L2.push_back(2);
    191   L1 = std::move(L2);
    192   EXPECT_EQ(1u, L1.size());
    193   EXPECT_EQ(2, L1.front());
    194   EXPECT_EQ(0u, L2.size());
    195 }
    196 
    197 TEST(BumpPtrListTest, moveCallsDestructors) {
    198   CountsDestructors::NumCalls = 0;
    199   BumpPtrList<CountsDestructors> L1, L2;
    200   L1.emplace_back();
    201   EXPECT_EQ(0u, CountsDestructors::NumCalls);
    202   L1 = std::move(L2);
    203   EXPECT_EQ(1u, CountsDestructors::NumCalls);
    204 }
    205 
    206 TEST(BumpPtrListTest, copy) {
    207   BumpPtrList<int> L1, L2;
    208   L1.push_back(1);
    209   L2.push_back(2);
    210   L1 = L2;
    211   EXPECT_EQ(1u, L1.size());
    212   EXPECT_EQ(2, L1.front());
    213   EXPECT_EQ(1u, L2.size());
    214   EXPECT_EQ(2, L2.front());
    215 }
    216 
    217 TEST(BumpPtrListTest, copyCallsDestructors) {
    218   CountsDestructors::NumCalls = 0;
    219   BumpPtrList<CountsDestructors> L1, L2;
    220   L1.emplace_back();
    221   EXPECT_EQ(0u, CountsDestructors::NumCalls);
    222   L1 = L2;
    223   EXPECT_EQ(1u, CountsDestructors::NumCalls);
    224 }
    225 
    226 TEST(BumpPtrListTest, resetAlloc) {
    227   // Resetting an empty list should work.
    228   BumpPtrList<int> L;
    229 
    230   // Resetting an empty list that has allocated should also work.
    231   L.resetAlloc();
    232   L.push_back(5);
    233   L.erase(L.begin());
    234   L.resetAlloc();
    235 
    236   // Resetting a non-empty list should crash.
    237   L.push_back(5);
    238 #if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG)
    239   EXPECT_DEATH(L.resetAlloc(), "Cannot reset allocator if not empty");
    240 #endif
    241 }
    242 
    243 } // end namespace
    244