| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709 | #ifndef __GBLIBCPP_BITS_RBTREE__#define __GBLIBCPP_BITS_RBTREE__#include "compressed_pair"#include <cstddef>#include <functional>#include <utility>#include <memory>namespace std::impl {template <typename T, typename Compare, typename Allocator>struct rbtree {    struct node {        node* parent;        node* left;        node* right;        T value;        enum class node_color : unsigned char { RED, BLACK, } color;        constexpr node(const T& val)            : parent {}, left {}, right {}            , value { val } , color {node_color::RED} {}        constexpr node(T&& val)            : parent {}, left {}, right {}            , value { std::move(val) } , color {node_color::RED} {}        template <typename... Args, std::enable_if_t<            (sizeof...(Args) > 1)            || !(... && std::is_same_v<T, std::remove_cvref_t<Args>>)        , bool> = true>        constexpr node(Args&&... args)            : parent {}, left {}, right {}            , value { std::forward<Args>(args)... }, color { node_color::RED } {}        constexpr node* grandparent(void) const        { return this->parent->parent; }        constexpr node* uncle(void) const        {            node* pp = this->grandparent();            if (this->parent == pp->left)                return pp->right;            return pp->left;        }        constexpr node* leftmost(void)        {            node* nd = this;            while (nd->left)                nd = nd->left;            return nd;        }        constexpr node* rightmost(void)        {            node* nd = this;            while (nd->right)                nd = nd->right;            return nd;        }        constexpr node* next(void)        {            if (this->right)                return this->right->leftmost();            if (this->is_root())                return nullptr;            if (this->is_left_child())                return this->parent;            node* ret = this;            do {                ret = ret->parent;            } while (!ret->is_root() && !ret->is_left_child());            return ret->parent;        }        constexpr node* prev(void)        {            if (this->left)                return this->left->rightmost();            if (this->is_root())                return nullptr;            if (this->is_right_child())                return this->parent;            node* ret = this;            do {                ret = ret->parent;            } while (!ret->is_root() && !ret->is_right_child());            return ret->parent;        }        static constexpr bool is_red(node* nd)        { return nd && nd->color == node_color::RED; }        static constexpr bool is_black(node* nd)        { return !node::is_red(nd); }        constexpr bool is_root(void) const        { return this->parent == nullptr; }        constexpr bool is_full(void) const        { return this->left && this->right; }        constexpr bool has_child(void) const        { return this->left || this->right; }        constexpr bool is_leaf(void) const        { return !this->has_child(); }        constexpr bool is_left_child(void) const        { return this == this->parent->left; }        constexpr bool is_right_child(void) const        { return this == this->parent->right; }        constexpr void tored(void)        { this->color = node_color::RED; }        constexpr void toblack(void)        { this->color = node_color::BLACK; }        static constexpr void swap(node* first, node* second)        {            if (node::is_red(first)) {                first->color = second->color;                second->color = node_color::RED;            } else {                first->color = second->color;                second->color = node_color::BLACK;            }            if (first->parent == second) {                node* tmp = first;                first = second;                second = tmp;            }            bool f_is_left_child = first->parent ? first->is_left_child() : false;            bool s_is_left_child = second->parent ? second->is_left_child() : false;            node* fp = first->parent;            node* fl = first->left;            node* fr = first->right;            node* sp = second->parent;            node* sl = second->left;            node* sr = second->right;            if (second->parent != first) {                first->parent = sp;                if (sp) {                    if (s_is_left_child)                        sp->left = first;                    else                        sp->right = first;                }                first->left = sl;                if (sl)                    sl->parent = first;                first->right = sr;                if (sr)                    sr->parent = first;                second->parent = fp;                if (fp) {                    if (f_is_left_child)                        fp->left = second;                    else                        fp->right = second;                }                second->left = fl;                if (fl)                    fl->parent = second;                second->right = fr;                if (fr)                    fr->parent = second;            } else {                first->left = sl;                if (sl)                    sl->parent = first;                first->right = sr;                if (sr)                    sr->parent = first;                second->parent = fp;                if (fp) {                    if (f_is_left_child)                        fp->left = second;                    else                        fp->right = second;                }                first->parent = second;                if (s_is_left_child) {                    second->left = first;                    second->right = fr;                    if (fr)                        fr->parent = second;                } else {                    second->right = first;                    second->left = fl;                    if (fl)                        fl->parent = second;                }            }        }    };    template <bool Const>    class _iterator {    public:        using node_pointer = node*;        using value_type = std::conditional_t<Const, const T, T>;        using pointer = std::add_pointer_t<value_type>;        using reference = std::add_lvalue_reference_t<value_type>;        friend rbtree;    private:        node_pointer p;    public:        constexpr _iterator() = default;        explicit constexpr _iterator(node_pointer ptr)            : p { ptr } {}        constexpr _iterator(const _iterator& iter) = default;        constexpr _iterator(_iterator&& iter) = default;        constexpr ~_iterator() = default;        constexpr _iterator& operator=(const _iterator& iter) = default;        constexpr _iterator& operator=(_iterator&& iter) = default;        constexpr bool operator==(const _iterator& iter) const = default;        constexpr reference operator*(void) const { return p->value; }        constexpr pointer operator&(void) const { return std::addressof(p->value); }        constexpr pointer operator->(void) const { return this->operator&(); }        constexpr _iterator& operator++(void)        { p = p->next(); return *this; }        constexpr _iterator operator++(int)        { _iterator ret(p); (void)this->operator++(); return ret; }        constexpr _iterator& operator--(void)        { p = p->prev(); return *this; }        constexpr _iterator operator--(int)        { _iterator ret(p); (void)this->operator--(); return ret; }        constexpr operator bool() const        { return p; }        constexpr operator _iterator<true>() const        { return _iterator<true> { p }; }    };    using iterator = _iterator<false>;    using const_iterator = _iterator<true>;    using node_allocator = typename        std::allocator_traits<Allocator>::template rebind_alloc<node>;    using node_alloc_traits = std::allocator_traits<node_allocator>;    compressed_pair<node*, node_allocator> root_data;    compressed_pair<std::size_t, Compare> size_data;private:    constexpr node*& _root() noexcept { return root_data.first(); }    constexpr node* const& _root() const noexcept { return root_data.first(); }    constexpr std::size_t& _size() noexcept { return size_data.first(); }    constexpr const std::size_t& _size() const noexcept { return size_data.first(); }    constexpr node_allocator& _alloc() noexcept { return root_data.second(); }    constexpr const node_allocator& _alloc() const noexcept { return root_data.second(); }    constexpr Compare& _comp() noexcept { return size_data.second(); }    constexpr const Compare& _comp() const noexcept { return size_data.second(); }    template <typename... Args>    constexpr node* newnode(Args&&... key)    {        node* ptr = node_alloc_traits::allocate(_alloc(), 1);        node_alloc_traits::construct(_alloc(), ptr, std::forward<Args>(key)...);        return ptr;    }    constexpr void delnode(node* nd)    {        node_alloc_traits::destroy(_alloc(), nd);        node_alloc_traits::deallocate(_alloc(), nd, 1);    }    constexpr void do_insertion(node* parent,        node*& child_inserted, node* nd)    {        nd->parent = parent;        child_inserted = nd;        this->balance(nd);        ++_size();    }public:    constexpr iterator end(void) noexcept    { return iterator(nullptr); }    constexpr const_iterator end(void) const noexcept    { return const_iterator(nullptr); }    constexpr const_iterator cend(void) const noexcept    { return const_iterator(nullptr); }    constexpr iterator begin(void) noexcept    { return _root() ? iterator(_root()->leftmost()) : end(); }    constexpr const_iterator begin(void) const noexcept    { return _root() ? const_iterator(_root()->leftmost()) : end(); }    constexpr const_iterator cbegin(void) const noexcept    { return _root() ? const_iterator(_root()->leftmost()) : end(); }    constexpr void destroy(node* nd)    {        if (!nd)            return;        destroy(nd->left);        destroy(nd->right);        delnode(nd);    }    constexpr void destroy() { destroy(_root()); _root() = nullptr; _size() = 0; }    constexpr node* copy(node* nd)    {        if (!nd)            return nullptr;        node* newnd = newnode(nd->value);        newnd->color = nd->color;        ++_size();        newnd->left = copy(nd->left);        if (newnd->left)            newnd->left->parent = newnd;        newnd->right = copy(nd->right);        if (newnd->right)            newnd->right->parent = newnd;        return newnd;    }    explicit constexpr rbtree(const Compare& comp, const node_allocator& alloc)        : root_data{nullptr, alloc}, size_data{0, comp} { }    constexpr rbtree(const rbtree& other)        : rbtree(other._comp(), other._alloc())    {        _root() = copy(other._root());        if (_root())            _root()->parent = nullptr;    }    constexpr rbtree(const rbtree& other, const node_allocator& alloc)        : rbtree(other._comp(), alloc)    {        _root() = copy(other._root());        if (_root())            _root()->parent = nullptr;    }    constexpr rbtree(rbtree&& other) noexcept        : root_data{std::exchange(other._root(), nullptr), std::move(other._alloc())}        , size_data{std::exchange(other._size(), 0), std::move(other._comp())} { }    constexpr rbtree(rbtree&& other, const node_allocator& alloc) noexcept        : root_data{std::exchange(other._root(), nullptr), alloc}        , size_data{std::exchange(other._size(), 0), std::move(other._comp())} { }    constexpr ~rbtree() { destroy(); }    constexpr rbtree& operator=(const rbtree& other)    {        destroy(_root());        _comp() = other._comp();        if constexpr (node_alloc_traits::            propagate_on_container_copy_assignment::value)            _alloc() = other._alloc();        _root() = copy(other._root());        if (_root())            _root()->parent = nullptr;        return *this;    }    constexpr rbtree& operator=(rbtree&& other) noexcept    {        destroy(_root());        _root() = std::exchange(other._root(), nullptr);        _size() = std::exchange(other._size(), 0);        _comp() = std::move(other._comp());        if constexpr (node_alloc_traits::            propagate_on_container_move_assignment::value)            _alloc() = std::move(other._alloc());        return *this;    }    constexpr void rotateleft(node* rt)    {        node* nrt = rt->right;        if (!rt->is_root()) {            if (rt->is_left_child())                rt->parent->left = nrt;            else                rt->parent->right = nrt;        } else {            _root() = nrt;        }        nrt->parent = rt->parent;        rt->parent = nrt;        rt->right = nrt->left;        if (rt->right)            rt->right->parent = rt;        nrt->left = rt;    }    constexpr void rotateright(node* rt)    {        node* nrt = rt->left;        if (!rt->is_root()) {            if (rt->is_left_child())                rt->parent->left = nrt;            else                rt->parent->right = nrt;        } else {            _root() = nrt;        }        nrt->parent = rt->parent;        rt->parent = nrt;        rt->left = nrt->right;        if (rt->left)            rt->left->parent = rt;        nrt->right = rt;    }    constexpr void balance(node* nd)    {        if (nd->is_root()) {            nd->toblack();            return;        }        if (node::is_black(nd->parent))            return;        node* p = nd->parent;        node* pp = nd->grandparent();        node* uncle = nd->uncle();        if (node::is_red(uncle)) {            p->toblack();            uncle->toblack();            pp->tored();            this->balance(pp);            return;        }        if (p->is_left_child()) {            if (nd->is_left_child()) {                p->toblack();                pp->tored();                this->rotateright(pp);            } else {                this->rotateleft(p);                this->balance(p);            }        } else {            if (nd->is_right_child()) {                p->toblack();                pp->tored();                this->rotateleft(pp);            } else {                this->rotateright(p);                this->balance(p);            }        }    }    template <typename U>    constexpr node* _find(const U& key) const    {        for (node* cur = _root(); cur; ) {            if (_comp()(key, cur->value))                cur = cur->left;            else if (_comp()(cur->value, key))                cur = cur->right;            else                return cur;        }        return nullptr;    }    template <typename U>    constexpr iterator find(const U& key) const    { return iterator { _find(key) }; }    // RBTREE RECURSIVE DELETE    // THIS FUNCTION DOES NOT DELLOCATE THE NODE    // CALLER IS RESPONSIBLE FOR FREEING THE MEMORY    // @param: nd is guaranteed to be a leaf node    constexpr void _erase(node* nd)    {        if (nd->is_root())            return;        if (node::is_black(nd)) {            node* p = nd->parent;            node* s = nullptr;            if (nd->is_left_child())                s = p->right;            else                s = p->left;            if (node::is_red(s)) {                p->tored();                s->toblack();                if (nd->is_right_child()) {                    this->rotateright(p);                    s = p->left;                } else {                    this->rotateleft(p);                    s = p->right;                }            }            node* r = nullptr;            if (node::is_red(s->left)) {                r = s->left;                if (s->is_left_child()) {                    r->toblack();                    s->color = p->color;                    this->rotateright(p);                    p->toblack();                } else {                    r->color = p->color;                    this->rotateright(s);                    this->rotateleft(p);                    p->toblack();                }            } else if (node::is_red(s->right)) {                r = s->right;                if (s->is_left_child()) {                    r->color = p->color;                    this->rotateleft(s);                    this->rotateright(p);                    p->toblack();                } else {                    r->toblack();                    s->color = p->color;                    this->rotateleft(p);                    p->toblack();                }            } else {                s->tored();                if (node::is_black(p))                    this->_erase(p);                else                    p->toblack();            }        }    }    // delete nd from the tree. make nd safe to deallocate    // THIS FUNCTION DOES NOT DELLOCATE THE NODE    // CALLER IS RESPONSIBLE FOR FREEING THE MEMORY    constexpr node* erase(node* nd)    {        if (nd->is_root() && nd->is_leaf()) {            _root() = nullptr;            return nullptr;        }        node* next = nd->next();        while (!nd->is_leaf()) {            node* alt = nd->right ? nd->right->leftmost() : nd->left;            if (nd->is_root())                _root() = alt;            node::swap(nd, alt);        }        this->_erase(nd);        if (nd->is_left_child())            nd->parent->left = nullptr;        else            nd->parent->right = nullptr;        return next;    }    constexpr iterator erase(iterator pos) noexcept    {        node* nextpos = erase(pos.p);        delnode(pos.p);        --_size();        return iterator { nextpos };    }    constexpr iterator erase(const_iterator pos) noexcept    {        node* nextpos = erase(pos.p);        delnode(pos.p);        --_size();        return iterator { nextpos };    }    template <typename U>    constexpr iterator lower_bound(U&& val) const    {        node* cur = _root();        node* result = nullptr;        while (cur) {            if (!_comp()(cur->value, val)) {                result = cur;                cur = cur->left;            }            else {                cur = cur->right;            }        }        return iterator { result };    }    template <typename U>    constexpr iterator upper_bound(U&& val) const    {        iterator iter = lower_bound(std::forward<U>(val));        if (iter && !_comp()(*iter, val) && !_comp()(val, *iter))            return ++iter;        return iter;    }    // value in nd MUST NOT exist in the rbtree,    // that is, if a < b, then a > b    constexpr void insert(node* nd)    {        node* cur = _root();        while (cur) {            if (_comp()(nd->value, cur->value)) {                if (!cur->left) {                    do_insertion(cur, cur->left, nd);                    return;                }                cur = cur->left;            } else {                if (!cur->right) {                    do_insertion(cur, cur->right, nd);                    return;                }                cur = cur->right;            }        }        do_insertion(cur, _root(), nd);    }    template <typename U>    constexpr std::pair<iterator, bool> insert(U&& value)    {        auto iter = find(value);        if (iter)            return { iter, false };        node* ptr = newnode(std::forward<U>(value));        insert(ptr);        return { iterator { ptr }, true };    }    template <typename... Args>    constexpr std::pair<iterator, bool> emplace(Args&&... args)    {        node* nd = newnode(std::forward<Args>(args)...);        node* exist_nd = _find(nd->value);        if (exist_nd) {            delnode(nd);            return { iterator { exist_nd }, false };        }        insert(nd);        return { iterator { nd }, true };    }    constexpr bool empty() const noexcept { return !_root(); }    constexpr std::size_t size() const noexcept { return _size(); }    constexpr void swap(rbtree& other)    {        std::swap(_root(), other._root());        std::swap(_size(), other._size());        std::swap(_comp(), other._comp());        if constexpr (node_alloc_traits::propagate_on_container_swap::value)            std::swap(_alloc(), other._alloc());    }};} // namespace std::impl#endif
 |