MeVisLab Toolbox Reference
SbMap.h
Go to the documentation of this file.
1 /*
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 
66 template <class KeyType, class ValueType>
67 class SbMapItem
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  }
93  void setParent(SbMapItem *p) {
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  }
118  SbMapItem *getParent() const {
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 
175 template <class KeyType, class ValueType>
176 class SbMap
177 {
178  public:
179 
181 
183  class Iterator
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
216  Iterator &operator =(const Iterator &src) {
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
331  ParentFirstIterator() : mRoot(nullptr), mCur(nullptr) {
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
419  ParentLastIterator() : mRoot(nullptr), mCur(nullptr) {
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 
603  Node *pChild=pNode->getLeftChild();
604  if(pChild) { // Append the left child of the former current node
605  mArray[mEndPos] = pChild;
606  mEndPos++;
607  }
608 
609  pChild = pNode->getRightChild();
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
680  ~SbMap() {
681  clear();
682  }
683 
684  // Assignment operator
685  SbMap &operator = (const SbMap &src) {
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'
706  Node *newNodesUncle = newNode->getParent()->getParent()->getRightChild();
707  if(newNodesUncle != nullptr && newNodesUncle->isRed()) {
708  // case 1 - change the colours
709  newNode->getParent()->setBlack();
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'
731  Node *newNodesUncle = newNode->getParent()->getParent()->getLeftChild();
732  if(newNodesUncle != nullptr && newNodesUncle->isRed()) {
733  // case 1 - change the colours
734  newNode->getParent()->setBlack();
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 
861  Iterator it(getRoot());
862  return it;
863  }
866  return it;
867  }
870  return it;
871  }
873  ByLevelIterator it(getRoot(),size());
874  return it;
875  }
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;
901  KeyType keyNew = newNode->getKey();
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.
Definition: SoKeyGrabber.h:24
Class SbMapItem is the element type of the SbMap tree.
Definition: SbMap.h:68
bool isRoot() const
Definition: SbMap.h:136
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
const KeyType & getKey() const
Definition: SbMap.h:131
unsigned int GetLevel() const
Definition: SbMap.h:148
const ValueType & getValue() const
Definition: SbMap.h:125
bool isRed() const
Definition: SbMap.h:152
SbMapItem * getRightChild() const
Definition: SbMap.h:115
void setParent(SbMapItem *p)
Definition: SbMap.h:93
virtual ~SbMapItem()
Definition: SbMap.h:77
ValueType getValue()
Definition: SbMap.h:122
bool isLeaf() const
Definition: SbMap.h:145
SbMapItem * getParent() const
Definition: SbMap.h:118
void setBlack()
Definition: SbMap.h:106
SbMapItem * getLeftChild() const
Definition: SbMap.h:112
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 & operator=(const ByLevelIterator &src)
Definition: SbMap.h:559
ByLevelIterator(const ByLevelIterator &src)
Definition: SbMap.h:517
bool atEnd() const
Definition: SbMap.h:551
void operator++(int)
Definition: SbMap.h:573
Node * operator->()
Definition: SbMap.h:578
Node * getNode()
Definition: SbMap.h:554
ByLevelIterator(Node *root, unsigned int size)
Definition: SbMap.h:512
Node & operator*()
Definition: SbMap.h:581
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:233
Iterator & operator=(const Iterator &src)
Definition: SbMap.h:216
Node * getNode()
Definition: SbMap.h:211
bool atEnd() const
Definition: SbMap.h:208
void reset(bool atLowest=true)
Definition: SbMap.h:203
void operator++(int)
Definition: SbMap.h:223
Node & operator*()
Definition: SbMap.h:236
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
bool atEnd() const
Definition: SbMap.h:344
SbMap::ParentFirstIterator for an SbMap, traversing the map from bottom to top.
Definition: SbMap.h:415
bool atEnd() const
Definition: SbMap.h:432
void operator++(int)
Definition: SbMap.h:447
ParentLastIterator(Node *root)
Definition: SbMap.h:423
ParentLastIterator & operator=(const ParentLastIterator &src)
Definition: SbMap.h:440
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
bool remove(const KeyType &k)
Definition: SbMap.h:773
SbMap()
Definition: SbMap.h:672
bool isEmpty() const
Definition: SbMap.h:823
SbMap & operator=(const SbMap &src)
Definition: SbMap.h:685