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