123d8306dSDuncan P. N. Exon Smith //===- unittests/ADT/BumpPtrListTest.cpp - BumpPtrList unit tests ---------===//
223d8306dSDuncan P. N. Exon Smith //
3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
623d8306dSDuncan P. N. Exon Smith //
723d8306dSDuncan P. N. Exon Smith //===----------------------------------------------------------------------===//
823d8306dSDuncan P. N. Exon Smith 
923d8306dSDuncan P. N. Exon Smith #include "llvm/ADT/AllocatorList.h"
1023d8306dSDuncan P. N. Exon Smith #include "llvm/ADT/STLExtras.h"
1123d8306dSDuncan P. N. Exon Smith #include "gtest/gtest.h"
1223d8306dSDuncan P. N. Exon Smith 
1323d8306dSDuncan P. N. Exon Smith using namespace llvm;
1423d8306dSDuncan P. N. Exon Smith 
1523d8306dSDuncan P. N. Exon Smith namespace {
1623d8306dSDuncan P. N. Exon Smith 
1723d8306dSDuncan P. N. Exon Smith struct CountsDestructors {
1823d8306dSDuncan P. N. Exon Smith   static unsigned NumCalls;
~CountsDestructors__anon0582668a0111::CountsDestructors1923d8306dSDuncan P. N. Exon Smith   ~CountsDestructors() { ++NumCalls; }
2023d8306dSDuncan P. N. Exon Smith };
2123d8306dSDuncan P. N. Exon Smith unsigned CountsDestructors::NumCalls = 0;
2223d8306dSDuncan P. N. Exon Smith 
2323d8306dSDuncan P. N. Exon Smith struct MoveOnly {
2423d8306dSDuncan P. N. Exon Smith   int V;
MoveOnly__anon0582668a0111::MoveOnly2523d8306dSDuncan P. N. Exon Smith   explicit MoveOnly(int V) : V(V) {}
2623d8306dSDuncan P. N. Exon Smith   MoveOnly() = delete;
MoveOnly__anon0582668a0111::MoveOnly2723d8306dSDuncan P. N. Exon Smith   MoveOnly(MoveOnly &&X) { V = X.V; }
2823d8306dSDuncan P. N. Exon Smith   MoveOnly(const MoveOnly &X) = delete;
2923d8306dSDuncan P. N. Exon Smith   MoveOnly &operator=(MoveOnly &&X) = delete;
3023d8306dSDuncan P. N. Exon Smith   MoveOnly &operator=(const MoveOnly &X) = delete;
3123d8306dSDuncan P. N. Exon Smith };
3223d8306dSDuncan P. N. Exon Smith 
3323d8306dSDuncan P. N. Exon Smith struct EmplaceOnly {
3423d8306dSDuncan P. N. Exon Smith   int V1, V2;
EmplaceOnly__anon0582668a0111::EmplaceOnly3523d8306dSDuncan P. N. Exon Smith   explicit EmplaceOnly(int V1, int V2) : V1(V1), V2(V2) {}
3623d8306dSDuncan P. N. Exon Smith   EmplaceOnly() = delete;
3723d8306dSDuncan P. N. Exon Smith   EmplaceOnly(EmplaceOnly &&X) = delete;
3823d8306dSDuncan P. N. Exon Smith   EmplaceOnly(const EmplaceOnly &X) = delete;
3923d8306dSDuncan P. N. Exon Smith   EmplaceOnly &operator=(EmplaceOnly &&X) = delete;
4023d8306dSDuncan P. N. Exon Smith   EmplaceOnly &operator=(const EmplaceOnly &X) = delete;
4123d8306dSDuncan P. N. Exon Smith };
4223d8306dSDuncan P. N. Exon Smith 
TEST(BumpPtrListTest,DefaultConstructor)4323d8306dSDuncan P. N. Exon Smith TEST(BumpPtrListTest, DefaultConstructor) {
4423d8306dSDuncan P. N. Exon Smith   BumpPtrList<int> L;
4523d8306dSDuncan P. N. Exon Smith   EXPECT_TRUE(L.empty());
4623d8306dSDuncan P. N. Exon Smith }
4723d8306dSDuncan P. N. Exon Smith 
TEST(BumpPtrListTest,pushPopBack)4823d8306dSDuncan P. N. Exon Smith TEST(BumpPtrListTest, pushPopBack) {
4923d8306dSDuncan P. N. Exon Smith   // Build a list with push_back.
5023d8306dSDuncan P. N. Exon Smith   BumpPtrList<int> L;
5123d8306dSDuncan P. N. Exon Smith   int Ns[] = {1, 3, 9, 5, 7};
5223d8306dSDuncan P. N. Exon Smith   for (const int N : Ns)
5323d8306dSDuncan P. N. Exon Smith     L.push_back(N);
5423d8306dSDuncan P. N. Exon Smith 
5523d8306dSDuncan P. N. Exon Smith   // Use iterators to check contents.
5623d8306dSDuncan P. N. Exon Smith   auto I = L.begin();
5723d8306dSDuncan P. N. Exon Smith   for (int N : Ns)
5823d8306dSDuncan P. N. Exon Smith     EXPECT_EQ(N, *I++);
5923d8306dSDuncan P. N. Exon Smith   EXPECT_EQ(I, L.end());
6023d8306dSDuncan P. N. Exon Smith 
6123d8306dSDuncan P. N. Exon Smith   // Unbuild the list with pop_back.
6223d8306dSDuncan P. N. Exon Smith   for (int N : llvm::reverse(Ns)) {
6323d8306dSDuncan P. N. Exon Smith     EXPECT_EQ(N, L.back());
6423d8306dSDuncan P. N. Exon Smith     L.pop_back();
6523d8306dSDuncan P. N. Exon Smith   }
6623d8306dSDuncan P. N. Exon Smith   EXPECT_TRUE(L.empty());
6723d8306dSDuncan P. N. Exon Smith }
6823d8306dSDuncan P. N. Exon Smith 
TEST(BumpPtrListTest,pushPopFront)6923d8306dSDuncan P. N. Exon Smith TEST(BumpPtrListTest, pushPopFront) {
7023d8306dSDuncan P. N. Exon Smith   // Build a list with push_front.
7123d8306dSDuncan P. N. Exon Smith   BumpPtrList<int> L;
7223d8306dSDuncan P. N. Exon Smith   int Ns[] = {1, 3, 9, 5, 7};
7323d8306dSDuncan P. N. Exon Smith   for (const int N : Ns)
7423d8306dSDuncan P. N. Exon Smith     L.push_front(N);
7523d8306dSDuncan P. N. Exon Smith 
7623d8306dSDuncan P. N. Exon Smith   // Use reverse iterators to check contents.
7723d8306dSDuncan P. N. Exon Smith   auto I = L.rbegin();
7823d8306dSDuncan P. N. Exon Smith   for (int N : Ns)
7923d8306dSDuncan P. N. Exon Smith     EXPECT_EQ(N, *I++);
8023d8306dSDuncan P. N. Exon Smith   EXPECT_EQ(I, L.rend());
8123d8306dSDuncan P. N. Exon Smith 
8223d8306dSDuncan P. N. Exon Smith   // Unbuild the list with pop_front.
8323d8306dSDuncan P. N. Exon Smith   for (int N : llvm::reverse(Ns)) {
8423d8306dSDuncan P. N. Exon Smith     EXPECT_EQ(N, L.front());
8523d8306dSDuncan P. N. Exon Smith     L.pop_front();
8623d8306dSDuncan P. N. Exon Smith   }
8723d8306dSDuncan P. N. Exon Smith   EXPECT_TRUE(L.empty());
8823d8306dSDuncan P. N. Exon Smith }
8923d8306dSDuncan P. N. Exon Smith 
TEST(BumpPtrListTest,pushBackMoveOnly)9023d8306dSDuncan P. N. Exon Smith TEST(BumpPtrListTest, pushBackMoveOnly) {
9123d8306dSDuncan P. N. Exon Smith   BumpPtrList<MoveOnly> L;
9223d8306dSDuncan P. N. Exon Smith   int Ns[] = {1, 3, 9, 5, 7};
9323d8306dSDuncan P. N. Exon Smith   for (const int N : Ns) {
9423d8306dSDuncan P. N. Exon Smith     L.push_back(MoveOnly(N));
9523d8306dSDuncan P. N. Exon Smith     EXPECT_EQ(N, L.back().V);
9623d8306dSDuncan P. N. Exon Smith   }
9723d8306dSDuncan P. N. Exon Smith   // Instantiate with MoveOnly.
9823d8306dSDuncan P. N. Exon Smith   while (!L.empty())
9923d8306dSDuncan P. N. Exon Smith     L.pop_back();
10023d8306dSDuncan P. N. Exon Smith }
10123d8306dSDuncan P. N. Exon Smith 
TEST(BumpPtrListTest,pushFrontMoveOnly)10223d8306dSDuncan P. N. Exon Smith TEST(BumpPtrListTest, pushFrontMoveOnly) {
10323d8306dSDuncan P. N. Exon Smith   BumpPtrList<MoveOnly> L;
10423d8306dSDuncan P. N. Exon Smith   int Ns[] = {1, 3, 9, 5, 7};
10523d8306dSDuncan P. N. Exon Smith   for (const int N : Ns) {
10623d8306dSDuncan P. N. Exon Smith     L.push_front(MoveOnly(N));
10723d8306dSDuncan P. N. Exon Smith     EXPECT_EQ(N, L.front().V);
10823d8306dSDuncan P. N. Exon Smith   }
10923d8306dSDuncan P. N. Exon Smith   // Instantiate with MoveOnly.
11023d8306dSDuncan P. N. Exon Smith   while (!L.empty())
11123d8306dSDuncan P. N. Exon Smith     L.pop_front();
11223d8306dSDuncan P. N. Exon Smith }
11323d8306dSDuncan P. N. Exon Smith 
TEST(BumpPtrListTest,emplaceBack)11423d8306dSDuncan P. N. Exon Smith TEST(BumpPtrListTest, emplaceBack) {
11523d8306dSDuncan P. N. Exon Smith   BumpPtrList<EmplaceOnly> L;
11623d8306dSDuncan P. N. Exon Smith   int N1s[] = {1, 3, 9, 5, 7};
11723d8306dSDuncan P. N. Exon Smith   int N2s[] = {7, 3, 1, 8, 2};
11823d8306dSDuncan P. N. Exon Smith   for (int I = 0; I != 5; ++I) {
11923d8306dSDuncan P. N. Exon Smith     L.emplace_back(N1s[I], N2s[I]);
12023d8306dSDuncan P. N. Exon Smith     EXPECT_EQ(N1s[I], L.back().V1);
12123d8306dSDuncan P. N. Exon Smith     EXPECT_EQ(N2s[I], L.back().V2);
12223d8306dSDuncan P. N. Exon Smith   }
12323d8306dSDuncan P. N. Exon Smith   // Instantiate with EmplaceOnly.
12423d8306dSDuncan P. N. Exon Smith   while (!L.empty())
12523d8306dSDuncan P. N. Exon Smith     L.pop_back();
12623d8306dSDuncan P. N. Exon Smith }
12723d8306dSDuncan P. N. Exon Smith 
TEST(BumpPtrListTest,emplaceFront)12823d8306dSDuncan P. N. Exon Smith TEST(BumpPtrListTest, emplaceFront) {
12923d8306dSDuncan P. N. Exon Smith   BumpPtrList<EmplaceOnly> L;
13023d8306dSDuncan P. N. Exon Smith   int N1s[] = {1, 3, 9, 5, 7};
13123d8306dSDuncan P. N. Exon Smith   int N2s[] = {7, 3, 1, 8, 2};
13223d8306dSDuncan P. N. Exon Smith   for (int I = 0; I != 5; ++I) {
13323d8306dSDuncan P. N. Exon Smith     L.emplace_front(N1s[I], N2s[I]);
13423d8306dSDuncan P. N. Exon Smith     EXPECT_EQ(N1s[I], L.front().V1);
13523d8306dSDuncan P. N. Exon Smith     EXPECT_EQ(N2s[I], L.front().V2);
13623d8306dSDuncan P. N. Exon Smith   }
13723d8306dSDuncan P. N. Exon Smith   // Instantiate with EmplaceOnly.
13823d8306dSDuncan P. N. Exon Smith   while (!L.empty())
13923d8306dSDuncan P. N. Exon Smith     L.pop_front();
14023d8306dSDuncan P. N. Exon Smith }
14123d8306dSDuncan P. N. Exon Smith 
TEST(BumpPtrListTest,swap)14223d8306dSDuncan P. N. Exon Smith TEST(BumpPtrListTest, swap) {
14323d8306dSDuncan P. N. Exon Smith   // Build two lists with different lifetimes and swap them.
14423d8306dSDuncan P. N. Exon Smith   int N1s[] = {1, 3, 5, 7, 9};
14523d8306dSDuncan P. N. Exon Smith   int N2s[] = {2, 4, 6, 8, 10};
14623d8306dSDuncan P. N. Exon Smith 
14723d8306dSDuncan P. N. Exon Smith   BumpPtrList<int> L1;
14823d8306dSDuncan P. N. Exon Smith   L1.insert(L1.end(), std::begin(N1s), std::end(N1s));
14923d8306dSDuncan P. N. Exon Smith   {
15023d8306dSDuncan P. N. Exon Smith     BumpPtrList<int> L2;
15123d8306dSDuncan P. N. Exon Smith     L2.insert(L2.end(), std::begin(N2s), std::end(N2s));
15223d8306dSDuncan P. N. Exon Smith 
15323d8306dSDuncan P. N. Exon Smith     // Swap the lists.
15423d8306dSDuncan P. N. Exon Smith     L1.swap(L2);
15523d8306dSDuncan P. N. Exon Smith 
15623d8306dSDuncan P. N. Exon Smith     // Check L2's contents before it goes out of scope.
15723d8306dSDuncan P. N. Exon Smith     auto I = L2.begin();
15823d8306dSDuncan P. N. Exon Smith     for (int N : N1s)
15923d8306dSDuncan P. N. Exon Smith       EXPECT_EQ(N, *I++);
16023d8306dSDuncan P. N. Exon Smith     EXPECT_EQ(I, L2.end());
16123d8306dSDuncan P. N. Exon Smith   }
16223d8306dSDuncan P. N. Exon Smith 
16323d8306dSDuncan P. N. Exon Smith   // Check L1's contents now that L2 is out of scope (with its allocation
16423d8306dSDuncan P. N. Exon Smith   // blocks).
16523d8306dSDuncan P. N. Exon Smith   auto I = L1.begin();
16623d8306dSDuncan P. N. Exon Smith   for (int N : N2s)
16723d8306dSDuncan P. N. Exon Smith     EXPECT_EQ(N, *I++);
16823d8306dSDuncan P. N. Exon Smith   EXPECT_EQ(I, L1.end());
16923d8306dSDuncan P. N. Exon Smith }
17023d8306dSDuncan P. N. Exon Smith 
TEST(BumpPtrListTest,clear)17123d8306dSDuncan P. N. Exon Smith TEST(BumpPtrListTest, clear) {
17223d8306dSDuncan P. N. Exon Smith   CountsDestructors::NumCalls = 0;
17323d8306dSDuncan P. N. Exon Smith   CountsDestructors N;
17423d8306dSDuncan P. N. Exon Smith   BumpPtrList<CountsDestructors> L;
17523d8306dSDuncan P. N. Exon Smith   L.push_back(N);
17623d8306dSDuncan P. N. Exon Smith   L.push_back(N);
17723d8306dSDuncan P. N. Exon Smith   L.push_back(N);
17823d8306dSDuncan P. N. Exon Smith   EXPECT_EQ(3u, L.size());
17923d8306dSDuncan P. N. Exon Smith   EXPECT_EQ(0u, CountsDestructors::NumCalls);
18023d8306dSDuncan P. N. Exon Smith   L.pop_back();
18123d8306dSDuncan P. N. Exon Smith   EXPECT_EQ(1u, CountsDestructors::NumCalls);
18223d8306dSDuncan P. N. Exon Smith   L.clear();
18323d8306dSDuncan P. N. Exon Smith   EXPECT_EQ(3u, CountsDestructors::NumCalls);
18423d8306dSDuncan P. N. Exon Smith }
18523d8306dSDuncan P. N. Exon Smith 
TEST(BumpPtrListTest,move)18623d8306dSDuncan P. N. Exon Smith TEST(BumpPtrListTest, move) {
18723d8306dSDuncan P. N. Exon Smith   BumpPtrList<int> L1, L2;
18823d8306dSDuncan P. N. Exon Smith   L1.push_back(1);
18923d8306dSDuncan P. N. Exon Smith   L2.push_back(2);
19023d8306dSDuncan P. N. Exon Smith   L1 = std::move(L2);
19123d8306dSDuncan P. N. Exon Smith   EXPECT_EQ(1u, L1.size());
19223d8306dSDuncan P. N. Exon Smith   EXPECT_EQ(2, L1.front());
19323d8306dSDuncan P. N. Exon Smith   EXPECT_EQ(0u, L2.size());
19423d8306dSDuncan P. N. Exon Smith }
19523d8306dSDuncan P. N. Exon Smith 
TEST(BumpPtrListTest,moveCallsDestructors)19623d8306dSDuncan P. N. Exon Smith TEST(BumpPtrListTest, moveCallsDestructors) {
19723d8306dSDuncan P. N. Exon Smith   CountsDestructors::NumCalls = 0;
19823d8306dSDuncan P. N. Exon Smith   BumpPtrList<CountsDestructors> L1, L2;
19923d8306dSDuncan P. N. Exon Smith   L1.emplace_back();
20023d8306dSDuncan P. N. Exon Smith   EXPECT_EQ(0u, CountsDestructors::NumCalls);
20123d8306dSDuncan P. N. Exon Smith   L1 = std::move(L2);
20223d8306dSDuncan P. N. Exon Smith   EXPECT_EQ(1u, CountsDestructors::NumCalls);
20323d8306dSDuncan P. N. Exon Smith }
20423d8306dSDuncan P. N. Exon Smith 
TEST(BumpPtrListTest,copy)20523d8306dSDuncan P. N. Exon Smith TEST(BumpPtrListTest, copy) {
20623d8306dSDuncan P. N. Exon Smith   BumpPtrList<int> L1, L2;
20723d8306dSDuncan P. N. Exon Smith   L1.push_back(1);
20823d8306dSDuncan P. N. Exon Smith   L2.push_back(2);
20923d8306dSDuncan P. N. Exon Smith   L1 = L2;
21023d8306dSDuncan P. N. Exon Smith   EXPECT_EQ(1u, L1.size());
21123d8306dSDuncan P. N. Exon Smith   EXPECT_EQ(2, L1.front());
21223d8306dSDuncan P. N. Exon Smith   EXPECT_EQ(1u, L2.size());
21323d8306dSDuncan P. N. Exon Smith   EXPECT_EQ(2, L2.front());
21423d8306dSDuncan P. N. Exon Smith }
21523d8306dSDuncan P. N. Exon Smith 
TEST(BumpPtrListTest,copyCallsDestructors)21623d8306dSDuncan P. N. Exon Smith TEST(BumpPtrListTest, copyCallsDestructors) {
21723d8306dSDuncan P. N. Exon Smith   CountsDestructors::NumCalls = 0;
21823d8306dSDuncan P. N. Exon Smith   BumpPtrList<CountsDestructors> L1, L2;
21923d8306dSDuncan P. N. Exon Smith   L1.emplace_back();
22023d8306dSDuncan P. N. Exon Smith   EXPECT_EQ(0u, CountsDestructors::NumCalls);
22123d8306dSDuncan P. N. Exon Smith   L1 = L2;
22223d8306dSDuncan P. N. Exon Smith   EXPECT_EQ(1u, CountsDestructors::NumCalls);
22323d8306dSDuncan P. N. Exon Smith }
22423d8306dSDuncan P. N. Exon Smith 
TEST(BumpPtrListTest,resetAlloc)22523d8306dSDuncan P. N. Exon Smith TEST(BumpPtrListTest, resetAlloc) {
22623d8306dSDuncan P. N. Exon Smith   // Resetting an empty list should work.
22723d8306dSDuncan P. N. Exon Smith   BumpPtrList<int> L;
22823d8306dSDuncan P. N. Exon Smith 
22923d8306dSDuncan P. N. Exon Smith   // Resetting an empty list that has allocated should also work.
23023d8306dSDuncan P. N. Exon Smith   L.resetAlloc();
23123d8306dSDuncan P. N. Exon Smith   L.push_back(5);
23223d8306dSDuncan P. N. Exon Smith   L.erase(L.begin());
23323d8306dSDuncan P. N. Exon Smith   L.resetAlloc();
23423d8306dSDuncan P. N. Exon Smith 
23523d8306dSDuncan P. N. Exon Smith   // Resetting a non-empty list should crash.
23623d8306dSDuncan P. N. Exon Smith   L.push_back(5);
23723d8306dSDuncan P. N. Exon Smith #if defined(GTEST_HAS_DEATH_TEST) && !defined(NDEBUG)
23823d8306dSDuncan P. N. Exon Smith   EXPECT_DEATH(L.resetAlloc(), "Cannot reset allocator if not empty");
23923d8306dSDuncan P. N. Exon Smith #endif
24023d8306dSDuncan P. N. Exon Smith }
24123d8306dSDuncan P. N. Exon Smith 
24223d8306dSDuncan P. N. Exon Smith } // end namespace
243