Nirtcpp 2.1.0
Nirtcpp is a high-performance c++ graphics engine.
Loading...
Searching...
No Matches
irrMap.hpp
1// Copyright (C) 2006-2012 by Kat'Oun
2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in nirtcpp/nirtcpp.hpp
4
5#ifndef NIRT_MAP_HPP_INCLUDED
6#define NIRT_MAP_HPP_INCLUDED
7
8#include <nirtcpp/core/engine/nirt_types.hpp>
9#include <nirtcpp/core/engine/irrMath.hpp>
10
11namespace nirt
12{
13namespace core
14{
15
17template <class KeyType, class ValueType>
18class map
19{
21 template <class KeyTypeRB, class ValueTypeRB>
22 class RBTree
23 {
24 public:
25
26 RBTree(const KeyTypeRB& k, const ValueTypeRB& v)
27 : LeftChild(0), RightChild(0), Parent(0), Key(k),
28 Value(v), IsRed(true) {}
29
30 void setLeftChild(RBTree* p)
31 {
32 LeftChild=p;
33 if (p)
34 p->setParent(this);
35 }
36
37 void setRightChild(RBTree* p)
38 {
39 RightChild=p;
40 if (p)
41 p->setParent(this);
42 }
43
44 void setParent(RBTree* p) { Parent=p; }
45
46 void setValue(const ValueTypeRB& v) { Value = v; }
47
48 void setRed() { IsRed = true; }
49 void setBlack() { IsRed = false; }
50
51 RBTree* getLeftChild() const { return LeftChild; }
52 RBTree* getRightChild() const { return RightChild; }
53 RBTree* getParent() const { return Parent; }
54
55 const ValueTypeRB& getValue() const
56 {
57 return Value;
58 }
59
60 ValueTypeRB& getValue()
61 {
62 return Value;
63 }
64
65 const KeyTypeRB& getKey() const
66 {
67 return Key;
68 }
69
70 bool isRoot() const
71 {
72 return Parent==0;
73 }
74
75 bool isLeftChild() const
76 {
77 return (Parent != 0) && (Parent->getLeftChild()==this);
78 }
79
80 bool isRightChild() const
81 {
82 return (Parent!=0) && (Parent->getRightChild()==this);
83 }
84
85 bool isLeaf() const
86 {
87 return (LeftChild==0) && (RightChild==0);
88 }
89
90 unsigned int getLevel() const
91 {
92 if (isRoot())
93 return 1;
94 else
95 return getParent()->getLevel() + 1;
96 }
97
98
99 bool isRed() const
100 {
101 return IsRed;
102 }
103
104 bool isBlack() const
105 {
106 return !IsRed;
107 }
108
109 private:
110 RBTree();
111
112 RBTree* LeftChild;
113 RBTree* RightChild;
114
115 RBTree* Parent;
116
117 KeyTypeRB Key;
118 ValueTypeRB Value;
119
120 bool IsRed;
121 }; // RBTree
122
123 public:
124
126 // We need the forward declaration for the friend declaration
127 class ConstIterator;
128
131 {
132 friend class ConstIterator;
133 public:
134
135 Iterator() : Root(0), Cur(0) {}
136
137 // Constructor(Node*)
138 Iterator(Node* root) : Root(root)
139 {
140 reset();
141 }
142
143 void reset(bool atLowest=true)
144 {
145 if (atLowest)
146 Cur = getMin(Root);
147 else
148 Cur = getMax(Root);
149 }
150
151 bool atEnd() const
152 {
153 return Cur==0;
154 }
155
156 Node* getNode() const
157 {
158 return Cur;
159 }
160
161 void operator++(int)
162 {
163 inc();
164 }
165
166 void operator--(int)
167 {
168 dec();
169 }
170
171 Node* operator->()
172 {
173 return getNode();
174 }
175
176 Node& operator*()
177 {
178 NIRT_DEBUG_BREAK_IF(atEnd()) // access violation
179
180 return *Cur;
181 }
182
183 private:
184
185 Node* getMin(Node* n) const
186 {
187 while(n && n->getLeftChild())
188 n = n->getLeftChild();
189 return n;
190 }
191
192 Node* getMax(Node* n) const
193 {
194 while(n && n->getRightChild())
195 n = n->getRightChild();
196 return n;
197 }
198
199 void inc()
200 {
201 // Already at end?
202 if (Cur==0)
203 return;
204
205 if (Cur->getRightChild())
206 {
207 // If current node has a right child, the next higher node is the
208 // node with lowest key beneath the right child.
209 Cur = getMin(Cur->getRightChild());
210 }
211 else if (Cur->isLeftChild())
212 {
213 // No right child? Well if current node is a left child then
214 // the next higher node is the parent
215 Cur = Cur->getParent();
216 }
217 else
218 {
219 // Current node neither is left child nor has a right child.
220 // I.e. it is either right child or root
221 // The next higher node is the parent of the first non-right
222 // child (i.e. either a left child or the root) up in the
223 // hierarchy. Root's parent is 0.
224 while(Cur->isRightChild())
225 Cur = Cur->getParent();
226 Cur = Cur->getParent();
227 }
228 }
229
230 void dec()
231 {
232 // Already at end?
233 if (Cur==0)
234 return;
235
236 if (Cur->getLeftChild())
237 {
238 // If current node has a left child, the next lower node is the
239 // node with highest key beneath the left child.
240 Cur = getMax(Cur->getLeftChild());
241 }
242 else if (Cur->isRightChild())
243 {
244 // No left child? Well if current node is a right child then
245 // the next lower node is the parent
246 Cur = Cur->getParent();
247 }
248 else
249 {
250 // Current node neither is right child nor has a left child.
251 // It is either left child or root
252 // The next higher node is the parent of the first non-left
253 // child (i.e. either a right child or the root) up in the
254 // hierarchy. Root's parent is 0.
255
256 while(Cur->isLeftChild())
257 Cur = Cur->getParent();
258 Cur = Cur->getParent();
259 }
260 }
261
262 Node* Root;
263 Node* Cur;
264 }; // Iterator
265
268 {
269 friend class Iterator;
270 public:
271
272 ConstIterator() : Root(0), Cur(0) {}
273
274 // Constructor(Node*)
275 ConstIterator(const Node* root) : Root(root)
276 {
277 reset();
278 }
279
280 // Constructor(Iterator)
281 ConstIterator(const Iterator& src) : Root(src.Root), Cur(src.Cur) {}
282
283 void reset(bool atLowest=true)
284 {
285 if (atLowest)
286 Cur = getMin(Root);
287 else
288 Cur = getMax(Root);
289 }
290
291 bool atEnd() const
292 {
293 return Cur==0;
294 }
295
296 const Node* getNode() const
297 {
298 return Cur;
299 }
300
301 void operator++(int)
302 {
303 inc();
304 }
305
306 void operator--(int)
307 {
308 dec();
309 }
310
311 const Node* operator->()
312 {
313 return getNode();
314 }
315
316 const Node& operator*()
317 {
318 NIRT_DEBUG_BREAK_IF(atEnd()) // access violation
319
320 return *Cur;
321 }
322
323 private:
324
325 const Node* getMin(const Node* n) const
326 {
327 while(n && n->getLeftChild())
328 n = n->getLeftChild();
329 return n;
330 }
331
332 const Node* getMax(const Node* n) const
333 {
334 while(n && n->getRightChild())
335 n = n->getRightChild();
336 return n;
337 }
338
339 void inc()
340 {
341 // Already at end?
342 if (Cur==0)
343 return;
344
345 if (Cur->getRightChild())
346 {
347 // If current node has a right child, the next higher node is the
348 // node with lowest key beneath the right child.
349 Cur = getMin(Cur->getRightChild());
350 }
351 else if (Cur->isLeftChild())
352 {
353 // No right child? Well if current node is a left child then
354 // the next higher node is the parent
355 Cur = Cur->getParent();
356 }
357 else
358 {
359 // Current node neither is left child nor has a right child.
360 // It is either right child or root
361 // The next higher node is the parent of the first non-right
362 // child (i.e. either a left child or the root) up in the
363 // hierarchy. Root's parent is 0.
364 while(Cur->isRightChild())
365 Cur = Cur->getParent();
366 Cur = Cur->getParent();
367 }
368 }
369
370 void dec()
371 {
372 // Already at end?
373 if (Cur==0)
374 return;
375
376 if (Cur->getLeftChild())
377 {
378 // If current node has a left child, the next lower node is the
379 // node with highest key beneath the left child.
380 Cur = getMax(Cur->getLeftChild());
381 }
382 else if (Cur->isRightChild())
383 {
384 // No left child? Well if current node is a right child then
385 // the next lower node is the parent
386 Cur = Cur->getParent();
387 }
388 else
389 {
390 // Current node neither is right child nor has a left child.
391 // It is either left child or root
392 // The next higher node is the parent of the first non-left
393 // child (i.e. either a right child or the root) up in the
394 // hierarchy. Root's parent is 0.
395
396 while(Cur->isLeftChild())
397 Cur = Cur->getParent();
398 Cur = Cur->getParent();
399 }
400 }
401
402 const Node* Root;
403 const Node* Cur;
404 }; // ConstIterator
405
406
408
413 {
414 public:
415
416 ParentFirstIterator() : Root(0), Cur(0) {}
417
418 explicit ParentFirstIterator(Node* root) : Root(root), Cur(0)
419 {
420 reset();
421 }
422
423 void reset()
424 {
425 Cur = Root;
426 }
427
428 bool atEnd() const
429 {
430 return Cur==0;
431 }
432
433 Node* getNode()
434 {
435 return Cur;
436 }
437
438 void operator++(int)
439 {
440 inc();
441 }
442
444 {
445 return getNode();
446 }
447
449 {
450 NIRT_DEBUG_BREAK_IF(atEnd()) // access violation
451
452 return *getNode();
453 }
454
455 private:
456
457 void inc()
458 {
459 // Already at end?
460 if (Cur==0)
461 return;
462
463 // First we try down to the left
464 if (Cur->getLeftChild())
465 {
466 Cur = Cur->getLeftChild();
467 }
468 else if (Cur->getRightChild())
469 {
470 // No left child? The we go down to the right.
471 Cur = Cur->getRightChild();
472 }
473 else
474 {
475 // No children? Move up in the hierarchy until
476 // we either reach 0 (and are finished) or
477 // find a right uncle.
478 while (Cur!=0)
479 {
480 // But if parent is left child and has a right "uncle" the parent
481 // has already been processed but the uncle hasn't. Move to
482 // the uncle.
483 if (Cur->isLeftChild() && Cur->getParent()->getRightChild())
484 {
485 Cur = Cur->getParent()->getRightChild();
486 return;
487 }
488 Cur = Cur->getParent();
489 }
490 }
491 }
492
493 Node* Root;
494 Node* Cur;
495
496 }; // ParentFirstIterator
497
498
500
505 {
506 public:
507
508 ParentLastIterator() : Root(0), Cur(0) {}
509
510 explicit ParentLastIterator(Node* root) : Root(root), Cur(0)
511 {
512 reset();
513 }
514
515 void reset()
516 {
517 Cur = getMin(Root);
518 }
519
520 bool atEnd() const
521 {
522 return Cur==0;
523 }
524
525 Node* getNode()
526 {
527 return Cur;
528 }
529
530 void operator++(int)
531 {
532 inc();
533 }
534
536 {
537 return getNode();
538 }
539
541 {
542 NIRT_DEBUG_BREAK_IF(atEnd()) // access violation
543
544 return *getNode();
545 }
546 private:
547
548 Node* getMin(Node* n)
549 {
550 while(n!=0 && (n->getLeftChild()!=0 || n->getRightChild()!=0))
551 {
552 if (n->getLeftChild())
553 n = n->getLeftChild();
554 else
555 n = n->getRightChild();
556 }
557 return n;
558 }
559
560 void inc()
561 {
562 // Already at end?
563 if (Cur==0)
564 return;
565
566 // Note: Starting point is the node as far down to the left as possible.
567
568 // If current node has an uncle to the right, go to the
569 // node as far down to the left from the uncle as possible
570 // else just go up a level to the parent.
571 if (Cur->isLeftChild() && Cur->getParent()->getRightChild())
572 {
573 Cur = getMin(Cur->getParent()->getRightChild());
574 }
575 else
576 Cur = Cur->getParent();
577 }
578
579 Node* Root;
580 Node* Cur;
581 }; // ParentLastIterator
582
583
584 // AccessClass is a temporary class used with the [] operator.
585 // It makes it possible to have different behavior in situations like:
586 // myTree["Foo"] = 32;
587 // If "Foo" already exists update its value else insert a new element.
588 // int i = myTree["Foo"]
589 // If "Foo" exists return its value.
591 {
592 // Let map be the only one who can instantiate this class.
593 friend class map<KeyType, ValueType>;
594
595 public:
596
597 // Assignment operator. Handles the myTree["Foo"] = 32; situation
598 void operator=(const ValueType& value)
599 {
600 // Just use the Set method, it handles already exist/not exist situation
601 Tree.set(Key,value);
602 }
603
604 // ValueType operator
605 operator ValueType()
606 {
607 Node* node = Tree.find(Key);
608
609 // Not found
610 NIRT_DEBUG_BREAK_IF(node==0) // access violation
611
612 return node->getValue();
613 }
614
615 private:
616
617 AccessClass(map& tree, const KeyType& key) : Tree(tree), Key(key) {}
618
619 AccessClass();
620
621 map& Tree;
622 const KeyType& Key;
623 }; // AccessClass
624
625
626 // Constructor.
627 map() : Root(0), Size(0) {}
628
629 // Destructor
630 ~map()
631 {
632 clear();
633 }
634
635 // using type aliases
636 using key_type = KeyType;
637 using value_type = ValueType;
638 using size_type = u32;
639
640 //------------------------------
641 // Public Commands
642 //------------------------------
643
645
648 bool insert(const KeyType& keyNew, const ValueType& v)
649 {
650 // First insert node the "usual" way (no fancy balance logic yet)
651 Node* newNode = new Node(keyNew,v);
652 if (!insert(newNode))
653 {
654 delete newNode;
655 return false;
656 }
657
658 // Then attend a balancing party
659 while (!newNode->isRoot() && (newNode->getParent()->isRed()))
660 {
661 if (newNode->getParent()->isLeftChild())
662 {
663 // If newNode is a left child, get its right 'uncle'
664 Node* newNodesUncle = newNode->getParent()->getParent()->getRightChild();
665 if ( newNodesUncle!=0 && newNodesUncle->isRed())
666 {
667 // case 1 - change the colors
668 newNode->getParent()->setBlack();
669 newNodesUncle->setBlack();
670 newNode->getParent()->getParent()->setRed();
671 // Move newNode up the tree
672 newNode = newNode->getParent()->getParent();
673 }
674 else
675 {
676 // newNodesUncle is a black node
677 if ( newNode->isRightChild())
678 {
679 // and newNode is to the right
680 // case 2 - move newNode up and rotate
681 newNode = newNode->getParent();
682 rotateLeft(newNode);
683 }
684 // case 3
685 newNode->getParent()->setBlack();
686 newNode->getParent()->getParent()->setRed();
687 rotateRight(newNode->getParent()->getParent());
688 }
689 }
690 else
691 {
692 // If newNode is a right child, get its left 'uncle'
693 Node* newNodesUncle = newNode->getParent()->getParent()->getLeftChild();
694 if ( newNodesUncle!=0 && newNodesUncle->isRed())
695 {
696 // case 1 - change the colors
697 newNode->getParent()->setBlack();
698 newNodesUncle->setBlack();
699 newNode->getParent()->getParent()->setRed();
700 // Move newNode up the tree
701 newNode = newNode->getParent()->getParent();
702 }
703 else
704 {
705 // newNodesUncle is a black node
706 if (newNode->isLeftChild())
707 {
708 // and newNode is to the left
709 // case 2 - move newNode up and rotate
710 newNode = newNode->getParent();
711 rotateRight(newNode);
712 }
713 // case 3
714 newNode->getParent()->setBlack();
715 newNode->getParent()->getParent()->setRed();
716 rotateLeft(newNode->getParent()->getParent());
717 }
718
719 }
720 }
721 // Color the root black
722 Root->setBlack();
723 return true;
724 }
725
727
729 void set(const KeyType& k, const ValueType& v)
730 {
731 Node* p = find(k);
732 if (p)
733 p->setValue(v);
734 else
735 insert(k,v);
736 }
737
739
743 {
744 Node* p = find(k);
745 if (p == 0)
746 return 0;
747
748 // Rotate p down to the left until it has no right child, will get there
749 // sooner or later.
750 while(p->getRightChild())
751 {
752 // "Pull up my right child and let it knock me down to the left"
753 rotateLeft(p);
754 }
755 // p now has no right child but might have a left child
756 Node* left = p->getLeftChild();
757
758 // Let p's parent point to p's child instead of point to p
759 if (p->isLeftChild())
760 p->getParent()->setLeftChild(left);
761
762 else if (p->isRightChild())
763 p->getParent()->setRightChild(left);
764
765 else
766 {
767 // p has no parent => p is the root.
768 // Let the left child be the new root.
769 setRoot(left);
770 }
771
772 // p is now gone from the tree in the sense that
773 // no one is pointing at it, so return it.
774
775 --Size;
776 return p;
777 }
778
780
781 bool remove(const KeyType& k)
782 {
783 Node* p = find(k);
784 return remove(p);
785 }
786
788
789 bool remove(Node* p)
790 {
791 if (p == 0)
792 {
793 return false;
794 }
795
796 // Rotate p down to the left until it has no right child, will get there
797 // sooner or later.
798 while(p->getRightChild())
799 {
800 // "Pull up my right child and let it knock me down to the left"
801 rotateLeft(p);
802 }
803 // p now has no right child but might have a left child
804 Node* left = p->getLeftChild();
805
806 // Let p's parent point to p's child instead of point to p
807 if (p->isLeftChild())
808 p->getParent()->setLeftChild(left);
809
810 else if (p->isRightChild())
811 p->getParent()->setRightChild(left);
812
813 else
814 {
815 // p has no parent => p is the root.
816 // Let the left child be the new root.
817 setRoot(left);
818 }
819
820 // p is now gone from the tree in the sense that
821 // no one is pointing at it. Let's get rid of it.
822 delete p;
823
824 --Size;
825 return true;
826 }
827
829 void clear()
830 {
832
833 while(!i.atEnd())
834 {
835 Node* p = i.getNode();
836 i++; // Increment it before it is deleted
837 // else iterator will get quite confused.
838 delete p;
839 }
840 Root = 0;
841 Size= 0;
842 }
843
846 bool empty() const
847 {
848 return Root == 0;
849 }
850
852 NIRT_DEPRECATED bool isEmpty() const
853 {
854 return empty();
855 }
856
860 Node* find(const KeyType& keyToFind) const
861 {
862 Node* pNode = Root;
863
864 while(pNode!=0)
865 {
866 const KeyType& key=pNode->getKey();
867
868 if (keyToFind == key)
869 return pNode;
870 else if (keyToFind < key)
871 pNode = pNode->getLeftChild();
872 else //keyToFind > key
873 pNode = pNode->getRightChild();
874 }
875
876 return 0;
877 }
878
882 Node* getRoot() const
883 {
884 return Root;
885 }
886
888 u32 size() const
889 {
890 return Size;
891 }
892
894
899 {
900 core::swap(Root, other.Root);
901 core::swap(Size, other.Size);
902 }
903
904 //------------------------------
905 // Public Iterators
906 //------------------------------
907
910 {
912 return it;
913 }
914
917 {
919 return it;
920 }
921
932
943
944 //------------------------------
945 // Public Operators
946 //------------------------------
947
949
951 {
952 return AccessClass(*this, k);
953 }
954 private:
955
956 //------------------------------
957 // Disabled methods
958 //------------------------------
959 // Copy constructor and assignment operator deliberately
960 // defined but not implemented. The tree should never be
961 // copied, pass along references to it instead.
962 explicit map(const map& src);
963 map& operator = (const map& src);
964
966
970 void setRoot(Node* newRoot)
971 {
972 Root = newRoot;
973 if (Root != 0)
974 {
975 Root->setParent(0);
976 Root->setBlack();
977 }
978 }
979
981
982 bool insert(Node* newNode)
983 {
984 bool result=true; // Assume success
985
986 if (Root==0)
987 {
988 setRoot(newNode);
989 Size = 1;
990 }
991 else
992 {
993 Node* pNode = Root;
994 const KeyType& keyNew = newNode->getKey();
995 while (pNode)
996 {
997 const KeyType& key=pNode->getKey();
998
999 if (keyNew == key)
1000 {
1001 result = false;
1002 pNode = 0;
1003 }
1004 else if (keyNew < key)
1005 {
1006 if (pNode->getLeftChild() == 0)
1007 {
1008 pNode->setLeftChild(newNode);
1009 pNode = 0;
1010 }
1011 else
1012 pNode = pNode->getLeftChild();
1013 }
1014 else // keyNew > key
1015 {
1016 if (pNode->getRightChild()==0)
1017 {
1018 pNode->setRightChild(newNode);
1019 pNode = 0;
1020 }
1021 else
1022 {
1023 pNode = pNode->getRightChild();
1024 }
1025 }
1026 }
1027
1028 if (result)
1029 ++Size;
1030 }
1031
1032 return result;
1033 }
1034
1037 void rotateLeft(Node* p)
1038 {
1039 Node* right = p->getRightChild();
1040
1041 p->setRightChild(right->getLeftChild());
1042
1043 if (p->isLeftChild())
1044 p->getParent()->setLeftChild(right);
1045 else if (p->isRightChild())
1046 p->getParent()->setRightChild(right);
1047 else
1048 setRoot(right);
1049
1050 right->setLeftChild(p);
1051 }
1052
1055 void rotateRight(Node* p)
1056 {
1057 Node* left = p->getLeftChild();
1058
1059 p->setLeftChild(left->getRightChild());
1060
1061 if (p->isLeftChild())
1062 p->getParent()->setLeftChild(left);
1063 else if (p->isRightChild())
1064 p->getParent()->setRightChild(left);
1065 else
1066 setRoot(left);
1067
1068 left->setRightChild(p);
1069 }
1070
1071 //------------------------------
1072 // Private Members
1073 //------------------------------
1074 Node* Root; // The top node. 0 if empty.
1075 u32 Size; // Number of nodes in the tree
1076};
1077
1078} // end namespace core
1079} // end namespace nirt
1080
1081#endif // NIRT_MAP_HPP_INCLUDED
Axis aligned bounding box in 3d dimensional space.
Definition aabbox3d.hpp:22
Definition irrMap.hpp:591
Const Iterator.
Definition irrMap.hpp:268
Normal Iterator.
Definition irrMap.hpp:131
Parent First Iterator.
Definition irrMap.hpp:413
Parent Last Iterator.
Definition irrMap.hpp:505
map template for associative arrays using a red-black tree
Definition irrMap.hpp:19
ParentLastIterator getParentLastIterator() const
Definition irrMap.hpp:938
ConstIterator getConstIterator() const
Returns a Constiterator.
Definition irrMap.hpp:916
NIRT_DEPRECATED bool isEmpty() const
Definition irrMap.hpp:852
void clear()
Clear the entire tree.
Definition irrMap.hpp:829
Iterator getIterator() const
Returns an iterator.
Definition irrMap.hpp:909
bool insert(const KeyType &keyNew, const ValueType &v)
Inserts a new node into the tree.
Definition irrMap.hpp:648
AccessClass operator[](const KeyType &k)
operator [] for access to elements
Definition irrMap.hpp:950
void swap(map< KeyType, ValueType > &other)
Swap the content of this map container with the content of another map.
Definition irrMap.hpp:898
Node * getRoot() const
Definition irrMap.hpp:882
bool remove(const KeyType &k)
Removes a node from the tree and deletes it.
Definition irrMap.hpp:781
bool remove(Node *p)
Removes a node from the tree and deletes it.
Definition irrMap.hpp:789
ParentFirstIterator getParentFirstIterator() const
Definition irrMap.hpp:927
Node * find(const KeyType &keyToFind) const
Definition irrMap.hpp:860
Node * delink(const KeyType &k)
Removes a node from the tree and returns it.
Definition irrMap.hpp:742
void set(const KeyType &k, const ValueType &v)
Replaces the value if the key already exists, otherwise inserts a new element.
Definition irrMap.hpp:729
bool empty() const
Definition irrMap.hpp:846
u32 size() const
Returns the number of nodes in the tree.
Definition irrMap.hpp:888
void swap(T1 &a, T2 &b)
swaps the content of the passed parameters
Definition irrMath.hpp:175
As of Nirtcpp 1.6, position2d is a synonym for vector2d.
Definition vector3d.hpp:11
unsigned int u32
32 bit unsigned variable.
Definition irrTypes.hpp:64

Nirtcpp    @cppfx.xyz

Esvcpp    esv::print