| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*  set.h                                                                */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       This file is part of:                           */ | 
					
						
							|  |  |  | /*                           GODOT ENGINE                                */ | 
					
						
							| 
									
										
										
										
											2017-08-27 14:16:55 +02:00
										 |  |  | /*                      https://godotengine.org                          */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2021-01-01 20:13:46 +01:00
										 |  |  | /* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */ | 
					
						
							|  |  |  | /* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* Permission is hereby granted, free of charge, to any person obtaining */ | 
					
						
							|  |  |  | /* a copy of this software and associated documentation files (the       */ | 
					
						
							|  |  |  | /* "Software"), to deal in the Software without restriction, including   */ | 
					
						
							|  |  |  | /* without limitation the rights to use, copy, modify, merge, publish,   */ | 
					
						
							|  |  |  | /* distribute, sublicense, and/or sell copies of the Software, and to    */ | 
					
						
							|  |  |  | /* permit persons to whom the Software is furnished to do so, subject to */ | 
					
						
							|  |  |  | /* the following conditions:                                             */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* The above copyright notice and this permission notice shall be        */ | 
					
						
							|  |  |  | /* included in all copies or substantial portions of the Software.       */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */ | 
					
						
							|  |  |  | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */ | 
					
						
							|  |  |  | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ | 
					
						
							|  |  |  | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */ | 
					
						
							|  |  |  | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */ | 
					
						
							|  |  |  | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */ | 
					
						
							|  |  |  | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2018-01-05 00:50:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #ifndef SET_H
 | 
					
						
							|  |  |  | #define SET_H
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-11 18:13:45 +02:00
										 |  |  | #include "core/os/memory.h"
 | 
					
						
							|  |  |  | #include "core/typedefs.h"
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | // based on the very nice implementation of rb-trees by:
 | 
					
						
							| 
									
										
										
										
											2019-07-23 21:06:12 -03:00
										 |  |  | // https://web.archive.org/web/20120507164830/http://web.mit.edu/~emin/www/source_code/red_black_tree/index.html
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | template <class T, class C = Comparator<T>, class A = DefaultAllocator> | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | class Set { | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 	enum Color { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		RED, | 
					
						
							|  |  |  | 		BLACK | 
					
						
							|  |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 	struct _Data; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | public: | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	class Element { | 
					
						
							|  |  |  | 	private: | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		friend class Set<T, C, A>; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		int color; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		Element *right; | 
					
						
							|  |  |  | 		Element *left; | 
					
						
							|  |  |  | 		Element *parent; | 
					
						
							|  |  |  | 		Element *_next; | 
					
						
							|  |  |  | 		Element *_prev; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		T value; | 
					
						
							|  |  |  | 		//_Data *data;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	public: | 
					
						
							|  |  |  | 		const Element *next() const { | 
					
						
							|  |  |  | 			return _next; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		Element *next() { | 
					
						
							|  |  |  | 			return _next; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		const Element *prev() const { | 
					
						
							|  |  |  | 			return _prev; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		Element *prev() { | 
					
						
							|  |  |  | 			return _prev; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		const T &get() const { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return value; | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 		Element() { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			color = RED; | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 			right = nullptr; | 
					
						
							|  |  |  | 			left = nullptr; | 
					
						
							|  |  |  | 			parent = nullptr; | 
					
						
							|  |  |  | 			_next = nullptr; | 
					
						
							|  |  |  | 			_prev = nullptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		}; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private: | 
					
						
							|  |  |  | 	struct _Data { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		Element *_root; | 
					
						
							|  |  |  | 		Element *_nil; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		int size_cache; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-20 18:52:40 +01:00
										 |  |  | 		_FORCE_INLINE_ _Data() { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #ifdef GLOBALNIL_DISABLED
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			_nil = memnew_allocator(Element, A); | 
					
						
							|  |  |  | 			_nil->parent = _nil->left = _nil->right = _nil; | 
					
						
							|  |  |  | 			_nil->color = BLACK; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			_nil = (Element *)&_GlobalNilClass::_nil; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 			_root = nullptr; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			size_cache = 0; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		void _create_root() { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			_root = memnew_allocator(Element, A); | 
					
						
							|  |  |  | 			_root->parent = _root->left = _root->right = _nil; | 
					
						
							|  |  |  | 			_root->color = BLACK; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		void _free_root() { | 
					
						
							|  |  |  | 			if (_root) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				memdelete_allocator<Element, A>(_root); | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 				_root = nullptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		~_Data() { | 
					
						
							|  |  |  | 			_free_root(); | 
					
						
							| 
									
										
										
										
											2017-09-20 18:52:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #ifdef GLOBALNIL_DISABLED
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			memdelete_allocator<Element, A>(_nil); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	_Data _data; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	inline void _set_color(Element *p_node, int p_color) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		ERR_FAIL_COND(p_node == _data._nil && p_color == RED); | 
					
						
							|  |  |  | 		p_node->color = p_color; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	inline void _rotate_left(Element *p_node) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		Element *r = p_node->right; | 
					
						
							|  |  |  | 		p_node->right = r->left; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (r->left != _data._nil) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			r->left->parent = p_node; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		r->parent = p_node->parent; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (p_node == p_node->parent->left) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			p_node->parent->left = r; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			p_node->parent->right = r; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		r->left = p_node; | 
					
						
							|  |  |  | 		p_node->parent = r; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	inline void _rotate_right(Element *p_node) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		Element *l = p_node->left; | 
					
						
							|  |  |  | 		p_node->left = l->right; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (l->right != _data._nil) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			l->right->parent = p_node; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		l->parent = p_node->parent; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (p_node == p_node->parent->right) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			p_node->parent->right = l; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			p_node->parent->left = l; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		l->right = p_node; | 
					
						
							|  |  |  | 		p_node->parent = l; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	inline Element *_successor(Element *p_node) const { | 
					
						
							|  |  |  | 		Element *node = p_node; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		if (node->right != _data._nil) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			node = node->right; | 
					
						
							| 
									
										
										
										
											2018-02-21 11:30:55 -05:00
										 |  |  | 			while (node->left != _data._nil) { /* returns the minimum of the right subtree of node */ | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				node = node->left; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			return node; | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			while (node == node->parent->right) { | 
					
						
							|  |  |  | 				node = node->parent; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			if (node->parent == _data._root) { | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 				return nullptr; // No successor, as p_node = last node
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return node->parent; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	inline Element *_predecessor(Element *p_node) const { | 
					
						
							|  |  |  | 		Element *node = p_node; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		if (node->left != _data._nil) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			node = node->left; | 
					
						
							| 
									
										
										
										
											2018-02-21 11:30:55 -05:00
										 |  |  | 			while (node->right != _data._nil) { /* returns the minimum of the left subtree of node */ | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				node = node->right; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			return node; | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			while (node == node->parent->left) { | 
					
						
							|  |  |  | 				node = node->parent; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			if (node == _data._root) { | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 				return nullptr; // No predecessor, as p_node = first node.
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return node->parent; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	Element *_find(const T &p_value) const { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		Element *node = _data._root->left; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 		C less; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		while (node != _data._nil) { | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			if (less(p_value, node->value)) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				node = node->left; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			} else if (less(node->value, p_value)) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				node = node->right; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 				return node; // found
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 		return nullptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	Element *_lower_bound(const T &p_value) const { | 
					
						
							| 
									
										
										
										
											2015-02-15 01:19:46 -03:00
										 |  |  | 		Element *node = _data._root->left; | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 		Element *prev = nullptr; | 
					
						
							| 
									
										
										
										
											2015-02-15 01:19:46 -03:00
										 |  |  | 		C less; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		while (node != _data._nil) { | 
					
						
							|  |  |  | 			prev = node; | 
					
						
							| 
									
										
										
										
											2015-02-15 01:19:46 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			if (less(p_value, node->value)) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				node = node->left; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			} else if (less(node->value, p_value)) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				node = node->right; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 				return node; // found
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-02-15 01:19:46 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (prev == nullptr) { | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 			return nullptr; // tree empty
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-02-15 01:19:46 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (less(prev->value, p_value)) { | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 			prev = prev->_next; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-02-15 01:19:46 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 		return prev; | 
					
						
							| 
									
										
										
										
											2015-02-15 01:19:46 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-20 18:52:40 +01:00
										 |  |  | 	void _insert_rb_fix(Element *p_new_node) { | 
					
						
							|  |  |  | 		Element *node = p_new_node; | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 		Element *nparent = node->parent; | 
					
						
							|  |  |  | 		Element *ngrand_parent; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 		while (nparent->color == RED) { | 
					
						
							|  |  |  | 			ngrand_parent = nparent->parent; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 			if (nparent == ngrand_parent->left) { | 
					
						
							|  |  |  | 				if (ngrand_parent->right->color == RED) { | 
					
						
							|  |  |  | 					_set_color(nparent, BLACK); | 
					
						
							|  |  |  | 					_set_color(ngrand_parent->right, BLACK); | 
					
						
							|  |  |  | 					_set_color(ngrand_parent, RED); | 
					
						
							|  |  |  | 					node = ngrand_parent; | 
					
						
							|  |  |  | 					nparent = node->parent; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				} else { | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 					if (node == nparent->right) { | 
					
						
							|  |  |  | 						_rotate_left(nparent); | 
					
						
							|  |  |  | 						node = nparent; | 
					
						
							|  |  |  | 						nparent = node->parent; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 					_set_color(nparent, BLACK); | 
					
						
							|  |  |  | 					_set_color(ngrand_parent, RED); | 
					
						
							|  |  |  | 					_rotate_right(ngrand_parent); | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 				if (ngrand_parent->left->color == RED) { | 
					
						
							|  |  |  | 					_set_color(nparent, BLACK); | 
					
						
							|  |  |  | 					_set_color(ngrand_parent->left, BLACK); | 
					
						
							|  |  |  | 					_set_color(ngrand_parent, RED); | 
					
						
							|  |  |  | 					node = ngrand_parent; | 
					
						
							|  |  |  | 					nparent = node->parent; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				} else { | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 					if (node == nparent->left) { | 
					
						
							|  |  |  | 						_rotate_right(nparent); | 
					
						
							|  |  |  | 						node = nparent; | 
					
						
							|  |  |  | 						nparent = node->parent; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 					_set_color(nparent, BLACK); | 
					
						
							|  |  |  | 					_set_color(ngrand_parent, RED); | 
					
						
							|  |  |  | 					_rotate_left(ngrand_parent); | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		_set_color(_data._root->left, BLACK); | 
					
						
							| 
									
										
										
										
											2017-09-20 18:52:40 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Element *_insert(const T &p_value) { | 
					
						
							|  |  |  | 		Element *new_parent = _data._root; | 
					
						
							|  |  |  | 		Element *node = _data._root->left; | 
					
						
							|  |  |  | 		C less; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		while (node != _data._nil) { | 
					
						
							|  |  |  | 			new_parent = node; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			if (less(p_value, node->value)) { | 
					
						
							| 
									
										
										
										
											2017-09-20 18:52:40 +01:00
										 |  |  | 				node = node->left; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			} else if (less(node->value, p_value)) { | 
					
						
							| 
									
										
										
										
											2017-09-20 18:52:40 +01:00
										 |  |  | 				node = node->right; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2017-09-20 18:52:40 +01:00
										 |  |  | 				return node; // Return existing node
 | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-20 18:52:40 +01:00
										 |  |  | 		Element *new_node = memnew_allocator(Element, A); | 
					
						
							|  |  |  | 		new_node->parent = new_parent; | 
					
						
							|  |  |  | 		new_node->right = _data._nil; | 
					
						
							|  |  |  | 		new_node->left = _data._nil; | 
					
						
							|  |  |  | 		new_node->value = p_value; | 
					
						
							|  |  |  | 		//new_node->data=_data;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (new_parent == _data._root || less(p_value, new_parent->value)) { | 
					
						
							|  |  |  | 			new_parent->left = new_node; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			new_parent->right = new_node; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		new_node->_next = _successor(new_node); | 
					
						
							|  |  |  | 		new_node->_prev = _predecessor(new_node); | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (new_node->_next) { | 
					
						
							| 
									
										
										
										
											2017-09-20 18:52:40 +01:00
										 |  |  | 			new_node->_next->_prev = new_node; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if (new_node->_prev) { | 
					
						
							| 
									
										
										
										
											2017-09-20 18:52:40 +01:00
										 |  |  | 			new_node->_prev->_next = new_node; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-09-20 18:52:40 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		_data.size_cache++; | 
					
						
							|  |  |  | 		_insert_rb_fix(new_node); | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 		return new_node; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-20 18:52:40 +01:00
										 |  |  | 	void _erase_fix_rb(Element *p_node) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		Element *root = _data._root->left; | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 		Element *node = _data._nil; | 
					
						
							|  |  |  | 		Element *sibling = p_node; | 
					
						
							|  |  |  | 		Element *parent = sibling->parent; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		while (node != root) { // If red node found, will exit at a break
 | 
					
						
							|  |  |  | 			if (sibling->color == RED) { | 
					
						
							|  |  |  | 				_set_color(sibling, BLACK); | 
					
						
							|  |  |  | 				_set_color(parent, RED); | 
					
						
							|  |  |  | 				if (sibling == parent->right) { | 
					
						
							|  |  |  | 					sibling = sibling->left; | 
					
						
							|  |  |  | 					_rotate_left(parent); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				} else { | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 					sibling = sibling->right; | 
					
						
							|  |  |  | 					_rotate_right(parent); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			if ((sibling->left->color == BLACK) && (sibling->right->color == BLACK)) { | 
					
						
							|  |  |  | 				_set_color(sibling, RED); | 
					
						
							|  |  |  | 				if (parent->color == RED) { | 
					
						
							|  |  |  | 					_set_color(parent, BLACK); | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} else { // loop: haven't found any red nodes yet
 | 
					
						
							|  |  |  | 					node = parent; | 
					
						
							|  |  |  | 					parent = node->parent; | 
					
						
							|  |  |  | 					sibling = (node == parent->left) ? parent->right : parent->left; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 			} else { | 
					
						
							|  |  |  | 				if (sibling == parent->right) { | 
					
						
							|  |  |  | 					if (sibling->right->color == BLACK) { | 
					
						
							|  |  |  | 						_set_color(sibling->left, BLACK); | 
					
						
							|  |  |  | 						_set_color(sibling, RED); | 
					
						
							|  |  |  | 						_rotate_right(sibling); | 
					
						
							|  |  |  | 						sibling = sibling->parent; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					_set_color(sibling, parent->color); | 
					
						
							|  |  |  | 					_set_color(parent, BLACK); | 
					
						
							|  |  |  | 					_set_color(sibling->right, BLACK); | 
					
						
							|  |  |  | 					_rotate_left(parent); | 
					
						
							|  |  |  | 					break; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				} else { | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 					if (sibling->left->color == BLACK) { | 
					
						
							|  |  |  | 						_set_color(sibling->right, BLACK); | 
					
						
							|  |  |  | 						_set_color(sibling, RED); | 
					
						
							|  |  |  | 						_rotate_left(sibling); | 
					
						
							|  |  |  | 						sibling = sibling->parent; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 					_set_color(sibling, parent->color); | 
					
						
							|  |  |  | 					_set_color(parent, BLACK); | 
					
						
							|  |  |  | 					_set_color(sibling->left, BLACK); | 
					
						
							|  |  |  | 					_rotate_right(parent); | 
					
						
							|  |  |  | 					break; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		ERR_FAIL_COND(_data._nil->color != BLACK); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	void _erase(Element *p_node) { | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 		Element *rp = ((p_node->left == _data._nil) || (p_node->right == _data._nil)) ? p_node : p_node->_next; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		Element *node = (rp->left == _data._nil) ? rp->right : rp->left; | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 		Element *sibling; | 
					
						
							|  |  |  | 		if (rp == rp->parent->left) { | 
					
						
							|  |  |  | 			rp->parent->left = node; | 
					
						
							|  |  |  | 			sibling = rp->parent->right; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 			rp->parent->right = node; | 
					
						
							|  |  |  | 			sibling = rp->parent->left; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (node->color == RED) { | 
					
						
							|  |  |  | 			node->parent = rp->parent; | 
					
						
							|  |  |  | 			_set_color(node, BLACK); | 
					
						
							|  |  |  | 		} else if (rp->color == BLACK && rp->parent != _data._root) { | 
					
						
							| 
									
										
										
										
											2017-09-20 18:52:40 +01:00
										 |  |  | 			_erase_fix_rb(sibling); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (rp != p_node) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			ERR_FAIL_COND(rp == _data._nil); | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			rp->left = p_node->left; | 
					
						
							|  |  |  | 			rp->right = p_node->right; | 
					
						
							|  |  |  | 			rp->parent = p_node->parent; | 
					
						
							|  |  |  | 			rp->color = p_node->color; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			if (p_node->left != _data._nil) { | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 				p_node->left->parent = rp; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			if (p_node->right != _data._nil) { | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 				p_node->right->parent = rp; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			if (p_node == p_node->parent->left) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				p_node->parent->left = rp; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				p_node->parent->right = rp; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (p_node->_next) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			p_node->_next->_prev = p_node->_prev; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if (p_node->_prev) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			p_node->_prev->_next = p_node->_next; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		memdelete_allocator<Element, A>(p_node); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		_data.size_cache--; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		ERR_FAIL_COND(_data._nil->color == RED); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	void _calculate_depth(Element *p_element, int &max_d, int d) const { | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (p_element == _data._nil) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-09-20 18:52:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		_calculate_depth(p_element->left, max_d, d + 1); | 
					
						
							|  |  |  | 		_calculate_depth(p_element->right, max_d, d + 1); | 
					
						
							| 
									
										
										
										
											2017-09-20 18:52:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (d > max_d) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			max_d = d; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	void _cleanup_tree(Element *p_element) { | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (p_element == _data._nil) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		_cleanup_tree(p_element->left); | 
					
						
							|  |  |  | 		_cleanup_tree(p_element->right); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		memdelete_allocator<Element, A>(p_element); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	void _copy_from(const Set &p_set) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		clear(); | 
					
						
							|  |  |  | 		// not the fastest way, but safeset to write.
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		for (Element *I = p_set.front(); I; I = I->next()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			insert(I->get()); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | public: | 
					
						
							|  |  |  | 	const Element *find(const T &p_value) const { | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (!_data._root) { | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 			return nullptr; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		const Element *res = _find(p_value); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return res; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	Element *find(const T &p_value) { | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (!_data._root) { | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 			return nullptr; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		Element *res = _find(p_value); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return res; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-20 18:52:40 +01:00
										 |  |  | 	Element *lower_bound(const T &p_value) const { | 
					
						
							|  |  |  | 		return _lower_bound(p_value); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	bool has(const T &p_value) const { | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 		return find(p_value) != nullptr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	Element *insert(const T &p_value) { | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (!_data._root) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			_data._create_root(); | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-09-20 18:52:40 +01:00
										 |  |  | 		return _insert(p_value); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	void erase(Element *p_element) { | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (!_data._root || !p_element) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		_erase(p_element); | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (_data.size_cache == 0 && _data._root) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			_data._free_root(); | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	bool erase(const T &p_value) { | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (!_data._root) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return false; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		Element *e = find(p_value); | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (!e) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return false; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		_erase(e); | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (_data.size_cache == 0 && _data._root) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			_data._free_root(); | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return true; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	Element *front() const { | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (!_data._root) { | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 			return nullptr; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		Element *e = _data._root->left; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (e == _data._nil) { | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 			return nullptr; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		while (e->left != _data._nil) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			e = e->left; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return e; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	Element *back() const { | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (!_data._root) { | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 			return nullptr; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		Element *e = _data._root->left; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (e == _data._nil) { | 
					
						
							| 
									
										
										
										
											2021-05-04 16:00:45 +02:00
										 |  |  | 			return nullptr; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		while (e->right != _data._nil) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			e = e->right; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return e; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-02-15 01:19:46 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-29 12:25:31 -03:00
										 |  |  | 	inline bool empty() const { return _data.size_cache == 0; } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	inline int size() const { return _data.size_cache; } | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	int calculate_depth() const { | 
					
						
							|  |  |  | 		// used for debug mostly
 | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (!_data._root) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return 0; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		int max_d = 0; | 
					
						
							|  |  |  | 		_calculate_depth(_data._root->left, max_d, 0); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		return max_d; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	void clear() { | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		if (!_data._root) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return; | 
					
						
							| 
									
										
										
										
											2021-05-05 12:44:11 +02:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		_cleanup_tree(_data._root->left); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		_data._root->left = _data._nil; | 
					
						
							|  |  |  | 		_data.size_cache = 0; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		_data._free_root(); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	void operator=(const Set &p_set) { | 
					
						
							|  |  |  | 		_copy_from(p_set); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	Set(const Set &p_set) { | 
					
						
							|  |  |  | 		_copy_from(p_set); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-08-30 01:18:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	_FORCE_INLINE_ Set() { | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	~Set() { | 
					
						
							| 
									
										
										
										
											2016-03-09 00:00:52 +01:00
										 |  |  | 		clear(); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 |