+++ /dev/null
-// Copyright (C) 2006-2012 by Kat'Oun\r
-// This file is part of the "Irrlicht Engine".\r
-// For conditions of distribution and use, see copyright notice in irrlicht.h\r
-\r
-#ifndef __IRR_MAP_H_INCLUDED__\r
-#define __IRR_MAP_H_INCLUDED__\r
-\r
-#include "irrTypes.h"\r
-#include "irrMath.h"\r
-\r
-namespace irr\r
-{\r
-namespace core\r
-{\r
-\r
-//! map template for associative arrays using a red-black tree\r
-template <class KeyType, class ValueType>\r
-class map\r
-{\r
- //! red/black tree for map\r
- template <class KeyTypeRB, class ValueTypeRB>\r
- class RBTree\r
- {\r
- public:\r
-\r
- RBTree(const KeyTypeRB& k, const ValueTypeRB& v)\r
- : LeftChild(0), RightChild(0), Parent(0), Key(k),\r
- Value(v), IsRed(true) {}\r
-\r
- void setLeftChild(RBTree* p)\r
- {\r
- LeftChild=p;\r
- if (p)\r
- p->setParent(this);\r
- }\r
-\r
- void setRightChild(RBTree* p)\r
- {\r
- RightChild=p;\r
- if (p)\r
- p->setParent(this);\r
- }\r
-\r
- void setParent(RBTree* p) { Parent=p; }\r
-\r
- void setValue(const ValueTypeRB& v) { Value = v; }\r
-\r
- void setRed() { IsRed = true; }\r
- void setBlack() { IsRed = false; }\r
-\r
- RBTree* getLeftChild() const { return LeftChild; }\r
- RBTree* getRightChild() const { return RightChild; }\r
- RBTree* getParent() const { return Parent; }\r
-\r
- const ValueTypeRB& getValue() const\r
- {\r
- return Value;\r
- }\r
-\r
- ValueTypeRB& getValue()\r
- {\r
- return Value;\r
- }\r
-\r
- const KeyTypeRB& getKey() const\r
- {\r
- return Key;\r
- }\r
-\r
- bool isRoot() const\r
- {\r
- return Parent==0;\r
- }\r
-\r
- bool isLeftChild() const\r
- {\r
- return (Parent != 0) && (Parent->getLeftChild()==this);\r
- }\r
-\r
- bool isRightChild() const\r
- {\r
- return (Parent!=0) && (Parent->getRightChild()==this);\r
- }\r
-\r
- bool isLeaf() const\r
- {\r
- return (LeftChild==0) && (RightChild==0);\r
- }\r
-\r
- unsigned int getLevel() const\r
- {\r
- if (isRoot())\r
- return 1;\r
- else\r
- return getParent()->getLevel() + 1;\r
- }\r
-\r
-\r
- bool isRed() const\r
- {\r
- return IsRed;\r
- }\r
-\r
- bool isBlack() const\r
- {\r
- return !IsRed;\r
- }\r
-\r
- private:\r
- RBTree();\r
-\r
- RBTree* LeftChild;\r
- RBTree* RightChild;\r
-\r
- RBTree* Parent;\r
-\r
- KeyTypeRB Key;\r
- ValueTypeRB Value;\r
-\r
- bool IsRed;\r
- }; // RBTree\r
-\r
- public:\r
-\r
- typedef RBTree<KeyType,ValueType> Node;\r
- // We need the forward declaration for the friend declaration\r
- class ConstIterator;\r
-\r
- //! Normal Iterator\r
- class Iterator\r
- {\r
- friend class ConstIterator;\r
- public:\r
-\r
- Iterator() : Root(0), Cur(0) {}\r
-\r
- // Constructor(Node*)\r
- Iterator(Node* root) : Root(root)\r
- {\r
- reset();\r
- }\r
-\r
- void reset(bool atLowest=true)\r
- {\r
- if (atLowest)\r
- Cur = getMin(Root);\r
- else\r
- Cur = getMax(Root);\r
- }\r
-\r
- bool atEnd() const\r
- {\r
- return Cur==0;\r
- }\r
-\r
- Node* getNode() const\r
- {\r
- return Cur;\r
- }\r
-\r
- void operator++(int)\r
- {\r
- inc();\r
- }\r
-\r
- void operator--(int)\r
- {\r
- dec();\r
- }\r
-\r
- Node* operator->()\r
- {\r
- return getNode();\r
- }\r
-\r
- Node& operator*()\r
- {\r
- _IRR_DEBUG_BREAK_IF(atEnd()) // access violation\r
-\r
- return *Cur;\r
- }\r
-\r
- private:\r
-\r
- Node* getMin(Node* n) const\r
- {\r
- while(n && n->getLeftChild())\r
- n = n->getLeftChild();\r
- return n;\r
- }\r
-\r
- Node* getMax(Node* n) const\r
- {\r
- while(n && n->getRightChild())\r
- n = n->getRightChild();\r
- return n;\r
- }\r
-\r
- void inc()\r
- {\r
- // Already at end?\r
- if (Cur==0)\r
- return;\r
-\r
- if (Cur->getRightChild())\r
- {\r
- // If current node has a right child, the next higher node is the\r
- // node with lowest key beneath the right child.\r
- Cur = getMin(Cur->getRightChild());\r
- }\r
- else if (Cur->isLeftChild())\r
- {\r
- // No right child? Well if current node is a left child then\r
- // the next higher node is the parent\r
- Cur = Cur->getParent();\r
- }\r
- else\r
- {\r
- // Current node neither is left child nor has a right child.\r
- // I.e. it is either right child or root\r
- // The next higher node is the parent of the first non-right\r
- // child (i.e. either a left child or the root) up in the\r
- // hierarchy. Root's parent is 0.\r
- while(Cur->isRightChild())\r
- Cur = Cur->getParent();\r
- Cur = Cur->getParent();\r
- }\r
- }\r
-\r
- void dec()\r
- {\r
- // Already at end?\r
- if (Cur==0)\r
- return;\r
-\r
- if (Cur->getLeftChild())\r
- {\r
- // If current node has a left child, the next lower node is the\r
- // node with highest key beneath the left child.\r
- Cur = getMax(Cur->getLeftChild());\r
- }\r
- else if (Cur->isRightChild())\r
- {\r
- // No left child? Well if current node is a right child then\r
- // the next lower node is the parent\r
- Cur = Cur->getParent();\r
- }\r
- else\r
- {\r
- // Current node neither is right child nor has a left child.\r
- // It is either left child or root\r
- // The next higher node is the parent of the first non-left\r
- // child (i.e. either a right child or the root) up in the\r
- // hierarchy. Root's parent is 0.\r
-\r
- while(Cur->isLeftChild())\r
- Cur = Cur->getParent();\r
- Cur = Cur->getParent();\r
- }\r
- }\r
-\r
- Node* Root;\r
- Node* Cur;\r
- }; // Iterator\r
-\r
- //! Const Iterator\r
- class ConstIterator\r
- {\r
- friend class Iterator;\r
- public:\r
-\r
- ConstIterator() : Root(0), Cur(0) {}\r
-\r
- // Constructor(Node*)\r
- ConstIterator(const Node* root) : Root(root)\r
- {\r
- reset();\r
- }\r
-\r
- // Constructor(Iterator)\r
- ConstIterator(const Iterator& src) : Root(src.Root), Cur(src.Cur) {}\r
-\r
- void reset(bool atLowest=true)\r
- {\r
- if (atLowest)\r
- Cur = getMin(Root);\r
- else\r
- Cur = getMax(Root);\r
- }\r
-\r
- bool atEnd() const\r
- {\r
- return Cur==0;\r
- }\r
-\r
- const Node* getNode() const\r
- {\r
- return Cur;\r
- }\r
-\r
- void operator++(int)\r
- {\r
- inc();\r
- }\r
-\r
- void operator--(int)\r
- {\r
- dec();\r
- }\r
-\r
- const Node* operator->()\r
- {\r
- return getNode();\r
- }\r
-\r
- const Node& operator*()\r
- {\r
- _IRR_DEBUG_BREAK_IF(atEnd()) // access violation\r
-\r
- return *Cur;\r
- }\r
-\r
- private:\r
-\r
- const Node* getMin(const Node* n) const\r
- {\r
- while(n && n->getLeftChild())\r
- n = n->getLeftChild();\r
- return n;\r
- }\r
-\r
- const Node* getMax(const Node* n) const\r
- {\r
- while(n && n->getRightChild())\r
- n = n->getRightChild();\r
- return n;\r
- }\r
-\r
- void inc()\r
- {\r
- // Already at end?\r
- if (Cur==0)\r
- return;\r
-\r
- if (Cur->getRightChild())\r
- {\r
- // If current node has a right child, the next higher node is the\r
- // node with lowest key beneath the right child.\r
- Cur = getMin(Cur->getRightChild());\r
- }\r
- else if (Cur->isLeftChild())\r
- {\r
- // No right child? Well if current node is a left child then\r
- // the next higher node is the parent\r
- Cur = Cur->getParent();\r
- }\r
- else\r
- {\r
- // Current node neither is left child nor has a right child.\r
- // It is either right child or root\r
- // The next higher node is the parent of the first non-right\r
- // child (i.e. either a left child or the root) up in the\r
- // hierarchy. Root's parent is 0.\r
- while(Cur->isRightChild())\r
- Cur = Cur->getParent();\r
- Cur = Cur->getParent();\r
- }\r
- }\r
-\r
- void dec()\r
- {\r
- // Already at end?\r
- if (Cur==0)\r
- return;\r
-\r
- if (Cur->getLeftChild())\r
- {\r
- // If current node has a left child, the next lower node is the\r
- // node with highest key beneath the left child.\r
- Cur = getMax(Cur->getLeftChild());\r
- }\r
- else if (Cur->isRightChild())\r
- {\r
- // No left child? Well if current node is a right child then\r
- // the next lower node is the parent\r
- Cur = Cur->getParent();\r
- }\r
- else\r
- {\r
- // Current node neither is right child nor has a left child.\r
- // It is either left child or root\r
- // The next higher node is the parent of the first non-left\r
- // child (i.e. either a right child or the root) up in the\r
- // hierarchy. Root's parent is 0.\r
-\r
- while(Cur->isLeftChild())\r
- Cur = Cur->getParent();\r
- Cur = Cur->getParent();\r
- }\r
- }\r
-\r
- const Node* Root;\r
- const Node* Cur;\r
- }; // ConstIterator\r
-\r
-\r
- //! Parent First Iterator.\r
- /** Traverses the tree from top to bottom. Typical usage is\r
- when storing the tree structure, because when reading it\r
- later (and inserting elements) the tree structure will\r
- be the same. */\r
- class ParentFirstIterator\r
- {\r
- public:\r
-\r
- ParentFirstIterator() : Root(0), Cur(0) {}\r
-\r
- explicit ParentFirstIterator(Node* root) : Root(root), Cur(0)\r
- {\r
- reset();\r
- }\r
-\r
- void reset()\r
- {\r
- Cur = Root;\r
- }\r
-\r
- bool atEnd() const\r
- {\r
- return Cur==0;\r
- }\r
-\r
- Node* getNode()\r
- {\r
- return Cur;\r
- }\r
-\r
- void operator++(int)\r
- {\r
- inc();\r
- }\r
-\r
- Node* operator -> ()\r
- {\r
- return getNode();\r
- }\r
-\r
- Node& operator* ()\r
- {\r
- _IRR_DEBUG_BREAK_IF(atEnd()) // access violation\r
-\r
- return *getNode();\r
- }\r
-\r
- private:\r
-\r
- void inc()\r
- {\r
- // Already at end?\r
- if (Cur==0)\r
- return;\r
-\r
- // First we try down to the left\r
- if (Cur->getLeftChild())\r
- {\r
- Cur = Cur->getLeftChild();\r
- }\r
- else if (Cur->getRightChild())\r
- {\r
- // No left child? The we go down to the right.\r
- Cur = Cur->getRightChild();\r
- }\r
- else\r
- {\r
- // No children? Move up in the hierarchy until\r
- // we either reach 0 (and are finished) or\r
- // find a right uncle.\r
- while (Cur!=0)\r
- {\r
- // But if parent is left child and has a right "uncle" the parent\r
- // has already been processed but the uncle hasn't. Move to\r
- // the uncle.\r
- if (Cur->isLeftChild() && Cur->getParent()->getRightChild())\r
- {\r
- Cur = Cur->getParent()->getRightChild();\r
- return;\r
- }\r
- Cur = Cur->getParent();\r
- }\r
- }\r
- }\r
-\r
- Node* Root;\r
- Node* Cur;\r
-\r
- }; // ParentFirstIterator\r
-\r
-\r
- //! Parent Last Iterator\r
- /** Traverse the tree from bottom to top.\r
- Typical usage is when deleting all elements in the tree\r
- because you must delete the children before you delete\r
- their parent. */\r
- class ParentLastIterator\r
- {\r
- public:\r
-\r
- ParentLastIterator() : Root(0), Cur(0) {}\r
-\r
- explicit ParentLastIterator(Node* root) : Root(root), Cur(0)\r
- {\r
- reset();\r
- }\r
-\r
- void reset()\r
- {\r
- Cur = getMin(Root);\r
- }\r
-\r
- bool atEnd() const\r
- {\r
- return Cur==0;\r
- }\r
-\r
- Node* getNode()\r
- {\r
- return Cur;\r
- }\r
-\r
- void operator++(int)\r
- {\r
- inc();\r
- }\r
-\r
- Node* operator -> ()\r
- {\r
- return getNode();\r
- }\r
-\r
- Node& operator* ()\r
- {\r
- _IRR_DEBUG_BREAK_IF(atEnd()) // access violation\r
-\r
- return *getNode();\r
- }\r
- private:\r
-\r
- Node* getMin(Node* n)\r
- {\r
- while(n!=0 && (n->getLeftChild()!=0 || n->getRightChild()!=0))\r
- {\r
- if (n->getLeftChild())\r
- n = n->getLeftChild();\r
- else\r
- n = n->getRightChild();\r
- }\r
- return n;\r
- }\r
-\r
- void inc()\r
- {\r
- // Already at end?\r
- if (Cur==0)\r
- return;\r
-\r
- // Note: Starting point is the node as far down to the left as possible.\r
-\r
- // If current node has an uncle to the right, go to the\r
- // node as far down to the left from the uncle as possible\r
- // else just go up a level to the parent.\r
- if (Cur->isLeftChild() && Cur->getParent()->getRightChild())\r
- {\r
- Cur = getMin(Cur->getParent()->getRightChild());\r
- }\r
- else\r
- Cur = Cur->getParent();\r
- }\r
-\r
- Node* Root;\r
- Node* Cur;\r
- }; // ParentLastIterator\r
-\r
-\r
- // AccessClass is a temporary class used with the [] operator.\r
- // It makes it possible to have different behavior in situations like:\r
- // myTree["Foo"] = 32;\r
- // If "Foo" already exists update its value else insert a new element.\r
- // int i = myTree["Foo"]\r
- // If "Foo" exists return its value.\r
- class AccessClass\r
- {\r
- // Let map be the only one who can instantiate this class.\r
- friend class map<KeyType, ValueType>;\r
-\r
- public:\r
-\r
- // Assignment operator. Handles the myTree["Foo"] = 32; situation\r
- void operator=(const ValueType& value)\r
- {\r
- // Just use the Set method, it handles already exist/not exist situation\r
- Tree.set(Key,value);\r
- }\r
-\r
- // ValueType operator\r
- operator ValueType()\r
- {\r
- Node* node = Tree.find(Key);\r
-\r
- // Not found\r
- _IRR_DEBUG_BREAK_IF(node==0) // access violation\r
-\r
- return node->getValue();\r
- }\r
-\r
- private:\r
-\r
- AccessClass(map& tree, const KeyType& key) : Tree(tree), Key(key) {}\r
-\r
- AccessClass();\r
-\r
- map& Tree;\r
- const KeyType& Key;\r
- }; // AccessClass\r
-\r
-\r
- // Constructor.\r
- map() : Root(0), Size(0) {}\r
-\r
- // Destructor\r
- ~map()\r
- {\r
- clear();\r
- }\r
-\r
- // typedefs\r
- typedef KeyType key_type;\r
- typedef ValueType value_type;\r
- typedef u32 size_type;\r
-\r
- //------------------------------\r
- // Public Commands\r
- //------------------------------\r
-\r
- //! Inserts a new node into the tree\r
- /** \param keyNew: the index for this value\r
- \param v: the value to insert\r
- \return True if successful, false if it fails (already exists) */\r
- bool insert(const KeyType& keyNew, const ValueType& v)\r
- {\r
- // First insert node the "usual" way (no fancy balance logic yet)\r
- Node* newNode = new Node(keyNew,v);\r
- if (!insert(newNode))\r
- {\r
- delete newNode;\r
- return false;\r
- }\r
-\r
- // Then attend a balancing party\r
- while (!newNode->isRoot() && (newNode->getParent()->isRed()))\r
- {\r
- if (newNode->getParent()->isLeftChild())\r
- {\r
- // If newNode is a left child, get its right 'uncle'\r
- Node* newNodesUncle = newNode->getParent()->getParent()->getRightChild();\r
- if ( newNodesUncle!=0 && newNodesUncle->isRed())\r
- {\r
- // case 1 - change the colors\r
- newNode->getParent()->setBlack();\r
- newNodesUncle->setBlack();\r
- newNode->getParent()->getParent()->setRed();\r
- // Move newNode up the tree\r
- newNode = newNode->getParent()->getParent();\r
- }\r
- else\r
- {\r
- // newNodesUncle is a black node\r
- if ( newNode->isRightChild())\r
- {\r
- // and newNode is to the right\r
- // case 2 - move newNode up and rotate\r
- newNode = newNode->getParent();\r
- rotateLeft(newNode);\r
- }\r
- // case 3\r
- newNode->getParent()->setBlack();\r
- newNode->getParent()->getParent()->setRed();\r
- rotateRight(newNode->getParent()->getParent());\r
- }\r
- }\r
- else\r
- {\r
- // If newNode is a right child, get its left 'uncle'\r
- Node* newNodesUncle = newNode->getParent()->getParent()->getLeftChild();\r
- if ( newNodesUncle!=0 && newNodesUncle->isRed())\r
- {\r
- // case 1 - change the colors\r
- newNode->getParent()->setBlack();\r
- newNodesUncle->setBlack();\r
- newNode->getParent()->getParent()->setRed();\r
- // Move newNode up the tree\r
- newNode = newNode->getParent()->getParent();\r
- }\r
- else\r
- {\r
- // newNodesUncle is a black node\r
- if (newNode->isLeftChild())\r
- {\r
- // and newNode is to the left\r
- // case 2 - move newNode up and rotate\r
- newNode = newNode->getParent();\r
- rotateRight(newNode);\r
- }\r
- // case 3\r
- newNode->getParent()->setBlack();\r
- newNode->getParent()->getParent()->setRed();\r
- rotateLeft(newNode->getParent()->getParent());\r
- }\r
-\r
- }\r
- }\r
- // Color the root black\r
- Root->setBlack();\r
- return true;\r
- }\r
-\r
- //! Replaces the value if the key already exists, otherwise inserts a new element.\r
- /** \param k The index for this value\r
- \param v The new value of */\r
- void set(const KeyType& k, const ValueType& v)\r
- {\r
- Node* p = find(k);\r
- if (p)\r
- p->setValue(v);\r
- else\r
- insert(k,v);\r
- }\r
-\r
- //! Removes a node from the tree and returns it.\r
- /** The returned node must be deleted by the user\r
- \param k the key to remove\r
- \return A pointer to the node, or 0 if not found */\r
- Node* delink(const KeyType& k)\r
- {\r
- Node* p = find(k);\r
- if (p == 0)\r
- return 0;\r
-\r
- // Rotate p down to the left until it has no right child, will get there\r
- // sooner or later.\r
- while(p->getRightChild())\r
- {\r
- // "Pull up my right child and let it knock me down to the left"\r
- rotateLeft(p);\r
- }\r
- // p now has no right child but might have a left child\r
- Node* left = p->getLeftChild();\r
-\r
- // Let p's parent point to p's child instead of point to p\r
- if (p->isLeftChild())\r
- p->getParent()->setLeftChild(left);\r
-\r
- else if (p->isRightChild())\r
- p->getParent()->setRightChild(left);\r
-\r
- else\r
- {\r
- // p has no parent => p is the root.\r
- // Let the left child be the new root.\r
- setRoot(left);\r
- }\r
-\r
- // p is now gone from the tree in the sense that\r
- // no one is pointing at it, so return it.\r
-\r
- --Size;\r
- return p;\r
- }\r
-\r
- //! Removes a node from the tree and deletes it.\r
- /** \return True if the node was found and deleted */\r
- bool remove(const KeyType& k)\r
- {\r
- Node* p = find(k);\r
- return remove(p);\r
- }\r
-\r
- //! Removes a node from the tree and deletes it.\r
- /** \return True if the node was found and deleted */\r
- bool remove(Node* p)\r
- {\r
- if (p == 0)\r
- {\r
- return false;\r
- }\r
-\r
- // Rotate p down to the left until it has no right child, will get there\r
- // sooner or later.\r
- while(p->getRightChild())\r
- {\r
- // "Pull up my right child and let it knock me down to the left"\r
- rotateLeft(p);\r
- }\r
- // p now has no right child but might have a left child\r
- Node* left = p->getLeftChild();\r
-\r
- // Let p's parent point to p's child instead of point to p\r
- if (p->isLeftChild())\r
- p->getParent()->setLeftChild(left);\r
-\r
- else if (p->isRightChild())\r
- p->getParent()->setRightChild(left);\r
-\r
- else\r
- {\r
- // p has no parent => p is the root.\r
- // Let the left child be the new root.\r
- setRoot(left);\r
- }\r
-\r
- // p is now gone from the tree in the sense that\r
- // no one is pointing at it. Let's get rid of it.\r
- delete p;\r
-\r
- --Size;\r
- return true;\r
- }\r
-\r
- //! Clear the entire tree\r
- void clear()\r
- {\r
- ParentLastIterator i(getParentLastIterator());\r
-\r
- while(!i.atEnd())\r
- {\r
- Node* p = i.getNode();\r
- i++; // Increment it before it is deleted\r
- // else iterator will get quite confused.\r
- delete p;\r
- }\r
- Root = 0;\r
- Size= 0;\r
- }\r
-\r
- //! Is the tree empty?\r
- //! \return Returns true if empty, false if not\r
- bool empty() const\r
- {\r
- return Root == 0;\r
- }\r
-\r
- //! \deprecated Use empty() instead. This method may be removed by Irrlicht 1.9\r
- _IRR_DEPRECATED_ bool isEmpty() const\r
- {\r
- return empty();\r
- }\r
-\r
- //! Search for a node with the specified key.\r
- //! \param keyToFind: The key to find\r
- //! \return Returns 0 if node couldn't be found.\r
- Node* find(const KeyType& keyToFind) const\r
- {\r
- Node* pNode = Root;\r
-\r
- while(pNode!=0)\r
- {\r
- const KeyType& key=pNode->getKey();\r
-\r
- if (keyToFind == key)\r
- return pNode;\r
- else if (keyToFind < key)\r
- pNode = pNode->getLeftChild();\r
- else //keyToFind > key\r
- pNode = pNode->getRightChild();\r
- }\r
-\r
- return 0;\r
- }\r
-\r
- //! Gets the root element.\r
- //! \return Returns a pointer to the root node, or\r
- //! 0 if the tree is empty.\r
- Node* getRoot() const\r
- {\r
- return Root;\r
- }\r
-\r
- //! Returns the number of nodes in the tree.\r
- u32 size() const\r
- {\r
- return Size;\r
- }\r
-\r
- //! Swap the content of this map container with the content of another map\r
- /** Afterwards this object will contain the content of the other object and the other\r
- object will contain the content of this object. Iterators will afterwards be valid for\r
- the swapped object.\r
- \param other Swap content with this object */\r
- void swap(map<KeyType, ValueType>& other)\r
- {\r
- core::swap(Root, other.Root);\r
- core::swap(Size, other.Size);\r
- }\r
-\r
- //------------------------------\r
- // Public Iterators\r
- //------------------------------\r
-\r
- //! Returns an iterator\r
- Iterator getIterator() const\r
- {\r
- Iterator it(getRoot());\r
- return it;\r
- }\r
-\r
- //! Returns a Constiterator\r
- ConstIterator getConstIterator() const\r
- {\r
- Iterator it(getRoot());\r
- return it;\r
- }\r
-\r
- //! Returns a ParentFirstIterator.\r
- //! Traverses the tree from top to bottom. Typical usage is\r
- //! when storing the tree structure, because when reading it\r
- //! later (and inserting elements) the tree structure will\r
- //! be the same.\r
- ParentFirstIterator getParentFirstIterator() const\r
- {\r
- ParentFirstIterator it(getRoot());\r
- return it;\r
- }\r
-\r
- //! Returns a ParentLastIterator to traverse the tree from\r
- //! bottom to top.\r
- //! Typical usage is when deleting all elements in the tree\r
- //! because you must delete the children before you delete\r
- //! their parent.\r
- ParentLastIterator getParentLastIterator() const\r
- {\r
- ParentLastIterator it(getRoot());\r
- return it;\r
- }\r
-\r
- //------------------------------\r
- // Public Operators\r
- //------------------------------\r
-\r
- //! operator [] for access to elements\r
- /** for example myMap["key"] */\r
- AccessClass operator[](const KeyType& k)\r
- {\r
- return AccessClass(*this, k);\r
- }\r
- private:\r
-\r
- //------------------------------\r
- // Disabled methods\r
- //------------------------------\r
- // Copy constructor and assignment operator deliberately\r
- // defined but not implemented. The tree should never be\r
- // copied, pass along references to it instead.\r
- explicit map(const map& src);\r
- map& operator = (const map& src);\r
-\r
- //! Set node as new root.\r
- /** The node will be set to black, otherwise core dumps may arise\r
- (patch provided by rogerborg).\r
- \param newRoot Node which will be the new root\r
- */\r
- void setRoot(Node* newRoot)\r
- {\r
- Root = newRoot;\r
- if (Root != 0)\r
- {\r
- Root->setParent(0);\r
- Root->setBlack();\r
- }\r
- }\r
-\r
- //! Insert a node into the tree without using any fancy balancing logic.\r
- /** \return false if that key already exist in the tree. */\r
- bool insert(Node* newNode)\r
- {\r
- bool result=true; // Assume success\r
-\r
- if (Root==0)\r
- {\r
- setRoot(newNode);\r
- Size = 1;\r
- }\r
- else\r
- {\r
- Node* pNode = Root;\r
- const KeyType& keyNew = newNode->getKey();\r
- while (pNode)\r
- {\r
- const KeyType& key=pNode->getKey();\r
-\r
- if (keyNew == key)\r
- {\r
- result = false;\r
- pNode = 0;\r
- }\r
- else if (keyNew < key)\r
- {\r
- if (pNode->getLeftChild() == 0)\r
- {\r
- pNode->setLeftChild(newNode);\r
- pNode = 0;\r
- }\r
- else\r
- pNode = pNode->getLeftChild();\r
- }\r
- else // keyNew > key\r
- {\r
- if (pNode->getRightChild()==0)\r
- {\r
- pNode->setRightChild(newNode);\r
- pNode = 0;\r
- }\r
- else\r
- {\r
- pNode = pNode->getRightChild();\r
- }\r
- }\r
- }\r
-\r
- if (result)\r
- ++Size;\r
- }\r
-\r
- return result;\r
- }\r
-\r
- //! Rotate left.\r
- //! Pull up node's right child and let it knock node down to the left\r
- void rotateLeft(Node* p)\r
- {\r
- Node* right = p->getRightChild();\r
-\r
- p->setRightChild(right->getLeftChild());\r
-\r
- if (p->isLeftChild())\r
- p->getParent()->setLeftChild(right);\r
- else if (p->isRightChild())\r
- p->getParent()->setRightChild(right);\r
- else\r
- setRoot(right);\r
-\r
- right->setLeftChild(p);\r
- }\r
-\r
- //! Rotate right.\r
- //! Pull up node's left child and let it knock node down to the right\r
- void rotateRight(Node* p)\r
- {\r
- Node* left = p->getLeftChild();\r
-\r
- p->setLeftChild(left->getRightChild());\r
-\r
- if (p->isLeftChild())\r
- p->getParent()->setLeftChild(left);\r
- else if (p->isRightChild())\r
- p->getParent()->setRightChild(left);\r
- else\r
- setRoot(left);\r
-\r
- left->setRightChild(p);\r
- }\r
-\r
- //------------------------------\r
- // Private Members\r
- //------------------------------\r
- Node* Root; // The top node. 0 if empty.\r
- u32 Size; // Number of nodes in the tree\r
-};\r
-\r
-} // end namespace core\r
-} // end namespace irr\r
-\r
-#endif // __IRR_MAP_H_INCLUDED__\r
-\r
#include "CMeshBuffer.h"\r
#include "SAnimatedMesh.h"\r
#include "os.h"\r
-#include "irrMap.h"\r
#include "triangle3d.h"\r
+#include <map>\r
\r
namespace irr\r
{\r
buf->Vertices.reallocate(vcount);\r
buf->Indices.reallocate(icount);\r
\r
- core::map<const video::S3DVertex, const u16> sind; // search index for fast operation\r
- typedef core::map<const video::S3DVertex, const u16>::Node snode;\r
+ std::map<const video::S3DVertex, const u16> sind; // search index for fast operation\r
+ typedef std::map<const video::S3DVertex, const u16>::iterator snode;\r
\r
// Main algorithm\r
u32 highest = 0;\r
// Output the best triangle\r
u16 newind = buf->Vertices.size();\r
\r
- snode *s = sind.find(v[tc[highest].ind[0]]);\r
+ snode s = sind.find(v[tc[highest].ind[0]]);\r
\r
- if (!s)\r
+ if (s == sind.end())\r
{\r
buf->Vertices.push_back(v[tc[highest].ind[0]]);\r
buf->Indices.push_back(newind);\r
- sind.insert(v[tc[highest].ind[0]], newind);\r
+ sind.emplace(v[tc[highest].ind[0]], newind);\r
newind++;\r
}\r
else\r
{\r
- buf->Indices.push_back(s->getValue());\r
+ buf->Indices.push_back(s->second);\r
}\r
\r
s = sind.find(v[tc[highest].ind[1]]);\r
\r
- if (!s)\r
+ if (s == sind.end())\r
{\r
buf->Vertices.push_back(v[tc[highest].ind[1]]);\r
buf->Indices.push_back(newind);\r
- sind.insert(v[tc[highest].ind[1]], newind);\r
+ sind.emplace(v[tc[highest].ind[1]], newind);\r
newind++;\r
}\r
else\r
{\r
- buf->Indices.push_back(s->getValue());\r
+ buf->Indices.push_back(s->second);\r
}\r
\r
s = sind.find(v[tc[highest].ind[2]]);\r
\r
- if (!s)\r
+ if (s == sind.end())\r
{\r
buf->Vertices.push_back(v[tc[highest].ind[2]]);\r
buf->Indices.push_back(newind);\r
- sind.insert(v[tc[highest].ind[2]], newind);\r
+ sind.emplace(v[tc[highest].ind[2]], newind);\r
}\r
else\r
{\r
- buf->Indices.push_back(s->getValue());\r
+ buf->Indices.push_back(s->second);\r
}\r
\r
vc[tc[highest].ind[0]].NumActiveTris--;\r
buf->Vertices.reallocate(vcount);\r
buf->Indices.reallocate(icount);\r
\r
- core::map<const video::S3DVertex2TCoords, const u16> sind; // search index for fast operation\r
- typedef core::map<const video::S3DVertex2TCoords, const u16>::Node snode;\r
+ std::map<const video::S3DVertex2TCoords, const u16> sind; // search index for fast operation\r
+ typedef std::map<const video::S3DVertex2TCoords, const u16>::iterator snode;\r
\r
// Main algorithm\r
u32 highest = 0;\r
// Output the best triangle\r
u16 newind = buf->Vertices.size();\r
\r
- snode *s = sind.find(v[tc[highest].ind[0]]);\r
+ snode s = sind.find(v[tc[highest].ind[0]]);\r
\r
- if (!s)\r
+ if (s == sind.end())\r
{\r
buf->Vertices.push_back(v[tc[highest].ind[0]]);\r
buf->Indices.push_back(newind);\r
- sind.insert(v[tc[highest].ind[0]], newind);\r
+ sind.emplace(v[tc[highest].ind[0]], newind);\r
newind++;\r
}\r
else\r
{\r
- buf->Indices.push_back(s->getValue());\r
+ buf->Indices.push_back(s->second);\r
}\r
\r
s = sind.find(v[tc[highest].ind[1]]);\r
\r
- if (!s)\r
+ if (s == sind.end())\r
{\r
buf->Vertices.push_back(v[tc[highest].ind[1]]);\r
buf->Indices.push_back(newind);\r
- sind.insert(v[tc[highest].ind[1]], newind);\r
+ sind.emplace(v[tc[highest].ind[1]], newind);\r
newind++;\r
}\r
else\r
{\r
- buf->Indices.push_back(s->getValue());\r
+ buf->Indices.push_back(s->second);\r
}\r
\r
s = sind.find(v[tc[highest].ind[2]]);\r
\r
- if (!s)\r
+ if (s == sind.end())\r
{\r
buf->Vertices.push_back(v[tc[highest].ind[2]]);\r
buf->Indices.push_back(newind);\r
- sind.insert(v[tc[highest].ind[2]], newind);\r
+ sind.emplace(v[tc[highest].ind[2]], newind);\r
}\r
else\r
{\r
- buf->Indices.push_back(s->getValue());\r
+ buf->Indices.push_back(s->second);\r
}\r
\r
vc[tc[highest].ind[0]].NumActiveTris--;\r
buf->Vertices.reallocate(vcount);\r
buf->Indices.reallocate(icount);\r
\r
- core::map<const video::S3DVertexTangents, const u16> sind; // search index for fast operation\r
- typedef core::map<const video::S3DVertexTangents, const u16>::Node snode;\r
+ std::map<const video::S3DVertexTangents, const u16> sind; // search index for fast operation\r
+ typedef std::map<const video::S3DVertexTangents, const u16>::iterator snode;\r
\r
// Main algorithm\r
u32 highest = 0;\r
// Output the best triangle\r
u16 newind = buf->Vertices.size();\r
\r
- snode *s = sind.find(v[tc[highest].ind[0]]);\r
+ snode s = sind.find(v[tc[highest].ind[0]]);\r
\r
- if (!s)\r
+ if (s == sind.end())\r
{\r
buf->Vertices.push_back(v[tc[highest].ind[0]]);\r
buf->Indices.push_back(newind);\r
- sind.insert(v[tc[highest].ind[0]], newind);\r
+ sind.emplace(v[tc[highest].ind[0]], newind);\r
newind++;\r
}\r
else\r
{\r
- buf->Indices.push_back(s->getValue());\r
+ buf->Indices.push_back(s->second);\r
}\r
\r
s = sind.find(v[tc[highest].ind[1]]);\r
\r
- if (!s)\r
+ if (s == sind.end())\r
{\r
buf->Vertices.push_back(v[tc[highest].ind[1]]);\r
buf->Indices.push_back(newind);\r
- sind.insert(v[tc[highest].ind[1]], newind);\r
+ sind.emplace(v[tc[highest].ind[1]], newind);\r
newind++;\r
}\r
else\r
{\r
- buf->Indices.push_back(s->getValue());\r
+ buf->Indices.push_back(s->second);\r
}\r
\r
s = sind.find(v[tc[highest].ind[2]]);\r
\r
- if (!s)\r
+ if (s == sind.end())\r
{\r
buf->Vertices.push_back(v[tc[highest].ind[2]]);\r
buf->Indices.push_back(newind);\r
- sind.insert(v[tc[highest].ind[2]], newind);\r
+ sind.emplace(v[tc[highest].ind[2]], newind);\r
}\r
else\r
{\r
- buf->Indices.push_back(s->getValue());\r
+ buf->Indices.push_back(s->second);\r
}\r
\r
vc[tc[highest].ind[0]].NumActiveTris--;\r