1 //===--------- ImmutableListTest.cpp - ImmutableList unit tests --*- C++ -*-==//
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-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/ADT/ImmutableList.h"
10 #include "gtest/gtest.h"
16 template <typename Fundamental
> struct Wrapper
: llvm::FoldingSetNode
{
19 Wrapper(Fundamental F
) : F(F
) {}
21 operator Fundamental() const { return F
; }
23 void Profile(FoldingSetNodeID
&ID
) const { ID
.AddInteger(F
); }
26 class ImmutableListTest
: public testing::Test
{};
28 void concat(const ImmutableList
<Wrapper
<char>> &L
, char *Buffer
) {
30 for (ImmutableList
<Wrapper
<char>>::iterator It
= L
.begin(), End
= L
.end();
32 Buffer
[Index
++] = *It
;
37 TEST_F(ImmutableListTest
, EmptyIntListTest
) {
38 ImmutableList
<Wrapper
<int>>::Factory f
;
40 EXPECT_TRUE(f
.getEmptyList() == f
.getEmptyList());
41 EXPECT_TRUE(f
.getEmptyList().isEqual(f
.getEmptyList()));
42 EXPECT_TRUE(f
.getEmptyList().isEmpty());
44 ImmutableList
<Wrapper
<int>> L
= f
.getEmptyList();
45 EXPECT_EQ(nullptr, L
.getTail().getInternalPointer());
46 EXPECT_TRUE(L
.getTail().isEmpty());
47 EXPECT_TRUE(L
.begin() == L
.end());
50 TEST_F(ImmutableListTest
, OneElemIntListTest
) {
51 ImmutableList
<Wrapper
<int>>::Factory f
;
52 ImmutableList
<Wrapper
<int>> L
= f
.getEmptyList();
54 ImmutableList
<Wrapper
<int>> L2
= f
.add(3, L
);
55 EXPECT_TRUE(L
.isEmpty());
56 EXPECT_FALSE(L2
.isEmpty());
57 EXPECT_TRUE(L2
.getTail().isEmpty());
59 EXPECT_FALSE(L
== L2
);
60 EXPECT_TRUE(L
== L2
.getTail());
61 EXPECT_FALSE(L
.isEqual(L2
));
62 EXPECT_TRUE(L
.isEqual(L2
.getTail()));
63 EXPECT_FALSE(L2
.begin() == L2
.end());
64 EXPECT_TRUE(L2
.begin() != L2
.end());
66 EXPECT_FALSE(L
.contains(3));
67 EXPECT_EQ(3, L2
.getHead());
68 EXPECT_TRUE(L2
.contains(3));
70 ImmutableList
<Wrapper
<int>> L3
= f
.add(2, L
);
71 EXPECT_TRUE(L
.isEmpty());
72 EXPECT_FALSE(L3
.isEmpty());
73 EXPECT_FALSE(L
== L3
);
74 EXPECT_FALSE(L
.contains(2));
75 EXPECT_TRUE(L3
.contains(2));
76 EXPECT_EQ(2, L3
.getHead());
78 EXPECT_FALSE(L2
== L3
);
79 EXPECT_FALSE(L2
.contains(2));
82 // We'll store references to objects of this type.
84 Unmodifiable() = default;
86 // We'll delete all of these special member functions to make sure no copy or
87 // move happens during insertation.
88 Unmodifiable(const Unmodifiable
&) = delete;
89 Unmodifiable(const Unmodifiable
&&) = delete;
90 Unmodifiable
&operator=(const Unmodifiable
&) = delete;
91 Unmodifiable
&operator=(const Unmodifiable
&&) = delete;
93 void doNothing() const {}
95 void Profile(FoldingSetNodeID
&ID
) const { ID
.AddPointer(this); }
98 // Mostly just a check whether ImmutableList::iterator can be instantiated
99 // with a reference type as a template argument.
100 TEST_F(ImmutableListTest
, ReferenceStoringTest
) {
101 ImmutableList
<const Unmodifiable
&>::Factory f
;
104 ImmutableList
<const Unmodifiable
&> L
= f
.create(N
);
105 for (ImmutableList
<const Unmodifiable
&>::iterator It
= L
.begin(),
112 TEST_F(ImmutableListTest
, CreatingIntListTest
) {
113 ImmutableList
<Wrapper
<int>>::Factory f
;
115 ImmutableList
<Wrapper
<int>> L
= f
.getEmptyList();
116 ImmutableList
<Wrapper
<int>> L2
= f
.create(3);
118 EXPECT_FALSE(L2
.isEmpty());
119 EXPECT_TRUE(L2
.getTail().isEmpty());
120 EXPECT_EQ(3, L2
.getHead());
121 EXPECT_TRUE(L
.isEqual(L2
.getTail()));
122 EXPECT_TRUE(L2
.getTail().isEqual(L
));
125 TEST_F(ImmutableListTest
, MultiElemIntListTest
) {
126 ImmutableList
<Wrapper
<int>>::Factory f
;
128 ImmutableList
<Wrapper
<int>> L
= f
.getEmptyList();
129 ImmutableList
<Wrapper
<int>> L2
= f
.add(5, f
.add(4, f
.add(3, L
)));
130 ImmutableList
<Wrapper
<int>> L3
= f
.add(43, f
.add(20, f
.add(9, L2
)));
131 ImmutableList
<Wrapper
<int>> L4
= f
.add(9, L2
);
132 ImmutableList
<Wrapper
<int>> L5
= f
.add(9, L2
);
134 EXPECT_TRUE(L
.isEmpty());
135 EXPECT_FALSE(L2
.isEmpty());
136 EXPECT_FALSE(L3
.isEmpty());
137 EXPECT_FALSE(L4
.isEmpty());
139 EXPECT_FALSE(L
.contains(3));
140 EXPECT_FALSE(L
.contains(9));
142 EXPECT_TRUE(L2
.contains(3));
143 EXPECT_TRUE(L2
.contains(4));
144 EXPECT_TRUE(L2
.contains(5));
145 EXPECT_FALSE(L2
.contains(9));
146 EXPECT_FALSE(L2
.contains(0));
148 EXPECT_EQ(5, L2
.getHead());
149 EXPECT_EQ(4, L2
.getTail().getHead());
150 EXPECT_EQ(3, L2
.getTail().getTail().getHead());
152 EXPECT_TRUE(L3
.contains(43));
153 EXPECT_TRUE(L3
.contains(20));
154 EXPECT_TRUE(L3
.contains(9));
155 EXPECT_TRUE(L3
.contains(3));
156 EXPECT_TRUE(L3
.contains(4));
157 EXPECT_TRUE(L3
.contains(5));
158 EXPECT_FALSE(L3
.contains(0));
160 EXPECT_EQ(43, L3
.getHead());
161 EXPECT_EQ(20, L3
.getTail().getHead());
162 EXPECT_EQ(9, L3
.getTail().getTail().getHead());
164 EXPECT_TRUE(L3
.getTail().getTail().getTail() == L2
);
165 EXPECT_TRUE(L2
== L3
.getTail().getTail().getTail());
166 EXPECT_TRUE(L3
.getTail().getTail().getTail().isEqual(L2
));
167 EXPECT_TRUE(L2
.isEqual(L3
.getTail().getTail().getTail()));
169 EXPECT_TRUE(L4
.contains(9));
170 EXPECT_TRUE(L4
.contains(3));
171 EXPECT_TRUE(L4
.contains(4));
172 EXPECT_TRUE(L4
.contains(5));
173 EXPECT_FALSE(L4
.contains(20));
174 EXPECT_FALSE(L4
.contains(43));
175 EXPECT_TRUE(L4
.isEqual(L4
));
176 EXPECT_TRUE(L4
.isEqual(L5
));
178 EXPECT_TRUE(L5
.isEqual(L4
));
179 EXPECT_TRUE(L5
.isEqual(L5
));
182 template <typename Fundamental
>
183 struct ExplicitCtorWrapper
: public Wrapper
<Fundamental
> {
184 explicit ExplicitCtorWrapper(Fundamental F
) : Wrapper
<Fundamental
>(F
) {}
185 ExplicitCtorWrapper(const ExplicitCtorWrapper
&) = delete;
186 ExplicitCtorWrapper(ExplicitCtorWrapper
&&) = default;
187 ExplicitCtorWrapper
&operator=(const ExplicitCtorWrapper
&) = delete;
188 ExplicitCtorWrapper
&operator=(ExplicitCtorWrapper
&&) = default;
191 TEST_F(ImmutableListTest
, EmplaceIntListTest
) {
192 ImmutableList
<ExplicitCtorWrapper
<int>>::Factory f
;
194 ImmutableList
<ExplicitCtorWrapper
<int>> L
= f
.getEmptyList();
195 ImmutableList
<ExplicitCtorWrapper
<int>> L2
= f
.emplace(L
, 3);
197 ImmutableList
<ExplicitCtorWrapper
<int>> L3
=
198 f
.add(ExplicitCtorWrapper
<int>(2), L2
);
200 ImmutableList
<ExplicitCtorWrapper
<int>> L4
=
201 f
.emplace(L3
, ExplicitCtorWrapper
<int>(1));
203 ImmutableList
<ExplicitCtorWrapper
<int>> L5
=
204 f
.add(ExplicitCtorWrapper
<int>(1), L3
);
206 EXPECT_FALSE(L2
.isEmpty());
207 EXPECT_TRUE(L2
.getTail().isEmpty());
208 EXPECT_EQ(3, L2
.getHead());
209 EXPECT_TRUE(L
.isEqual(L2
.getTail()));
210 EXPECT_TRUE(L2
.getTail().isEqual(L
));
212 EXPECT_FALSE(L3
.isEmpty());
213 EXPECT_FALSE(L2
== L3
);
214 EXPECT_EQ(2, L3
.getHead());
215 EXPECT_TRUE(L2
== L3
.getTail());
217 EXPECT_FALSE(L4
.isEmpty());
218 EXPECT_EQ(1, L4
.getHead());
219 EXPECT_TRUE(L3
== L4
.getTail());
221 EXPECT_TRUE(L4
== L5
);
222 EXPECT_TRUE(L3
== L5
.getTail());
225 TEST_F(ImmutableListTest
, CharListOrderingTest
) {
226 ImmutableList
<Wrapper
<char>>::Factory f
;
227 ImmutableList
<Wrapper
<char>> L
= f
.getEmptyList();
229 ImmutableList
<Wrapper
<char>> L2
= f
.add('i', f
.add('e', f
.add('a', L
)));
230 ImmutableList
<Wrapper
<char>> L3
= f
.add('u', f
.add('o', L2
));
235 ASSERT_STREQ("uoiea", Buffer
);
238 TEST_F(ImmutableListTest
, LongListOrderingTest
) {
239 ImmutableList
<Wrapper
<long>>::Factory f
;
240 ImmutableList
<Wrapper
<long>> L
= f
.getEmptyList();
242 ImmutableList
<Wrapper
<long>> L2
= f
.add(3, f
.add(4, f
.add(5, L
)));
243 ImmutableList
<Wrapper
<long>> L3
= f
.add(0, f
.add(1, f
.add(2, L2
)));
246 for (ImmutableList
<Wrapper
<long>>::iterator I
= L
.begin(), E
= L
.end();
254 for (ImmutableList
<Wrapper
<long>>::iterator I
= L2
.begin(), E
= L2
.end();
262 for (ImmutableList
<Wrapper
<long>>::iterator I
= L3
.begin(), E
= L3
.end();
270 static_assert(is_trivially_copyable
<ImmutableList
<Wrapper
<long>>>::value
,
271 "trivially copyable");