llvm.org GIT mirror llvm / e86c615
ADT: Explode include/llvm/ADT/{ilist,ilist_node}.h, NFC I'm working on a lower-level intrusive list that can be used stand-alone, and splitting the files up a bit will make the code easier to organize. Explode the ilist headers in advance to improve blame lists in the future. - Move ilist_node_base from ilist_node.h to ilist_node_base.h. - Move ilist_base from ilist.h to ilist_base.h. - Move ilist_iterator from ilist.h to ilist_iterator.h. - Move ilist_node_access from ilist.h to ilist_node.h to support ilist_iterator. - Update unit tests to #include smaller headers. - Clang-format the moved things. I noticed in transit that there is a simplify_type specialization for ilist_iterator. Since there is no longer an implicit conversion from ilist<T>::iterator to T*, this doesn't make sense (effectively it's a form of implicit conversion). For now I've added a FIXME. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@280047 91177308-0d34-0410-b5e6-96231b3b80d8 Duncan P. N. Exon Smith 3 years ago
7 changed file(s) with 330 addition(s) and 269 deletion(s). Raw diff Collapse all Expand all
2323 #ifndef LLVM_ADT_ILIST_H
2424 #define LLVM_ADT_ILIST_H
2525
26 #include "llvm/ADT/ilist_base.h"
27 #include "llvm/ADT/ilist_iterator.h"
2628 #include "llvm/ADT/ilist_node.h"
2729 #include "llvm/Support/Compiler.h"
2830 #include
3436 namespace llvm {
3537
3638 template class iplist;
37 template class ilist_iterator;
38
39 /// An access class for ilist_node private API.
40 ///
41 /// This gives access to the private parts of ilist nodes. Nodes for an ilist
42 /// should friend this class if they inherit privately from ilist_node.
43 ///
44 /// It's strongly discouraged to *use* this class outside of the ilist
45 /// implementation.
46 struct ilist_node_access {
47 template static ilist_node *getNodePtr(T *N) { return N; }
48 template static const ilist_node *getNodePtr(const T *N) {
49 return N;
50 }
51
52 template static ilist_node *getPrev(ilist_node &N) {
53 return N.getPrev();
54 }
55 template static ilist_node *getNext(ilist_node &N) {
56 return N.getNext();
57 }
58 template
59 static const ilist_node *getPrev(const ilist_node &N) {
60 return N.getPrev();
61 }
62 template
63 static const ilist_node *getNext(const ilist_node &N) {
64 return N.getNext();
65 }
66 };
6739
6840 namespace ilist_detail {
6941
137109 // Const traits are the same as nonconst traits...
138110 template
139111 struct ilist_traits : public ilist_traits {};
140
141 namespace ilist_detail {
142 template struct ConstCorrectNodeType {
143 typedef ilist_node type;
144 };
145 template struct ConstCorrectNodeType {
146 typedef const ilist_node type;
147 };
148
149 template struct IteratorHelper {
150 template static void increment(T *&I) {
151 I = ilist_node_access::getNext(*I);
152 }
153 template static void decrement(T *&I) {
154 I = ilist_node_access::getPrev(*I);
155 }
156 };
157 template <> struct IteratorHelper {
158 template static void increment(T *&I) {
159 IteratorHelper::decrement(I);
160 }
161 template static void decrement(T *&I) {
162 IteratorHelper::increment(I);
163 }
164 };
165
166 } // end namespace ilist_detail
167
168 //===----------------------------------------------------------------------===//
169 // Iterator for intrusive list.
170 //
171 template
172 class ilist_iterator
173 : public std::iterator {
174 public:
175 typedef std::iterator
176 super;
177
178 typedef typename super::value_type value_type;
179 typedef typename super::difference_type difference_type;
180 typedef typename super::pointer pointer;
181 typedef typename super::reference reference;
182
183 typedef typename std::add_const::type *const_pointer;
184 typedef typename std::add_const::type &const_reference;
185
186 typedef typename ilist_detail::ConstCorrectNodeType::type node_type;
187 typedef node_type *node_pointer;
188 typedef node_type &node_reference;
189
190 private:
191 node_pointer NodePtr;
192
193 public:
194 /// Create from an ilist_node.
195 explicit ilist_iterator(node_reference N) : NodePtr(&N) {}
196
197 explicit ilist_iterator(pointer NP) : NodePtr(NP) {}
198 explicit ilist_iterator(reference NR) : NodePtr(&NR) {}
199 ilist_iterator() : NodePtr(nullptr) {}
200
201 // This is templated so that we can allow constructing a const iterator from
202 // a nonconst iterator...
203 template
204 ilist_iterator(
205 const ilist_iterator &RHS,
206 typename std::enable_if::value,
207 void *>::type = nullptr)
208 : NodePtr(RHS.getNodePtr()) {}
209
210 // This is templated so that we can allow assigning to a const iterator from
211 // a nonconst iterator...
212 template
213 const ilist_iterator &
214 operator=(const ilist_iterator &RHS) {
215 NodePtr = RHS.getNodePtr();
216 return *this;
217 }
218
219 /// Convert from an iterator to its reverse.
220 ///
221 /// TODO: Roll this into the implicit constructor once we're sure that no one
222 /// is relying on the std::reverse_iterator off-by-one semantics.
223 ilist_iterator getReverse() const {
224 if (NodePtr)
225 return ilist_iterator(*NodePtr);
226 return ilist_iterator();
227 }
228
229 void reset(pointer NP) { NodePtr = NP; }
230
231 // Accessors...
232 reference operator*() const {
233 assert(!NodePtr->isKnownSentinel());
234 return static_cast(*getNodePtr());
235 }
236 pointer operator->() const { return &operator*(); }
237
238 // Comparison operators
239 friend bool operator==(const ilist_iterator &LHS, const ilist_iterator &RHS) {
240 return LHS.NodePtr == RHS.NodePtr;
241 }
242 friend bool operator!=(const ilist_iterator &LHS, const ilist_iterator &RHS) {
243 return LHS.NodePtr != RHS.NodePtr;
244 }
245
246 // Increment and decrement operators...
247 ilist_iterator &operator--() {
248 ilist_detail::IteratorHelper::decrement(NodePtr);
249 return *this;
250 }
251 ilist_iterator &operator++() {
252 ilist_detail::IteratorHelper::increment(NodePtr);
253 return *this;
254 }
255 ilist_iterator operator--(int) {
256 ilist_iterator tmp = *this;
257 --*this;
258 return tmp;
259 }
260 ilist_iterator operator++(int) {
261 ilist_iterator tmp = *this;
262 ++*this;
263 return tmp;
264 }
265
266 /// Get the underlying ilist_node.
267 node_pointer getNodePtr() const { return static_cast(NodePtr); }
268 };
269
270 // Allow ilist_iterators to convert into pointers to a node automatically when
271 // used by the dyn_cast, cast, isa mechanisms...
272
273 template struct simplify_type;
274
275 template struct simplify_type > {
276 typedef NodeTy* SimpleType;
277
278 static SimpleType getSimplifiedValue(ilist_iterator &Node) {
279 return &*Node;
280 }
281 };
282 template struct simplify_type > {
283 typedef /*const*/ NodeTy* SimpleType;
284
285 static SimpleType getSimplifiedValue(const ilist_iterator &Node) {
286 return &*Node;
287 }
288 };
289
290 /// Implementations of list algorithms using ilist_node_base.
291 class ilist_base {
292 public:
293 static void insertBeforeImpl(ilist_node_base &Next, ilist_node_base &N) {
294 ilist_node_base &Prev = *Next.getPrev();
295 N.setNext(&Next);
296 N.setPrev(&Prev);
297 Prev.setNext(&N);
298 Next.setPrev(&N);
299 }
300
301 static void removeImpl(ilist_node_base &N) {
302 ilist_node_base *Prev = N.getPrev();
303 ilist_node_base *Next = N.getNext();
304 Next->setPrev(Prev);
305 Prev->setNext(Next);
306
307 // Not strictly necessary, but helps catch a class of bugs.
308 N.setPrev(nullptr);
309 N.setNext(nullptr);
310 }
311
312 static void transferBeforeImpl(ilist_node_base &Next, ilist_node_base &First,
313 ilist_node_base &Last) {
314 assert(&Next != &Last && "Should be checked by callers");
315 assert(&First != &Last && "Should be checked by callers");
316 // Position cannot be contained in the range to be transferred.
317 assert(&Next != &First &&
318 // Check for the most common mistake.
319 "Insertion point can't be one of the transferred nodes");
320
321 ilist_node_base &Final = *Last.getPrev();
322
323 // Detach from old list/position.
324 First.getPrev()->setNext(&Last);
325 Last.setPrev(First.getPrev());
326
327 // Splice [First, Final] into its new list/position.
328 ilist_node_base &Prev = *Next.getPrev();
329 Final.setNext(&Next);
330 First.setPrev(&Prev);
331 Prev.setNext(&First);
332 Next.setPrev(&Final);
333 }
334
335 template
336 static void insertBefore(ilist_node &Next, ilist_node &N) {
337 insertBeforeImpl(Next, N);
338 }
339
340 template static void remove(ilist_node &N) { removeImpl(N); }
341
342 template
343 static void transferBefore(ilist_node &Next, ilist_node &First,
344 ilist_node &Last) {
345 transferBeforeImpl(Next, First, Last);
346 }
347 };
348112
349113 //===----------------------------------------------------------------------===//
350114 //
0 //===- llvm/ADT/ilist_base.h - Intrusive List Base ---------------*- C++ -*-==//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_ADT_ILIST_BASE_H
10 #define LLVM_ADT_ILIST_BASE_H
11
12 #include "llvm/ADT/ilist_node_base.h"
13 #include
14 #include
15 #include
16
17 namespace llvm {
18
19 /// Implementations of list algorithms using ilist_node_base.
20 class ilist_base {
21 public:
22 static void insertBeforeImpl(ilist_node_base &Next, ilist_node_base &N) {
23 ilist_node_base &Prev = *Next.getPrev();
24 N.setNext(&Next);
25 N.setPrev(&Prev);
26 Prev.setNext(&N);
27 Next.setPrev(&N);
28 }
29
30 static void removeImpl(ilist_node_base &N) {
31 ilist_node_base *Prev = N.getPrev();
32 ilist_node_base *Next = N.getNext();
33 Next->setPrev(Prev);
34 Prev->setNext(Next);
35
36 // Not strictly necessary, but helps catch a class of bugs.
37 N.setPrev(nullptr);
38 N.setNext(nullptr);
39 }
40
41 static void transferBeforeImpl(ilist_node_base &Next, ilist_node_base &First,
42 ilist_node_base &Last) {
43 assert(&Next != &Last && "Should be checked by callers");
44 assert(&First != &Last && "Should be checked by callers");
45 // Position cannot be contained in the range to be transferred.
46 assert(&Next != &First &&
47 // Check for the most common mistake.
48 "Insertion point can't be one of the transferred nodes");
49
50 ilist_node_base &Final = *Last.getPrev();
51
52 // Detach from old list/position.
53 First.getPrev()->setNext(&Last);
54 Last.setPrev(First.getPrev());
55
56 // Splice [First, Final] into its new list/position.
57 ilist_node_base &Prev = *Next.getPrev();
58 Final.setNext(&Next);
59 First.setPrev(&Prev);
60 Prev.setNext(&First);
61 Next.setPrev(&Final);
62 }
63
64 template static void insertBefore(T &Next, T &N) {
65 insertBeforeImpl(Next, N);
66 }
67
68 template static void remove(T &N) { removeImpl(N); }
69
70 template static void transferBefore(T &Next, T &First, T &Last) {
71 transferBeforeImpl(Next, First, Last);
72 }
73 };
74
75 } // end namespace llvm
76
77 #endif // LLVM_ADT_ILIST_BASE_H
0 //===- llvm/ADT/ilist_iterator.h - Intrusive List Iterator -------*- C++ -*-==//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_ADT_ILIST_ITERATOR_H
10 #define LLVM_ADT_ILIST_ITERATOR_H
11
12 #include "llvm/ADT/ilist_node.h"
13 #include
14 #include
15 #include
16 #include
17
18 namespace llvm {
19
20 namespace ilist_detail {
21
22 template struct ConstCorrectNodeType {
23 typedef ilist_node type;
24 };
25 template struct ConstCorrectNodeType {
26 typedef const ilist_node type;
27 };
28
29 template struct IteratorHelper {
30 template static void increment(T *&I) {
31 I = ilist_node_access::getNext(*I);
32 }
33 template static void decrement(T *&I) {
34 I = ilist_node_access::getPrev(*I);
35 }
36 };
37 template <> struct IteratorHelper {
38 template static void increment(T *&I) {
39 IteratorHelper::decrement(I);
40 }
41 template static void decrement(T *&I) {
42 IteratorHelper::increment(I);
43 }
44 };
45
46 } // end namespace ilist_detail
47
48 /// Iterator for intrusive lists based on ilist_node.
49 template
50 class ilist_iterator
51 : public std::iterator {
52 public:
53 typedef std::iterator
54 super;
55
56 typedef typename super::value_type value_type;
57 typedef typename super::difference_type difference_type;
58 typedef typename super::pointer pointer;
59 typedef typename super::reference reference;
60
61 typedef typename std::add_const::type *const_pointer;
62 typedef typename std::add_const::type &const_reference;
63
64 typedef typename ilist_detail::ConstCorrectNodeType::type node_type;
65 typedef node_type *node_pointer;
66 typedef node_type &node_reference;
67
68 private:
69 node_pointer NodePtr;
70
71 public:
72 /// Create from an ilist_node.
73 explicit ilist_iterator(node_reference N) : NodePtr(&N) {}
74
75 explicit ilist_iterator(pointer NP) : NodePtr(NP) {}
76 explicit ilist_iterator(reference NR) : NodePtr(&NR) {}
77 ilist_iterator() : NodePtr(nullptr) {}
78
79 // This is templated so that we can allow constructing a const iterator from
80 // a nonconst iterator...
81 template
82 ilist_iterator(
83 const ilist_iterator &RHS,
84 typename std::enable_if::value,
85 void *>::type = nullptr)
86 : NodePtr(RHS.getNodePtr()) {}
87
88 // This is templated so that we can allow assigning to a const iterator from
89 // a nonconst iterator...
90 template
91 const ilist_iterator &
92 operator=(const ilist_iterator &RHS) {
93 NodePtr = RHS.getNodePtr();
94 return *this;
95 }
96
97 /// Convert from an iterator to its reverse.
98 ///
99 /// TODO: Roll this into the implicit constructor once we're sure that no one
100 /// is relying on the std::reverse_iterator off-by-one semantics.
101 ilist_iterator getReverse() const {
102 if (NodePtr)
103 return ilist_iterator(*NodePtr);
104 return ilist_iterator();
105 }
106
107 void reset(pointer NP) { NodePtr = NP; }
108
109 // Accessors...
110 reference operator*() const {
111 assert(!NodePtr->isKnownSentinel());
112 return static_cast(*getNodePtr());
113 }
114 pointer operator->() const { return &operator*(); }
115
116 // Comparison operators
117 friend bool operator==(const ilist_iterator &LHS, const ilist_iterator &RHS) {
118 return LHS.NodePtr == RHS.NodePtr;
119 }
120 friend bool operator!=(const ilist_iterator &LHS, const ilist_iterator &RHS) {
121 return LHS.NodePtr != RHS.NodePtr;
122 }
123
124 // Increment and decrement operators...
125 ilist_iterator &operator--() {
126 ilist_detail::IteratorHelper::decrement(NodePtr);
127 return *this;
128 }
129 ilist_iterator &operator++() {
130 ilist_detail::IteratorHelper::increment(NodePtr);
131 return *this;
132 }
133 ilist_iterator operator--(int) {
134 ilist_iterator tmp = *this;
135 --*this;
136 return tmp;
137 }
138 ilist_iterator operator++(int) {
139 ilist_iterator tmp = *this;
140 ++*this;
141 return tmp;
142 }
143
144 /// Get the underlying ilist_node.
145 node_pointer getNodePtr() const { return static_cast(NodePtr); }
146 };
147
148 template struct simplify_type;
149
150 /// Allow ilist_iterators to convert into pointers to a node automatically when
151 /// used by the dyn_cast, cast, isa mechanisms...
152 ///
153 /// FIXME: remove this, since there is no implicit conversion to NodeTy.
154 template struct simplify_type> {
155 typedef NodeTy *SimpleType;
156
157 static SimpleType getSimplifiedValue(ilist_iterator &Node) {
158 return &*Node;
159 }
160 };
161 template struct simplify_type> {
162 typedef /*const*/ NodeTy *SimpleType;
163
164 static SimpleType getSimplifiedValue(const ilist_iterator &Node) {
165 return &*Node;
166 }
167 };
168
169 } // end namespace llvm
170
171 #endif // LLVM_ADT_ILIST_ITERATOR_H
1414 #ifndef LLVM_ADT_ILIST_NODE_H
1515 #define LLVM_ADT_ILIST_NODE_H
1616
17 #include "llvm/ADT/PointerIntPair.h"
17 #include "llvm/ADT/ilist_node_base.h"
1818
1919 namespace llvm {
2020
2121 template
2222 struct ilist_traits;
23
24 /// Base class for ilist nodes.
25 class ilist_node_base {
26 #ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS
27 PointerIntPair PrevAndSentinel;
28 #else
29 ilist_node_base *Prev = nullptr;
30 #endif
31 ilist_node_base *Next = nullptr;
32
33 public:
34 #ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS
35 void setPrev(ilist_node_base *Prev) { PrevAndSentinel.setPointer(Prev); }
36 ilist_node_base *getPrev() const { return PrevAndSentinel.getPointer(); }
37
38 bool isKnownSentinel() const { return PrevAndSentinel.getInt(); }
39 void initializeSentinel() { PrevAndSentinel.setInt(true); }
40 #else
41 void setPrev(ilist_node_base *Prev) { this->Prev = Prev; }
42 ilist_node_base *getPrev() const { return Prev; }
43
44 bool isKnownSentinel() const { return false; }
45 void initializeSentinel() {}
46 #endif
47
48 void setNext(ilist_node_base *Next) { this->Next = Next; }
49 ilist_node_base *getNext() const { return Next; }
50 };
5123
5224 struct ilist_node_access;
5325 template class ilist_iterator;
9062 }
9163
9264 using ilist_node_base::isKnownSentinel;
65 };
66
67 /// An access class for ilist_node private API.
68 ///
69 /// This gives access to the private parts of ilist nodes. Nodes for an ilist
70 /// should friend this class if they inherit privately from ilist_node.
71 ///
72 /// Using this class outside of the ilist implementation is unsupported.
73 struct ilist_node_access {
74 template static ilist_node *getNodePtr(T *N) { return N; }
75 template static const ilist_node *getNodePtr(const T *N) {
76 return N;
77 }
78
79 template static ilist_node *getPrev(ilist_node &N) {
80 return N.getPrev();
81 }
82 template static ilist_node *getNext(ilist_node &N) {
83 return N.getNext();
84 }
85 template
86 static const ilist_node *getPrev(const ilist_node &N) {
87 return N.getPrev();
88 }
89 template
90 static const ilist_node *getNext(const ilist_node &N) {
91 return N.getNext();
92 }
9393 };
9494
9595 template class ilist_sentinel : public ilist_node {
0 //===- llvm/ADT/ilist_node_base.h - Intrusive List Node Base -----*- C++ -*-==//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_ADT_ILIST_NODE_BASE_H
10 #define LLVM_ADT_ILIST_NODE_BASE_H
11
12 #include "llvm/ADT/PointerIntPair.h"
13
14 namespace llvm {
15
16 /// Base class for ilist nodes.
17 class ilist_node_base {
18 #ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS
19 PointerIntPair PrevAndSentinel;
20 #else
21 ilist_node_base *Prev = nullptr;
22 #endif
23 ilist_node_base *Next = nullptr;
24
25 public:
26 #ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS
27 void setPrev(ilist_node_base *Prev) { PrevAndSentinel.setPointer(Prev); }
28 ilist_node_base *getPrev() const { return PrevAndSentinel.getPointer(); }
29
30 bool isKnownSentinel() const { return PrevAndSentinel.getInt(); }
31 void initializeSentinel() { PrevAndSentinel.setInt(true); }
32 #else
33 void setPrev(ilist_node_base *Prev) { this->Prev = Prev; }
34 ilist_node_base *getPrev() const { return Prev; }
35
36 bool isKnownSentinel() const { return false; }
37 void initializeSentinel() {}
38 #endif
39
40 void setNext(ilist_node_base *Next) { this->Next = Next; }
41 ilist_node_base *getNext() const { return Next; }
42 };
43
44 } // end namespace llvm
45
46 #endif // LLVM_ADT_ILIST_NODE_BASE_H
66 //
77 //===----------------------------------------------------------------------===//
88
9 #include "llvm/ADT/ilist.h"
9 #include "llvm/ADT/ilist_base.h"
1010 #include "gtest/gtest.h"
1111
1212 using namespace llvm;
66 //
77 //===----------------------------------------------------------------------===//
88
9 #include "llvm/ADT/ilist_node.h"
9 #include "llvm/ADT/ilist_node_base.h"
1010 #include "gtest/gtest.h"
1111
1212 using namespace llvm;