summaryrefslogtreecommitdiff
path: root/core/map.h
diff options
context:
space:
mode:
Diffstat (limited to 'core/map.h')
-rw-r--r--core/map.h507
1 files changed, 244 insertions, 263 deletions
diff --git a/core/map.h b/core/map.h
index d1a4c209ad..e9700ff371 100644
--- a/core/map.h
+++ b/core/map.h
@@ -37,7 +37,7 @@
// based on the very nice implementation of rb-trees by:
// http://web.mit.edu/~emin/www/source_code/red_black_tree/index.html
-template <class K,class V,class C=Comparator<K>,class A=DefaultAllocator>
+template <class K, class V, class C = Comparator<K>, class A = DefaultAllocator>
class Map {
enum Color {
@@ -45,26 +45,25 @@ class Map {
BLACK
};
struct _Data;
-public:
+public:
class Element {
private:
- friend class Map<K,V,C,A>;
+ friend class Map<K, V, C, A>;
//Color color;
int color;
- Element* right;
- Element* left;
- Element* parent;
- Element* _next;
- Element* _prev;
+ Element *right;
+ Element *left;
+ Element *parent;
+ Element *_next;
+ Element *_prev;
K _key;
V _value;
//_Data *data;
public:
-
const Element *next() const {
return _next;
@@ -81,64 +80,62 @@ public:
return _prev;
}
- const K& key() const {
+ const K &key() const {
return _key;
};
- V& value() {
+ V &value() {
return _value;
};
- const V& value() const {
+ const V &value() const {
return _value;
};
- V& get() {
+ V &get() {
return _value;
};
- const V& get() const {
+ const V &get() const {
return _value;
};
Element() {
- color=RED;
- right=NULL;
- left=NULL;
- parent=NULL;
- _next=NULL;
- _prev=NULL;
+ color = RED;
+ right = NULL;
+ left = NULL;
+ parent = NULL;
+ _next = NULL;
+ _prev = NULL;
};
};
-
private:
-
struct _Data {
- Element* _root;
- Element* _nil;
+ Element *_root;
+ Element *_nil;
int size_cache;
_FORCE_INLINE_ _Data() {
#ifdef GLOBALNIL_DISABLED
- _nil = memnew_allocator( Element, A );
- _nil->parent=_nil->left=_nil->right=_nil;
- _nil->color=BLACK;
+ _nil = memnew_allocator(Element, A);
+ _nil->parent = _nil->left = _nil->right = _nil;
+ _nil->color = BLACK;
#else
- _nil=(Element*)&_GlobalNilClass::_nil;
+ _nil = (Element *)&_GlobalNilClass::_nil;
#endif
- _root=NULL;
- size_cache=0;
+ _root = NULL;
+ size_cache = 0;
}
void _create_root() {
- _root = memnew_allocator( Element,A );
- _root->parent=_root->left=_root->right=_nil;
- _root->color=BLACK;
+ _root = memnew_allocator(Element, A);
+ _root->parent = _root->left = _root->right = _nil;
+ _root->color = BLACK;
}
void _free_root() {
if (_root) {
- memdelete_allocator<Element,A>(_root);
- _root=NULL;
+ memdelete_allocator<Element, A>(_root);
+ _root = NULL;
}
}
@@ -147,7 +144,7 @@ private:
_free_root();
#ifdef GLOBALNIL_DISABLED
- memdelete_allocator<Element,A>(_nil);
+ memdelete_allocator<Element, A>(_nil);
#endif
//memdelete_allocator<Element,A>(_root);
}
@@ -157,58 +154,56 @@ private:
inline void _set_color(Element *p_node, int p_color) {
- ERR_FAIL_COND( p_node == _data._nil && p_color == RED );
- p_node->color=p_color;
+ ERR_FAIL_COND(p_node == _data._nil && p_color == RED);
+ p_node->color = p_color;
}
inline void _rotate_left(Element *p_node) {
- Element *r=p_node->right;
- p_node->right=r->left;
- if (r->left != _data._nil )
- r->left->parent=p_node;
- r->parent=p_node->parent;
- if (p_node==p_node->parent->left)
- p_node->parent->left=r;
+ Element *r = p_node->right;
+ p_node->right = r->left;
+ if (r->left != _data._nil)
+ r->left->parent = p_node;
+ r->parent = p_node->parent;
+ if (p_node == p_node->parent->left)
+ p_node->parent->left = r;
else
- p_node->parent->right=r;
-
- r->left=p_node;
- p_node->parent=r;
+ p_node->parent->right = r;
+ r->left = p_node;
+ p_node->parent = r;
}
inline void _rotate_right(Element *p_node) {
- Element *l=p_node->left;
- p_node->left=l->right;
+ Element *l = p_node->left;
+ p_node->left = l->right;
if (l->right != _data._nil)
- l->right->parent=p_node;
- l->parent=p_node->parent;
- if (p_node==p_node->parent->right)
- p_node->parent->right=l;
+ l->right->parent = p_node;
+ l->parent = p_node->parent;
+ if (p_node == p_node->parent->right)
+ p_node->parent->right = l;
else
- p_node->parent->left=l;
-
- l->right=p_node;
- p_node->parent=l;
+ p_node->parent->left = l;
+ l->right = p_node;
+ p_node->parent = l;
}
- inline Element* _successor(Element *p_node) const {
+ inline Element *_successor(Element *p_node) const {
- Element *node=p_node;
+ Element *node = p_node;
if (node->right != _data._nil) {
- node=node->right;
- while(node->left != _data._nil) { /* returns the minium of the right subtree of node */
- node=node->left;
+ node = node->right;
+ while (node->left != _data._nil) { /* returns the minium of the right subtree of node */
+ node = node->left;
}
return node;
} else {
- while(node == node->parent->right) {
- node=node->parent;
+ while (node == node->parent->right) {
+ node = node->parent;
}
if (node->parent == _data._root)
return NULL;
@@ -216,419 +211,408 @@ private:
}
}
- inline Element* _predecessor(Element *p_node) const {
- Element *node=p_node;
+ inline Element *_predecessor(Element *p_node) const {
+ Element *node = p_node;
if (node->left != _data._nil) {
- node=node->left;
- while(node->right != _data._nil) { /* returns the minium of the left subtree of node */
- node=node->right;
+ node = node->left;
+ while (node->right != _data._nil) { /* returns the minium of the left subtree of node */
+ node = node->right;
}
return node;
} else {
- while(node == node->parent->left) {
+ while (node == node->parent->left) {
if (node->parent == _data._root)
return NULL;
- node=node->parent;
+ node = node->parent;
}
return node->parent;
}
}
-
- Element *_find(const K& p_key) const {
+ Element *_find(const K &p_key) const {
Element *node = _data._root->left;
C less;
- while(node!=_data._nil) {
+ while (node != _data._nil) {
- if (less(p_key,node->_key))
- node=node->left;
- else if (less(node->_key,p_key))
- node=node->right;
+ if (less(p_key, node->_key))
+ node = node->left;
+ else if (less(node->_key, p_key))
+ node = node->right;
else
break; // found
}
- return (node!=_data._nil)?node:NULL;
+ return (node != _data._nil) ? node : NULL;
}
- Element *_find_closest(const K& p_key) const {
+ Element *_find_closest(const K &p_key) const {
Element *node = _data._root->left;
Element *prev = NULL;
C less;
- while(node!=_data._nil) {
- prev=node;
+ while (node != _data._nil) {
+ prev = node;
- if (less(p_key,node->_key))
- node=node->left;
- else if (less(node->_key,p_key))
- node=node->right;
+ if (less(p_key, node->_key))
+ node = node->left;
+ else if (less(node->_key, p_key))
+ node = node->right;
else
break; // found
}
- if (node==_data._nil) {
- if (prev==NULL)
+ if (node == _data._nil) {
+ if (prev == NULL)
return NULL;
- if (less(p_key,prev->_key)) {
+ if (less(p_key, prev->_key)) {
- prev=prev->_prev;
+ prev = prev->_prev;
}
return prev;
} else
return node;
-
}
- Element *_insert(const K& p_key, bool& r_exists) {
+ Element *_insert(const K &p_key, bool &r_exists) {
- Element *new_parent=_data._root;
+ Element *new_parent = _data._root;
Element *node = _data._root->left;
C less;
- while (node!=_data._nil) {
+ while (node != _data._nil) {
- new_parent=node;
+ new_parent = node;
- if (less(p_key,node->_key))
- node=node->left;
- else if (less(node->_key,p_key))
- node=node->right;
+ if (less(p_key, node->_key))
+ node = node->left;
+ else if (less(node->_key, p_key))
+ node = node->right;
else {
- r_exists=true;
+ r_exists = true;
return node;
}
}
- Element *new_node = memnew_allocator( Element, A );
+ Element *new_node = memnew_allocator(Element, A);
-
- new_node->parent=new_parent;
- new_node->right=_data._nil;
- new_node->left=_data._nil;
- new_node->_key=p_key;
+ new_node->parent = new_parent;
+ new_node->right = _data._nil;
+ new_node->left = _data._nil;
+ new_node->_key = p_key;
//new_node->data=_data;
- if (new_parent==_data._root || less(p_key,new_parent->_key)) {
+ if (new_parent == _data._root || less(p_key, new_parent->_key)) {
- new_parent->left=new_node;
+ new_parent->left = new_node;
} else {
- new_parent->right=new_node;
+ new_parent->right = new_node;
}
- r_exists=false;
+ r_exists = false;
- new_node->_next=_successor(new_node);
- new_node->_prev=_predecessor(new_node);
+ new_node->_next = _successor(new_node);
+ new_node->_prev = _predecessor(new_node);
if (new_node->_next)
- new_node->_next->_prev=new_node;
+ new_node->_next->_prev = new_node;
if (new_node->_prev)
- new_node->_prev->_next=new_node;
-
+ new_node->_prev->_next = new_node;
return new_node;
}
- Element * _insert_rb(const K& p_key, const V& p_value) {
+ Element *_insert_rb(const K &p_key, const V &p_value) {
- bool exists=false;
- Element *new_node = _insert(p_key,exists);
+ bool exists = false;
+ Element *new_node = _insert(p_key, exists);
if (new_node) {
- new_node->_value=p_value;
+ new_node->_value = p_value;
}
if (exists)
return new_node;
- Element *node=new_node;
+ Element *node = new_node;
_data.size_cache++;
- while(node->parent->color==RED) {
+ while (node->parent->color == RED) {
if (node->parent == node->parent->parent->left) {
- Element *aux=node->parent->parent->right;
+ Element *aux = node->parent->parent->right;
- if (aux->color==RED) {
- _set_color(node->parent,BLACK);
- _set_color(aux,BLACK);
- _set_color(node->parent->parent,RED);
- node=node->parent->parent;
+ if (aux->color == RED) {
+ _set_color(node->parent, BLACK);
+ _set_color(aux, BLACK);
+ _set_color(node->parent->parent, RED);
+ node = node->parent->parent;
} else {
if (node == node->parent->right) {
- node=node->parent;
+ node = node->parent;
_rotate_left(node);
}
- _set_color(node->parent,BLACK);
- _set_color(node->parent->parent,RED);
+ _set_color(node->parent, BLACK);
+ _set_color(node->parent->parent, RED);
_rotate_right(node->parent->parent);
}
} else {
- Element *aux=node->parent->parent->left;
+ Element *aux = node->parent->parent->left;
- if (aux->color==RED) {
- _set_color(node->parent,BLACK);
- _set_color(aux,BLACK);
- _set_color(node->parent->parent,RED);
- node=node->parent->parent;
+ if (aux->color == RED) {
+ _set_color(node->parent, BLACK);
+ _set_color(aux, BLACK);
+ _set_color(node->parent->parent, RED);
+ node = node->parent->parent;
} else {
if (node == node->parent->left) {
- node=node->parent;
+ node = node->parent;
_rotate_right(node);
}
- _set_color(node->parent,BLACK);
- _set_color(node->parent->parent,RED);
+ _set_color(node->parent, BLACK);
+ _set_color(node->parent->parent, RED);
_rotate_left(node->parent->parent);
}
}
}
- _set_color(_data._root->left,BLACK);
+ _set_color(_data._root->left, BLACK);
return new_node;
}
void _erase_fix(Element *p_node) {
Element *root = _data._root->left;
- Element *node=p_node;
-
+ Element *node = p_node;
- while( (node->color==BLACK) && (root != node)) {
+ while ((node->color == BLACK) && (root != node)) {
if (node == node->parent->left) {
- Element *aux=node->parent->right;
- if (aux->color==RED) {
- _set_color(aux,BLACK);
- _set_color(node->parent,RED);
+ Element *aux = node->parent->right;
+ if (aux->color == RED) {
+ _set_color(aux, BLACK);
+ _set_color(node->parent, RED);
_rotate_left(node->parent);
- aux=node->parent->right;
+ aux = node->parent->right;
}
- if ( (aux->right->color==BLACK) && (aux->left->color==BLACK) ) {
- _set_color(aux,RED);
- node=node->parent;
+ if ((aux->right->color == BLACK) && (aux->left->color == BLACK)) {
+ _set_color(aux, RED);
+ node = node->parent;
} else {
- if (aux->right->color==BLACK) {
- _set_color(aux->left,BLACK);
- _set_color(aux,RED);
+ if (aux->right->color == BLACK) {
+ _set_color(aux->left, BLACK);
+ _set_color(aux, RED);
_rotate_right(aux);
- aux=node->parent->right;
+ aux = node->parent->right;
}
- _set_color(aux,node->parent->color);
- _set_color(node->parent,BLACK);
- _set_color(aux->right,BLACK);
+ _set_color(aux, node->parent->color);
+ _set_color(node->parent, BLACK);
+ _set_color(aux->right, BLACK);
_rotate_left(node->parent);
- node=root; /* this is to exit while loop */
+ node = root; /* this is to exit while loop */
}
} else { /* the code below is has left and right switched from above */
- Element *aux=node->parent->left;
- if (aux->color==RED) {
- _set_color(aux,BLACK);
- _set_color(node->parent,RED);
+ Element *aux = node->parent->left;
+ if (aux->color == RED) {
+ _set_color(aux, BLACK);
+ _set_color(node->parent, RED);
_rotate_right(node->parent);
- aux=node->parent->left;
+ aux = node->parent->left;
}
- if ( (aux->right->color==BLACK) && (aux->left->color==BLACK) ) {
- _set_color(aux,RED);
- node=node->parent;
+ if ((aux->right->color == BLACK) && (aux->left->color == BLACK)) {
+ _set_color(aux, RED);
+ node = node->parent;
} else {
- if (aux->left->color==BLACK) {
- _set_color(aux->right,BLACK);
- _set_color(aux,RED);
+ if (aux->left->color == BLACK) {
+ _set_color(aux->right, BLACK);
+ _set_color(aux, RED);
_rotate_left(aux);
- aux=node->parent->left;
+ aux = node->parent->left;
}
- _set_color(aux,node->parent->color);
- _set_color(node->parent,BLACK);
- _set_color(aux->left,BLACK);
+ _set_color(aux, node->parent->color);
+ _set_color(node->parent, BLACK);
+ _set_color(aux->left, BLACK);
_rotate_right(node->parent);
- node=root;
+ node = root;
}
}
}
- _set_color(node,BLACK);
+ _set_color(node, BLACK);
- ERR_FAIL_COND(_data._nil->color!=BLACK);
+ ERR_FAIL_COND(_data._nil->color != BLACK);
}
void _erase(Element *p_node) {
-
- Element *rp= ((p_node->left == _data._nil) || (p_node->right == _data._nil)) ? p_node : _successor(p_node);
+ Element *rp = ((p_node->left == _data._nil) || (p_node->right == _data._nil)) ? p_node : _successor(p_node);
if (!rp)
- rp=_data._nil;
- Element *node= (rp->left == _data._nil) ? rp->right : rp->left;
+ rp = _data._nil;
+ Element *node = (rp->left == _data._nil) ? rp->right : rp->left;
- if (_data._root == (node->parent=rp->parent) ) {
- _data._root->left=node;
+ if (_data._root == (node->parent = rp->parent)) {
+ _data._root->left = node;
} else {
if (rp == rp->parent->left) {
- rp->parent->left=node;
+ rp->parent->left = node;
} else {
- rp->parent->right=node;
+ rp->parent->right = node;
}
}
if (rp != p_node) {
- ERR_FAIL_COND( rp == _data._nil );
+ ERR_FAIL_COND(rp == _data._nil);
- if (rp->color==BLACK)
+ if (rp->color == BLACK)
_erase_fix(node);
-
- rp->left=p_node->left;
- rp->right=p_node->right;
- rp->parent=p_node->parent;
- rp->color=p_node->color;
- p_node->left->parent=rp;
- p_node->right->parent=rp;
+ rp->left = p_node->left;
+ rp->right = p_node->right;
+ rp->parent = p_node->parent;
+ rp->color = p_node->color;
+ p_node->left->parent = rp;
+ p_node->right->parent = rp;
if (p_node == p_node->parent->left) {
- p_node->parent->left=rp;
+ p_node->parent->left = rp;
} else {
- p_node->parent->right=rp;
+ p_node->parent->right = rp;
}
} else {
- if (p_node->color==BLACK)
+ if (p_node->color == BLACK)
_erase_fix(node);
-
}
-
if (p_node->_next)
- p_node->_next->_prev=p_node->_prev;
+ p_node->_next->_prev = p_node->_prev;
if (p_node->_prev)
- p_node->_prev->_next=p_node->_next;
+ p_node->_prev->_next = p_node->_next;
- memdelete_allocator<Element,A>(p_node);
+ memdelete_allocator<Element, A>(p_node);
_data.size_cache--;
- ERR_FAIL_COND( _data._nil->color==RED );
+ ERR_FAIL_COND(_data._nil->color == RED);
}
+ void _calculate_depth(Element *p_element, int &max_d, int d) const {
- void _calculate_depth(Element *p_element,int &max_d,int d) const {
-
- if (p_element==_data._nil) {
+ if (p_element == _data._nil) {
return;
}
- _calculate_depth(p_element->left,max_d,d+1);
- _calculate_depth(p_element->right,max_d,d+1);
- if (d>max_d)
- max_d=d;
+ _calculate_depth(p_element->left, max_d, d + 1);
+ _calculate_depth(p_element->right, max_d, d + 1);
+ if (d > max_d)
+ max_d = d;
}
void _cleanup_tree(Element *p_element) {
- if (p_element==_data._nil)
+ if (p_element == _data._nil)
return;
_cleanup_tree(p_element->left);
_cleanup_tree(p_element->right);
- memdelete_allocator<Element,A>( p_element );
+ memdelete_allocator<Element, A>(p_element);
}
- void _copy_from( const Map& p_map) {
+ void _copy_from(const Map &p_map) {
clear();
// not the fastest way, but safeset to write.
- for(Element *I=p_map.front();I;I=I->next()) {
+ for (Element *I = p_map.front(); I; I = I->next()) {
- insert(I->key(),I->value());
+ insert(I->key(), I->value());
}
}
-public:
- const Element *find(const K& p_key) const {
+public:
+ const Element *find(const K &p_key) const {
if (!_data._root)
return NULL;
- const Element *res=_find(p_key);
+ const Element *res = _find(p_key);
return res;
}
- Element *find(const K& p_key) {
+ Element *find(const K &p_key) {
if (!_data._root)
return NULL;
- Element *res=_find(p_key);
+ Element *res = _find(p_key);
return res;
}
- const Element *find_closest(const K& p_key) const {
+ const Element *find_closest(const K &p_key) const {
if (!_data._root)
return NULL;
- const Element *res=_find_closest(p_key);
+ const Element *res = _find_closest(p_key);
return res;
}
- Element *find_closest(const K& p_key) {
+ Element *find_closest(const K &p_key) {
if (!_data._root)
return NULL;
- Element *res=_find_closest(p_key);
+ Element *res = _find_closest(p_key);
return res;
}
- Element *insert(const K& p_key,const V& p_value) {
+ Element *insert(const K &p_key, const V &p_value) {
if (!_data._root)
_data._create_root();
- return _insert_rb(p_key,p_value);
-
+ return _insert_rb(p_key, p_value);
}
- void erase(Element* p_element) {
+ void erase(Element *p_element) {
if (!_data._root)
return;
_erase(p_element);
- if (_data.size_cache==0 && _data._root)
+ if (_data.size_cache == 0 && _data._root)
_data._free_root();
}
- bool erase(const K& p_key) {
+ bool erase(const K &p_key) {
if (!_data._root)
return false;
- Element *e=find(p_key);
+ Element *e = find(p_key);
if (!e)
return false;
_erase(e);
return true;
}
- bool has(const K& p_key) const {
+ bool has(const K &p_key) const {
if (!_data._root)
return false;
return find(p_key) != NULL;
}
- const V& operator[](const K& p_key) const {
+ const V &operator[](const K &p_key) const {
- ERR_FAIL_COND_V(!_data._root, *(V*)NULL); // crash on purpose
- const Element *e=find(p_key);
- ERR_FAIL_COND_V(!e, *(V*)NULL); // crash on purpose
+ ERR_FAIL_COND_V(!_data._root, *(V *)NULL); // crash on purpose
+ const Element *e = find(p_key);
+ ERR_FAIL_COND_V(!e, *(V *)NULL); // crash on purpose
return e->_value;
}
- V& operator[](const K& p_key) {
+ V &operator[](const K &p_key) {
if (!_data._root)
_data._create_root();
- Element *e=find(p_key);
+ Element *e = find(p_key);
if (!e)
- e=insert(p_key,V());
+ e = insert(p_key, V());
- ERR_FAIL_COND_V(!e, *(V*)NULL); // crash on purpose
+ ERR_FAIL_COND_V(!e, *(V *)NULL); // crash on purpose
return e->_value;
}
@@ -637,12 +621,12 @@ public:
if (!_data._root)
return NULL;
- Element *e=_data._root->left;
- if (e==_data._nil)
+ Element *e = _data._root->left;
+ if (e == _data._nil)
return NULL;
- while(e->left!=_data._nil)
- e=e->left;
+ while (e->left != _data._nil)
+ e = e->left;
return e;
}
@@ -651,24 +635,24 @@ public:
if (!_data._root)
return NULL;
- Element *e=_data._root->left;
- if (e==_data._nil)
+ Element *e = _data._root->left;
+ if (e == _data._nil)
return NULL;
- while(e->right!=_data._nil)
- e=e->right;
+ while (e->right != _data._nil)
+ e = e->right;
return e;
}
- inline bool empty() const { return _data.size_cache==0; }
+ inline bool empty() const { return _data.size_cache == 0; }
inline int size() const { return _data.size_cache; }
int calculate_depth() const {
// used for debug mostly
if (!_data._root)
return 0;
- int max_d=0;
- _calculate_depth(_data._root->left,max_d,0);
+ int max_d = 0;
+ _calculate_depth(_data._root->left, max_d, 0);
return max_d;
}
@@ -677,32 +661,29 @@ public:
if (!_data._root)
return;
_cleanup_tree(_data._root->left);
- _data._root->left=_data._nil;
- _data.size_cache=0;
- _data._nil->parent=_data._nil;
+ _data._root->left = _data._nil;
+ _data.size_cache = 0;
+ _data._nil->parent = _data._nil;
_data._free_root();
}
- void operator=(const Map& p_map) {
+ void operator=(const Map &p_map) {
- _copy_from( p_map );
+ _copy_from(p_map);
}
- Map(const Map& p_map) {
+ Map(const Map &p_map) {
- _copy_from( p_map );
+ _copy_from(p_map);
}
_FORCE_INLINE_ Map() {
-
}
-
~Map() {
clear();
}
-
};
#endif