MeVisLab Toolbox Reference
SbMap.h
Go to the documentation of this file.
1
3/*
4 * SbMap is based on BinTree - Binary tree template class written by
5 * Per Nilsson, It is Freeware and not copyrighted.
6 *
7 _______________________________________________________________________
8 _______________________________________________________________________
9 |
10 |
11 | Description:
12 | SbMap is a container that associates objects of type KeyType with
13 | objects of type ValueType. No two elements will have the same key.
14 | SbMap has the important property that inserting a new element into
15 | a map does not invalidate iterators that point to existing elements.
16 | Erasing an element from a map also does not invalidate any iterators,
17 | except, of course, for iterators that actually point to the element
18 | that is being erased.
19 |
20 | Classes:
21 |
22 | // The map item class.
23 | template <class KeyType, class ValueType> class SbMapItem
24 |
25 | // The map class
26 | template <class KeyType, class ValueType> class SbMap
27 | {
28 | public:
29 |
30 | // Regular low->high (++) and high->low (--) iterator
31 | class Iterator
32 |
33 | // Top to bottom iterator
34 | class ParentFirstIterator
35 |
36 | // Bottom to top iterator
37 | class ParentLastIterator
38 |
39 | // Top to bottom, level by level iterator
40 | class ByLevelIterator
41 | }
42 |
43 | Requirements:
44 |
45 | The KeyType class must support:
46 | 1. < and == operations.
47 | 2. Copy construction.
48 |
49 | The ValueType must support:
50 | 1. Copy construction.
51 | 2. Assignment operation (=) if SbMapItem::setValue is used
52 |
53 |
54 | Author(s) : Per Nilsson, Felix Ritter
55 |
56 _______________________________________________________________________
57 _______________________________________________________________________
58 */
59
60#ifndef _SB_MAP_
61#define _SB_MAP_
62
63#include "SoShaderSystem.h"
64
66template <class KeyType, class ValueType>
68{
69 public:
70
71 // Constructor(Key, Value)
72 SbMapItem(const KeyType &k, const ValueType &v)
73 :mKey(k), mValue(v), mLeftChild(nullptr), mRightChild(nullptr), mParent(nullptr), mIsRed(true) {
74 }
75
76 // Destructor
77 virtual ~SbMapItem() {
78 }
79
80 // Set methods
81
82 // set*Child also updates the the child's parent attribute.
84 mLeftChild = p;
85 if(p)
86 p->setParent(this);
87 }
89 mRightChild = p;
90 if(p)
91 p->setParent(this);
92 }
94 mParent = p;
95 }
96
97 void setValue(const ValueType &v) {
98 mValue = v;
99 }
100 // Note: Deliberately no SetKey, that could easily screw up the tree.
101 // If a key shall be changed, delete node from tree and insert a new one instead.
102
103 void setRed() {
104 mIsRed = true;
105 }
106 void setBlack() {
107 mIsRed = false;
108 }
109
110 // Get methods
111
113 return mLeftChild;
114 }
116 return mRightChild;
117 }
119 return mParent;
120 }
121
122 ValueType getValue() {
123 return mValue;
124 }
125 const ValueType &getValue() const {
126 return mValue;
127 }
129 return mKey;
130 }
131 const KeyType &getKey() const {
132 return mKey;
133 }
134
135 // Some more or less useful queries
136 bool isRoot() const {
137 return mParent == nullptr;
138 }
139 bool isLeftChild() const {
140 return mParent != nullptr && mParent->getLeftChild() == this;
141 }
142 bool isRightChild() const {
143 return mParent != nullptr && mParent->getRightChild() == this;
144 }
145 bool isLeaf() const {
146 return mLeftChild == nullptr && mRightChild == nullptr;
147 }
148 unsigned int GetLevel() const {
149 return (isRoot()) ? 1 : getParent()->GetLevel() + 1;
150 }
151
152 bool isRed() const {
153 return mIsRed;
154 };
155 bool isBlack() const {
156 return !mIsRed;
157 };
158
159 private:
160
161 // Default constructor - deliberately not implemented
162 SbMapItem();
163
164 SbMapItem *mLeftChild;
165 SbMapItem *mRightChild;
166 SbMapItem *mParent;
167
168 KeyType mKey;
169 ValueType mValue;
170
171 bool mIsRed;
172};
173
175template <class KeyType, class ValueType>
176class SbMap
177{
178 public:
179
181
184 {
185 public:
186
187 // Default Constructor
188 Iterator() : mRoot(nullptr), mCur(nullptr) {
189 }
190
191 // Constructor(Node *)
192 Iterator(Node *root) : mRoot(root) {
193 reset();
194 }
195
196 // Copy constructor
197 Iterator(const Iterator &src) : mRoot(src.mRoot), mCur(src.mCur) {
198 }
199
200 // reset the iterator
201 // atLowest : true - reset at lowest key value (and then ++ your way through)
202 // false - reset at highest key value (and then -- your way through)
203 void reset(bool atLowest = true) {
204 mCur = (atLowest) ? minNode(mRoot) : maxNode(mRoot);
205 }
206
207 // Has the iterator reached the end?
208 bool atEnd() const {
209 return mCur == nullptr;
210 }
212 return mCur;
213 }
214
215 // Assignment operator
217 mRoot = src.mRoot;
218 mCur = src.mCur;
219 return *this;
220 }
221
222 // Increment operator
223 void operator ++(int) {
224 Inc();
225 }
226
227 // Decrement operator
228 void operator --(int) {
229 Dec();
230 }
231
232 // Access operators
234 return getNode();
235 }
237 if(atEnd()) {
238 throw "Iterator at end";
239 }
240 return *getNode();
241 }
242
243 private:
244
245 // minNode: Returns node with lowest key from n and down.
246 // Ie the node all down to the left
247 Node *minNode(Node *n) {
248 while(n && n->getLeftChild())
249 n = n->getLeftChild();
250 return n;
251 }
252 // maxNode: Returns node with highest key from n and down.
253 // Ie the node all down to the right
254 Node *maxNode(Node *n) {
255 while(n && n->getRightChild())
256 n = n->getRightChild();
257 return n;
258 }
259
260 // ++
261 void Inc() {
262 // Already at end?
263 if(mCur == nullptr)
264 return;
265
266 if(mCur->getRightChild()) {
267 // If current node has a right child, the next higher node is the
268 // node with lowest key beneath the right child.
269 mCur = minNode(mCur->getRightChild());
270 }
271 else if(mCur->isLeftChild()) {
272 // No right child? Well if current node is a left child then
273 // the next higher node is the parent
274 mCur = mCur->getParent();
275 }
276 else {
277 // Current node neither is left child nor has a right child.
278 // Ie it is either right child or root
279 // The next higher node is the parent of the first non-right
280 // child (ie either a left child or the root) up in the
281 // hierarchy. Root's parent is 0.
282 while(mCur->isRightChild())
283 mCur = mCur->getParent();
284 mCur = mCur->getParent();
285 }
286 }
287
288 // --
289 void Dec() {
290 // Already at end?
291 if(mCur == nullptr)
292 return;
293
294 if(mCur->getLeftChild()) {
295 // If current node has a left child, the next lower node is the
296 // node with highest key beneath the left child.
297 mCur = maxNode(mCur->getLeftChild());
298 }
299 else if(mCur->isRightChild()) {
300 // No left child? Well if current node is a right child then
301 // the next lower node is the parent
302 mCur = mCur->getParent();
303 }
304 else {
305 // Current node neither is right child nor has a left child.
306 // Ie it is either left child or root
307 // The next higher node is the parent of the first non-left
308 // child (ie either a right child or the root) up in the
309 // hierarchy. Root's parent is 0.
310
311 while(mCur->isLeftChild())
312 mCur = mCur->getParent();
313 mCur = mCur->getParent();
314 }
315 }
316
317 Node *mRoot;
318 Node *mCur;
319 }; // Iterator
320
322 // Traverses the tree from top to bottom. Typical usage is
323 // when storing the tree structure, because when reading it
324 // later (and inserting elements) the tree structure will
325 // be the same.
327 {
328 public:
329
330 // Default constructor
332 }
333
334 // Constructor(Node*)
335 explicit ParentFirstIterator(Node *root) : mRoot(root), mCur(nullptr) {
336 reset();
337 }
338
339 void reset() {
340 mCur = mRoot;
341 };
342
343 // Has the iterator reached the end?
344 bool atEnd() const {
345 return mCur==nullptr;
346 }
348 return mCur;
349 }
350
351 // Assignment operator
353 mRoot = src.mRoot;
354 mCur = src.mCur;
355 return *this;
356 }
357
358 // Increment operator
359 void operator ++(int) {
360 Inc();
361 }
362
363 // Access operators
365 return getNode();
366 }
368 if(atEnd())
369 throw "ParentFirstIterator at end";
370 return *getNode();
371 }
372
373 private:
374
375 void Inc() {
376 // Already at end?
377 if(mCur == nullptr)
378 return;
379
380 // First we try down to the left
381 if(mCur->getLeftChild()) {
382 mCur = mCur->getLeftChild();
383 }
384 else if(mCur->getRightChild()) {
385 // No left child? The we go down to the right.
386 mCur = mCur->getRightChild();
387 }
388 else {
389 // No children? Move up in the hierarcy until
390 // we either reach 0 (and are finished) or
391 // find a right uncle.
392 while(mCur != nullptr) {
393 // But if parent is left child and has a right "uncle" the parent
394 // has already been processed but the uncle hasn't. Move to
395 // the uncle.
396 if(mCur->isLeftChild() && mCur->getParent()->getRightChild()) {
397 mCur = mCur->getParent()->getRightChild();
398 return;
399 }
400 mCur = mCur->getParent();
401 }
402 }
403 }
404
405 Node *mRoot;
406 Node *mCur;
407
408 }; // ParentFirstIterator
409
411 // Typical usage is when deleting all elements in the tree
412 // because you must delete the children before you delete
413 // their parent.
415 {
416 public:
417
418 // Default constructor
420 }
421
422 // Constructor(Node*)
423 explicit ParentLastIterator(Node *root) : mRoot(root), mCur(nullptr) {
424 reset();
425 }
426
427 void reset() {
428 mCur = minNode(mRoot);
429 }
430
431 // Has the iterator reached the end?
432 bool atEnd() const {
433 return mCur == nullptr;
434 }
436 return mCur;
437 }
438
439 // Assignment operator
441 mRoot = src.mRoot;
442 mCur = src.mCur;
443 return *this;
444 }
445
446 // Increment operator
447 void operator ++(int) {
448 Inc();
449 }
450
451 // Access operators
453 return getNode();
454 }
456 if(atEnd())
457 throw "ParentLastIterator at end";
458 return *getNode();
459 }
460
461 private:
462
463 // minNode: Returns the node as far down to the left as possible.
464 Node *minNode(Node *n) {
465 while(n != nullptr && (n->getLeftChild() != 0 || n->getRightChild() != 0)) {
466 n = (n->getLeftChild()) ? n->getLeftChild() : n->getRightChild();
467 }
468 return n;
469 }
470
471 void Inc() {
472 // Already at end?
473 if(mCur == nullptr)
474 return;
475
476 // Note: Starting point is the node as far down to the left as possible.
477
478 // If current node has an uncle to the right, go to the
479 // node as far down to the left from the uncle as possible
480 // else just go up a level to the parent.
481 if(mCur->isLeftChild() && mCur->getParent()->getRightChild()) {
482 mCur = minNode(mCur->getParent()->getRightChild());
483 }
484 else {
485 mCur = mCur->getParent();
486 }
487 }
488
489 Node *mRoot;
490 Node *mCur;
491 }; // ParentLastIterator
492
494 // ByLevelIterator. Traverse tree top to bottom, level by level left to right.
495 // Typical usage : I don't know. Perhaps if the tree should be displayed
496 // in some fancy way.
497 // It is the most memory consuming of all iterators as it will allocate an
498 // array of (size()+1)/2 Node*s.
499 // Impl. desc:
500 // mArray[0] is the current node we're looking at, initially set to mRoot.
501 // When ++:ing the children of mArray[0] (if any) are put last in the
502 // array and the array is shifted down 1 step
504 {
505 public:
506
507 // Default constructor
508 ByLevelIterator() : mRoot(nullptr), mArray(nullptr), mSize(0) {
509 }
510
511 // Constructor(treeRoot, elementsInTree)
512 ByLevelIterator(Node *root, unsigned int size) : mRoot(root), mSize(size), mArray(nullptr) {
513 reset();
514 }
515
516 // Copy constructor
517 ByLevelIterator(const ByLevelIterator &src) : mRoot(src.mRoot), mSize(src.mSize), mEndPos(src.mEndPos) {
518 if(src.mArray != nullptr) {
519 mArray = new Node*[(mSize+1)/2];
520 memcpy(mArray, src.mArray, sizeof(Node*)*(mSize+1)/2);
521 }
522 else
523 mArray = 0;
524 }
525
526 // Destructor
528 if(mArray != nullptr) {
529 delete [] mArray;
530 mArray = 0;
531 }
532 }
533
534 void reset() {
535 if(mSize > 0) {
536 // Only allocate the first time reset is called
537 if(mArray == nullptr) {
538 // mArray must be able to hold the maximum "width" of the tree which
539 // at most can be (NumberOfNodesInTree + 1 ) / 2
540 mArray = new Node*[(mSize+1)/2];
541 }
542 // Initialize the array with 1 element, the mRoot.
543 mArray[0] = mRoot;
544 mEndPos = 1;
545 }
546 else
547 mEndPos=0;
548 }
549
550 // Has the iterator reached the end?
551 bool atEnd() const {
552 return mEndPos == 0;
553 }
555 return mArray[0];
556 }
557
558 // Assignment Operator
560 mRoot = src.mRoot;
561 mSize = src.mSize;
562 if(src.mArray != nullptr) {
563 mArray = new Node*[(mSize+1)/2];
564 memcpy(mArray, src.mArray, sizeof(Node*)*(mSize+1)/2);
565 }
566 else
567 mArray = 0;
568
569 return *this;
570 }
571
572 // Increment operator
573 void operator ++(int) {
574 Inc();
575 }
576
577 // Access operators
579 return getNode();
580 }
582 if(atEnd())
583 throw "ParentLastIterator at end";
584 return *getNode();
585 }
586
587 private:
588
589 void Inc() {
590 if(mEndPos == 0)
591 return;
592
593 // Current node is mArray[0]
594 Node *pNode = mArray[0];
595
596 // Move the array down one notch, ie we have a new current node
597 // (the one than just was mArray[1])
598 for(unsigned int i = 0; i < mEndPos; i++) {
599 mArray[i] = mArray[i+1];
600 }
601 mEndPos--;
602
604 if(pChild) { // Append the left child of the former current node
605 mArray[mEndPos] = pChild;
606 mEndPos++;
607 }
608
610 if(pChild) { // Append the right child of the former current node
611 mArray[mEndPos] = pChild;
612 mEndPos++;
613 }
614
615 }
616
617 Node **mArray;
618 Node *mRoot;
619 unsigned int mSize;
620 unsigned int mEndPos;
621 }; // ByLevelIterator
622
624 // It makes it possible to have different behavior in situations like:
625 // myTree["Foo"] = 32;
626 // If "Foo" already exist, just update its value else insert a new
627 // element.
628 // int i = myTree["Foo"]
629 // If "Foo" exists return its value, else throw an exception.
630 //
632 {
633 // Let SbMap be the only one who can instantiate this class.
634 friend class SbMap<KeyType, ValueType>;
635
636 public:
637
638 // Assignment operator. Handles the myTree["Foo"] = 32; situation
639 operator =(const ValueType &value) {
640 // Just use the set method, it handles already exist/not exist situation
641 mTree.set(mKey, value);
642 }
643
644 // ValueType operator
645 operator ValueType() {
646 Node *node = mTree.find(mKey);
647
648 // Not found
649 if(node == nullptr) {
650 throw "Item not found";
651 }
652
653 return node->getValue();
654 }
655
656
657 private:
658
659 // Private Construction
660 AccessClass(SbMap &tree, const KeyType &key) : mTree(tree), mKey(key) {
661 }
662
663 // Default constructor
664 AccessClass();
665
666 SbMap &mTree;
667 const KeyType &mKey;
668 }; // AccessClass
669
670
671 // Constructor.
672 SbMap() : mRoot(nullptr), mSize(0) {}
673
674 // Copy constructor
675 explicit SbMap(const SbMap &src) : mRoot(nullptr), mSize(0) {
676 *this = src;
677 }
678
679 // Destructor
681 clear();
682 }
683
684 // Assignment operator
686 clear();
687
688 for(ParentFirstIterator i(src.getParentFirstIterator()); !i.atEnd(); i++) {
689 set(i->getKey(), i->getValue());
690 }
691 }
692
693
694 bool insert(const KeyType &keyNew, const ValueType &v) {
695 // First insert node the "usual" way (no fancy balance logic yet)
696 Node *newNode = new Node(keyNew, v);
697 if(!insert(newNode)) {
698 delete newNode;
699 return false;
700 }
701
702 // Then attend a balancing party
703 while(!newNode->isRoot() && (newNode->getParent()->isRed())) {
704 if(newNode->getParent()->isLeftChild()) {
705 // If newNode is a left child, get its right 'uncle'
707 if(newNodesUncle != nullptr && newNodesUncle->isRed()) {
708 // case 1 - change the colours
710 newNodesUncle->setBlack();
711 newNode->getParent()->getParent()->setRed();
712 // Move newNode up the tree
713 newNode = newNode->getParent()->getParent();
714 }
715 else {
716 // newNodesUncle is a black node
717 if(newNode->isRightChild()) {
718 // and newNode is to the right
719 // case 2 - move newNode up and rotate
720 newNode = newNode->getParent();
721 RotateLeft(newNode);
722 }
723 // case 3
724 newNode->getParent()->setBlack();
725 newNode->getParent()->getParent()->setRed();
726 RotateRight(newNode->getParent()->getParent());
727 }
728 }
729 else {
730 // If newNode is a right child, get its left 'uncle'
732 if(newNodesUncle != nullptr && newNodesUncle->isRed()) {
733 // case 1 - change the colours
735 newNodesUncle->setBlack();
736 newNode->getParent()->getParent()->setRed();
737 // Move newNode up the tree
738 newNode = newNode->getParent()->getParent();
739 }
740 else {
741 // newNodesUncle is a black node
742 if(newNode->isLeftChild()) {
743 // and newNode is to the left
744 // case 2 - move newNode up and rotate
745 newNode = newNode->getParent();
746 RotateRight(newNode);
747 }
748 // case 3
749 newNode->getParent()->setBlack();
750 newNode->getParent()->getParent()->setRed();
751 RotateLeft(newNode->getParent()->getParent());
752 }
753 }
754 }
755 // Color the root black
756 mRoot->setBlack();
757 return true;
758 }
759
760 // set. If the key already exist just replace the value
761 // else insert a new element.
762 void set(const KeyType &k, const ValueType &v) {
763 Node *p = find(k);
764 if(p) {
765 p->setValue(v);
766 }
767 else
768 insert(k,v);
769 }
770
771 // Remove a node.Return true if the node could
772 // be found (and was removed) in the tree.
773 bool remove(const KeyType &k) {
774 Node *p = find(k);
775 if(p == nullptr)
776 return false;
777
778 // Rotate p down to the left until it has no right child, will get there
779 // sooner or later.
780 while(p->getRightChild()) {
781 // "Pull up my right child and let it knock me down to the left"
782 RotateLeft(p);
783 }
784 // p now has no right child but might have a left child
785 Node *left = p->getLeftChild();
786
787 // Let p's parent point to p's child instead of point to p
788 if(p->isLeftChild()) {
789 p->getParent()->setLeftChild(left);
790 }
791 else if(p->isRightChild()) {
792 p->getParent()->setRightChild(left);
793 }
794 else {
795 // p has no parent => p is the root.
796 // Let the left child be the new root.
797 setRoot(left);
798 }
799
800 // p is now gone from the tree in the sense that
801 // no one is pointing at it. Let's get rid of it.
802 delete p;
803
804 mSize--;
805 return true;
806 }
807
808 // Wipe out the entire tree.
809 void clear() {
811
812 while(!i.atEnd()) {
813 Node *p = i.getNode();
814 i++; // Increment it before it is deleted
815 // else iterator will get quite confused.
816 delete p;
817 }
818 mRoot = 0;
819 mSize = 0;
820 }
821
822 // Is the tree empty?
823 bool isEmpty() const {
824 return mRoot == nullptr;
825 }
826
827 // Search for the node.
828 // Returns 0 if node couldn't be found.
829 Node *find(const KeyType &keyToFind) const {
830 Node *pNode = mRoot;
831
832 while(pNode != nullptr) {
833 KeyType key(pNode->getKey());
834
835 if(keyToFind == key) {
836 // Found it! Return it! Wheee!
837 return pNode;
838 }
839 else if(keyToFind < key) {
840 pNode = pNode->getLeftChild();
841 }
842 else { // keyToFind > key
843 pNode = pNode->getRightChild();
844 }
845 }
846
847 return nullptr;
848 }
849
850 // Get the root element. 0 if tree is empty.
851 Node *getRoot() const {
852 return mRoot;
853 }
854
855 // Number of nodes in the tree.
856 unsigned int size() const {
857 return mSize;
858 }
859
862 return it;
863 }
876
877 // operator [] for access to elements
879 return AccessClass(*this, k);
880 }
881
882 private:
883
884 void setRoot(Node *newRoot) {
885 mRoot = newRoot;
886 if(mRoot != nullptr)
887 mRoot->setParent(0);
888 }
889
890 // insert a node into the tree without using any fancy balancing logic.
891 // Returns false if that key already exist in the tree.
892 bool insert(Node *newNode) {
893 bool result = true; // Assume success
894
895 if(mRoot == nullptr) {
896 setRoot(newNode);
897 mSize = 1;
898 }
899 else {
900 Node *pNode = mRoot;
902 while(pNode) {
903 KeyType key(pNode->getKey());
904
905 if(keyNew == key) {
906 result = false;
907 pNode = 0;
908 }
909 else if(keyNew < key) {
910 if(pNode->getLeftChild() == 0) {
911 pNode->setLeftChild(newNode);
912 pNode = 0;
913 }
914 else {
915 pNode = pNode->getLeftChild();
916 }
917 }
918 else {
919 // keyNew > key
920 if(pNode->getRightChild() == 0) {
921 pNode->setRightChild(newNode);
922 pNode = 0;
923 }
924 else {
925 pNode = pNode->getRightChild();
926 }
927 }
928 }
929
930 if(result) {
931 mSize++;
932 }
933 }
934
935 return result;
936 }
937
938 // Rotate left.
939 // Pull up node's right child and let it knock node down to the left
940 void RotateLeft(Node *p) {
941 Node *right = p->getRightChild();
942
943 p->setRightChild(right->getLeftChild());
944
945 if(p->isLeftChild()) {
946 p->getParent()->setLeftChild(right);
947 }
948 else if(p->isRightChild()) {
949 p->getParent()->setRightChild(right);
950 }
951 else {
952 setRoot(right);
953 }
954 right->setLeftChild(p);
955 }
956
957 // Rotate right.
958 // Pull up node's left child and let it knock node down to the right
959 void RotateRight(Node *p) {
960 Node *left = p->getLeftChild();
961
962 p->setLeftChild(left->getRightChild());
963
964 if(p->isLeftChild()) {
965 p->getParent()->setLeftChild(left);
966 }
967 else if(p->isRightChild()) {
968 p->getParent()->setRightChild(left);
969 }
970 else {
971 setRoot(left);
972 }
973 left->setRightChild(p);
974 }
975
976 Node *mRoot; // The top node. 0 if empty.
977 unsigned int mSize; // Number of nodes in the tree
978};
979
980#endif // _SB_MAP_
KeyType
SoKeyGrabber is a general facility to grab keyboard events.
Class SbMapItem is the element type of the SbMap tree.
Definition SbMap.h:68
SbMapItem * getParent() const
Definition SbMap.h:118
bool isRoot() const
Definition SbMap.h:136
const KeyType & getKey() const
Definition SbMap.h:131
KeyType getKey()
Definition SbMap.h:128
SbMapItem(const KeyType &k, const ValueType &v)
Definition SbMap.h:72
bool isBlack() const
Definition SbMap.h:155
bool isRightChild() const
Definition SbMap.h:142
void setLeftChild(SbMapItem *p)
Definition SbMap.h:83
void setRightChild(SbMapItem *p)
Definition SbMap.h:88
void setValue(const ValueType &v)
Definition SbMap.h:97
bool isLeftChild() const
Definition SbMap.h:139
unsigned int GetLevel() const
Definition SbMap.h:148
bool isRed() const
Definition SbMap.h:152
void setParent(SbMapItem *p)
Definition SbMap.h:93
virtual ~SbMapItem()
Definition SbMap.h:77
const ValueType & getValue() const
Definition SbMap.h:125
SbMapItem * getLeftChild() const
Definition SbMap.h:112
SbMapItem * getRightChild() const
Definition SbMap.h:115
ValueType getValue()
Definition SbMap.h:122
bool isLeaf() const
Definition SbMap.h:145
void setBlack()
Definition SbMap.h:106
void setRed()
Definition SbMap.h:103
AccessClass is a temporary class used with the [] operator on an SbMap.
Definition SbMap.h:632
operator=(const ValueType &value)
Definition SbMap.h:639
SbMap::ByLevelIterator for an SbMap, traversing the map top to bottom, level by level left to right....
Definition SbMap.h:504
ByLevelIterator(const ByLevelIterator &src)
Definition SbMap.h:517
Node * operator->()
Definition SbMap.h:578
bool atEnd() const
Definition SbMap.h:551
void operator++(int)
Definition SbMap.h:573
ByLevelIterator(Node *root, unsigned int size)
Definition SbMap.h:512
ByLevelIterator & operator=(const ByLevelIterator &src)
Definition SbMap.h:559
Regular low->high (++) and high->low (–) iterator class for an SbMap.
Definition SbMap.h:184
Iterator(Node *root)
Definition SbMap.h:192
Iterator(const Iterator &src)
Definition SbMap.h:197
void operator--(int)
Definition SbMap.h:228
Node & operator*()
Definition SbMap.h:236
bool atEnd() const
Definition SbMap.h:208
Iterator & operator=(const Iterator &src)
Definition SbMap.h:216
void reset(bool atLowest=true)
Definition SbMap.h:203
void operator++(int)
Definition SbMap.h:223
Node * operator->()
Definition SbMap.h:233
Node * getNode()
Definition SbMap.h:211
SbMap::ParentFirstIterator for an SbMap, traversing the map from top to bottom.
Definition SbMap.h:327
ParentFirstIterator(Node *root)
Definition SbMap.h:335
ParentFirstIterator & operator=(const ParentFirstIterator &src)
Definition SbMap.h:352
SbMap::ParentFirstIterator for an SbMap, traversing the map from bottom to top.
Definition SbMap.h:415
ParentLastIterator & operator=(const ParentLastIterator &src)
Definition SbMap.h:440
bool atEnd() const
Definition SbMap.h:432
ParentLastIterator(Node *root)
Definition SbMap.h:423
Open Inventor container that associates objects of type KeyType with objects of type ValueType.
Definition SbMap.h:177
Iterator getIterator()
Definition SbMap.h:860
SbMap(const SbMap &src)
Definition SbMap.h:675
ParentFirstIterator getParentFirstIterator()
Definition SbMap.h:864
ByLevelIterator getByLevelIterator()
Definition SbMap.h:872
void set(const KeyType &k, const ValueType &v)
Definition SbMap.h:762
~SbMap()
Definition SbMap.h:680
SbMapItem< KeyType, ValueType > Node
Definition SbMap.h:180
AccessClass operator[](const KeyType &k)
Definition SbMap.h:878
bool insert(const KeyType &keyNew, const ValueType &v)
Definition SbMap.h:694
ParentLastIterator getParentLastIterator()
Definition SbMap.h:868
unsigned int size() const
Definition SbMap.h:856
void clear()
Definition SbMap.h:809
Node * find(const KeyType &keyToFind) const
Definition SbMap.h:829
Node * getRoot() const
Definition SbMap.h:851
SbMap & operator=(const SbMap &src)
Definition SbMap.h:685
bool remove(const KeyType &k)
Definition SbMap.h:773
SbMap()
Definition SbMap.h:672
bool isEmpty() const
Definition SbMap.h:823
Target mlrange_cast(Source arg)
Generic version of checked ML casts.