rb_tree 源码

/*====================================================================
BSD 2-Clause License

Copyright (c) 2023, Ruler
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
====================================================================*/
#pragma once

#ifndef __CORE_RB_TREE_H__
#define __CORE_RB_TREE_H__

#include <memory>
#include <stdexcept>
#include <iterator>
#include <functional>
#include <utility>

#ifndef DEFAULT_ALLOCATOR
#define DEFAULT_ALLOCATOR(T) std::allocator<T>
#endif // !DEFAULT_ALLOCATOR

namespace core
{
	using rb_tree_color_type = bool;
	static constexpr rb_tree_color_type rb_tree_red   = false;
	static constexpr rb_tree_color_type rb_tree_black = true;

	using rb_tree_node_state = signed char;
	static constexpr rb_tree_node_state rb_tree_state_parent  = -0x10;
	static constexpr rb_tree_node_state rb_tree_state_sibling =  0x01;
	static constexpr rb_tree_node_state rb_tree_state_left    =  0x12;
	static constexpr rb_tree_node_state rb_tree_state_right   =  0x13;
	static constexpr rb_tree_node_state rb_tree_state_root    =  0x04;


	// Class template rb_tree_node
	template <class T>
	struct rb_tree_node
	{
		using node_type            = rb_tree_node<T>;
		using node_pointer         = node_type*;
		using const_node_pointer   = const node_type*;
		using node_reference       = node_type&;
		using const_node_reference = const node_type&;

		node_pointer               parent;
		node_pointer               left;
		node_pointer               right;
		rb_tree_color_type         color;
		T                          data;
	};


	// Class template rb_tree_type_traits

	template <class Tree, bool IsConst>
	struct rb_tree_type_traits
	{
		using value_type      = typename Tree::value_type;
		using pointer         = typename Tree::pointer;
		using size_type       = typename Tree::size_type;
		using difference_type = typename Tree::difference_type;
		using node_type       = typename Tree::node_type;
		using node_pointer    = typename Tree::node_pointer;
		using reference       = value_type&;
	};

	template <class Tree>
	struct rb_tree_type_traits<Tree, true>
	{
		using value_type      = typename Tree::value_type;
		using pointer         = typename Tree::const_pointer;
		using size_type       = typename Tree::size_type;
		using difference_type = typename Tree::difference_type;
		using node_type       = typename Tree::node_type;
		using node_pointer    = typename Tree::node_pointer;
		using reference       = const value_type&;
	};


	// Class template rb_tree_iterator
	template <class Tree, bool IsConst>
	class rb_tree_iterator
	{
	public:
		// types:

		using value_type        = typename rb_tree_type_traits<Tree, IsConst>::value_type;
		using pointer           = typename rb_tree_type_traits<Tree, IsConst>::pointer;
		using reference         = typename rb_tree_type_traits<Tree, IsConst>::reference;
		using size_type         = typename rb_tree_type_traits<Tree, IsConst>::size_type;
		using difference_type   = typename rb_tree_type_traits<Tree, IsConst>::difference_type;
		using node_type         = typename rb_tree_type_traits<Tree, IsConst>::node_type;
		using node_pointer      = typename rb_tree_type_traits<Tree, IsConst>::node_pointer;

		using iterator_type     = rb_tree_iterator<Tree, IsConst>;
		using iterator_category = std::bidirectional_iterator_tag;

		// construct/copy/destroy:

		rb_tree_iterator(void) noexcept
			: node(nullptr)
		{}
		explicit rb_tree_iterator(const node_pointer p) noexcept
			: node(p)
		{}
		rb_tree_iterator(const rb_tree_iterator<Tree, IsConst>& other) noexcept
			: node(other.get_pointer())
		{}

		inline rb_tree_iterator<Tree, IsConst>& operator=(const rb_tree_iterator<Tree, IsConst>& other) noexcept
		{
			if (this != &other)
				node = other.get_pointer();
			return *this;
		}

		inline operator rb_tree_iterator<Tree, true>(void) const noexcept
		{
			return rb_tree_iterator<Tree, true>(node);
		}

		// rb_tree_iterator operations:

		inline node_pointer get_parent(void) noexcept
		{
			return node->parent;
		}
		inline const node_pointer get_parent(void) const noexcept
		{
			return node->parent;
		}

		inline node_pointer get_pointer(void) noexcept
		{
			return node;
		}
		inline const node_pointer get_pointer(void) const noexcept
		{
			return node;
		}

		inline rb_tree_color_type get_color(void) const noexcept
		{
			return node->color;
		}

		inline reference operator*(void) const noexcept
		{
			return node->data;
		}

		inline pointer operator->(void) const noexcept
		{
			return &(operator*());
		}

		// increment / decrement

		rb_tree_iterator<Tree, IsConst>& operator++(void) noexcept
		{
			if (node->right)
			{
				node = node->right;
				while (node->left)
					node = node->left;
			}
			else
			{
				node_pointer p = node->parent;
				while (node == p->right)
				{
					node = p;
					p = p->parent;
				}
				if (node->right != p)
					node = p;
			}
			return *this;
		}

		rb_tree_iterator<Tree, IsConst>& operator--(void) noexcept
		{
			if (node->color == rb_tree_red && node->parent->parent == node)
				node = node->right;
			else if (node->left)
			{
				node_pointer p = node->left;
				while (p->right)
					p = p->right;
				node = p;
			}
			else
			{
				node_pointer p = node->parent;
				while (node == p->left)
				{
					node = p;
					p = p->parent;
				}
				node = p;
			}
			return *this;
		}

		inline rb_tree_iterator<Tree, IsConst> operator++(int) noexcept
		{
			iterator_type tmp(*this);
			this->operator++();
			return tmp;
		}

		inline rb_tree_iterator<Tree, IsConst> operator--(int) noexcept
		{
			iterator_type tmp(*this);
			this->operator--();
			return tmp;
		}

		// relational operators:

		template <bool is_const>
		inline bool operator==(const rb_tree_iterator<Tree, is_const>& rhs) const noexcept
		{
			return (node == rhs.get_pointer());
		}

		template <bool is_const>
		inline bool operator!=(const rb_tree_iterator<Tree, is_const>& rhs) const noexcept
		{
			return (node != rhs.get_pointer());
		}

	private:
		node_pointer node;
	};


	// Class template rb_tree_primitive_iterator
	template <class Tree, bool IsConst>
	class rb_tree_primitive_iterator
	{
	public:
		// types:

		using value_type        = typename rb_tree_type_traits<Tree, IsConst>::value_type;
		using pointer           = typename rb_tree_type_traits<Tree, IsConst>::pointer;
		using reference         = typename rb_tree_type_traits<Tree, IsConst>::reference;
		using size_type         = typename rb_tree_type_traits<Tree, IsConst>::size_type;
		using difference_type   = typename rb_tree_type_traits<Tree, IsConst>::difference_type;
		using node_type         = typename rb_tree_type_traits<Tree, IsConst>::node_type;
		using node_pointer      = typename rb_tree_type_traits<Tree, IsConst>::node_pointer;

		using iterator_type     = rb_tree_primitive_iterator<Tree, IsConst>;
		using iterator_category = std::bidirectional_iterator_tag;

		// construct/copy/destroy:

		rb_tree_primitive_iterator(void) noexcept
			: node(nullptr)
			, state(rb_tree_state_root)
		{}
		explicit rb_tree_primitive_iterator(const node_pointer p) noexcept
			: node(p)
			, state(rb_tree_state_root)
		{}
		rb_tree_primitive_iterator(const rb_tree_primitive_iterator<Tree, IsConst>& other) noexcept
			: node(other.get_pointer())
			, state(other.get_state())
		{}

		inline rb_tree_primitive_iterator<Tree, IsConst>& operator=(const rb_tree_primitive_iterator<Tree, IsConst>& other) noexcept
		{
			if (this != &other)
			{
				node = other.get_pointer();
				state = other.get_state();
			}
			return *this;
		}

		inline operator rb_tree_primitive_iterator<Tree, true>(void) const noexcept
		{
			return rb_tree_primitive_iterator<Tree, true>(node);
		}

		// rb_tree_primitive_iterator operations:

		inline node_pointer get_parent(void) noexcept
		{
			return node->parent;
		}
		inline const node_pointer get_parent(void) const noexcept
		{
			return node->parent;
		}

		inline node_pointer get_pointer(void) noexcept
		{
			return node;
		}
		inline const node_pointer get_pointer(void) const noexcept
		{
			return node;
		}

		inline rb_tree_node_state get_state(void) const noexcept
		{
			return state;
		}

		inline intptr_t get_depth(void) const noexcept
		{
			return static_cast<intptr_t>(state >> 4);
		}

		inline rb_tree_color_type get_color(void) const noexcept
		{
			return node->color;
		}

		inline reference operator*(void) const noexcept
		{
			return node->data;
		}

		inline pointer operator->(void) const noexcept
		{
			return &(operator*());
		}

		// increment / decrement

		rb_tree_primitive_iterator<Tree, IsConst>& operator++(void) noexcept
		{
			if (state != rb_tree_state_parent && node->left)
			{
				node = node->left;
				state = rb_tree_state_left;
			}
			else if (state != rb_tree_state_parent && node->right)
			{
				node = node->right;
				state = rb_tree_state_right;
			}
			else if (node != node->parent->parent &&
				node->parent->right && node != node->parent->right)
			{
				node = node->parent->right;
				state = rb_tree_state_sibling;
			}
			else
			{
				node = node->parent;
				state = rb_tree_state_parent;
			}
			return *this;
		}

		rb_tree_primitive_iterator<Tree, IsConst>& operator--(void) noexcept
		{
			if (state != rb_tree_state_parent && node->right)
			{
				node = node->right;
				state = rb_tree_state_right;
			}
			else if (state != rb_tree_state_parent && node->left)
			{
				node = node->left;
				state = rb_tree_state_left;
			}
			else if (node != node->parent->parent &&
				node->parent->left && node != node->parent->left)
			{
				node = node->parent->left;
				state = rb_tree_state_sibling;
			}
			else
			{
				node = node->parent;
				state = rb_tree_state_parent;
			}
			return *this;
		}

		inline rb_tree_primitive_iterator<Tree, IsConst> operator++(int) noexcept
		{
			iterator_type tmp(*this);
			this->operator++();
			return tmp;
		}

		inline rb_tree_primitive_iterator<Tree, IsConst> operator--(int) noexcept
		{
			iterator_type tmp(*this);
			this->operator--();
			return tmp;
		}

		// relational operators:

		template <bool is_const>
		inline bool operator==(const rb_tree_primitive_iterator<Tree, is_const>& rhs) const noexcept
		{
			return (node == rhs.get_pointer());
		}

		template <bool is_const>
		inline bool operator!=(const rb_tree_primitive_iterator<Tree, is_const>& rhs) const noexcept
		{
			return (node != rhs.get_pointer());
		}

	private:
		node_pointer       node;
		rb_tree_node_state state;
	};


	// Class template rb_tree_node_allocator
	template <class T, class Allocator>
	class rb_tree_node_allocator
	{
	public:
		// types:

		using tree_traits_type     = std::allocator_traits<Allocator>;
		using tree_node_type       = typename rb_tree_node<T>::node_type;
		using allocator_type       = typename tree_traits_type::template rebind_alloc<T>;
		using traits_type          = typename tree_traits_type::template rebind_traits<T>;
		using node_allocator_type  = typename tree_traits_type::template rebind_alloc<tree_node_type>;
		using node_traits_type     = typename tree_traits_type::template rebind_traits<tree_node_type>;
		using node_type            = typename node_traits_type::value_type;
		using node_pointer         = typename node_traits_type::pointer;
		using node_size_type       = typename node_traits_type::size_type;
		using node_difference_type = typename node_traits_type::difference_type;

		// construct/copy/destroy:

		rb_tree_node_allocator(void)
			: allocator()
		{}
		explicit rb_tree_node_allocator(const Allocator& alloc)
			: allocator(alloc)
		{}
		explicit rb_tree_node_allocator(Allocator&& alloc)
			: allocator(std::forward<Allocator>(alloc))
		{}

		// rb_tree_node_allocator operations:

		inline allocator_type get_allocator(void) noexcept
		{
			return allocator;
		}
		inline const allocator_type get_allocator(void) const noexcept
		{
			return allocator;
		}

		inline node_size_type max_size(void) const noexcept
		{
			return node_alloc.max_size();
		}

	protected:

		template<class ...Args>
		inline node_pointer create_node(Args&&... args)
		{
			node_pointer p = node_traits_type::allocate(node_alloc, 1);
			traits_type::construct(allocator, std::addressof(p->data), std::forward<Args>(args)...);
			return p;
		}

		inline void destroy_node(const node_pointer p)
		{
			traits_type::destroy(allocator, std::addressof(p->data));
			node_traits_type::deallocate(node_alloc, p, 1);
		}

	private:
		allocator_type      allocator;
		node_allocator_type node_alloc;
	};


	// Class template rb_tree
	template <class T, class Compare = std::less<T>, class Allocator = DEFAULT_ALLOCATOR(T)>
	class rb_tree : public rb_tree_node_allocator<T, Allocator>
	{
	public:
		// types:

		using compare_type                     = Compare;
		using tree_type                        = rb_tree<T, Compare, Allocator>;
		using tree_traits_type                 = std::allocator_traits<Allocator>;
		using node_type                        = typename rb_tree_node<T>::node_type;
		using node_pointer                     = typename rb_tree_node<T>::node_pointer;
		using const_node_pointer               = typename rb_tree_node<T>::const_node_pointer;
		using node_allocator_type              = typename tree_traits_type::template rebind_alloc<node_type>;
		using allocator_type                   = typename tree_traits_type::template rebind_alloc<T>;
		using traits_type                      = typename tree_traits_type::template rebind_traits<T>;
		using value_type                       = typename traits_type::value_type;
		using reference                        = value_type&;
		using const_reference                  = const value_type&;
		using pointer                          = typename traits_type::pointer;
		using const_pointer                    = typename traits_type::const_pointer;
		using size_type                        = typename traits_type::size_type;
		using difference_type                  = typename traits_type::difference_type;

		using iterator                         = rb_tree_iterator<tree_type, false>;
		using const_iterator                   = rb_tree_iterator<tree_type, true>;
		using primitive_iterator               = rb_tree_primitive_iterator<tree_type, false>;
		using const_primitive_iterator         = rb_tree_primitive_iterator<tree_type, true>;
		using reverse_iterator                 = std::reverse_iterator<iterator>;
		using const_reverse_iterator           = std::reverse_iterator<const_iterator>;
		using reverse_primitive_iterator       = std::reverse_iterator<primitive_iterator>;
		using const_reverse_primitive_iterator = std::reverse_iterator<const_primitive_iterator>;

		// construct/copy/destroy:

		explicit rb_tree(const Compare& compare = Compare(), const Allocator& alloc = Allocator())
			: rb_tree_node_allocator<T, Allocator>(alloc)
			, comp(compare)
			, header(nullptr)
			, count(0)
		{
			create_header();
		}
		explicit rb_tree(const Allocator& alloc)
			: rb_tree_node_allocator<T, Allocator>(alloc)
			, comp(Compare())
			, header(nullptr)
			, count(0)
		{
			create_header();
		}
		rb_tree(const tree_type& other)
			: rb_tree_node_allocator<T, Allocator>(other.get_allocator())
			, comp(other.comp)
			, header(nullptr)
			, count(0)
		{
			create_header();
			if (other.header->parent)
				copy_node(other.header->parent);
			count = other.count;
		}
		rb_tree(const tree_type& other, const Allocator& alloc)
			: rb_tree_node_allocator<T, Allocator>(alloc)
			, comp(other.comp)
			, header(nullptr)
			, count(0)
		{
			create_header();
			if (other.header->parent)
				copy_node(other.header->parent);
			count = other.count;
		}
		rb_tree(tree_type&& other) noexcept
			: rb_tree_node_allocator<T, Allocator>(other.get_allocator())
			, comp(Compare())
			, header(nullptr)
			, count(0)
		{
			create_header();
			swap(other);
		}
		rb_tree(tree_type&& other, const Allocator& alloc) noexcept
			: rb_tree_node_allocator<T, Allocator>(alloc)
			, comp(Compare())
			, header(nullptr)
			, count(0)
		{
			create_header();
			swap(other);
		}
		rb_tree(std::initializer_list<T> init, const Allocator& alloc = Allocator())
			: rb_tree_node_allocator<T, Allocator>(alloc)
			, comp(Compare())
			, header(nullptr)
			, count(0)
		{
			create_header();
			insert_unique(init.begin(), init.end());
		}

		~rb_tree(void)
		{
			clear();
			destroy_header();
		}

		inline tree_type& operator=(const tree_type& other)
		{
			if (this != &other)
			{
				clear();
				if (other.header->parent)
					copy_node(other.header->parent);
				comp = other.comp;
				count = other.count;
			}
			return *this;
		}
		inline tree_type& operator=(tree_type&& other) noexcept
		{
			if (this != &other)
				swap(other);
			return *this;
		}

		inline void assign_equal(size_type n, const value_type& value)
		{
			clear();
			insert_equal(n, value);
		}
		template <class InputIt>
		inline void assign_equal(InputIt first, InputIt last)
		{
			clear();
			insert_equal(first, last);
		}
		inline void assign_equal(std::initializer_list<value_type> init)
		{
			assign_equal(init.begin(), init.end());
		}

		inline void assign_unique(const value_type& value)
		{
			clear();
			insert_unique(value);
		}
		template <class InputIt>
		inline void assign_unique(InputIt first, InputIt last)
		{
			clear();
			insert_unique(first, last);
		}
		inline void assign_unique(std::initializer_list<value_type> init)
		{
			assign_unique(init.begin(), init.end());
		}

		// iterators:

		inline iterator begin(void) noexcept
		{
			return iterator(header->left);
		}
		inline const_iterator begin(void) const noexcept
		{
			return const_iterator(header->left);
		}
		inline const_iterator cbegin(void) const noexcept
		{
			return const_iterator(header->left);
		}
		inline iterator end(void) noexcept
		{
			return iterator(header);
		}
		inline const_iterator end(void) const noexcept
		{
			return const_iterator(header);
		}
		inline const_iterator cend(void) const noexcept
		{
			return const_iterator(header);
		}

		inline reverse_iterator rbegin(void) noexcept
		{
			return reverse_iterator(end());
		}
		inline const_reverse_iterator rbegin(void) const noexcept
		{
			return const_reverse_iterator(end());
		}
		inline const_reverse_iterator crbegin(void) const noexcept
		{
			return const_reverse_iterator(cend());
		}
		inline reverse_iterator rend(void) noexcept
		{
			return reverse_iterator(begin());
		}
		inline const_reverse_iterator rend(void) const noexcept
		{
			return const_reverse_iterator(begin());
		}
		inline const_reverse_iterator crend(void) const noexcept
		{
			return const_reverse_iterator(cbegin());
		}

		inline primitive_iterator pbegin(void) noexcept
		{
			return primitive_iterator(root());
		}
		inline const_primitive_iterator pbegin(void) const noexcept
		{
			return const_primitive_iterator(root());
		}
		inline const_primitive_iterator cpbegin(void) const noexcept
		{
			return const_primitive_iterator(root());
		}
		inline primitive_iterator pend(void) noexcept
		{
			return primitive_iterator(header);
		}
		inline const_primitive_iterator pend(void) const noexcept
		{
			return const_primitive_iterator(header);
		}
		inline const_primitive_iterator cpend(void) const noexcept
		{
			return const_primitive_iterator(header);
		}

		inline reverse_primitive_iterator rpbegin(void) noexcept
		{
			return reverse_primitive_iterator(pend());
		}
		inline const_reverse_primitive_iterator rpbegin(void) const noexcept
		{
			return const_reverse_primitive_iterator(pend());
		}
		inline const_reverse_primitive_iterator crpbegin(void) const noexcept
		{
			return const_reverse_primitive_iterator(cpend());
		}
		inline reverse_primitive_iterator rpend(void) noexcept
		{
			return reverse_primitive_iterator(pbegin());
		}
		inline const_reverse_primitive_iterator rpend(void) const noexcept
		{
			return const_reverse_primitive_iterator(pbegin());
		}
		inline const_reverse_primitive_iterator crpend(void) const noexcept
		{
			return const_reverse_primitive_iterator(cpbegin());
		}

		// capacity:

		inline bool empty(void) const noexcept
		{
			return !header->parent;
		}

		inline size_type size(void) const noexcept
		{
			return count;
		}

		// element access:

		template <class KeyType>
		inline reference at(const KeyType& key)
		{
			if (empty())
				throw std::domain_error(RBT_NOT_INITIALIZED);
			iterator itr = find(key);
			if (itr == end())
				throw std::out_of_range(RBT_OUT_OF_RANGE);
			return itr->data;
		}
		template <class KeyType>
		inline const_reference at(const KeyType& key) const
		{
			if (empty())
				throw std::domain_error(RBT_NOT_INITIALIZED);
			const_iterator itr = find(key);
			if (itr == cend())
				throw std::out_of_range(RBT_OUT_OF_RANGE);
			return itr->data;
		}

		// observers:

		inline compare_type compare(void) const
		{
			return comp;
		}

		// modifiers:

		template <class... Args>
		inline iterator emplace_equal(Args&&... args)
		{
			return iterator(insert_equal_node(std::forward<Args>(args)...));
		}

		inline iterator insert_equal(const value_type& value)
		{
			return iterator(insert_equal_node(value));
		}
		inline iterator insert_equal(value_type&& value)
		{
			return iterator(insert_equal_node(std::forward<value_type>(value)));
		}
		inline iterator insert_equal(size_type n, const value_type& value)
		{
			node_pointer t = header;
			if (n != 0)
			{
				t = insert_equal_node(value);
				for (; n > 1; --n)
					insert_equal_node(value);
			}
			return iterator(t);
		}
		template <class InputIt>
		inline iterator insert_equal(InputIt first, InputIt last)
		{
			node_pointer t = header;
			if (first != last)
			{
				t = insert_equal_node(*first);
				for (++first; first != last; ++first)
					insert_equal_node(*first);
			}
			return iterator(t);
		}
		inline iterator insert_equal(std::initializer_list<value_type> init)
		{
			return insert_equal(init.begin(), init.end());
		}

		template <class... Args>
		inline std::pair<iterator, bool> emplace_unique(Args&&... args)
		{
			std::pair<node_pointer, bool> res = insert_unique_node(std::forward<Args>(args)...);
			return std::make_pair(iterator(res.first), res.second);
		}

		inline std::pair<iterator, bool> insert_unique(const value_type& value)
		{
			std::pair<node_pointer, bool> res = insert_unique_node(value);
			return std::make_pair(iterator(res.first), res.second);
		}
		inline std::pair<iterator, bool> insert_unique(value_type&& value)
		{
			std::pair<node_pointer, bool> res = insert_unique_node(std::forward<value_type>(value));
			return std::make_pair(iterator(res.first), res.second);
		}
		template <class InputIt>
		inline void insert_unique(InputIt first, InputIt last)
		{
			for (; first != last; ++first)
				insert_unique_node(*first);
		}
		inline void insert_unique(std::initializer_list<value_type> init)
		{
			insert_unique(init.begin(), init.end());
		}

		inline iterator erase(const_iterator pos)
		{
			iterator next = iterator(pos.get_pointer());
			if (pos != cend())
			{
				++next;
				erase_node(pos.get_pointer());
			}
			return next;
		}
		inline iterator erase(const_iterator first, const_iterator last)
		{
			iterator next = iterator(last.get_pointer());
			if (first == cbegin() && last == cend())
				clear();
			else
				while (first != last)
					erase(first++);
			return next;
		}
		template <class KeyType>
		inline size_type erase(const KeyType& key)
		{
			size_type n = 0;
			iterator first = lower_bound(key);
			iterator last = upper_bound(key);
			while (first != last)
			{
				++n;
				erase(first++);
			}
			return n;
		}

		inline void swap(tree_type& rhs) noexcept
		{
			if (this != &rhs)
			{
				std::swap(header, rhs.header);
				std::swap(comp, rhs.comp);
				std::swap(count, rhs.count);
			}
		}

		inline void clear(void)
		{
			if (header->parent)
			{
				erase_root();
				header->parent = nullptr;
				header->left = header;
				header->right = header;
				count = 0;
			}
		}

		// operations:

		template <class KeyType>
		inline iterator find(const KeyType& key) noexcept
		{
			return iterator(find_node(key));
		}
		template <class KeyType>
		inline const_iterator find(const KeyType& key) const noexcept
		{
			return const_iterator(find_node(key));
		}

		template <class KeyType>
		inline iterator lower_bound(const KeyType& key) noexcept
		{
			return iterator(lower_bound_node(key));
		}
		template <class KeyType>
		inline const_iterator lower_bound(const KeyType& key) const noexcept
		{
			return const_iterator(lower_bound_node(key));
		}

		template <class KeyType>
		inline iterator upper_bound(const KeyType& key) noexcept
		{
			return iterator(upper_bound_node(key));
		}
		template <class KeyType>
		inline const_iterator upper_bound(const KeyType& key) const noexcept
		{
			return const_iterator(upper_bound_node(key));
		}

	private:

		inline node_pointer root(void) const noexcept
		{
			return header->parent ? header->parent : header;
		}

		inline node_pointer leftmost(node_pointer t) const noexcept
		{
			while (t->left)
				t = t->left;
			return t;
		}

		inline node_pointer rightmost(node_pointer t) const noexcept
		{
			while (t->right)
				t = t->right;
			return t;
		}

		inline void create_header(void)
		{
			if (!header)
			{
				header = this->create_node(value_type());
				header->color = rb_tree_red;
				header->parent = nullptr;
				header->left = header;
				header->right = header;
			}
		}

		inline void destroy_header(void)
		{
			if (header)
			{
				this->destroy_node(header);
				header = nullptr;
			}
		}

		template <class KeyType>
		node_pointer find_node(const KeyType& key) const noexcept
		{
			node_pointer pre = header;
			node_pointer cur = header->parent;
			while (cur)
			{
				if (!comp(cur->data, key))
				{
					pre = cur;
					cur = cur->left;
				}
				else
					cur = cur->right;
			}
			if (comp(key, pre->data))
				pre = header;
			return pre;
		}

		template <class KeyType>
		node_pointer lower_bound_node(const KeyType& key) const noexcept
		{
			node_pointer pre = header;
			node_pointer cur = header->parent;
			while (cur)
			{
				if (!comp(cur->data, key))
				{
					pre = cur;
					cur = cur->left;
				}
				else
					cur = cur->right;
			}
			return pre;
		}

		template <class KeyType>
		node_pointer upper_bound_node(const KeyType& key) const noexcept
		{
			node_pointer pre = header;
			node_pointer cur = header->parent;
			while (cur)
			{
				if (comp(key, cur->data))
				{
					pre = cur;
					cur = cur->left;
				}
				else
					cur = cur->right;
			}
			return pre;
		}

		void copy_node(const node_pointer t)
		{
			bool flag = true;
			node_pointer src = t;
			node_pointer dst = header;
			// copies the t node
			node_pointer n = this->create_node(t->data);
			n->color = t->color;
			n->parent = dst;
			n->left = nullptr;
			n->right = nullptr;
			dst->parent = n;
			// update dst to root node
			dst = n;
			do
			{
				if (flag && src->left)
				{
					src = src->left;
					// copies the left child node
					n = this->create_node(src->data);
					n->parent = dst;
					n->left = nullptr;
					n->right = nullptr;
					n->color = src->color;
					dst->left = n;
					// update dst to left child node
					dst = n;
				}
				else if (flag && src->right)
				{
					src = src->right;
					// copies the right child node
					n = this->create_node(src->data);
					n->parent = dst;
					n->left = nullptr;
					n->right = nullptr;
					n->color = src->color;
					dst->right = n;
					// update dst to right child node
					dst = n;
				}
				else if (src->parent->right && src != src->parent->right)
				{
					src = src->parent->right;
					// copies the sibling node
					n = this->create_node(src->data);
					n->parent = dst->parent;
					n->left = nullptr;
					n->right = nullptr;
					n->color = src->color;
					dst->parent->right = n;
					// update dst to sibling node
					dst = n;
					// update flag to true
					flag = true;
				}
				else
				{
					// return to parent node
					src = src->parent;
					dst = dst->parent;
					// update flag to false
					flag = false;
				}
			} while (src != t);
			// the minimum value
			header->left = leftmost(header->parent);
			// the maximum value
			header->right = rightmost(header->parent);
		}

		template<class ...Args>
		node_pointer insert_equal_node(Args&&... args)
		{
			// creates a new node
			node_pointer n = this->create_node(std::forward<Args>(args)...);
			n->left = nullptr;
			n->right = nullptr;
			// if the tree is not empty
			if (header->parent)
			{
				// the initial value is root
				node_pointer t = header->parent;
				while (t)
				{
					if (comp(n->data, t->data))
					{
						if (t->left)
							t = t->left;
						else
						{
							// inserts the node
							n->parent = t;
							t->left = n;
							// replaces minimum value
							if (t == header->left)
								header->left = n;
							t = nullptr;
						}
					}
					else
					{
						if (t->right)
							t = t->right;
						else
						{
							// inserts the node
							n->parent = t;
							t->right = n;
							// replaces maximum value
							if (t == header->right)
								header->right = n;
							t = nullptr;
						}
					}
				}
				// rebalance after insertion
				insert_rebalance(n, header->parent);
			}
			else
			{
				// inserts the node
				n->parent = header;
				n->color = rb_tree_black;
				header->parent = n;
				// the minimum value
				header->left = n;
				// the maximum value
				header->right = n;
			}
			++count;
			return n;
		}

		template<class ...Args>
		std::pair<node_pointer, bool> insert_unique_node(Args&&... args)
		{
			node_pointer n = nullptr;
			value_type val = value_type(std::forward<Args>(args)...);
			// if the tree is not empty
			if (header->parent)
			{
				// the initial value is root
				node_pointer t = header->parent;
				while (t)
				{
					if (comp(val, t->data))
					{
						if (t->left)
							t = t->left;
						else
						{
							// creates a new node
							n = this->create_node(std::forward<value_type>(val));
							n->left = nullptr;
							n->right = nullptr;
							// inserts the node
							n->parent = t;
							t->left = n;
							// replaces minimum value
							if (t == header->left)
								header->left = n;
							t = nullptr;
						}
					}
					else
					{
						// if it already exists
						if (!comp(t->data, val))
							return std::make_pair(t, false);
						if (t->right)
							t = t->right;
						else
						{
							// creates a new node
							n = this->create_node(std::forward<value_type>(val));
							n->left = nullptr;
							n->right = nullptr;
							// inserts the node
							n->parent = t;
							t->right = n;
							// replaces maximum value
							if (t == header->right)
								header->right = n;
							t = nullptr;
						}
					}
				}
				// rebalance after insertion
				insert_rebalance(n, header->parent);
			}
			else
			{
				// creates a new node
				n = this->create_node(std::forward<value_type>(val));
				n->left = nullptr;
				n->right = nullptr;
				n->color = rb_tree_black;
				// inserts the node
				n->parent = header;
				header->parent = n;
				// the minimum value
				header->left = n;
				// the maximum value
				header->right = n;
			}
			++count;
			return std::make_pair(n, true);
		}

		void erase_node(node_pointer t)
		{
			node_pointer x;
			rb_tree_color_type color;
			// case 1. has one child node at most
			if (!t->left || !t->right)
			{
				x = t->left ? t->left : t->right;
				// removes t node
				if (x)
					x->parent = t->parent;
				if (t == header->parent)
					header->parent = x;
				else if (t == t->parent->left)
					t->parent->left = x;
				else
					t->parent->right = x;
				// replaces minimum value
				if (t == header->left)
					header->left = x ? leftmost(x) : t->parent;
				// replaces maximum value
				if (t == header->right)
					header->right = x ? rightmost(x) : t->parent;
				// rebalance after deletion
				if (t->color != rb_tree_red)
					erase_rebalance(t->parent, x, root);
			}
			// case 2. has two child nodes
			else
			{
				node_pointer p;
				x = leftmost(t->right);
				// replaces t node with x node and removes t node
				t->left->parent = x;
				x->left = t->left;
				if (x != t->right)
				{
					p = x;
					t->right->parent = x;
					x->right = t->right;
					x->parent->left = x->right;
					if (x->right)
						x->right->parent = x->parent;
				}
				else
					p = x->parent;
				if (t == header->parent)
					header->parent = x;
				else if (t == t->parent->left)
					t->parent->left = x;
				else
					t->parent->right = x;
				x->parent = t->parent;
				x->color = t->color;
				// rebalance after deletion
				if (t->color != rb_tree_red)
					erase_rebalance(p, x->right, root);
			}
			// destroy node
			this->destroy_node(t);
			--count;
		}

		void erase_root(void)
		{
			node_pointer next;
			node_pointer cur = header->parent;
			do
			{
				while (cur->left)
					cur = cur->left;
				if (cur->right)
					cur = cur->right;
				else
				{
					next = cur->parent;
					if (cur == next->left)
						next->left = nullptr;
					else
						next->right = nullptr;
					this->destroy_node(cur);
					cur = next;
				}
			} while (cur != header);
		}

		void rotate_left(node_pointer t) const noexcept
		{
			node_pointer r = t->right;
			t->right = r->left;
			if (r->left)
				r->left->parent = t;
			r->parent = t->parent;
			if (t == header->parent)
				header->parent = r;
			else if (t == t->parent->left)
				t->parent->left = r;
			else
				t->parent->right = r;
			r->left = t;
			t->parent = r;
		}

		void rotate_right(node_pointer t) const noexcept
		{
			node_pointer l = t->left;
			t->left = l->right;
			if (l->right)
				l->right->parent = t;
			l->parent = t->parent;
			if (t == header->parent)
				header->parent = l;
			else if (t == t->parent->right)
				t->parent->right = l;
			else
				t->parent->left = l;
			l->right = t;
			t->parent = l;
		}

		void insert_rebalance(node_pointer x, node_pointer& root) const noexcept
		{
			x->color = rb_tree_red;
			while (x != root && x->parent->color == rb_tree_red)
			{
				if (x->parent == x->parent->parent->left)
				{
					node_pointer y = x->parent->parent->right;
					if (y && y->color == rb_tree_red)
					{
						x->parent->color = rb_tree_black;
						y->color = rb_tree_black;
						x->parent->parent->color = rb_tree_red;
						x = x->parent->parent;
					}
					else
					{
						if (x == x->parent->right)
						{
							x = x->parent;
							rotate_left(x);
						}
						x->parent->color = rb_tree_black;
						x->parent->parent->color = rb_tree_red;
						rotate_right(x->parent->parent);
					}
				}
				else
				{
					node_pointer y = x->parent->parent->left;
					if (y && y->color == rb_tree_red)
					{
						x->parent->color = rb_tree_black;
						y->color = rb_tree_black;
						x->parent->parent->color = rb_tree_red;
						x = x->parent->parent;
					}
					else
					{
						if (x == x->parent->left)
						{
							x = x->parent;
							rotate_right(x);
						}
						x->parent->color = rb_tree_black;
						x->parent->parent->color = rb_tree_red;
						rotate_left(x->parent->parent);
					}
				}
			}
			root->color = rb_tree_black;
		}

		void erase_rebalance(node_pointer p, node_pointer x, node_pointer& root) const noexcept
		{
			while (x != root && (!x || x->color == rb_tree_black))
			{
				if (x == p->left)
				{
					node_pointer s = p->right;
					if (s->color == rb_tree_red)
					{
						s->color = rb_tree_black;
						p->color = rb_tree_red;
						rotate_left(p, root);
						s = p->right;
					}
					if ((!s->left || s->left->color == rb_tree_black) &&
						(!s->right || s->right->color == rb_tree_black))
					{
						s->color = rb_tree_red;
						x = p;
						p = x->parent;
					}
					else
					{
						if (!s->right || s->right->color == rb_tree_black)
						{
							s->color = rb_tree_red;
							s->left->color = rb_tree_black;
							rotate_right(s, root);
							s = p->right;
						}
						s->color = p->color;
						p->color = rb_tree_black;
						s->right->color = rb_tree_black;
						rotate_left(p, root);
						break;
					}
				}
				else
				{
					node_pointer s = p->left;
					if (s->color == rb_tree_red)
					{
						s->color = rb_tree_black;
						p->color = rb_tree_red;
						rotate_right(p, root);
						s = p->left;
					}
					if ((!s->right || s->right->color == rb_tree_black) &&
						(!s->left || s->left->color == rb_tree_black))
					{
						s->color = rb_tree_red;
						x = p;
						p = x->parent;
					}
					else
					{
						if (!s->left || s->left->color == rb_tree_black)
						{
							s->color = rb_tree_red;
							s->right->color = rb_tree_black;
							rotate_left(s, root);
							s = p->left;
						}
						s->color = p->color;
						p->color = rb_tree_black;
						s->left->color = rb_tree_black;
						rotate_right(p, root);
						break;
					}
				}
			}
			if (x)
				x->color = rb_tree_black;
		}

	private:
		compare_type comp;
		node_pointer header;
		size_type    count;
	};

} // namespace core

#endif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值