1 | //===- unittests/ADT/IListIteratorTest.cpp - ilist_iterator 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-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "llvm/ADT/simple_ilist.h" |
10 | #include "gtest/gtest.h" |
11 | |
12 | using namespace llvm; |
13 | |
14 | namespace { |
15 | |
16 | struct Node : ilist_node<Node> {}; |
17 | |
18 | TEST(IListIteratorTest, DefaultConstructor) { |
19 | simple_ilist<Node>::iterator I; |
20 | simple_ilist<Node>::reverse_iterator RI; |
21 | simple_ilist<Node>::const_iterator CI; |
22 | simple_ilist<Node>::const_reverse_iterator CRI; |
23 | EXPECT_EQ(nullptr, I.getNodePtr()); |
24 | EXPECT_EQ(nullptr, CI.getNodePtr()); |
25 | EXPECT_EQ(nullptr, RI.getNodePtr()); |
26 | EXPECT_EQ(nullptr, CRI.getNodePtr()); |
27 | EXPECT_EQ(I, I); |
28 | EXPECT_EQ(I, CI); |
29 | EXPECT_EQ(CI, I); |
30 | EXPECT_EQ(CI, CI); |
31 | EXPECT_EQ(RI, RI); |
32 | EXPECT_EQ(RI, CRI); |
33 | EXPECT_EQ(CRI, RI); |
34 | EXPECT_EQ(CRI, CRI); |
35 | EXPECT_EQ(I, RI.getReverse()); |
36 | EXPECT_EQ(RI, I.getReverse()); |
37 | } |
38 | |
39 | TEST(IListIteratorTest, Empty) { |
40 | simple_ilist<Node> L; |
41 | |
42 | // Check iterators of L. |
43 | EXPECT_EQ(L.begin(), L.end()); |
44 | EXPECT_EQ(L.rbegin(), L.rend()); |
45 | |
46 | // Reverse of end should be rend (since the sentinel sits on both sides). |
47 | EXPECT_EQ(L.end(), L.rend().getReverse()); |
48 | EXPECT_EQ(L.rend(), L.end().getReverse()); |
49 | |
50 | // Iterators shouldn't match default constructors. |
51 | simple_ilist<Node>::iterator I; |
52 | simple_ilist<Node>::reverse_iterator RI; |
53 | EXPECT_NE(I, L.begin()); |
54 | EXPECT_NE(I, L.end()); |
55 | EXPECT_NE(RI, L.rbegin()); |
56 | EXPECT_NE(RI, L.rend()); |
57 | } |
58 | |
59 | TEST(IListIteratorTest, OneNodeList) { |
60 | simple_ilist<Node> L; |
61 | Node A; |
62 | L.insert(I: L.end(), Node&: A); |
63 | |
64 | // Check address of reference. |
65 | EXPECT_EQ(&A, &*L.begin()); |
66 | EXPECT_EQ(&A, &*L.rbegin()); |
67 | |
68 | // Check that the handle matches. |
69 | EXPECT_EQ(L.rbegin().getNodePtr(), L.begin().getNodePtr()); |
70 | |
71 | // Check iteration. |
72 | EXPECT_EQ(L.end(), ++L.begin()); |
73 | EXPECT_EQ(L.begin(), --L.end()); |
74 | EXPECT_EQ(L.rend(), ++L.rbegin()); |
75 | EXPECT_EQ(L.rbegin(), --L.rend()); |
76 | |
77 | // Check conversions. |
78 | EXPECT_EQ(L.rbegin(), L.begin().getReverse()); |
79 | EXPECT_EQ(L.begin(), L.rbegin().getReverse()); |
80 | } |
81 | |
82 | TEST(IListIteratorTest, TwoNodeList) { |
83 | simple_ilist<Node> L; |
84 | Node A, B; |
85 | L.insert(I: L.end(), Node&: A); |
86 | L.insert(I: L.end(), Node&: B); |
87 | |
88 | // Check order. |
89 | EXPECT_EQ(&A, &*L.begin()); |
90 | EXPECT_EQ(&B, &*++L.begin()); |
91 | EXPECT_EQ(L.end(), ++++L.begin()); |
92 | EXPECT_EQ(&B, &*L.rbegin()); |
93 | EXPECT_EQ(&A, &*++L.rbegin()); |
94 | EXPECT_EQ(L.rend(), ++++L.rbegin()); |
95 | |
96 | // Check conversions. |
97 | EXPECT_EQ(++L.rbegin(), L.begin().getReverse()); |
98 | EXPECT_EQ(L.rbegin(), (++L.begin()).getReverse()); |
99 | EXPECT_EQ(++L.begin(), L.rbegin().getReverse()); |
100 | EXPECT_EQ(L.begin(), (++L.rbegin()).getReverse()); |
101 | } |
102 | |
103 | TEST(IListIteratorTest, CheckEraseForward) { |
104 | simple_ilist<Node> L; |
105 | Node A, B; |
106 | L.insert(I: L.end(), Node&: A); |
107 | L.insert(I: L.end(), Node&: B); |
108 | |
109 | // Erase nodes. |
110 | auto I = L.begin(); |
111 | EXPECT_EQ(&A, &*I); |
112 | L.remove(N&: *I++); |
113 | EXPECT_EQ(&B, &*I); |
114 | L.remove(N&: *I++); |
115 | EXPECT_EQ(L.end(), I); |
116 | } |
117 | |
118 | TEST(IListIteratorTest, CheckEraseReverse) { |
119 | simple_ilist<Node> L; |
120 | Node A, B; |
121 | L.insert(I: L.end(), Node&: A); |
122 | L.insert(I: L.end(), Node&: B); |
123 | |
124 | // Erase nodes. |
125 | auto RI = L.rbegin(); |
126 | EXPECT_EQ(&B, &*RI); |
127 | L.remove(N&: *RI++); |
128 | EXPECT_EQ(&A, &*RI); |
129 | L.remove(N&: *RI++); |
130 | EXPECT_EQ(L.rend(), RI); |
131 | } |
132 | |
133 | TEST(IListIteratorTest, ReverseConstructor) { |
134 | simple_ilist<Node> L; |
135 | const simple_ilist<Node> &CL = L; |
136 | Node A, B; |
137 | L.insert(I: L.end(), Node&: A); |
138 | L.insert(I: L.end(), Node&: B); |
139 | |
140 | // Save typing. |
141 | typedef simple_ilist<Node>::iterator iterator; |
142 | typedef simple_ilist<Node>::reverse_iterator reverse_iterator; |
143 | typedef simple_ilist<Node>::const_iterator const_iterator; |
144 | typedef simple_ilist<Node>::const_reverse_iterator const_reverse_iterator; |
145 | |
146 | // Check conversion values. |
147 | EXPECT_EQ(L.begin(), iterator(L.rend())); |
148 | EXPECT_EQ(++L.begin(), iterator(++L.rbegin())); |
149 | EXPECT_EQ(L.end(), iterator(L.rbegin())); |
150 | EXPECT_EQ(L.rbegin(), reverse_iterator(L.end())); |
151 | EXPECT_EQ(++L.rbegin(), reverse_iterator(++L.begin())); |
152 | EXPECT_EQ(L.rend(), reverse_iterator(L.begin())); |
153 | |
154 | // Check const iterator constructors. |
155 | EXPECT_EQ(CL.begin(), const_iterator(L.rend())); |
156 | EXPECT_EQ(CL.begin(), const_iterator(CL.rend())); |
157 | EXPECT_EQ(CL.rbegin(), const_reverse_iterator(L.end())); |
158 | EXPECT_EQ(CL.rbegin(), const_reverse_iterator(CL.end())); |
159 | |
160 | // Confirm lack of implicit conversions. |
161 | static_assert(!std::is_convertible_v<iterator, reverse_iterator>, |
162 | "unexpected implicit conversion" ); |
163 | static_assert(!std::is_convertible_v<reverse_iterator, iterator>, |
164 | "unexpected implicit conversion" ); |
165 | static_assert(!std::is_convertible_v<const_iterator, const_reverse_iterator>, |
166 | "unexpected implicit conversion" ); |
167 | static_assert(!std::is_convertible_v<const_reverse_iterator, const_iterator>, |
168 | "unexpected implicit conversion" ); |
169 | } |
170 | |
171 | } // end namespace |
172 | |