OpenBarnyard
 
Loading...
Searching...
No Matches
T2DList.h
Go to the documentation of this file.
1#pragma once
2#include "T2Iterator.h"
3
5
6//-----------------------------------------------------------------------------
7// TOSHI 2.0 - Doubly linked list
8// Usage example:
9//
10// class AMyClass : public Toshi::T2DList<AMyClass>::Node { ... };
11//
12// Toshi::T2DList<AMyClass> list;
13// list.PushBack(new AMyClass);
14//-----------------------------------------------------------------------------
16{
17public:
18 class Node
19 {
20 protected:
22 template <class T> friend class T2DList;
24
25 public:
26 constexpr Node()
27 : m_pPrev( this ), m_pNext( this )
28 {}
29
31 {
32 m_pNext->m_pPrev = m_pPrev;
33 m_pPrev->m_pNext = m_pNext;
34 m_pNext = this;
35 m_pPrev = this;
36 }
37
39 {
40 return m_pNext != this;
41 }
42
43 void InsertBefore( Node* pInsertBefore )
44 {
45 TASSERT( !IsLinked() );
46 m_pNext = pInsertBefore;
47 m_pPrev = pInsertBefore->m_pPrev;
48 pInsertBefore->m_pPrev = this;
49 m_pPrev->m_pNext = this;
50 }
51
52 void InsertAfter( Node* pInsertAfter )
53 {
54 TASSERT( !IsLinked() );
55 m_pPrev = pInsertAfter;
56 m_pNext = pInsertAfter->m_pNext;
57 pInsertAfter->m_pNext = this;
58 m_pNext->m_pPrev = this;
59 }
60
61 void Remove()
62 {
63 TASSERT( IsLinked() );
64 m_pPrev->m_pNext = this->m_pNext;
65 m_pNext->m_pPrev = this->m_pPrev;
66 m_pNext = this;
67 m_pPrev = this;
68 }
69
70 Node* Next() const
71 {
72 return m_pNext;
73 }
74
75 Node* Prev() const
76 {
77 return m_pPrev;
78 }
79
80 private:
81 Node* m_pNext;
82 Node* m_pPrev;
83 };
84
85public:
86 T2GenericDList() = default;
87
89 {
90 TASSERT( m_oRoot.m_pNext == &m_oRoot );
91 TASSERT( TFALSE == IsLinked() );
92 }
93
95 {
96 return m_oRoot.IsLinked();
97 }
98
99 void ClearBefore( Node* pNode )
100 {
101 if ( pNode != &m_oRoot )
102 {
103 Node* pCurrentNode = m_oRoot.m_pNext;
104
105 while ( pCurrentNode != pNode )
106 {
107 IsLinked();
108 pCurrentNode->Remove();
109 pCurrentNode = m_oRoot.m_pNext;
110 }
111 }
112 }
113
114 void Clear()
115 {
116 Node* pNode = m_oRoot.m_pNext;
117
118 while ( pNode != &m_oRoot )
119 {
120 IsLinked();
121 pNode->Remove();
122 pNode = m_oRoot.m_pNext;
123 }
124 }
125
126 TBOOL IsInList( Node* pNode ) const
127 {
128 for ( Node* pCNode = m_oRoot.m_pNext; pCNode != &m_oRoot; pCNode = pCNode->m_pNext )
129 {
130 if ( pCNode == pCNode ) return TTRUE;
131 }
132
133 return TFALSE;
134 }
135
136 TUINT Size() const
137 {
138 TUINT uiSize = 0;
139
140 for ( Node* pNode = m_oRoot.m_pNext; pNode != &m_oRoot; pNode = pNode->m_pNext )
141 {
142 uiSize++;
143 }
144
145 return uiSize;
146 }
147
148protected:
149 mutable Node m_oRoot;
150};
151
152template <class T>
154{
155public:
157
158public:
160 {
161 TSTATICASSERT( std::is_base_of<T2GenericDList::Node, T>::value );
162 }
163
165 {
166 TASSERT( IsEmpty() );
167 }
168
170 {
171 TASSERT( !IsEmpty() );
172 return m_oRoot.Next();
173 }
174
176 {
177 TASSERT( !IsEmpty() );
178 return m_oRoot.Prev();
179 }
180
182 {
183 return m_oRoot.Next();
184 }
185
186 Iterator End() const
187 {
188 return &m_oRoot;
189 }
190
192 {
193 return m_oRoot.Next();
194 }
195
197 {
198 return &m_oRoot;
199 }
200
202 {
203 return m_oRoot.Next();
204 }
205
207 {
208 return m_oRoot.Prev();
209 }
210
211 void Delete( Iterator iter )
212 {
213 iter->Remove();
214 delete TSTATICCAST( T, iter );
215 }
216
218 {
219 while ( Begin() != End() )
220 {
221 Delete( Begin() );
222 }
223 }
224
226 {
227 Iterator itNext = iter.Next();
228 iter->Remove();
229
230 return itNext;
231 }
232
233 TBOOL Exists( T* a_pItem )
234 {
235 for ( auto it = Begin(); it != End(); it++ )
236 {
237 if ( it == a_pItem )
238 return TTRUE;
239 }
240
241 return TFALSE;
242 }
243
245 {
246 return !m_oRoot.IsLinked();
247 }
248
249 void PushBack( T* pItem )
250 {
251 pItem->InsertBefore( &m_oRoot );
252 }
253
254 void PushFront( T* pItem )
255 {
256 pItem->InsertAfter( &m_oRoot );
257 }
258
260 {
261 auto node = Back();
262 node->Remove();
263 return node;
264 }
265
267 {
268 auto node = Front();
269 node->Remove();
270 return node;
271 }
272};
273
274//-----------------------------------------------------------------------------
275// Purpose: wraps typename T making it T2DList::Node
276//-----------------------------------------------------------------------------
277template <typename T>
278class T2DListNodeWrapper : public T2DList<T2DListNodeWrapper<T>>::Node
279{
280public:
281 using Type = T;
282
283public:
284 // constructors/destructor
285 constexpr T2DListNodeWrapper() = default;
286
287 constexpr T2DListNodeWrapper( T* a_pValue )
288 : m_pValue( a_pValue ) {}
289
291
292 constexpr T* GetNodeValue() { return m_pValue; }
293 constexpr const T* GetNodeValue() const { return m_pValue; }
294 constexpr T* operator->() { return m_pValue; }
295 constexpr const T* operator->() const { return m_pValue; }
296
297 constexpr void SetNodeValue( T* a_pValue ) { m_pValue = a_pValue; }
298
299 constexpr T2DListNodeWrapper& operator=( T* a_pValue )
300 {
301 SetNodeValue( a_pValue );
302 return *this;
303 }
304
305private:
306 T* m_pValue;
307};
308
310
311// $Barnyard: FUNCTION 006c8140
312// Toshi::T2DList::Exists
#define TASSERT(X,...)
Definition Defines.h:138
#define TSTATICCAST(POINTERTYPE, VALUE)
Definition Defines.h:69
#define TOSHI_NAMESPACE_START
Definition Defines.h:47
#define TSTATICASSERT(...)
Definition Defines.h:67
#define TOSHI_NAMESPACE_END
Definition Defines.h:50
#define T2_DEFINE_ITERATOR(TYPE, NODE_TYPE)
Definition T2Iterator.h:19
#define T2_DEFINE_ITERATOR_FRIEND()
Definition T2Iterator.h:16
unsigned int TUINT
Definition Typedefs.h:8
#define TFALSE
Definition Typedefs.h:24
#define TTRUE
Definition Typedefs.h:25
bool TBOOL
Definition Typedefs.h:6
TBOOL IsInList(Node *pNode) const
Definition T2DList.h:126
TBOOL IsLinked() const
Definition T2DList.h:94
void Clear()
Definition T2DList.h:114
TUINT Size() const
Definition T2DList.h:136
T2GenericDList()=default
void ClearBefore(Node *pNode)
Definition T2DList.h:99
void InsertBefore(Node *pInsertBefore)
Definition T2DList.h:43
TBOOL IsLinked() const
Definition T2DList.h:38
Node * Next() const
Definition T2DList.h:70
constexpr Node()
Definition T2DList.h:26
friend T2GenericDList
Definition T2DList.h:21
Node * Prev() const
Definition T2DList.h:75
void InsertAfter(Node *pInsertAfter)
Definition T2DList.h:52
friend class T2DList
Definition T2DList.h:22
Iterator Begin() const
Definition T2DList.h:181
void PushFront(T *pItem)
Definition T2DList.h:254
T * PopBack()
Definition T2DList.h:259
T2DList()
Definition T2DList.h:159
Iterator Erase(Iterator iter)
Definition T2DList.h:225
~T2DList()
Definition T2DList.h:164
void DeleteAll()
Definition T2DList.h:217
void Delete(Iterator iter)
Definition T2DList.h:211
Iterator Front() const
Definition T2DList.h:201
Iterator Tail() const
Definition T2DList.h:175
Iterator RBegin() const
Definition T2DList.h:191
void PushBack(T *pItem)
Definition T2DList.h:249
Iterator Back() const
Definition T2DList.h:206
T * PopFront()
Definition T2DList.h:266
TBOOL Exists(T *a_pItem)
Definition T2DList.h:233
TBOOL IsEmpty() const
Definition T2DList.h:244
Toshi::T2Iterator< T, Node > Iterator
Definition T2DList.h:156
Iterator REnd() const
Definition T2DList.h:196
Iterator Head() const
Definition T2DList.h:169
Iterator End() const
Definition T2DList.h:186
~T2DListNodeWrapper()=default
constexpr const T * operator->() const
Definition T2DList.h:295
constexpr T2DListNodeWrapper()=default
constexpr void SetNodeValue(T *a_pValue)
Definition T2DList.h:297
constexpr T2DListNodeWrapper & operator=(T *a_pValue)
Definition T2DList.h:299
constexpr T2DListNodeWrapper(T *a_pValue)
Definition T2DList.h:287
constexpr const T * GetNodeValue() const
Definition T2DList.h:293
constexpr T * operator->()
Definition T2DList.h:294
constexpr T * GetNodeValue()
Definition T2DList.h:292