OpenBarnyard
 
Loading...
Searching...
No Matches
T2RedBlackTree.h
Go to the documentation of this file.
1
11
12#pragma once
13#include "Toshi/TComparator.h"
14#include "T2Allocator.h"
15
17
19{
20public:
22
23 template <class T>
24 friend class T2RedBlackTree;
25
26protected:
28 {
29 red = 0;
30 m_pLeft = this;
31 m_pRight = this;
32 m_pParent = this;
33 }
34
36 {
37 red = 0;
38 m_pLeft = pNil;
39 m_pRight = pNil;
40 m_pParent = pNil;
41 }
42
43protected:
48};
49
51{
52protected:
54 : m_oRoot( ms_oNil )
55 {
56 m_pAllocator = pAllocator;
58 }
59
64
66 {
67 return m_pAllocator;
68 }
69
70 size_t GetNumElements() const
71 {
72 return m_iNumElements;
73 }
74
79
84
85private:
86 void CheckValid()
87 {
88 TASSERT( ms_oNil.red == 0 );
89 TASSERT( m_oRoot.red == 0 );
90 }
91
92protected:
94
95protected:
99};
100
101template <class T>
103{
104public:
105 template <class T>
106 friend class T2RedBlackTree;
107
108public:
109 T2RedBlackTreeNode( const T& value )
110 : m_Value( value )
111 {
112 }
113
115 : m_Value( std::move( value ) )
116 {
117 }
118
120 {
121 return &m_Value;
122 }
123
124 TBOOL IsLeftNodeNext( const T& value ) const
125 {
126 // Insert same values to the right side
127 if ( TComparator<T>::IsEqual( m_Value, value ) )
128 return TFALSE;
129
130 return TComparator<T>::IsLess( m_Value, value );
131 }
132
133 TBOOL operator==( const T& other ) const
134 {
135 return TComparator<T>::IsEqual( m_Value, other );
136 }
137
139 {
140 return TComparator<T>::IsEqual( m_Value, other.m_Value );
141 }
142
143 TBOOL operator!=( const T& other ) const
144 {
145 return !TComparator<T>::IsEqual( m_Value, other );
146 }
147
149 {
150 return !TComparator<T>::IsEqual( m_Value, other.m_Value );
151 }
152
154 {
155 return TComparator<T>::IsGreater( m_Value, other.m_Value );
156 }
157
159 {
160 return TComparator<T>::IsLess( m_Value, other.m_Value );
161 }
162
164 {
165 return TComparator<T>::IsLessOrEqual( m_Value, other.m_Value );
166 }
167
169 {
170 return TComparator<T>::IsGreaterOrEqual( m_Value, other.m_Value );
171 }
172
173private:
174 T m_Value;
175};
176
177template <class T>
179{
180public:
182
184 {
185 public:
187 : m_pNode( a_pNode ) {}
188
190 {
191 Iterator next = *this;
192 m_pNode = TSTATICCAST( Node, T2RedBlackTree::GetSuccessorOf( m_pNode ) );
193 return next;
194 }
195
197 {
198 Iterator prev = *this;
199 m_pNode = TSTATICCAST( Node, T2RedBlackTree::GetPredecessorOf( m_pNode ) );
200 return prev;
201 }
202
204 {
205 return m_pNode;
206 }
207
209 {
210 return &m_pNode->m_Value;
211 }
212
213 TFORCEINLINE TBOOL operator==( const Iterator& other ) const
214 {
215 return m_pNode == other.m_pNode;
216 }
217
219 {
220 return m_pNode->m_Value;
221 }
222
224 {
225 return &m_pNode->m_Value;
226 }
227
228 TFORCEINLINE operator T*() const
229 {
230 return &m_pNode->m_Value;
231 }
232
234 {
235 return Next();
236 }
237
239 {
240 m_pNode = TSTATICCAST( Node, T2RedBlackTree::GetSuccessorOf( m_pNode ) );
241 return *this;
242 }
243
245 {
246 return Prev();
247 }
248
250 {
251 m_pNode = TSTATICCAST( Node, T2RedBlackTree::GetPredecessorOf( m_pNode ) );
252 return *this;
253 }
254
255 private:
256 Node* m_pNode;
257
258 friend class CIterator;
259 };
260
262 {
263 public:
264 TFORCEINLINE CIterator( const Node* a_pNode )
265 : m_pNode( a_pNode ) {}
266
267 TFORCEINLINE CIterator( const Iterator& a_rcIterator )
268 : m_pNode( a_rcIterator.m_pNode ) {}
269
271 {
272 CIterator next = *this;
273 m_pNode = TSTATICCAST( const Node, T2RedBlackTree::GetSuccessorOf( m_pNode ) );
274 return next;
275 }
276
278 {
279 CIterator prev = *this;
280 m_pNode = TSTATICCAST( const Node, T2RedBlackTree::GetPredecessorOf( m_pNode ) );
281 return prev;
282 }
283
285 {
286 return m_pNode;
287 }
288
289 TFORCEINLINE const T* GetValue() const
290 {
291 return &m_pNode->m_Value;
292 }
293
294 TFORCEINLINE TBOOL operator==( const Iterator& other ) const
295 {
296 return m_pNode == other.m_pNode;
297 }
298
300 {
301 return m_pNode == other.m_pNode;
302 }
303
304 TFORCEINLINE const T& operator*() const
305 {
306 return m_pNode->m_Value;
307 }
308
309 TFORCEINLINE const T* operator->() const
310 {
311 return &m_pNode->m_Value;
312 }
313
314 TFORCEINLINE operator const T*() const
315 {
316 return &m_pNode->m_Value;
317 }
318
320 {
321 return Next();
322 }
323
325 {
326 m_pNode = TSTATICCAST( const Node, T2RedBlackTree::GetSuccessorOf( m_pNode ) );
327 return *this;
328 }
329
331 {
332 return Prev();
333 }
334
336 {
337 m_pNode = TSTATICCAST( const Node, T2RedBlackTree::GetPredecessorOf( m_pNode ) );
338 return *this;
339 }
340
341 private:
342 const Node* m_pNode;
343
344 friend class Iterator;
345 };
346
347public:
349 : T2GenericRedBlackTree( pAllocator )
350 {
351 }
352
353 TBOOL IsRoot( Node* pNode )
354 {
355 return pNode == &m_oRoot;
356 }
357
358 Iterator Begin()
359 {
360 return Iterator( TREINTERPRETCAST( Node*, GetFirstNode() ) );
361 }
362
363 Iterator End()
364 {
365 return Iterator( TREINTERPRETCAST( Node*, &m_oRoot ) );
366 }
367
368 const CIterator Begin() const
369 {
370 return CIterator( TREINTERPRETCAST( const Node*, GetFirstNode() ) );
371 }
372
373 const CIterator End() const
374 {
375 return CIterator( TREINTERPRETCAST( const Node*, &m_oRoot ) );
376 }
377
379 {
380 while ( GetNumElements() > 0 )
381 {
383 }
384 }
385
386 void Delete( Node* a_pNode )
387 {
388 m_pAllocator->Delete( DeleteNode( a_pNode ) );
389 }
390
391 void Erase( Node* a_pFrom, Node* a_pTo )
392 {
393 Node* pNode = a_pFrom;
394
395 while ( pNode != a_pTo )
396 {
397 auto pNext = GetSuccessorOf( pNode );
398 Delete( pNode );
399 pNode = pNext;
400 }
401 }
402
403 Iterator Insert( const T& value )
404 {
405 Node* pNode = m_pAllocator->New<Node>( value );
406 pNode->m_pLeft = &ms_oNil;
407 pNode->m_pRight = &ms_oNil;
408
409 return InsertImpl( pNode );
410 }
411
412 Iterator Insert( T&& value )
413 {
414 Node* pNode = m_pAllocator->New<Node>( value );
415 pNode->m_pLeft = &ms_oNil;
416 pNode->m_pRight = &ms_oNil;
417
418 return InsertImpl( pNode );
419 }
420
421 Iterator Find( const T& value ) const
422 {
423 Node* pCurrentNode = TSTATICCAST( Node, m_oRoot.m_pLeft );
424
425 while ( pCurrentNode != &ms_oNil )
426 {
427 if ( pCurrentNode->operator==( value ) )
428 {
429 return pCurrentNode;
430 }
431
432 if ( pCurrentNode->IsLeftNodeNext( value ) )
433 {
434 pCurrentNode = TSTATICCAST( Node, pCurrentNode->m_pLeft );
435 }
436 else
437 {
438 pCurrentNode = TSTATICCAST( Node, pCurrentNode->m_pRight );
439 }
440 }
441
442 return TSTATICCAST( Node, &m_oRoot );
443 }
444
445 Iterator FindNext( const Node* a_pNextAfter, const T& value ) const
446 {
447 Node* pNode = TSTATICCAST( Node, GetSuccessorOf( a_pNextAfter ) );
448
449 if ( pNode->operator==( value ) )
450 {
451 return pNode;
452 }
453
454 return TSTATICCAST( Node, &m_oRoot );
455 }
456
457 TSIZE Size() const
458 {
459 return GetNumElements();
460 }
461
463 {
464 return m_pAllocator;
465 }
466
467private:
468 Iterator InsertImpl( Node* pNode )
469 {
470 Node* pCurrentNode = TSTATICCAST( Node, m_oRoot.m_pLeft );
471 Node* pInsertTo = TSTATICCAST( Node, &m_oRoot );
472
473 while ( pCurrentNode != &ms_oNil )
474 {
475 pInsertTo = pCurrentNode;
476
477 if ( pCurrentNode->IsLeftNodeNext( *pNode->GetValue() ) )
478 {
479 pCurrentNode = TSTATICCAST( Node, pCurrentNode->m_pLeft );
480 }
481 else
482 {
483 pCurrentNode = TSTATICCAST( Node, pCurrentNode->m_pRight );
484 }
485 }
486
487 pNode->m_pParent = pInsertTo;
488
489 if ( pInsertTo == &m_oRoot || pInsertTo->IsLeftNodeNext( *pNode->GetValue() ) )
490 {
491 pInsertTo->m_pLeft = pNode;
492 }
493 else
494 {
495 pInsertTo->m_pRight = pNode;
496 }
497
498 TASSERT( ms_oNil.red == 0, "ms_oNil not red in T2GenericRedBlackTree::TreeInsertHelp" ); // TreeInsertHelp????
500
501 return pNode;
502 }
503};
504
#define TASSERT(X,...)
Definition Defines.h:138
#define TSTATICCAST(POINTERTYPE, VALUE)
Definition Defines.h:69
#define TREINTERPRETCAST(TYPE, VALUE)
Definition Defines.h:68
#define TOSHI_NAMESPACE_START
Definition Defines.h:47
#define TFORCEINLINE
Definition Defines.h:74
#define TOSHI_NAMESPACE_END
Definition Defines.h:50
TFORCEINLINE T2Allocator * GetGlobalAllocator()
Definition T2Allocator.h:49
size_t TSIZE
Definition Typedefs.h:9
int TINT
Definition Typedefs.h:7
#define TFALSE
Definition Typedefs.h:24
bool TBOOL
Definition Typedefs.h:6
T2GenericRedBlackTreeNode * m_pParent
T2GenericRedBlackTreeNode * m_pRight
constexpr T2GenericRedBlackTreeNode()
friend class T2GenericRedBlackTree
T2GenericRedBlackTreeNode(T2GenericRedBlackTreeNode *pNil)
T2GenericRedBlackTreeNode * m_pLeft
T2GenericRedBlackTreeNode * GetFirstNode() const
size_t GetNumElements() const
static T2GenericRedBlackTreeNode * GetSuccessorOf(const T2GenericRedBlackTreeNode *pNode)
void DeleteFixUp(T2GenericRedBlackTreeNode *pNode)
void LeftRotate(T2GenericRedBlackTreeNode *pNode)
static constinit T2GenericRedBlackTreeNode ms_oNil
T2GenericRedBlackTreeNode * DeleteNode(T2GenericRedBlackTreeNode *pNode)
T2GenericRedBlackTreeNode * Insert(T2GenericRedBlackTreeNode *pNode)
static T2GenericRedBlackTreeNode * GetPredecessorOf(const T2GenericRedBlackTreeNode *pNode)
T2Allocator * m_pAllocator
T2GenericRedBlackTreeNode m_oRoot
T2Allocator * GetAllocator() const
void RightRotate(T2GenericRedBlackTreeNode *pNode)
T2GenericRedBlackTree(T2Allocator *pAllocator)
TBOOL operator!=(const T2RedBlackTreeNode< T > &other) const
TBOOL IsLeftNodeNext(const T &value) const
TBOOL operator>=(const T2RedBlackTreeNode< T > &other) const
TBOOL operator!=(const T &other) const
TBOOL operator==(const T &other) const
T2RedBlackTreeNode(T &&value)
TBOOL operator<(const T2RedBlackTreeNode< T > &other) const
friend class T2RedBlackTree
T2RedBlackTreeNode(const T &value)
TBOOL operator<=(const T2RedBlackTreeNode< T > &other) const
TBOOL operator>(const T2RedBlackTreeNode< T > &other) const
TBOOL operator==(const T2RedBlackTreeNode< T > &other) const
Iterator Insert(T &&value)
T2RedBlackTree(T2Allocator *pAllocator=GetGlobalAllocator())
T2Allocator * GetAllocator() const
void Delete(Node *a_pNode)
TSIZE Size() const
Iterator FindNext(const Node *a_pNextAfter, const T &value) const
void Erase(Node *a_pFrom, Node *a_pTo)
TBOOL IsRoot(Node *pNode)
const CIterator End() const
const CIterator Begin() const
Iterator Insert(const T &value)
Iterator Find(const T &value) const
T2RedBlackTreeNode< Pair > Node
TFORCEINLINE Iterator Prev()
TFORCEINLINE Iterator Next()
TFORCEINLINE Node * GetNode()
TFORCEINLINE T & operator*() const
TFORCEINLINE Iterator & operator--()
TFORCEINLINE TBOOL operator==(const Iterator &other) const
TFORCEINLINE Iterator(Node *a_pNode)
TFORCEINLINE Iterator operator--(TINT)
TFORCEINLINE T * operator->() const
TFORCEINLINE T * GetValue()
TFORCEINLINE Iterator & operator++()
TFORCEINLINE Iterator operator++(TINT)
TFORCEINLINE const T & operator*() const
TFORCEINLINE CIterator(const Iterator &a_rcIterator)
TFORCEINLINE TBOOL operator==(const CIterator &other) const
TFORCEINLINE const T * operator->() const
TFORCEINLINE CIterator & operator--()
TFORCEINLINE const Node * GetNode()
TFORCEINLINE TBOOL operator==(const Iterator &other) const
TFORCEINLINE CIterator(const Node *a_pNode)
TFORCEINLINE const T * GetValue() const
TFORCEINLINE CIterator operator++(TINT)
TFORCEINLINE CIterator operator--(TINT)
TFORCEINLINE CIterator & operator++()
TFORCEINLINE CIterator Next()
TFORCEINLINE CIterator Prev()
static TBOOL IsGreaterOrEqual(const T &a, const T &b)
Definition TComparator.h:29
static TBOOL IsLess(const T &a, const T &b)
Definition TComparator.h:19
static TBOOL IsEqual(const T &a, const T &b)
Definition TComparator.h:9
static TBOOL IsLessOrEqual(const T &a, const T &b)
Definition TComparator.h:24
static TBOOL IsGreater(const T &a, const T &b)
Definition TComparator.h:14