1 //===- unittests/ADT/SimpleIListTest.cpp - simple_ilist unit tests --------===//
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/simple_ilist.h"
10 #include "llvm/ADT/STLExtras.h"
11 #include "gtest/gtest.h"
17 struct Node
: ilist_node
<Node
> {};
18 bool operator<(const Node
&L
, const Node
&R
) { return &L
< &R
; }
19 bool makeFalse(const Node
&, const Node
&) { return false; }
21 struct deleteNode
: std::default_delete
<Node
> {};
22 void doNothing(Node
*) {}
24 TEST(SimpleIListTest
, DefaultConstructor
) {
26 EXPECT_EQ(L
.begin(), L
.end());
27 EXPECT_TRUE(L
.empty());
28 EXPECT_EQ(0u, L
.size());
31 TEST(SimpleIListTest
, pushPopFront
) {
36 EXPECT_EQ(&A
, &L
.front());
37 EXPECT_EQ(&B
, &L
.back());
38 EXPECT_FALSE(L
.empty());
39 EXPECT_EQ(2u, L
.size());
41 // Pop front and check the new front.
43 EXPECT_EQ(&B
, &L
.front());
47 EXPECT_TRUE(L
.empty());
50 TEST(SimpleIListTest
, pushPopBack
) {
55 EXPECT_EQ(&A
, &L
.front());
56 EXPECT_EQ(&B
, &L
.back());
57 EXPECT_FALSE(L
.empty());
58 EXPECT_EQ(2u, L
.size());
60 // Pop back and check the new front.
62 EXPECT_EQ(&A
, &L
.back());
66 EXPECT_TRUE(L
.empty());
69 TEST(SimpleIListTest
, swap
) {
70 simple_ilist
<Node
> L1
, L2
;
75 EXPECT_TRUE(L1
.empty());
76 EXPECT_EQ(0u, L1
.size());
77 EXPECT_EQ(&A
, &L2
.front());
78 EXPECT_EQ(&B
, &L2
.back());
79 EXPECT_FALSE(L2
.empty());
80 EXPECT_EQ(2u, L2
.size());
83 TEST(SimpleIListTest
, insertEraseAtEnd
) {
88 EXPECT_EQ(&A
, &L
.front());
89 EXPECT_EQ(&B
, &L
.back());
90 EXPECT_FALSE(L
.empty());
91 EXPECT_EQ(2u, L
.size());
94 TEST(SimpleIListTest
, insertAtBegin
) {
97 L
.insert(L
.begin(), B
);
98 L
.insert(L
.begin(), A
);
99 EXPECT_EQ(&A
, &L
.front());
100 EXPECT_EQ(&B
, &L
.back());
101 EXPECT_FALSE(L
.empty());
102 EXPECT_EQ(2u, L
.size());
105 TEST(SimpleIListTest
, remove
) {
106 simple_ilist
<Node
> L
;
111 EXPECT_EQ(&A
, &L
.front());
112 EXPECT_EQ(&B
, &*++L
.begin());
113 EXPECT_EQ(&C
, &L
.back());
114 EXPECT_EQ(3u, L
.size());
117 EXPECT_EQ(&A
, &L
.front());
118 EXPECT_EQ(&C
, &L
.back());
119 EXPECT_EQ(2u, L
.size());
122 EXPECT_EQ(&C
, &L
.front());
123 EXPECT_EQ(1u, L
.size());
126 EXPECT_TRUE(L
.empty());
129 TEST(SimpleIListTest
, removeAndDispose
) {
130 simple_ilist
<Node
> L
;
136 EXPECT_EQ(&A
, &L
.front());
137 EXPECT_EQ(B
, &*++L
.begin());
138 EXPECT_EQ(&C
, &L
.back());
139 EXPECT_EQ(3u, L
.size());
141 L
.removeAndDispose(*B
, deleteNode());
142 EXPECT_EQ(&A
, &L
.front());
143 EXPECT_EQ(&C
, &L
.back());
144 EXPECT_EQ(2u, L
.size());
147 TEST(SimpleIListTest
, removeAndDisposeNullDeleter
) {
148 simple_ilist
<Node
> L
;
153 EXPECT_EQ(&A
, &L
.front());
154 EXPECT_EQ(&B
, &*++L
.begin());
155 EXPECT_EQ(&C
, &L
.back());
156 EXPECT_EQ(3u, L
.size());
158 L
.removeAndDispose(B
, doNothing
);
159 EXPECT_EQ(&A
, &L
.front());
160 EXPECT_EQ(&C
, &L
.back());
161 EXPECT_EQ(2u, L
.size());
164 TEST(SimpleIListTest
, erase
) {
165 simple_ilist
<Node
> L
;
170 EXPECT_EQ(&A
, &L
.front());
171 EXPECT_EQ(&B
, &*++L
.begin());
172 EXPECT_EQ(&C
, &L
.back());
173 EXPECT_EQ(3u, L
.size());
175 EXPECT_EQ(C
.getIterator(), L
.erase(B
.getIterator()));
176 EXPECT_EQ(&A
, &L
.front());
177 EXPECT_EQ(&C
, &L
.back());
178 EXPECT_EQ(2u, L
.size());
181 TEST(SimpleIListTest
, reverse_iterator
) {
182 simple_ilist
<Node
> L
;
188 auto ReverseIter
= L
.rbegin();
189 EXPECT_EQ(C
.getReverseIterator(), ReverseIter
);
191 EXPECT_EQ(B
.getReverseIterator(), ReverseIter
);
193 EXPECT_EQ(A
.getReverseIterator(), ReverseIter
);
195 EXPECT_EQ(L
.rend(), ReverseIter
);
198 TEST(SimpleIListTest
, eraseAndDispose
) {
199 simple_ilist
<Node
> L
;
205 EXPECT_EQ(&A
, &L
.front());
206 EXPECT_EQ(B
, &*++L
.begin());
207 EXPECT_EQ(&C
, &L
.back());
208 EXPECT_EQ(3u, L
.size());
210 L
.eraseAndDispose(B
->getIterator(), deleteNode());
211 EXPECT_EQ(&A
, &L
.front());
212 EXPECT_EQ(&C
, &L
.back());
213 EXPECT_EQ(2u, L
.size());
216 TEST(SimpleIListTest
, eraseAndDisposeNullDeleter
) {
217 simple_ilist
<Node
> L
;
222 EXPECT_EQ(&A
, &L
.front());
223 EXPECT_EQ(&B
, &*++L
.begin());
224 EXPECT_EQ(&C
, &L
.back());
225 EXPECT_EQ(3u, L
.size());
227 L
.eraseAndDispose(B
.getIterator(), doNothing
);
228 EXPECT_EQ(&A
, &L
.front());
229 EXPECT_EQ(&C
, &L
.back());
230 EXPECT_EQ(2u, L
.size());
233 TEST(SimpleIListTest
, eraseRange
) {
234 simple_ilist
<Node
> L
;
242 EXPECT_EQ(&A
, &*I
++);
243 EXPECT_EQ(&B
, &*I
++);
244 EXPECT_EQ(&C
, &*I
++);
245 EXPECT_EQ(&D
, &*I
++);
246 EXPECT_EQ(&E
, &*I
++);
247 EXPECT_EQ(L
.end(), I
);
248 EXPECT_EQ(5u, L
.size());
251 EXPECT_EQ(E
.getIterator(), L
.erase(B
.getIterator(), E
.getIterator()));
252 EXPECT_EQ(&A
, &L
.front());
253 EXPECT_EQ(&E
, &L
.back());
254 EXPECT_EQ(2u, L
.size());
257 TEST(SimpleIListTest
, eraseAndDisposeRange
) {
258 simple_ilist
<Node
> L
;
259 Node A
, *B
= new Node
, *C
= new Node
, *D
= new Node
, E
;
266 EXPECT_EQ(&A
, &*I
++);
270 EXPECT_EQ(&E
, &*I
++);
271 EXPECT_EQ(L
.end(), I
);
272 EXPECT_EQ(5u, L
.size());
275 EXPECT_EQ(E
.getIterator(),
276 L
.eraseAndDispose(B
->getIterator(), E
.getIterator(), deleteNode()));
277 EXPECT_EQ(&A
, &L
.front());
278 EXPECT_EQ(&E
, &L
.back());
279 EXPECT_EQ(2u, L
.size());
282 TEST(SimpleIListTest
, eraseAndDisposeRangeNullDeleter
) {
283 simple_ilist
<Node
> L
;
291 EXPECT_EQ(&A
, &*I
++);
292 EXPECT_EQ(&B
, &*I
++);
293 EXPECT_EQ(&C
, &*I
++);
294 EXPECT_EQ(&D
, &*I
++);
295 EXPECT_EQ(&E
, &*I
++);
296 EXPECT_EQ(L
.end(), I
);
297 EXPECT_EQ(5u, L
.size());
300 EXPECT_EQ(E
.getIterator(),
301 L
.eraseAndDispose(B
.getIterator(), E
.getIterator(), doNothing
));
302 EXPECT_EQ(&A
, &L
.front());
303 EXPECT_EQ(&E
, &L
.back());
304 EXPECT_EQ(2u, L
.size());
307 TEST(SimpleIListTest
, clear
) {
308 simple_ilist
<Node
> L
;
313 EXPECT_TRUE(L
.empty());
314 EXPECT_EQ(0u, L
.size());
317 TEST(SimpleIListTest
, clearAndDispose
) {
318 simple_ilist
<Node
> L
;
323 L
.clearAndDispose(deleteNode());
324 EXPECT_TRUE(L
.empty());
325 EXPECT_EQ(0u, L
.size());
328 TEST(SimpleIListTest
, clearAndDisposeNullDeleter
) {
329 simple_ilist
<Node
> L
;
333 L
.clearAndDispose(doNothing
);
334 EXPECT_TRUE(L
.empty());
335 EXPECT_EQ(0u, L
.size());
338 TEST(SimpleIListTest
, spliceList
) {
339 simple_ilist
<Node
> L1
, L2
;
350 // Splice in L2, giving [A, B, C, D].
351 L1
.splice(--L1
.end(), L2
);
352 EXPECT_TRUE(L2
.empty());
353 EXPECT_EQ(4u, L1
.size());
355 EXPECT_EQ(&A
, &*I
++);
356 EXPECT_EQ(&B
, &*I
++);
357 EXPECT_EQ(&C
, &*I
++);
358 EXPECT_EQ(&D
, &*I
++);
359 EXPECT_EQ(L1
.end(), I
);
362 TEST(SimpleIListTest
, spliceSingle
) {
363 simple_ilist
<Node
> L1
, L2
;
375 // Splice B from L2 to L1, giving [A, B, C] and [D, E].
376 L1
.splice(--L1
.end(), L2
, ++L2
.begin());
378 EXPECT_EQ(&A
, &*I
++);
379 EXPECT_EQ(&B
, &*I
++);
380 EXPECT_EQ(&C
, &*I
++);
381 EXPECT_EQ(L1
.end(), I
);
384 EXPECT_EQ(&D
, &*I
++);
385 EXPECT_EQ(&E
, &*I
++);
386 EXPECT_EQ(L2
.end(), I
);
389 TEST(SimpleIListTest
, spliceRange
) {
390 simple_ilist
<Node
> L1
, L2
;
391 Node A
, B
, C
, D
, E
, F
;
403 // Splice B from L2 to L1, giving [A, B, C, D] and [E, F].
404 L1
.splice(--L1
.end(), L2
, ++L2
.begin(), --L2
.end());
406 EXPECT_EQ(&A
, &*I
++);
407 EXPECT_EQ(&B
, &*I
++);
408 EXPECT_EQ(&C
, &*I
++);
409 EXPECT_EQ(&D
, &*I
++);
410 EXPECT_EQ(L1
.end(), I
);
413 EXPECT_EQ(&E
, &*I
++);
414 EXPECT_EQ(&F
, &*I
++);
415 EXPECT_EQ(L2
.end(), I
);
418 TEST(SimpleIListTest
, merge
) {
419 for (bool IsL1LHS
: {false, true}) {
420 simple_ilist
<Node
> L1
, L2
;
438 EXPECT_EQ(4u, L1
.size());
439 EXPECT_EQ(6u, L2
.size());
440 EXPECT_TRUE(llvm::is_sorted(L1
));
441 EXPECT_TRUE(llvm::is_sorted(L2
));
444 auto &LHS
= IsL1LHS
? L1
: L2
;
445 auto &RHS
= IsL1LHS
? L2
: L1
;
447 EXPECT_TRUE(RHS
.empty());
448 EXPECT_FALSE(LHS
.empty());
449 EXPECT_TRUE(llvm::is_sorted(LHS
));
450 auto I
= LHS
.begin();
452 EXPECT_EQ(&N
, &*I
++);
453 EXPECT_EQ(LHS
.end(), I
);
457 TEST(SimpleIListTest
, mergeIsStable
) {
458 simple_ilist
<Node
> L1
, L2
;
462 EXPECT_TRUE(L1
.empty());
463 EXPECT_TRUE(L2
.empty());
475 EXPECT_EQ(3u, L1
.size());
476 EXPECT_EQ(2u, L2
.size());
477 EXPECT_TRUE(llvm::is_sorted(L1
, makeFalse
));
478 EXPECT_TRUE(llvm::is_sorted(L2
, makeFalse
));
481 // Merge. Should be stable.
483 L1
.merge(L2
, makeFalse
);
484 EXPECT_TRUE(L2
.empty());
485 EXPECT_FALSE(L1
.empty());
486 EXPECT_TRUE(llvm::is_sorted(L1
, makeFalse
));
488 EXPECT_EQ(&Ns
[0], &*I
++);
489 EXPECT_EQ(&Ns
[3], &*I
++);
490 EXPECT_EQ(&Ns
[4], &*I
++);
491 EXPECT_EQ(&Ns
[1], &*I
++);
492 EXPECT_EQ(&Ns
[2], &*I
++);
493 EXPECT_EQ(L1
.end(), I
);
495 // Merge the other way. Should be stable.
498 L2
.merge(L1
, makeFalse
);
499 EXPECT_TRUE(L1
.empty());
500 EXPECT_FALSE(L2
.empty());
501 EXPECT_TRUE(llvm::is_sorted(L2
, makeFalse
));
503 EXPECT_EQ(&Ns
[1], &*I
++);
504 EXPECT_EQ(&Ns
[2], &*I
++);
505 EXPECT_EQ(&Ns
[0], &*I
++);
506 EXPECT_EQ(&Ns
[3], &*I
++);
507 EXPECT_EQ(&Ns
[4], &*I
++);
508 EXPECT_EQ(L2
.end(), I
);
511 TEST(SimpleIListTest
, mergeEmpty
) {
512 for (bool IsL1LHS
: {false, true}) {
513 simple_ilist
<Node
> L1
, L2
;
523 EXPECT_EQ(4u, L1
.size());
524 EXPECT_TRUE(L2
.empty());
525 EXPECT_TRUE(llvm::is_sorted(L1
));
528 auto &LHS
= IsL1LHS
? L1
: L2
;
529 auto &RHS
= IsL1LHS
? L2
: L1
;
531 EXPECT_TRUE(RHS
.empty());
532 EXPECT_FALSE(LHS
.empty());
533 EXPECT_TRUE(llvm::is_sorted(LHS
));
534 auto I
= LHS
.begin();
536 EXPECT_EQ(&N
, &*I
++);
537 EXPECT_EQ(LHS
.end(), I
);
541 TEST(SimpleIListTest
, mergeBothEmpty
) {
542 simple_ilist
<Node
> L1
, L2
;
544 EXPECT_TRUE(L1
.empty());
545 EXPECT_TRUE(L2
.empty());
548 TEST(SimpleIListTest
, sort
) {
549 simple_ilist
<Node
> L
;
553 for (int I
: {3, 4, 0, 8, 1, 2, 6, 7, 9, 5})
557 EXPECT_EQ(10u, L
.size());
558 EXPECT_FALSE(llvm::is_sorted(L
));
562 EXPECT_TRUE(llvm::is_sorted(L
));
565 EXPECT_EQ(&N
, &*I
++);
566 EXPECT_EQ(L
.end(), I
);
569 TEST(SimpleIListTest
, sortIsStable
) {
570 simple_ilist
<Node
> L
;
573 // Compare such that nodes are partitioned but not fully sorted.
574 auto partition
= [&](const Node
&N
) { return &N
>= &Ns
[5]; };
575 auto compare
= [&](const Node
&L
, const Node
&R
) {
576 return partition(L
) < partition(R
);
580 for (int I
: {3, 4, 7, 8, 1, 2, 6, 0, 9, 5})
584 EXPECT_EQ(10u, L
.size());
585 EXPECT_FALSE(llvm::is_sorted(L
, compare
));
589 EXPECT_TRUE(llvm::is_sorted(L
, compare
));
591 for (int O
: {3, 4, 1, 2, 0})
592 EXPECT_EQ(&Ns
[O
], &*I
++);
593 for (int O
: {7, 8, 6, 9, 5})
594 EXPECT_EQ(&Ns
[O
], &*I
++);
595 EXPECT_EQ(L
.end(), I
);
598 TEST(SimpleIListTest
, sortEmpty
) {
599 simple_ilist
<Node
> L
;
606 struct DoubleNode
: ilist_node
<DoubleNode
, ilist_tag
<Tag1
>>,
607 ilist_node
<DoubleNode
, ilist_tag
<Tag2
>> {
608 typedef ilist_node
<DoubleNode
, ilist_tag
<Tag1
>> Node1Type
;
609 typedef ilist_node
<DoubleNode
, ilist_tag
<Tag2
>> Node2Type
;
611 Node1Type::self_iterator
getIterator1() { return Node1Type::getIterator(); }
612 Node2Type::self_iterator
getIterator2() { return Node2Type::getIterator(); }
613 Node1Type::const_self_iterator
getIterator1() const {
614 return Node1Type::getIterator();
616 Node2Type::const_self_iterator
getIterator2() const {
617 return Node2Type::getIterator();
620 typedef simple_ilist
<DoubleNode
, ilist_tag
<Tag1
>> TaggedList1Type
;
621 typedef simple_ilist
<DoubleNode
, ilist_tag
<Tag2
>> TaggedList2Type
;
623 TEST(SimpleIListTest
, TaggedLists
) {
627 // Build the two lists, sharing a couple of nodes.
629 int Order1
[] = {0, 1, 2, 3, 4, 7, 9};
630 int Order2
[] = {2, 5, 6, 7, 8, 4, 9, 1};
636 // Check that each list is correct.
637 EXPECT_EQ(std::size(Order1
), L1
.size());
638 auto I1
= L1
.begin();
639 for (int I
: Order1
) {
640 EXPECT_EQ(Ns
[I
].getIterator1(), I1
);
641 EXPECT_EQ(&Ns
[I
], &*I1
++);
643 EXPECT_EQ(L1
.end(), I1
);
645 EXPECT_EQ(std::size(Order2
), L2
.size());
646 auto I2
= L2
.begin();
647 for (int I
: Order2
) {
648 EXPECT_EQ(Ns
[I
].getIterator2(), I2
);
649 EXPECT_EQ(&Ns
[I
], &*I2
++);
651 EXPECT_EQ(L2
.end(), I2
);