Plasma Engine  2.0
Loading...
Searching...
No Matches
Set_inl.h
1#pragma once
2
3#include <Foundation/Math/Math.h>
4
5#define STACK_SIZE 64
6
7// ***** Const Iterator *****
8template <typename KeyType, typename Comparer>
9template <bool REVERSE>
11{
12 if (m_pElement == nullptr)
13 {
14 PL_ASSERT_DEBUG(m_pElement != nullptr, "The Iterator is invalid (end).");
15 return;
16 }
17
18 // if this element has a right child, go there and then search for the left most child of that
19 if (m_pElement->m_pLink[dir1] != m_pElement->m_pLink[dir1]->m_pLink[dir1])
20 {
21 m_pElement = m_pElement->m_pLink[dir1];
22
23 while (m_pElement->m_pLink[dir0] != m_pElement->m_pLink[dir0]->m_pLink[dir0])
24 m_pElement = m_pElement->m_pLink[dir0];
25
26 return;
27 }
28
29 // if this element has a parent and this element is that parents left child, go directly to the parent
30 if ((m_pElement->m_pParent != m_pElement->m_pParent->m_pParent) && (m_pElement->m_pParent->m_pLink[dir0] == m_pElement))
31 {
32 m_pElement = m_pElement->m_pParent;
33 return;
34 }
35
36 // if this element has a parent and this element is that parents right child, search for the next parent, whose left child this is
37 if ((m_pElement->m_pParent != m_pElement->m_pParent->m_pParent) && (m_pElement->m_pParent->m_pLink[dir1] == m_pElement))
38 {
39 while (m_pElement->m_pParent->m_pLink[dir1] == m_pElement)
40 m_pElement = m_pElement->m_pParent;
41
42 // if we are at the root node..
43 if ((m_pElement->m_pParent == nullptr) || (m_pElement->m_pParent == m_pElement->m_pParent->m_pParent))
44 {
45 m_pElement = nullptr;
46 return;
47 }
48
49 m_pElement = m_pElement->m_pParent;
50 return;
51 }
52
53 m_pElement = nullptr;
54}
55
56template <typename KeyType, typename Comparer>
57template <bool REVERSE>
59{
60 if constexpr (REVERSE)
61 {
62 Advance(1, 0);
63 }
64 else
65 {
66 Advance(0, 1);
67 }
69
70template <typename KeyType, typename Comparer>
71template <bool REVERSE>
73{
74 if constexpr (REVERSE)
75 {
76 Advance(0, 1);
77 }
78 else
79 {
80 Advance(1, 0);
81 }
82}
83
84// ***** plSetBase *****
85
86template <typename KeyType, typename Comparer>
88{
89 m_uiCount = 0;
90
91 m_NilNode.m_uiLevel = 0;
92 m_NilNode.m_pLink[0] = reinterpret_cast<Node*>(&m_NilNode);
93 m_NilNode.m_pLink[1] = reinterpret_cast<Node*>(&m_NilNode);
94 m_NilNode.m_pParent = reinterpret_cast<Node*>(&m_NilNode);
95
96 m_pFreeElementStack = nullptr;
97 m_pRoot = reinterpret_cast<Node*>(&m_NilNode);
98}
99
100template <typename KeyType, typename Comparer>
101plSetBase<KeyType, Comparer>::plSetBase(const Comparer& comparer, plAllocator* pAllocator)
102 : m_Elements(pAllocator)
103 , m_Comparer(comparer)
104{
105 Constructor();
107
108template <typename KeyType, typename Comparer>
110 : m_Elements(pAllocator)
111{
112 Constructor();
114 operator=(cc);
115}
117template <typename KeyType, typename Comparer>
120 Clear();
121}
123template <typename KeyType, typename Comparer>
125{
126 Clear();
127
128 for (Iterator it = rhs.GetIterator(); it.IsValid(); ++it)
129 Insert(it.Key());
131
132template <typename KeyType, typename Comparer>
134{
135 for (Iterator it = GetIterator(); it.IsValid(); ++it)
136 plMemoryUtils::Destruct<Node>(it.m_pElement, 1);
137
138 m_pFreeElementStack = nullptr;
139 m_Elements.Clear();
140
141 m_uiCount = 0;
142
143 m_NilNode.m_uiLevel = 0;
144 m_NilNode.m_pLink[0] = reinterpret_cast<Node*>(&m_NilNode);
145 m_NilNode.m_pLink[1] = reinterpret_cast<Node*>(&m_NilNode);
146 m_NilNode.m_pParent = reinterpret_cast<Node*>(&m_NilNode);
147
148 m_pRoot = reinterpret_cast<Node*>(&m_NilNode);
149}
150
151template <typename KeyType, typename Comparer>
152PL_ALWAYS_INLINE bool plSetBase<KeyType, Comparer>::IsEmpty() const
153{
154 return (m_uiCount == 0);
155}
156
157template <typename KeyType, typename Comparer>
158PL_ALWAYS_INLINE plUInt32 plSetBase<KeyType, Comparer>::GetCount() const
159{
160 return m_uiCount;
161}
162
164template <typename KeyType, typename Comparer>
166{
167 return Iterator(GetLeftMost());
168}
170template <typename KeyType, typename Comparer>
172{
173 return ReverseIterator(GetRightMost());
174}
175
176template <typename KeyType, typename Comparer>
177typename plSetBase<KeyType, Comparer>::Node* plSetBase<KeyType, Comparer>::GetLeftMost() const
178{
179 if (IsEmpty())
180 return nullptr;
181
182 Node* pNode = m_pRoot;
183
184 while (pNode->m_pLink[0] != &m_NilNode)
185 pNode = pNode->m_pLink[0];
186
187 return pNode;
188}
189
190template <typename KeyType, typename Comparer>
191typename plSetBase<KeyType, Comparer>::Node* plSetBase<KeyType, Comparer>::GetRightMost() const
192{
193 if (IsEmpty())
194 return nullptr;
195
196 Node* pNode = m_pRoot;
197
198 while (pNode->m_pLink[1] != &m_NilNode)
199 pNode = pNode->m_pLink[1];
200
201 return pNode;
202}
203
204template <typename KeyType, typename Comparer>
205template <typename CompatibleKeyType>
206typename plSetBase<KeyType, Comparer>::Node* plSetBase<KeyType, Comparer>::Internal_Find(const CompatibleKeyType& key) const
207{
208 Node* pNode = m_pRoot;
209
210 while (pNode != &m_NilNode) // && (pNode->m_Key != key))
211 {
212 const plInt32 dir = (plInt32)m_Comparer.Less(pNode->m_Key, key);
213 const plInt32 dir2 = (plInt32)m_Comparer.Less(key, pNode->m_Key);
214
215 if (dir == dir2)
216 break;
217
218 pNode = pNode->m_pLink[dir];
219 }
220
221 if (pNode == &m_NilNode)
222 return nullptr;
223
224 return pNode;
225}
226
227template <typename KeyType, typename Comparer>
228template <typename CompatibleKeyType>
229PL_ALWAYS_INLINE typename plSetBase<KeyType, Comparer>::Iterator plSetBase<KeyType, Comparer>::Find(const CompatibleKeyType& key) const
230{
231 return Iterator(Internal_Find(key));
232}
233
234template <typename KeyType, typename Comparer>
235template <typename CompatibleKeyType>
236PL_ALWAYS_INLINE bool plSetBase<KeyType, Comparer>::Contains(const CompatibleKeyType& key) const
237{
238 return Internal_Find(key) != nullptr;
239}
240
241template <typename KeyType, typename Comparer>
243{
244 for (const KeyType& key : operand)
245 {
246 if (!Contains(key))
247 return false;
248 }
249
250 return true;
251}
252
253template <typename KeyType, typename Comparer>
254template <typename CompatibleKeyType>
255typename plSetBase<KeyType, Comparer>::Node* plSetBase<KeyType, Comparer>::Internal_LowerBound(const CompatibleKeyType& key) const
256{
257 Node* pNode = m_pRoot;
258 Node* pNodeSmaller = nullptr;
259
260 while (pNode != &m_NilNode)
261 {
262 const plInt32 dir = (plInt32)m_Comparer.Less(pNode->m_Key, key);
263 const plInt32 dir2 = (plInt32)m_Comparer.Less(key, pNode->m_Key);
264
265 if (dir == dir2)
266 return pNode;
267
268 if (dir == 0)
269 pNodeSmaller = pNode;
270
271 pNode = pNode->m_pLink[dir];
272 }
273
274 return pNodeSmaller;
275}
276
277template <typename KeyType, typename Comparer>
278template <typename CompatibleKeyType>
279PL_ALWAYS_INLINE typename plSetBase<KeyType, Comparer>::Iterator plSetBase<KeyType, Comparer>::LowerBound(const CompatibleKeyType& key) const
280{
281 return Iterator(Internal_LowerBound(key));
282}
283
284template <typename KeyType, typename Comparer>
285template <typename CompatibleKeyType>
286typename plSetBase<KeyType, Comparer>::Node* plSetBase<KeyType, Comparer>::Internal_UpperBound(const CompatibleKeyType& key) const
287{
288 Node* pNode = m_pRoot;
289 Node* pNodeSmaller = nullptr;
290
291 while (pNode != &m_NilNode)
292 {
293 const plInt32 dir = (plInt32)m_Comparer.Less(pNode->m_Key, key);
294 const plInt32 dir2 = (plInt32)m_Comparer.Less(key, pNode->m_Key);
295
296 if (dir == dir2)
297 {
298 Iterator it(pNode);
299 ++it;
300 return it.m_pElement;
301 }
302
303 if (dir == 0)
304 pNodeSmaller = pNode;
305
306 pNode = pNode->m_pLink[dir];
307 }
308
309 return pNodeSmaller;
310}
311
312template <typename KeyType, typename Comparer>
313template <typename CompatibleKeyType>
314PL_ALWAYS_INLINE typename plSetBase<KeyType, Comparer>::Iterator plSetBase<KeyType, Comparer>::UpperBound(const CompatibleKeyType& key) const
315{
316 return Iterator(Internal_UpperBound(key));
317}
318
319template <typename KeyType, typename Comparer>
321{
322 for (const auto& key : operand)
323 {
324 Insert(key);
325 }
326}
327
328template <typename KeyType, typename Comparer>
330{
331 for (const auto& key : operand)
332 {
333 Remove(key);
334 }
335}
336
337template <typename KeyType, typename Comparer>
339{
340 for (auto it = GetIterator(); it.IsValid();)
341 {
342 if (!operand.Contains(it.Key()))
343 it = Remove(it);
344 else
345 ++it;
346 }
347}
348
349template <typename KeyType, typename Comparer>
350template <typename CompatibleKeyType>
352{
353 Node* pInsertedNode = nullptr;
354
355 m_pRoot = Insert(m_pRoot, std::forward<CompatibleKeyType>(key), pInsertedNode);
356 m_pRoot->m_pParent = reinterpret_cast<Node*>(&m_NilNode);
357 m_NilNode.m_pParent = reinterpret_cast<Node*>(&m_NilNode);
358
359 return Iterator(pInsertedNode);
360}
361
362template <typename KeyType, typename Comparer>
363template <typename CompatibleKeyType>
364bool plSetBase<KeyType, Comparer>::Remove(const CompatibleKeyType& key)
365{
366 bool bRemoved = true;
367 m_pRoot = Remove(m_pRoot, key, bRemoved);
368 m_pRoot->m_pParent = reinterpret_cast<Node*>(&m_NilNode);
369 m_NilNode.m_pParent = reinterpret_cast<Node*>(&m_NilNode);
370
371 return bRemoved;
372}
373
374template <typename KeyType, typename Comparer>
375template <typename CompatibleKeyType>
376typename plSetBase<KeyType, Comparer>::Node* plSetBase<KeyType, Comparer>::AcquireNode(CompatibleKeyType&& key, plUInt16 uiLevel, Node* pParent)
377{
378 Node* pNode;
379
380 if (m_pFreeElementStack == nullptr)
381 {
382 m_Elements.PushBack();
383 pNode = &m_Elements.PeekBack();
384 }
385 else
386 {
387 pNode = m_pFreeElementStack;
388 m_pFreeElementStack = m_pFreeElementStack->m_pParent;
389 }
390
392
393 pNode->m_pParent = pParent;
394 pNode->m_Key = std::forward<CompatibleKeyType>(key);
395 pNode->m_uiLevel = uiLevel;
396 pNode->m_pLink[0] = reinterpret_cast<Node*>(&m_NilNode);
397 pNode->m_pLink[1] = reinterpret_cast<Node*>(&m_NilNode);
398
399 ++m_uiCount;
400
401 return pNode;
402}
403
404template <typename KeyType, typename Comparer>
406{
407 PL_ASSERT_DEBUG(pNode != nullptr, "pNode is invalid.");
408
410
411 // try to reduce the element array, if possible
412 if (pNode == &m_Elements.PeekBack())
413 {
414 m_Elements.PopBack();
415 }
416 else if (pNode == &m_Elements.PeekFront())
417 {
418 m_Elements.PopFront();
419 }
420 else
421 {
422 pNode->m_pParent = m_pFreeElementStack;
423 m_pFreeElementStack = pNode;
424 }
425
426 --m_uiCount;
427}
428
429template <typename KeyType, typename Comparer>
430typename plSetBase<KeyType, Comparer>::Node* plSetBase<KeyType, Comparer>::SkewNode(Node* root)
431{
432 if ((root->m_pLink[0]->m_uiLevel == root->m_uiLevel) && (root->m_uiLevel != 0))
433 {
434 Node* save = root->m_pLink[0];
435 root->m_pLink[0] = save->m_pLink[1];
436 root->m_pLink[0]->m_pParent = root;
437 save->m_pLink[1] = root;
438 save->m_pLink[1]->m_pParent = save;
439 root = save;
440 }
441
442 return root;
443}
444
445template <typename KeyType, typename Comparer>
446typename plSetBase<KeyType, Comparer>::Node* plSetBase<KeyType, Comparer>::SplitNode(Node* root)
447{
448 if ((root->m_pLink[1]->m_pLink[1]->m_uiLevel == root->m_uiLevel) && (root->m_uiLevel != 0))
449 {
450 Node* save = root->m_pLink[1];
451 root->m_pLink[1] = save->m_pLink[0];
452 root->m_pLink[1]->m_pParent = root;
453 save->m_pLink[0] = root;
454 save->m_pLink[0]->m_pParent = save;
455 root = save;
456 ++root->m_uiLevel;
457 }
458
459 return root;
460}
461
462template <typename KeyType, typename Comparer>
463template <typename CompatibleKeyType>
464typename plSetBase<KeyType, Comparer>::Node* plSetBase<KeyType, Comparer>::Insert(Node* root, CompatibleKeyType&& key, Node*& pInsertedNode)
465{
466 if (root == &m_NilNode)
467 {
468 pInsertedNode = AcquireNode(std::forward<CompatibleKeyType>(key), 1, reinterpret_cast<Node*>(&m_NilNode));
469 root = pInsertedNode;
470 }
471 else
472 {
473 Node* it = root;
474 Node* up[STACK_SIZE];
475
476 plInt32 top = 0;
477 plInt32 dir = 0;
478
479 while (true)
480 {
481 PL_ASSERT_DEBUG(top < STACK_SIZE, "plSetBase's internal stack is not large enough to be able to sort {0} elements.", GetCount());
482 up[top++] = it;
483 dir = m_Comparer.Less(it->m_Key, key) ? 1 : 0;
484
485 // element is identical => do not insert
486 if ((plInt32)m_Comparer.Less(key, it->m_Key) == dir)
487 {
488 pInsertedNode = it;
489 return root;
490 }
491
492 if (it->m_pLink[dir] == &m_NilNode)
493 break;
494
495 it = it->m_pLink[dir];
496 }
497
498 pInsertedNode = AcquireNode(std::forward<CompatibleKeyType>(key), 1, it);
499 it->m_pLink[dir] = pInsertedNode;
500
501 while (--top >= 0)
502 {
503 if (top != 0)
504 dir = up[top - 1]->m_pLink[1] == up[top];
505
506 up[top] = SkewNode(up[top]);
507 up[top] = SplitNode(up[top]);
508
509 if (top != 0)
510 {
511 up[top - 1]->m_pLink[dir] = up[top];
512 up[top - 1]->m_pLink[dir]->m_pParent = up[top - 1];
513 }
514 else
515 root = up[top];
516 }
517 }
518
519 return root;
520}
521
522template <typename KeyType, typename Comparer>
523template <typename CompatibleKeyType>
524typename plSetBase<KeyType, Comparer>::Node* plSetBase<KeyType, Comparer>::Remove(Node* root, const CompatibleKeyType& key, bool& bRemoved)
525{
526 bRemoved = false;
527
528 Node* ToErase = reinterpret_cast<Node*>(&m_NilNode);
529 Node* ToOverride = reinterpret_cast<Node*>(&m_NilNode);
530
531 if (root != &m_NilNode)
532 {
533 Node* it = root;
534 Node* up[STACK_SIZE];
535 plInt32 top = 0;
536 plInt32 dir = 0;
537
538 while (true)
539 {
540 PL_ASSERT_DEBUG(top >= 0 && top < STACK_SIZE, "Implementation error");
541 up[top++] = it;
542
543 if (it == &m_NilNode)
544 return root;
545
546 plInt32 newdir = (plInt32)(m_Comparer.Less(it->m_Key, key));
547
548 if (newdir == (plInt32)(m_Comparer.Less(key, it->m_Key)))
549 break;
550
551 dir = newdir;
552
553 it = it->m_pLink[dir];
554 }
555
556 ToOverride = it;
557
558 if ((it->m_pLink[0] == &m_NilNode) || (it->m_pLink[1] == &m_NilNode))
559 {
560 plInt32 dir2 = it->m_pLink[0] == &m_NilNode;
561
562 if (--top != 0)
563 {
564 PL_ASSERT_DEBUG(top >= 1 && top < STACK_SIZE, "Implementation error");
565 up[top - 1]->m_pLink[dir] = it->m_pLink[dir2];
566 up[top - 1]->m_pLink[dir]->m_pParent = up[top - 1];
567 }
568 else
569 root = it->m_pLink[1];
570 }
571 else
572 {
573 Node* heir = it->m_pLink[1];
574 Node* prev = it;
575
576 while (heir->m_pLink[0] != &m_NilNode)
577 {
578 PL_ASSERT_DEBUG(top >= 0 && top < STACK_SIZE, "Implementation error");
579 up[top++] = prev = heir;
580
581 heir = heir->m_pLink[0];
582 }
583
584 ToErase = heir;
585 ToOverride = it;
586
587 prev->m_pLink[prev == it] = heir->m_pLink[1];
588 prev->m_pLink[prev == it]->m_pParent = prev;
589 }
590
591 while (--top >= 0)
592 {
593 if (top != 0)
594 {
595 PL_ASSERT_DEBUG(top >= 1 && top < STACK_SIZE, "Implementation error");
596 dir = up[top - 1]->m_pLink[1] == up[top];
597 }
598
599 PL_ASSERT_DEBUG(top >= 0 && top < STACK_SIZE, "Implementation error");
600
601 if ((up[top]->m_pLink[0]->m_uiLevel < up[top]->m_uiLevel - 1) || (up[top]->m_pLink[1]->m_uiLevel < up[top]->m_uiLevel - 1))
602 {
603 if (up[top]->m_pLink[1]->m_uiLevel > --up[top]->m_uiLevel)
604 up[top]->m_pLink[1]->m_uiLevel = up[top]->m_uiLevel;
605
606 up[top] = SkewNode(up[top]);
607 up[top]->m_pLink[1] = SkewNode(up[top]->m_pLink[1]);
608 up[top]->m_pLink[1]->m_pParent = up[top];
609
610 up[top]->m_pLink[1]->m_pLink[1] = SkewNode(up[top]->m_pLink[1]->m_pLink[1]);
611 up[top] = SplitNode(up[top]);
612 up[top]->m_pLink[1] = SplitNode(up[top]->m_pLink[1]);
613 up[top]->m_pLink[1]->m_pParent = up[top];
614 }
615
616 if (top != 0)
617 {
618 PL_ASSERT_DEBUG(top >= 1 && top < STACK_SIZE, "Implementation error");
619
620 up[top - 1]->m_pLink[dir] = up[top];
621 up[top - 1]->m_pLink[dir]->m_pParent = up[top - 1];
622 }
623 else
624 {
625 PL_ASSERT_DEBUG(top >= 0 && top < STACK_SIZE, "Implementation error");
626 root = up[top];
627 }
628 }
629 }
630
631 root->m_pParent = reinterpret_cast<Node*>(&m_NilNode);
632
633
634 // if necessary, swap nodes
635 if (ToErase != &m_NilNode)
636 {
637 Node* parent = ToOverride->m_pParent;
638
639 if (parent != &m_NilNode)
640 {
641 if (parent->m_pLink[0] == ToOverride)
642 {
643 parent->m_pLink[0] = ToErase;
644 parent->m_pLink[0]->m_pParent = parent;
645 }
646 if (parent->m_pLink[1] == ToOverride)
647 {
648 parent->m_pLink[1] = ToErase;
649 parent->m_pLink[1]->m_pParent = parent;
650 }
651 }
652 else
653 root = ToErase;
654
655 ToErase->m_uiLevel = ToOverride->m_uiLevel;
656 ToErase->m_pLink[0] = ToOverride->m_pLink[0];
657 ToErase->m_pLink[0]->m_pParent = ToErase;
658 ToErase->m_pLink[1] = ToOverride->m_pLink[1];
659 ToErase->m_pLink[1]->m_pParent = ToErase;
660 }
661
662 // remove the erased node
663 if (ToOverride != &m_NilNode)
664 {
665 bRemoved = true;
666 ReleaseNode(ToOverride);
667 }
668
669 return root;
670}
671
672template <typename KeyType, typename Comparer>
674{
675 PL_ASSERT_DEBUG(pos.m_pElement != nullptr, "The Iterator(pos) is invalid.");
676
677 Iterator temp(pos);
678 ++temp;
679 Remove(pos.Key());
680 return temp;
681}
682
683template <typename KeyType, typename Comparer>
685{
686 if (GetCount() != rhs.GetCount())
687 return false;
688
689 auto itLhs = GetIterator();
690 auto itRhs = rhs.GetIterator();
691
692 while (itLhs.IsValid())
693 {
694 if (!m_Comparer.Equal(itLhs.Key(), itRhs.Key()))
695 return false;
696
697 ++itLhs;
698 ++itRhs;
699 }
700
701 return true;
702}
703
704#undef STACK_SIZE
705
706template <typename KeyType, typename Comparer, typename AllocatorWrapper>
708 : plSetBase<KeyType, Comparer>(Comparer(), AllocatorWrapper::GetAllocator())
709{
710}
711
712template <typename KeyType, typename Comparer, typename AllocatorWrapper>
714 : plSetBase<KeyType, Comparer>(Comparer(), pAllocator)
715{
716}
717
718template <typename KeyType, typename Comparer, typename AllocatorWrapper>
719plSet<KeyType, Comparer, AllocatorWrapper>::plSet(const Comparer& comparer, plAllocator* pAllocator)
720 : plSetBase<KeyType, Comparer>(comparer, pAllocator)
721{
722}
723
724template <typename KeyType, typename Comparer, typename AllocatorWrapper>
726 : plSetBase<KeyType, Comparer>(other, AllocatorWrapper::GetAllocator())
727{
728}
729
730template <typename KeyType, typename Comparer, typename AllocatorWrapper>
732 : plSetBase<KeyType, Comparer>(other, AllocatorWrapper::GetAllocator())
733{
734}
735
736template <typename KeyType, typename Comparer, typename AllocatorWrapper>
738{
740}
741
742template <typename KeyType, typename Comparer, typename AllocatorWrapper>
744{
746}
747
748template <typename KeyType, typename Comparer>
750{
751 SwapNilNode(this->m_pRoot, &this->m_NilNode, &other.m_NilNode);
752 SwapNilNode(other.m_pRoot, &other.m_NilNode, &this->m_NilNode);
753
754 plMath::Swap(this->m_pRoot, other.m_pRoot);
755 plMath::Swap(this->m_uiCount, other.m_uiCount);
756 plMath::Swap(this->m_pFreeElementStack, other.m_pFreeElementStack);
757 plMath::Swap(this->m_Comparer, other.m_Comparer);
758
759 // after we swapped the root nodes, fix up their parent nodes
760 this->m_pRoot->m_pParent = reinterpret_cast<Node*>(&this->m_NilNode);
761 other.m_pRoot->m_pParent = reinterpret_cast<Node*>(&other.m_NilNode);
762
763 // the set allocator is stored in this array
764 m_Elements.Swap(other.m_Elements);
765}
766
767template <typename KeyType, typename Comparer>
768void plSetBase<KeyType, Comparer>::SwapNilNode(Node*& pCurNode, NilNode* pOld, NilNode* pNew)
769{
770 if (pCurNode == pOld)
771 {
772 pCurNode = reinterpret_cast<Node*>(pNew);
773 return;
774 }
775
776 SwapNilNode(pCurNode->m_pLink[0], pOld, pNew);
777 SwapNilNode(pCurNode->m_pLink[1], pOld, pNew);
778}
Base class for all memory allocators.
Definition Allocator.h:23
static void Construct(T *pDestination, size_t uiCount=1)
Constructs uiCount objects of type T in a raw buffer at pDestination.
static void Destruct(T *pDestination, size_t uiCount=1)
Destructs uiCount objects of type T at pDestination.
A set container that only stores whether an element resides in it or not. Similar to STL::set.
Definition Set.h:13
bool ContainsSet(const plSetBase< KeyType, Comparer > &operand) const
Checks whether all keys of the given set are in the container.
Definition Set_inl.h:242
void Intersection(const plSetBase< KeyType, Comparer > &operand)
Makes this set the intersection of itself and the operand.
Definition Set_inl.h:338
Iterator GetIterator() const
Returns a constant Iterator to the very first element.
Definition Set_inl.h:165
void Clear()
Destroys all elements in the set and resets its size to zero.
Definition Set_inl.h:133
void Union(const plSetBase< KeyType, Comparer > &operand)
Makes this set the union of itself and the operand.
Definition Set_inl.h:320
void operator=(const plSetBase< KeyType, Comparer > &rhs)
Copies all keys from the given set into this one.
Definition Set_inl.h:124
plSetBase(const Comparer &comparer, plAllocator *pAllocator)
Initializes the set to be empty.
Definition Set_inl.h:101
void Swap(plSetBase< KeyType, Comparer > &other)
Swaps this map with the other one.
Definition Set_inl.h:749
Iterator Insert(CompatibleKeyType &&key)
Inserts the key into the tree and returns an Iterator to it. O(log n) operation.
Definition Set_inl.h:351
void Difference(const plSetBase< KeyType, Comparer > &operand)
Makes this set the difference of itself and the operand, i.e. subtracts operand.
Definition Set_inl.h:329
plUInt32 GetCount() const
Returns the number of elements currently stored in the set. O(1) operation.
Definition Set_inl.h:158
ReverseIterator GetReverseIterator() const
Returns a constant ReverseIterator to the very last element.
Definition Set_inl.h:171
bool Remove(const CompatibleKeyType &key)
Erases the element with the given key, if it exists. O(log n) operation.
Definition Set_inl.h:364
bool operator==(const plSetBase< KeyType, Comparer > &rhs) const
Comparison operator.
Definition Set_inl.h:684
bool IsEmpty() const
Returns whether there are no elements in the set. O(1) operation.
Definition Set_inl.h:152
bool Contains(const CompatibleKeyType &key) const
Checks whether the given key is in the container.
Iterator UpperBound(const CompatibleKeyType &key) const
Returns an Iterator to the element with a key that is LARGER than the given key. Returns an invalid i...
Iterator Find(const CompatibleKeyType &key) const
Searches for key, returns an Iterator to it or an invalid iterator, if no such key is found....
Iterator LowerBound(const CompatibleKeyType &key) const
Returns an Iterator to the element with a key equal or larger than the given key. Returns an invalid ...
~plSetBase()
Destroys all elements in the set.
Definition Set_inl.h:118
Definition Set.h:238
PL_ALWAYS_INLINE void Swap(T &ref_f1, T &ref_f2)
Swaps the values in the two variables f1 and f2.
Definition Math_inl.h:224
Base class for all iterators.
Definition Set.h:35
PL_FORCE_INLINE const KeyType & Key() const
Returns the 'key' of the element that this iterator points to.
Definition Set.h:58
PL_ALWAYS_INLINE bool IsValid() const
Checks whether this iterator points to a valid element.
Definition Set.h:51