NSMBW-Decomp
A decompilation of New Super Mario Bros. Wii
Loading...
Searching...
No Matches
ut_LinkList.h
1#ifndef NW4R_UT_LINK_LIST_H
2#define NW4R_UT_LINK_LIST_H
3#include <nw4r/types_nw4r.h>
4
5#include <nw4r/ut/ut_NonCopyable.h>
6
7namespace nw4r {
8namespace ut {
9
10// Forward declarations
11namespace detail {
12class LinkListImpl;
13} // namespace detail
14
15/******************************************************************************
16 *
17 * Linked list node
18 *
19 ******************************************************************************/
20class LinkListNode : private NonCopyable {
21 friend class detail::LinkListImpl;
22
23public:
24 LinkListNode() : mNext(NULL), mPrev(NULL) {}
25
26 LinkListNode* GetNext() const {
27 return mNext;
28 }
29 LinkListNode* GetPrev() const {
30 return mPrev;
31 }
32
33private:
34 LinkListNode* mNext; // at 0x0
35 LinkListNode* mPrev; // at 0x4
36};
37
38namespace detail {
39
40/******************************************************************************
41 *
42 * Linked list implementation
43 *
44 ******************************************************************************/
45class LinkListImpl : private NonCopyable {
46public:
47 // Forward declarations
48 class ConstIterator;
49
50 /******************************************************************************
51 * Iterator implementation
52 ******************************************************************************/
53 class Iterator {
54 friend class LinkListImpl;
55 friend class ConstIterator;
56
57 public:
58 Iterator() : mNode(NULL) {}
59 explicit Iterator(LinkListNode* pNode) : mNode(pNode) {}
60
61 Iterator& operator++() {
62 mNode = mNode->GetNext();
63 return *this;
64 }
65
66 Iterator& operator--() {
67 mNode = mNode->GetPrev();
68 return *this;
69 }
70
71 LinkListNode* operator->() const {
72 return mNode;
73 }
74
75 friend bool operator==(LinkListImpl::Iterator lhs,
77 return lhs.mNode == rhs.mNode;
78 }
79
80 private:
81 LinkListNode* mNode; // at 0x0
82 };
83
84 /******************************************************************************
85 * Iterator implementation (const-view)
86 ******************************************************************************/
87 class ConstIterator {
88 friend class LinkListImpl;
89
90 public:
91 explicit ConstIterator(Iterator it) : mNode(it.mNode) {}
92
93 ConstIterator& operator++() {
94 mNode = mNode->GetNext();
95 return *this;
96 }
97
98 ConstIterator& operator--() {
99 mNode = mNode->GetPrev();
100 return *this;
101 }
102
103 const LinkListNode* operator->() const {
104 return mNode;
105 }
106
107 friend bool operator==(LinkListImpl::ConstIterator lhs,
109 return lhs.mNode == rhs.mNode;
110 }
111
112 private:
113 LinkListNode* mNode; // at 0x0
114 };
115
116protected:
117 static Iterator GetIteratorFromPointer(LinkListNode* pNode) {
118 return Iterator(pNode);
119 }
120
121 LinkListImpl() {
122 Initialize_();
123 }
124 ~LinkListImpl();
125
126 Iterator GetBeginIter() {
127 return Iterator(mNode.GetNext());
128 }
129 Iterator GetEndIter() {
130 return Iterator(&mNode);
131 }
132
133 Iterator Insert(Iterator it, LinkListNode* pNode);
134
135 Iterator Erase(Iterator it);
136 Iterator Erase(LinkListNode* pNode);
137 Iterator Erase(Iterator begin, Iterator end);
138
139public:
140 ulong GetSize() const {
141 return mSize;
142 }
143 bool IsEmpty() const {
144 return mSize == 0;
145 }
146
147 void PopFront() {
148 Erase(GetBeginIter());
149 }
150 void PopBack() {
151 Erase(--GetEndIter());
152 }
153
154 void Clear();
155
156private:
157 void Initialize_() {
158 mSize = 0;
159 mNode.mNext = &mNode;
160 mNode.mPrev = &mNode;
161 }
162
163private:
164 ulong mSize; // at 0x0
165 LinkListNode mNode; // at 0x4
166};
167
168/******************************************************************************
169 *
170 * Reverse iterator
171 *
172 ******************************************************************************/
173template <typename TIter> class ReverseIterator {
174public:
175 explicit ReverseIterator(TIter it) : mCurrent(it) {}
176
177 TIter GetBase() const {
178 return mCurrent;
179 }
180
181 ReverseIterator& operator++() {
182 --mCurrent;
183 return *this;
184 }
185
186 const typename TIter::TElem* operator->() const {
187 return &this->operator*();
188 }
189
190 typename TIter::TElem& operator*() const {
191 TIter it = mCurrent;
192 return *--it;
193 }
194
195 friend bool operator==(const ReverseIterator& rLhs,
196 const ReverseIterator& rRhs) {
197 return rLhs.mCurrent == rRhs.mCurrent;
198 }
199
200 friend bool operator!=(const ReverseIterator& rLhs,
201 const ReverseIterator& rRhs) {
202 return !(rLhs.mCurrent == rRhs.mCurrent);
203 }
204
205private:
206 TIter mCurrent; // at 0x0
207};
208
209} // namespace detail
210
211/******************************************************************************
212 *
213 * Templated linked list
214 *
215 ******************************************************************************/
216template <typename T, int Ofs> class LinkList : public detail::LinkListImpl {
217public:
218 // Forward declarations
219 class ConstIterator;
220
221 /******************************************************************************
222 * Templated iterator
223 ******************************************************************************/
224 class Iterator {
225 friend class LinkList;
226 friend class ConstIterator;
227
228 public:
229 // Element type must be visible to ReverseIterator
230 typedef T TElem;
231
232 public:
233 Iterator() : mIterator(NULL) {}
234 explicit Iterator(LinkListImpl::Iterator it) : mIterator(it) {}
235
236 Iterator& operator++() {
237 ++mIterator;
238 return *this;
239 }
240
241 Iterator& operator--() {
242 --mIterator;
243 return *this;
244 }
245
246 Iterator operator++(int) {
247 Iterator ret = *this;
248 ++*this;
249 return ret;
250 }
251
252 T* operator->() const {
253 return GetPointerFromNode(mIterator.operator->());
254 }
255
256 T& operator*() const {
257 return *this->operator->();
258 }
259
260 friend bool operator==(Iterator lhs, Iterator rhs) {
261 return lhs.mIterator == rhs.mIterator;
262 }
263
264 friend bool operator!=(Iterator lhs, Iterator rhs) {
265 return !(lhs == rhs);
266 }
267
268 private:
269 LinkListImpl::Iterator mIterator; // at 0x0
270 };
271
272 /******************************************************************************
273 * Templated iterator (const-view)
274 ******************************************************************************/
275 class ConstIterator {
276 friend class LinkList;
277
278 public:
279 // Element type must be visible to ReverseIterator
280 typedef T TElem;
281
282 public:
283 explicit ConstIterator(LinkListImpl::Iterator it) : mIterator(it) {}
284 explicit ConstIterator(Iterator it) : mIterator(it.mIterator) {}
285
286 ConstIterator& operator++() {
287 ++mIterator;
288 return *this;
289 }
290
291 ConstIterator& operator--() {
292 --mIterator;
293 return *this;
294 }
295
296 ConstIterator operator++(int) {
297 ConstIterator ret = *this;
298 ++*this;
299 return ret;
300 }
301
302 const T* operator->() const {
303 return GetPointerFromNode(mIterator.operator->());
304 }
305
306 const T& operator*() const {
307 return *this->operator->();
308 }
309
310 friend bool operator==(ConstIterator lhs, ConstIterator rhs) {
311 return lhs.mIterator == rhs.mIterator;
312 }
313
314 friend bool operator!=(ConstIterator lhs, ConstIterator rhs) {
315 return !(lhs == rhs);
316 }
317
318 private:
319 LinkListImpl::ConstIterator mIterator; // at 0x0
320 };
321
322public:
323 // Shorthand names for reverse iterator types
324 typedef detail::ReverseIterator<Iterator> RevIterator;
325 typedef detail::ReverseIterator<ConstIterator> ConstRevIterator;
326
327public:
328 LinkList() {}
329
330 Iterator GetBeginIter() {
331 return Iterator(LinkListImpl::GetBeginIter());
332 }
333 ConstIterator GetBeginIter() const {
334 return ConstIterator(const_cast<LinkList*>(this)->GetBeginIter());
335 }
336 RevIterator GetBeginReverseIter() {
337 return RevIterator(GetBeginIter());
338 }
339 ConstRevIterator GetBeginReverseIter() const {
340 return ConstRevIterator(GetBeginIter());
341 }
342
343 Iterator GetEndIter() {
344 return Iterator(LinkListImpl::GetEndIter());
345 }
346 ConstIterator GetEndIter() const {
347 return ConstIterator(const_cast<LinkList*>(this)->GetEndIter());
348 }
349 RevIterator GetEndReverseIter() {
350 return RevIterator(GetEndIter());
351 }
352 ConstRevIterator GetEndReverseIter() const {
353 return ConstRevIterator(GetEndIter());
354 }
355
356 Iterator Insert(Iterator it, T* pElem) {
357 return Iterator(
358 LinkListImpl::Insert(it.mIterator, GetNodeFromPointer(pElem)));
359 }
360
361 Iterator Erase(T* pElem) {
362 return Iterator(LinkListImpl::Erase(GetNodeFromPointer(pElem)));
363 }
364 Iterator Erase(Iterator it) {
365 return Iterator(LinkListImpl::Erase(it.mIterator));
366 }
367
368 void PushBack(T* pElem) {
369 Insert(GetEndIter(), pElem);
370 }
371
372 T& GetFront() {
373 return *GetBeginIter();
374 }
375 const T& GetFront() const {
376 return *GetBeginIter();
377 }
378
379 T& GetBack() {
380 return *--GetEndIter();
381 }
382 const T& GetBack() const {
383 return *--GetEndIter();
384 }
385
386 static Iterator GetIteratorFromPointer(T* pElem) {
387 return GetIteratorFromPointer(GetNodeFromPointer(pElem));
388 }
389
390 static Iterator GetIteratorFromPointer(LinkListNode* pNode) {
391 return Iterator(LinkListImpl::GetIteratorFromPointer(pNode));
392 }
393
394 static LinkListNode* GetNodeFromPointer(T* pElem) {
395 return reinterpret_cast<LinkListNode*>(reinterpret_cast<char*>(pElem) +
396 Ofs);
397 }
398
399 static T* GetPointerFromNode(LinkListNode* pNode) {
400 return reinterpret_cast<T*>(reinterpret_cast<char*>(pNode) - Ofs);
401 }
402
403 static const T* GetPointerFromNode(const LinkListNode* pNode) {
404 return reinterpret_cast<const T*>(reinterpret_cast<const char*>(pNode) -
405 Ofs);
406 }
407};
408
409} // namespace ut
410} // namespace nw4r
411
412/******************************************************************************
413 *
414 * Macros
415 *
416 ******************************************************************************/
417/**
418 * Declare typedef for linked-list specialization.
419 */
420#define NW4R_UT_LINKLIST_TYPEDEF_DECL(T) \
421 typedef nw4r::ut::LinkList<T, offsetof(T, node)> T##List;
422
423/**
424 * Declare typedef for linked-list specialization.
425 *
426 * Use the specified link node (name suffix) for classes with multiple nodes.
427 */
428#define NW4R_UT_LINKLIST_TYPEDEF_DECL_EX(T, SUFFIX) \
429 typedef nw4r::ut::LinkList<T, offsetof(T, node##SUFFIX)> T##SUFFIX##List;
430
431/**
432 * Declare a member LinkListNode for use with the typedef.
433 */
434#define NW4R_UT_LINKLIST_NODE_DECL() nw4r::ut::LinkListNode node
435
436/**
437 * Declare a member LinkListNode for use with the typedef.
438 *
439 * Use the specified link node (name suffix) for classes with multiple nodes.
440 */
441#define NW4R_UT_LINKLIST_NODE_DECL_EX(SUFFIX) \
442 nw4r::ut::LinkListNode node##SUFFIX
443
444/**
445 * Explicitly instantiate a linked list specialization.
446 * (RESERVED FOR MATCHING DECOMP HACKS)
447 */
448#ifndef __DECOMP_NON_MATCHING
449#define NW4R_UT_LINKLIST_TYPEDEF_FORCE(T) \
450 template struct nw4r::ut::LinkList<T, offsetof(T, node)>
451#else
452#define NW4R_UT_LINKLIST_TYPEDEF_FORCE(T)
453#endif
454
455/**
456 * Linked-list for-each macro.
457 *
458 * @param NAME Element name
459 * @param LIST Reference to list
460 * @param ... Statement(s) to execute
461 */
462#define NW4R_UT_LINKLIST_FOREACH(NAME, LIST, ...) \
463 { \
464 typedef DECLTYPE((LIST).GetBeginIter()) IterType; \
465 \
466 for (IterType NAME = (LIST).GetBeginIter(); \
467 NAME != (LIST).GetEndIter(); ++NAME) { \
468 \
469 __VA_ARGS__; \
470 } \
471 }
472
473/**
474 * List for-each macro, with robust iteration.
475 *
476 * @param NAME Element name
477 * @param LIST Reference to list
478 * @param ... Statement(s) to execute
479 */
480#define NW4R_UT_LINKLIST_FOREACH_SAFE(NAME, LIST, ...) \
481 { \
482 typedef DECLTYPE((LIST).GetBeginIter()) IterType; \
483 \
484 for (IterType __impl__ = (LIST).GetBeginIter(); \
485 __impl__ != (LIST).GetEndIter();) { \
486 \
487 IterType NAME = __impl__++; \
488 __VA_ARGS__; \
489 } \
490 }
491
492#endif
Debugging library which includes various utilities used by the rest of nw4r.
Definition ut_list.cpp:4