18ed38f2eSKristof Umann //===--------- ImmutableListTest.cpp - ImmutableList unit tests --*- C++ -*-==//
28ed38f2eSKristof Umann //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
68ed38f2eSKristof Umann //
78ed38f2eSKristof Umann //===----------------------------------------------------------------------===//
88ed38f2eSKristof Umann
98ed38f2eSKristof Umann #include "llvm/ADT/ImmutableList.h"
108ed38f2eSKristof Umann #include "gtest/gtest.h"
118ed38f2eSKristof Umann
128ed38f2eSKristof Umann using namespace llvm;
138ed38f2eSKristof Umann
148ed38f2eSKristof Umann namespace {
158ed38f2eSKristof Umann
168ed38f2eSKristof Umann template <typename Fundamental> struct Wrapper : llvm::FoldingSetNode {
178ed38f2eSKristof Umann Fundamental F;
188ed38f2eSKristof Umann
Wrapper__anon74673e430111::Wrapper198ed38f2eSKristof Umann Wrapper(Fundamental F) : F(F) {}
208ed38f2eSKristof Umann
operator Fundamental__anon74673e430111::Wrapper218ed38f2eSKristof Umann operator Fundamental() const { return F; }
228ed38f2eSKristof Umann
Profile__anon74673e430111::Wrapper238ed38f2eSKristof Umann void Profile(FoldingSetNodeID &ID) const { ID.AddInteger(F); }
248ed38f2eSKristof Umann };
258ed38f2eSKristof Umann
268ed38f2eSKristof Umann class ImmutableListTest : public testing::Test {};
278ed38f2eSKristof Umann
concat(const ImmutableList<Wrapper<char>> & L,char * Buffer)288ed38f2eSKristof Umann void concat(const ImmutableList<Wrapper<char>> &L, char *Buffer) {
298ed38f2eSKristof Umann int Index = 0;
308ed38f2eSKristof Umann for (ImmutableList<Wrapper<char>>::iterator It = L.begin(), End = L.end();
318ed38f2eSKristof Umann It != End; ++It) {
328ed38f2eSKristof Umann Buffer[Index++] = *It;
338ed38f2eSKristof Umann }
348ed38f2eSKristof Umann Buffer[Index] = '\0';
358ed38f2eSKristof Umann }
368ed38f2eSKristof Umann
TEST_F(ImmutableListTest,EmptyIntListTest)378ed38f2eSKristof Umann TEST_F(ImmutableListTest, EmptyIntListTest) {
388ed38f2eSKristof Umann ImmutableList<Wrapper<int>>::Factory f;
398ed38f2eSKristof Umann
408ed38f2eSKristof Umann EXPECT_TRUE(f.getEmptyList() == f.getEmptyList());
418ed38f2eSKristof Umann EXPECT_TRUE(f.getEmptyList().isEqual(f.getEmptyList()));
428ed38f2eSKristof Umann EXPECT_TRUE(f.getEmptyList().isEmpty());
438ed38f2eSKristof Umann
448ed38f2eSKristof Umann ImmutableList<Wrapper<int>> L = f.getEmptyList();
458ed38f2eSKristof Umann EXPECT_EQ(nullptr, L.getTail().getInternalPointer());
468ed38f2eSKristof Umann EXPECT_TRUE(L.getTail().isEmpty());
478ed38f2eSKristof Umann EXPECT_TRUE(L.begin() == L.end());
488ed38f2eSKristof Umann }
498ed38f2eSKristof Umann
TEST_F(ImmutableListTest,OneElemIntListTest)508ed38f2eSKristof Umann TEST_F(ImmutableListTest, OneElemIntListTest) {
518ed38f2eSKristof Umann ImmutableList<Wrapper<int>>::Factory f;
528ed38f2eSKristof Umann ImmutableList<Wrapper<int>> L = f.getEmptyList();
538ed38f2eSKristof Umann
548ed38f2eSKristof Umann ImmutableList<Wrapper<int>> L2 = f.add(3, L);
558ed38f2eSKristof Umann EXPECT_TRUE(L.isEmpty());
568ed38f2eSKristof Umann EXPECT_FALSE(L2.isEmpty());
578ed38f2eSKristof Umann EXPECT_TRUE(L2.getTail().isEmpty());
588ed38f2eSKristof Umann
598ed38f2eSKristof Umann EXPECT_FALSE(L == L2);
608ed38f2eSKristof Umann EXPECT_TRUE(L == L2.getTail());
618ed38f2eSKristof Umann EXPECT_FALSE(L.isEqual(L2));
628ed38f2eSKristof Umann EXPECT_TRUE(L.isEqual(L2.getTail()));
638ed38f2eSKristof Umann EXPECT_FALSE(L2.begin() == L2.end());
648ed38f2eSKristof Umann EXPECT_TRUE(L2.begin() != L2.end());
658ed38f2eSKristof Umann
668ed38f2eSKristof Umann EXPECT_FALSE(L.contains(3));
678ed38f2eSKristof Umann EXPECT_EQ(3, L2.getHead());
688ed38f2eSKristof Umann EXPECT_TRUE(L2.contains(3));
698ed38f2eSKristof Umann
708ed38f2eSKristof Umann ImmutableList<Wrapper<int>> L3 = f.add(2, L);
718ed38f2eSKristof Umann EXPECT_TRUE(L.isEmpty());
728ed38f2eSKristof Umann EXPECT_FALSE(L3.isEmpty());
738ed38f2eSKristof Umann EXPECT_FALSE(L == L3);
748ed38f2eSKristof Umann EXPECT_FALSE(L.contains(2));
758ed38f2eSKristof Umann EXPECT_TRUE(L3.contains(2));
768ed38f2eSKristof Umann EXPECT_EQ(2, L3.getHead());
778ed38f2eSKristof Umann
788ed38f2eSKristof Umann EXPECT_FALSE(L2 == L3);
798ed38f2eSKristof Umann EXPECT_FALSE(L2.contains(2));
808ed38f2eSKristof Umann }
818ed38f2eSKristof Umann
82c5f0f2f1SKristof Umann // We'll store references to objects of this type.
83c5f0f2f1SKristof Umann struct Unmodifiable {
84c5f0f2f1SKristof Umann Unmodifiable() = default;
85c5f0f2f1SKristof Umann
86c5f0f2f1SKristof Umann // We'll delete all of these special member functions to make sure no copy or
87c5f0f2f1SKristof Umann // move happens during insertation.
88c5f0f2f1SKristof Umann Unmodifiable(const Unmodifiable &) = delete;
89c5f0f2f1SKristof Umann Unmodifiable(const Unmodifiable &&) = delete;
90c5f0f2f1SKristof Umann Unmodifiable &operator=(const Unmodifiable &) = delete;
91c5f0f2f1SKristof Umann Unmodifiable &operator=(const Unmodifiable &&) = delete;
92c5f0f2f1SKristof Umann
doNothing__anon74673e430111::Unmodifiable93c5f0f2f1SKristof Umann void doNothing() const {}
94c5f0f2f1SKristof Umann
Profile__anon74673e430111::Unmodifiable95c5f0f2f1SKristof Umann void Profile(FoldingSetNodeID &ID) const { ID.AddPointer(this); }
96c5f0f2f1SKristof Umann };
97c5f0f2f1SKristof Umann
98c5f0f2f1SKristof Umann // Mostly just a check whether ImmutableList::iterator can be instantiated
99c5f0f2f1SKristof Umann // with a reference type as a template argument.
TEST_F(ImmutableListTest,ReferenceStoringTest)100c5f0f2f1SKristof Umann TEST_F(ImmutableListTest, ReferenceStoringTest) {
101c5f0f2f1SKristof Umann ImmutableList<const Unmodifiable &>::Factory f;
102c5f0f2f1SKristof Umann
103c5f0f2f1SKristof Umann Unmodifiable N;
104c5f0f2f1SKristof Umann ImmutableList<const Unmodifiable &> L = f.create(N);
105c5f0f2f1SKristof Umann for (ImmutableList<const Unmodifiable &>::iterator It = L.begin(),
106c5f0f2f1SKristof Umann E = L.end();
107c5f0f2f1SKristof Umann It != E; ++It) {
108c5f0f2f1SKristof Umann It->doNothing();
109c5f0f2f1SKristof Umann }
110c5f0f2f1SKristof Umann }
111c5f0f2f1SKristof Umann
TEST_F(ImmutableListTest,CreatingIntListTest)1128ed38f2eSKristof Umann TEST_F(ImmutableListTest, CreatingIntListTest) {
1138ed38f2eSKristof Umann ImmutableList<Wrapper<int>>::Factory f;
1148ed38f2eSKristof Umann
1158ed38f2eSKristof Umann ImmutableList<Wrapper<int>> L = f.getEmptyList();
1168ed38f2eSKristof Umann ImmutableList<Wrapper<int>> L2 = f.create(3);
1178ed38f2eSKristof Umann
1188ed38f2eSKristof Umann EXPECT_FALSE(L2.isEmpty());
1198ed38f2eSKristof Umann EXPECT_TRUE(L2.getTail().isEmpty());
1208ed38f2eSKristof Umann EXPECT_EQ(3, L2.getHead());
1218ed38f2eSKristof Umann EXPECT_TRUE(L.isEqual(L2.getTail()));
1228ed38f2eSKristof Umann EXPECT_TRUE(L2.getTail().isEqual(L));
1238ed38f2eSKristof Umann }
1248ed38f2eSKristof Umann
TEST_F(ImmutableListTest,MultiElemIntListTest)1258ed38f2eSKristof Umann TEST_F(ImmutableListTest, MultiElemIntListTest) {
1268ed38f2eSKristof Umann ImmutableList<Wrapper<int>>::Factory f;
1278ed38f2eSKristof Umann
1288ed38f2eSKristof Umann ImmutableList<Wrapper<int>> L = f.getEmptyList();
1298ed38f2eSKristof Umann ImmutableList<Wrapper<int>> L2 = f.add(5, f.add(4, f.add(3, L)));
1308ed38f2eSKristof Umann ImmutableList<Wrapper<int>> L3 = f.add(43, f.add(20, f.add(9, L2)));
1318ed38f2eSKristof Umann ImmutableList<Wrapper<int>> L4 = f.add(9, L2);
1328ed38f2eSKristof Umann ImmutableList<Wrapper<int>> L5 = f.add(9, L2);
1338ed38f2eSKristof Umann
1348ed38f2eSKristof Umann EXPECT_TRUE(L.isEmpty());
1358ed38f2eSKristof Umann EXPECT_FALSE(L2.isEmpty());
1368ed38f2eSKristof Umann EXPECT_FALSE(L3.isEmpty());
1378ed38f2eSKristof Umann EXPECT_FALSE(L4.isEmpty());
1388ed38f2eSKristof Umann
1398ed38f2eSKristof Umann EXPECT_FALSE(L.contains(3));
1408ed38f2eSKristof Umann EXPECT_FALSE(L.contains(9));
1418ed38f2eSKristof Umann
1428ed38f2eSKristof Umann EXPECT_TRUE(L2.contains(3));
1438ed38f2eSKristof Umann EXPECT_TRUE(L2.contains(4));
1448ed38f2eSKristof Umann EXPECT_TRUE(L2.contains(5));
1458ed38f2eSKristof Umann EXPECT_FALSE(L2.contains(9));
1468ed38f2eSKristof Umann EXPECT_FALSE(L2.contains(0));
1478ed38f2eSKristof Umann
1488ed38f2eSKristof Umann EXPECT_EQ(5, L2.getHead());
1498ed38f2eSKristof Umann EXPECT_EQ(4, L2.getTail().getHead());
1508ed38f2eSKristof Umann EXPECT_EQ(3, L2.getTail().getTail().getHead());
1518ed38f2eSKristof Umann
1528ed38f2eSKristof Umann EXPECT_TRUE(L3.contains(43));
1538ed38f2eSKristof Umann EXPECT_TRUE(L3.contains(20));
1548ed38f2eSKristof Umann EXPECT_TRUE(L3.contains(9));
1558ed38f2eSKristof Umann EXPECT_TRUE(L3.contains(3));
1568ed38f2eSKristof Umann EXPECT_TRUE(L3.contains(4));
1578ed38f2eSKristof Umann EXPECT_TRUE(L3.contains(5));
1588ed38f2eSKristof Umann EXPECT_FALSE(L3.contains(0));
1598ed38f2eSKristof Umann
1608ed38f2eSKristof Umann EXPECT_EQ(43, L3.getHead());
1618ed38f2eSKristof Umann EXPECT_EQ(20, L3.getTail().getHead());
1628ed38f2eSKristof Umann EXPECT_EQ(9, L3.getTail().getTail().getHead());
1638ed38f2eSKristof Umann
1648ed38f2eSKristof Umann EXPECT_TRUE(L3.getTail().getTail().getTail() == L2);
1658ed38f2eSKristof Umann EXPECT_TRUE(L2 == L3.getTail().getTail().getTail());
1668ed38f2eSKristof Umann EXPECT_TRUE(L3.getTail().getTail().getTail().isEqual(L2));
1678ed38f2eSKristof Umann EXPECT_TRUE(L2.isEqual(L3.getTail().getTail().getTail()));
1688ed38f2eSKristof Umann
1698ed38f2eSKristof Umann EXPECT_TRUE(L4.contains(9));
1708ed38f2eSKristof Umann EXPECT_TRUE(L4.contains(3));
1718ed38f2eSKristof Umann EXPECT_TRUE(L4.contains(4));
1728ed38f2eSKristof Umann EXPECT_TRUE(L4.contains(5));
1738ed38f2eSKristof Umann EXPECT_FALSE(L4.contains(20));
1748ed38f2eSKristof Umann EXPECT_FALSE(L4.contains(43));
1758ed38f2eSKristof Umann EXPECT_TRUE(L4.isEqual(L4));
1768ed38f2eSKristof Umann EXPECT_TRUE(L4.isEqual(L5));
1778ed38f2eSKristof Umann
1788ed38f2eSKristof Umann EXPECT_TRUE(L5.isEqual(L4));
1798ed38f2eSKristof Umann EXPECT_TRUE(L5.isEqual(L5));
1808ed38f2eSKristof Umann }
1818ed38f2eSKristof Umann
182d0202395SKristof Umann template <typename Fundamental>
183d0202395SKristof Umann struct ExplicitCtorWrapper : public Wrapper<Fundamental> {
ExplicitCtorWrapper__anon74673e430111::ExplicitCtorWrapper184d0202395SKristof Umann explicit ExplicitCtorWrapper(Fundamental F) : Wrapper<Fundamental>(F) {}
185d0202395SKristof Umann ExplicitCtorWrapper(const ExplicitCtorWrapper &) = delete;
186d0202395SKristof Umann ExplicitCtorWrapper(ExplicitCtorWrapper &&) = default;
187d0202395SKristof Umann ExplicitCtorWrapper &operator=(const ExplicitCtorWrapper &) = delete;
188d0202395SKristof Umann ExplicitCtorWrapper &operator=(ExplicitCtorWrapper &&) = default;
189d0202395SKristof Umann };
190d0202395SKristof Umann
TEST_F(ImmutableListTest,EmplaceIntListTest)191d0202395SKristof Umann TEST_F(ImmutableListTest, EmplaceIntListTest) {
192d0202395SKristof Umann ImmutableList<ExplicitCtorWrapper<int>>::Factory f;
193d0202395SKristof Umann
194d0202395SKristof Umann ImmutableList<ExplicitCtorWrapper<int>> L = f.getEmptyList();
195d0202395SKristof Umann ImmutableList<ExplicitCtorWrapper<int>> L2 = f.emplace(L, 3);
196d0202395SKristof Umann
197d0202395SKristof Umann ImmutableList<ExplicitCtorWrapper<int>> L3 =
198d0202395SKristof Umann f.add(ExplicitCtorWrapper<int>(2), L2);
199d0202395SKristof Umann
200d0202395SKristof Umann ImmutableList<ExplicitCtorWrapper<int>> L4 =
201d0202395SKristof Umann f.emplace(L3, ExplicitCtorWrapper<int>(1));
202d0202395SKristof Umann
203d0202395SKristof Umann ImmutableList<ExplicitCtorWrapper<int>> L5 =
204d0202395SKristof Umann f.add(ExplicitCtorWrapper<int>(1), L3);
205d0202395SKristof Umann
206d0202395SKristof Umann EXPECT_FALSE(L2.isEmpty());
207d0202395SKristof Umann EXPECT_TRUE(L2.getTail().isEmpty());
208d0202395SKristof Umann EXPECT_EQ(3, L2.getHead());
209d0202395SKristof Umann EXPECT_TRUE(L.isEqual(L2.getTail()));
210d0202395SKristof Umann EXPECT_TRUE(L2.getTail().isEqual(L));
211d0202395SKristof Umann
212d0202395SKristof Umann EXPECT_FALSE(L3.isEmpty());
213d0202395SKristof Umann EXPECT_FALSE(L2 == L3);
214d0202395SKristof Umann EXPECT_EQ(2, L3.getHead());
215d0202395SKristof Umann EXPECT_TRUE(L2 == L3.getTail());
216d0202395SKristof Umann
217d0202395SKristof Umann EXPECT_FALSE(L4.isEmpty());
218d0202395SKristof Umann EXPECT_EQ(1, L4.getHead());
219d0202395SKristof Umann EXPECT_TRUE(L3 == L4.getTail());
220d0202395SKristof Umann
221d0202395SKristof Umann EXPECT_TRUE(L4 == L5);
222d0202395SKristof Umann EXPECT_TRUE(L3 == L5.getTail());
223d0202395SKristof Umann }
224d0202395SKristof Umann
TEST_F(ImmutableListTest,CharListOrderingTest)2258ed38f2eSKristof Umann TEST_F(ImmutableListTest, CharListOrderingTest) {
2268ed38f2eSKristof Umann ImmutableList<Wrapper<char>>::Factory f;
2278ed38f2eSKristof Umann ImmutableList<Wrapper<char>> L = f.getEmptyList();
2288ed38f2eSKristof Umann
2298ed38f2eSKristof Umann ImmutableList<Wrapper<char>> L2 = f.add('i', f.add('e', f.add('a', L)));
2308ed38f2eSKristof Umann ImmutableList<Wrapper<char>> L3 = f.add('u', f.add('o', L2));
2318ed38f2eSKristof Umann
2328ed38f2eSKristof Umann char Buffer[10];
2338ed38f2eSKristof Umann concat(L3, Buffer);
2348ed38f2eSKristof Umann
2358ed38f2eSKristof Umann ASSERT_STREQ("uoiea", Buffer);
2368ed38f2eSKristof Umann }
2378ed38f2eSKristof Umann
TEST_F(ImmutableListTest,LongListOrderingTest)2388ed38f2eSKristof Umann TEST_F(ImmutableListTest, LongListOrderingTest) {
2398ed38f2eSKristof Umann ImmutableList<Wrapper<long>>::Factory f;
2408ed38f2eSKristof Umann ImmutableList<Wrapper<long>> L = f.getEmptyList();
2418ed38f2eSKristof Umann
2428ed38f2eSKristof Umann ImmutableList<Wrapper<long>> L2 = f.add(3, f.add(4, f.add(5, L)));
2438ed38f2eSKristof Umann ImmutableList<Wrapper<long>> L3 = f.add(0, f.add(1, f.add(2, L2)));
2448ed38f2eSKristof Umann
2458ed38f2eSKristof Umann int i = 0;
2468ed38f2eSKristof Umann for (ImmutableList<Wrapper<long>>::iterator I = L.begin(), E = L.end();
2478ed38f2eSKristof Umann I != E; ++I) {
2488ed38f2eSKristof Umann i++;
2498ed38f2eSKristof Umann }
2508ed38f2eSKristof Umann ASSERT_EQ(0, i);
2518ed38f2eSKristof Umann
2528ed38f2eSKristof Umann i = 3;
2538ed38f2eSKristof Umann for (ImmutableList<Wrapper<long>>::iterator I = L2.begin(), E = L2.end();
2548ed38f2eSKristof Umann I != E; ++I) {
2558ed38f2eSKristof Umann ASSERT_EQ(i, *I);
2568ed38f2eSKristof Umann i++;
2578ed38f2eSKristof Umann }
2588ed38f2eSKristof Umann ASSERT_EQ(6, i);
2598ed38f2eSKristof Umann
2608ed38f2eSKristof Umann i = 0;
2618ed38f2eSKristof Umann for (ImmutableList<Wrapper<long>>::iterator I = L3.begin(), E = L3.end();
2628ed38f2eSKristof Umann I != E; ++I) {
2638ed38f2eSKristof Umann ASSERT_EQ(i, *I);
2648ed38f2eSKristof Umann i++;
2658ed38f2eSKristof Umann }
2668ed38f2eSKristof Umann ASSERT_EQ(6, i);
2678ed38f2eSKristof Umann }
2688ed38f2eSKristof Umann
269*6aa050a6SNathan James static_assert(std::is_trivially_copyable_v<ImmutableList<Wrapper<long>>>,
270be88539bSSerge Guelton "trivially copyable");
271be88539bSSerge Guelton
2728ed38f2eSKristof Umann } // namespace
273