/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #ifndef HPL1_TREE_H #define HPL1_TREE_H #include "common/func.h" #include "hpl1/std/pair.h" namespace Hpl1 { namespace Std { template > class Tree { public: using ValueType = pair; struct Node { Node *parent; Node *left; Node *right; ValueType value; }; template class Iterator { public: friend Tree; Iterator() = default; Iterator(const Iterator &) = default; Iterator &operator=(const Iterator &) = default; Ref operator*() const { return _current->value; } Ptr operator->() const { return &_current->value; } Iterator &operator++() { if (_current->right) { _current = leftmost(_current->right); } else { auto p = _current->parent; while (p && p->right == _current) { _current = p; p = p->parent; } _current = p; } return *this; } Iterator operator++(int) { auto temp = *this; ++(*this); return temp; } bool operator==(const Iterator &rhs) const { return _current == rhs._current; } bool operator!=(const Iterator &rhs) const { return _current != rhs._current; } private: Iterator(Node *n) : _current(n) {} Node *_current = nullptr; }; using BasicIterator = Iterator; using ConstIterator = Iterator; void clear() { erase(begin(), end()); _size = 0; _root = nullptr; _leftmost = nullptr; } BasicIterator begin() { return BasicIterator{_leftmost}; } ConstIterator begin() const { return ConstIterator{_leftmost}; } BasicIterator end() { return BasicIterator{nullptr}; } ConstIterator end() const { return ConstIterator{nullptr}; } BasicIterator lowerBound(const Key &key) { Node *it = _root; Node *res = nullptr; while (it) { if (!_comp(it->value.first, key)) { res = it; it = it->left; } else { it = it->right; } } return BasicIterator{res}; } ConstIterator lowerBound(const Key &key) const { Node *it = _root; Node *res = nullptr; while (it) { if (!_comp(it->value.first, key)) { res = it; it = it->left; } else { it = it->right; } } return ConstIterator{res}; } BasicIterator upperBound(const Key &key) { Node *it = _root; Node *res = nullptr; while (it) { if (!_comp(key, it->value.first)) { it = it->right; } else { res = it; it = it->left; } } return BasicIterator{res}; } ConstIterator upperBound(const Key &key) const { Node *it = _root; Node *res = nullptr; while (it) { if (!_comp(key, it->value.first)) { it = it->right; } else { res = it; it = it->left; } } return ConstIterator{res}; } BasicIterator erase(BasicIterator it) { auto const u = it._current; if (!u) return {nullptr}; auto v = merge(u->left, u->right); if (u->parent) { auto const p = u->parent; if (p->left == u) p->left = v; else p->right = v; } else { _root = v; } if (v) v->parent = u->parent; if (u == _leftmost) _leftmost = v ? v : u->parent; --_size; auto const ret = ++it; delete u; return ret; } BasicIterator erase(BasicIterator first, BasicIterator last) { while (first != last) erase(first++); return last; } BasicIterator insert(const ValueType &val) { auto it = &_root; Node *parent = nullptr; bool wentRight = false; while (*it) { parent = *it; if (_comp((*it)->value.first, val.first)) { it = &(*it)->right; wentRight = true; } else { it = &(*it)->left; } } *it = new Node{parent, nullptr, nullptr, val}; if (!wentRight) _leftmost = *it; ++_size; return BasicIterator{*it}; } std::size_t size() const { return _size; } bool isEmpty() const { return _size == 0; } ~Tree() { clear(); } private: KeyComp _comp; Node *_root = nullptr; Node *_leftmost = nullptr; std::size_t _size = 0; Node *merge(Node *left, Node *right) { if (!right) return left; else if (!left) return right; else { auto lm = leftmost(right); lm->left = left; left->parent = lm; return right; } } static Node *leftmost(Node *n) { while (n->left) n = n->left; return n; } }; } // namespace Std } // namespace Hpl1 #endif