#pragma once
#ifndef _STLTREE_H_
#define _STLTREE_H_
//#include <cstddef>
//#include <iterator>
//#include <memory>
//#include <xutility>

#include <stddef.h>
#include <stliter.h>
#include <stlmem.h>
#include <stlxutil.h>

#ifdef  _MSC_VER
#pragma pack(push,8)
#endif  /* _MSC_VER */

_STD_BEGIN

// TEMPLATE CLASS _Tree
template<class _K, class _Ty, class _Kfn, class _Pr, class _A>
class _Tree
{
protected:
    typedef _POINTER_X(void, _A) _Genptr;
    enum _Redbl
    {
        _Red, _Black
    };
    struct _Node;
    friend struct _Node;
    struct _Node
    {
        _Genptr _Left, _Parent, _Right;
        _Ty _Value;
        _Redbl _Color;
    };
    typedef _POINTER_X(_Node, _A) _Nodeptr;
    typedef _REFERENCE_X(_Nodeptr, _A) _Nodepref;
    typedef _REFERENCE_X(const _K, _A) _Keyref;
    typedef _REFERENCE_X(_Redbl, _A) _Rbref;
    typedef _REFERENCE_X(_Ty, _A) _Vref;
    static _Rbref _Color(_Nodeptr _P)
    {
        return ((_Rbref)(*_P)._Color);
    }
    static _Keyref _Key(_Nodeptr _P)
    {
        return (_Kfn()(_Value(_P)));
    }
    static _Nodepref _Left(_Nodeptr _P)
    {
        return ((_Nodepref)(*_P)._Left);
    }
    static _Nodepref _Parent(_Nodeptr _P)
    {
        return ((_Nodepref)(*_P)._Parent);
    }
    static _Nodepref _Right(_Nodeptr _P)
    {
        return ((_Nodepref)(*_P)._Right);
    }
    static _Vref _Value(_Nodeptr _P)
    {
        return ((_Vref)(*_P)._Value);
    }
public:
    typedef _Tree<_K, _Ty, _Kfn, _Pr, _A> _Myt;
    typedef _K key_type;
    typedef _Ty value_type;
    typedef _A::size_type size_type;
    typedef _A::difference_type difference_type;
    typedef _POINTER_X(_Ty, _A) _Tptr;
    typedef _POINTER_X(const _Ty, _A) _Ctptr;
    typedef _REFERENCE_X(_Ty, _A) reference;
    typedef _REFERENCE_X(const _Ty, _A) const_reference;
    // CLASS iterator
    class iterator;
    friend class iterator;
    class iterator : public _Bidit<_Ty, difference_type>
    {
    public:
        iterator()
        {
        }
        iterator(_Nodeptr _P) : _Ptr(_P)
        {
        }
        reference operator*() const
        {
            return (_Value(_Ptr));
        }
        _Tptr operator->() const
        {
            return (&**this);
        }
        iterator& operator++()
        {
            _Inc();
            return (*this);
        }
        iterator operator++(int)
        {
            iterator _Tmp = *this;
            ++*this;
            return (_Tmp);
        }
        iterator& operator--()
        {
            _Dec();
            return (*this);
        }
        iterator operator--(int)
        {
            iterator _Tmp = *this;
            --*this;
            return (_Tmp);
        }
        bool operator==(const iterator& _X) const
        {
            return (_Ptr == _X._Ptr);
        }
        bool operator!=(const iterator& _X) const
        {
            return (!(*this == _X));
        }
        void _Dec()
        {
            //_Lockit _Lk;
            if (_Color(_Ptr) == _Red
                && _Parent(_Parent(_Ptr)) == _Ptr)
                _Ptr = _Right(_Ptr);
            else if (_Left(_Ptr) != _Nil)
                _Ptr = _Max(_Left(_Ptr));
            else
            {
                _Nodeptr _P;
                while (_Ptr == _Left(_P = _Parent(_Ptr)))
                    _Ptr = _P;
                _Ptr = _P;
            }
        }
        void _Inc()
        {
            //_Lockit _Lk;
            if (_Right(_Ptr) != _Nil)
                _Ptr = _Min(_Right(_Ptr));
            else
            {
                _Nodeptr _P;
                while (_Ptr == _Right(_P = _Parent(_Ptr)))
                    _Ptr = _P;
                if (_Right(_Ptr) != _P)
                    _Ptr = _P;
            }
        }
        _Nodeptr _Mynode() const
        {
            return (_Ptr);
        }
    protected:
        _Nodeptr _Ptr;
    };
    // CLASS const_iterator
    class const_iterator;
    friend class const_iterator;
    class const_iterator : public iterator
    {
    public:
        const_iterator()
        {

        }
        const_iterator(_Nodeptr _P)
        : iterator(_P)
        {

        }
        const_iterator(const iterator& _X)
        : iterator(_X)
        {

        }
        const_reference operator*() const
        {
            return (_Value(_Ptr));
        }
        _Ctptr operator->() const
        {
            return (&**this);
        }
        const_iterator& operator++()
        {
            _Inc();
            return (*this);
        }
        const_iterator operator++(int)
        {
            iterator _Tmp = *this;
            ++*this;
            return (_Tmp);
        }
        const_iterator& operator--()
        {
            _Dec();
            return (*this);
        }
        const_iterator operator--(int)
        {
            iterator _Tmp = *this;
            --*this;
            return (_Tmp);
        }
        bool operator==(const const_iterator& _X) const
        {
            return (_Ptr == _X._Ptr);
        }
        bool operator!=(const const_iterator& _X) const
        {
            return (!(*this == _X));
        }
    };
    typedef reverse_bidirectional_iterator<iterator,
    value_type, reference, _Tptr, difference_type>
    reverse_iterator;
    typedef reverse_bidirectional_iterator<const_iterator,
    value_type, const_reference, _Ctptr, difference_type>
    const_reverse_iterator;
    typedef pair<iterator, bool> _Pairib;
    typedef pair<iterator, iterator> _Pairii;
    typedef pair<const_iterator, const_iterator> _Paircc;
    explicit _Tree(const _Pr& _Parg, bool _Marg = true,
                   const _A& _Al = _A())
    : allocator(_Al),
    key_compare(_Parg), _Multi(_Marg)
    {
        _Init();
    }
    _Tree(const _Ty *_F, const _Ty *_L,
          const _Pr& _Parg, bool _Marg = true,
          const _A& _Al = _A())
    : allocator(_Al),
    key_compare(_Parg), _Multi(_Marg)
    {
        _Init();
        insert(_F, _L);
    }
    _Tree(const _Myt& _X)
    : allocator(_X.allocator),
    key_compare(_X.key_compare), _Multi(_X._Multi)
    {
        _Init();
        _Copy(_X);
    }
    ~_Tree()
    {
        erase(begin(), end());
        _Freenode(_Head);
        _Head = 0, _Size = 0;
        {
            //_Lockit _Lk;
            if (--_Nilrefs == 0)
            {
                _Freenode(_Nil);
                _Nil = 0;
            }
        }
    }
    _Myt& operator=(const _Myt& _X)
    {
        if (this != &_X)
        {
            erase(begin(), end());
            key_compare = _X.key_compare;
            _Copy(_X);
        }
        return (*this);
    }
    iterator begin()
    {
        return (iterator(_Lmost()));
    }
    const_iterator begin() const
    {
        return (const_iterator(_Lmost()));
    }
    iterator end()
    {
        return (iterator(_Head));
    }
    const_iterator end() const
    {
        return (const_iterator(_Head));
    }
    reverse_iterator rbegin()
    {
        return (reverse_iterator(end()));
    }
    const_reverse_iterator rbegin() const
    {
        return (const_reverse_iterator(end()));
    }
    reverse_iterator rend()
    {
        return (reverse_iterator(begin()));
    }
    const_reverse_iterator rend() const
    {
        return (const_reverse_iterator(begin()));
    }
    size_type size() const
    {
        return (_Size);
    }
    size_type max_size() const
    {
        return (allocator.max_size());
    }
    bool empty() const
    {
        return (size() == 0);
    }
    _A get_allocator() const
    {
        return (allocator);
    }
    _Pr key_comp() const
    {
        return (key_compare);
    }
    _Pairib insert(const value_type& _V)
    {
        _Nodeptr _X = _Root();
        _Nodeptr _Y = _Head;
        bool _Ans = true;
        {
            //_Lockit Lk;
            while (_X != _Nil)
            {
                _Y = _X;
                _Ans = key_compare(_Kfn()(_V), _Key(_X));
                _X = _Ans ? _Left(_X) : _Right(_X);
            }
        }
        if (_Multi)
            return (_Pairib(_Insert(_X, _Y, _V), true));
        iterator _P = iterator(_Y);
        if (!_Ans)
            ;
        else if (_P == begin())
            return (_Pairib(_Insert(_X, _Y, _V), true));
        else
            --_P;
        if (key_compare(_Key(_P._Mynode()), _Kfn()(_V)))
            return (_Pairib(_Insert(_X, _Y, _V), true));
        return (_Pairib(_P, false));
    }
    iterator insert(iterator _P, const value_type& _V)
    {
        if (size() == 0)
            ;
        else if (_P == begin())
        {
            if (key_compare(_Kfn()(_V), _Key(_P._Mynode())))
                return (_Insert(_Head, _P._Mynode(), _V));
        }
        else if (_P == end())
        {
            //_Lockit Lk;
            if (key_compare(_Key(_Rmost()), _Kfn()(_V)))
                return (_Insert(_Nil, _Rmost(), _V));
        }
        else
        {
            iterator _Pb = _P;
            if (key_compare(_Key((--_Pb)._Mynode()), _Kfn()(_V))
                && key_compare(_Kfn()(_V), _Key(_P._Mynode())))
            {
                //_Lockit _Lk;
                if (_Right(_Pb._Mynode()) == _Nil)
                    return (_Insert(_Nil, _Pb._Mynode(), _V));
                else
                    return (_Insert(_Head, _P._Mynode(), _V));
            }
        }
        return (insert(_V).first);
    }
    void insert(iterator _F, iterator _L)
    {
        for (; _F != _L; ++_F)
            insert(*_F);
    }
    void insert(const value_type *_F, const value_type *_L)
    {
        for (; _F != _L; ++_F)
            insert(*_F);
    }
    iterator erase(iterator _P)
    {
        _Nodeptr _X;
        _Nodeptr _Y = (_P++)._Mynode();
        _Nodeptr _Z = _Y;
        //_Lockit _Lk;
        if (_Left(_Y) == _Nil)
            _X = _Right(_Y);
        else if (_Right(_Y) == _Nil)
            _X = _Left(_Y);
        else
            _Y = _Min(_Right(_Y)), _X = _Right(_Y);
        if (_Y != _Z)
        {
            _Parent(_Left(_Z)) = _Y;
            _Left(_Y) = _Left(_Z);
            if (_Y == _Right(_Z))
                _Parent(_X) = _Y;
            else
            {
                _Parent(_X) = _Parent(_Y);
                _Left(_Parent(_Y)) = _X;
                _Right(_Y) = _Right(_Z);
                _Parent(_Right(_Z)) = _Y;
            }
            if (_Root() == _Z)
                _Root() = _Y;
            else if (_Left(_Parent(_Z)) == _Z)
                _Left(_Parent(_Z)) = _Y;
            else
                _Right(_Parent(_Z)) = _Y;
            _Parent(_Y) = _Parent(_Z);
            std::swap(_Color(_Y), _Color(_Z));
            _Y = _Z;
        }
        else
        {
            _Parent(_X) = _Parent(_Y);
            if (_Root() == _Z)
                _Root() = _X;
            else if (_Left(_Parent(_Z)) == _Z)
                _Left(_Parent(_Z)) = _X;
            else
                _Right(_Parent(_Z)) = _X;
            if (_Lmost() != _Z)
                ;
            else if (_Right(_Z) == _Nil)
                _Lmost() = _Parent(_Z);
            else
                _Lmost() = _Min(_X);
            if (_Rmost() != _Z)
                ;
            else if (_Left(_Z) == _Nil)
                _Rmost() = _Parent(_Z);
            else
                _Rmost() = _Max(_X);
        }
        if (_Color(_Y) == _Black)
        {
            while (_X != _Root() && _Color(_X) == _Black)
                if (_X == _Left(_Parent(_X)))
                {
                    _Nodeptr _W = _Right(_Parent(_X));
                    if (_Color(_W) == _Red)
                    {
                        _Color(_W) = _Black;
                        _Color(_Parent(_X)) = _Red;
                        _Lrotate(_Parent(_X));
                        _W = _Right(_Parent(_X));
                    }
                    if (_Color(_Left(_W)) == _Black
                        && _Color(_Right(_W)) == _Black)
                    {
                        _Color(_W) = _Red;
                        _X = _Parent(_X);
                    }
                    else
                    {
                        if (_Color(_Right(_W)) == _Black)
                        {
                            _Color(_Left(_W)) = _Black;
                            _Color(_W) = _Red;
                            _Rrotate(_W);
                            _W = _Right(_Parent(_X));
                        }
                        _Color(_W) = _Color(_Parent(_X));
                        _Color(_Parent(_X)) = _Black;
                        _Color(_Right(_W)) = _Black;
                        _Lrotate(_Parent(_X));
                        break;
                    }
                }
                else
                {
                    _Nodeptr _W = _Left(_Parent(_X));
                    if (_Color(_W) == _Red)
                    {
                        _Color(_W) = _Black;
                        _Color(_Parent(_X)) = _Red;
                        _Rrotate(_Parent(_X));
                        _W = _Left(_Parent(_X));
                    }
                    if (_Color(_Right(_W)) == _Black
                        && _Color(_Left(_W)) == _Black)
                    {
                        _Color(_W) = _Red;
                        _X = _Parent(_X);
                    }
                    else
                    {
                        if (_Color(_Left(_W)) == _Black)
                        {
                            _Color(_Right(_W)) = _Black;
                            _Color(_W) = _Red;
                            _Lrotate(_W);
                            _W = _Left(_Parent(_X));
                        }
                        _Color(_W) = _Color(_Parent(_X));
                        _Color(_Parent(_X)) = _Black;
                        _Color(_Left(_W)) = _Black;
                        _Rrotate(_Parent(_X));
                        break;
                    }
                }
            _Color(_X) = _Black;
        }
        _Destval(&_Value(_Y));
        _Freenode(_Y);
        --_Size;
        return (_P);
    }
    iterator erase(iterator _F, iterator _L)
    {
        if (size() == 0 || _F != begin() || _L != end())
        {
            while (_F != _L)
                erase(_F++);
            return (_F);
        }
        else
        {
            //_Lockit Lk;
            _Erase(_Root());
            _Root() = _Nil, _Size = 0;
            _Lmost() = _Head, _Rmost() = _Head;
            return (begin());
        }
    }
    size_type erase(const _K& _X)
    {
        _Pairii _P = equal_range(_X);
        size_type _N = 0;
        _Distance(_P.first, _P.second, _N);
        erase(_P.first, _P.second);
        return (_N);
    }
    void erase(const _K *_F, const _K *_L)
    {
        for (; _F != _L; ++_F)
            erase(*_F);
    }
    void clear()
    {
        erase(begin(), end());
    }
    iterator find(const _K& _Kv)
    {
        iterator _P = lower_bound(_Kv);
        return (_P == end()
                || key_compare(_Kv, _Key(_P._Mynode()))
                ? end() : _P);
    }
    const_iterator find(const _K& _Kv) const
    {
        const_iterator _P = lower_bound(_Kv);
        return (_P == end()
                || key_compare(_Kv, _Key(_P._Mynode()))
                ? end() : _P);
    }
    size_type count(const _K& _Kv) const
    {
        _Paircc _Ans = equal_range(_Kv);
        size_type _N = 0;
        _Distance(_Ans.first, _Ans.second, _N);
        return (_N);
    }
    iterator lower_bound(const _K& _Kv)
    {
        return (iterator(_Lbound(_Kv)));
    }
    const_iterator lower_bound(const _K& _Kv) const
    {
        return (const_iterator(_Lbound(_Kv)));
    }
    iterator upper_bound(const _K& _Kv)
    {
        return (iterator(_Ubound(_Kv)));
    }
    const_iterator upper_bound(const _K& _Kv) const
    {
        return (iterator(_Ubound(_Kv)));
    }
    _Pairii equal_range(const _K& _Kv)
    {
        return (_Pairii(lower_bound(_Kv), upper_bound(_Kv)));
    }
    _Paircc equal_range(const _K& _Kv) const
    {
        return (_Paircc(lower_bound(_Kv), upper_bound(_Kv)));
    }
    void swap(_Myt& _X)
    {
        std::swap(key_compare, _X.key_compare);
        if (allocator == _X.allocator)
        {
            std::swap(_Head, _X._Head);
            std::swap(_Multi, _X._Multi);
            std::swap(_Size, _X._Size);
        }
        else
        {
            _Myt _Ts = *this; *this = _X, _X = _Ts;
        }
    }
    friend void swap(_Myt& _X, _Myt& _Y)
    {
        _X.swap(_Y);
    }
protected:
    static _Nodeptr _Nil;
    static size_t _Nilrefs;
    void _Copy(const _Myt& _X)
    {
        //_Lockit _Lk;
        _Root() = _Copy(_X._Root(), _Head);
        _Size = _X.size();
        if (_Root() != _Nil)
        {
            _Lmost() = _Min(_Root());
            _Rmost() = _Max(_Root());
        }
        else
            _Lmost() = _Head, _Rmost() = _Head;
    }
    _Nodeptr _Copy(_Nodeptr _X, _Nodeptr _P)
    {
        //_Lockit _Lk;
        _Nodeptr _R = _X;
        for (; _X != _Nil; _X = _Left(_X))
        {
            _Nodeptr _Y = _Buynode(_P, _Color(_X));
            if (_R == _X)
                _R = _Y;
            _Right(_Y) = _Copy(_Right(_X), _Y);
            _Consval(&_Value(_Y), _Value(_X));
            _Left(_P) = _Y;
            _P = _Y;
        }
        _Left(_P) = _Nil;
        return (_R);
    }
    void _Erase(_Nodeptr _X)
    {
        //_Lockit _Lk;
        for (_Nodeptr _Y = _X; _Y != _Nil; _X = _Y)
        {
            _Erase(_Right(_Y));
            _Y = _Left(_Y);
            _Destval(&_Value(_X));
            _Freenode(_X);
        }
    }
    void _Init()
    {
        //_Lockit _Lk;
        if (_Nil == 0)
        {
            _Nil = _Buynode(0, _Black);
            _Left(_Nil) = 0, _Right(_Nil) = 0;
        }
        ++_Nilrefs;
        _Head = _Buynode(_Nil, _Red), _Size = 0;
        _Lmost() = _Head, _Rmost() = _Head;
    }
    iterator _Insert(_Nodeptr _X, _Nodeptr _Y, const _Ty& _V)
    {
        //_Lockit _Lk;
        _Nodeptr _Z = _Buynode(_Y, _Red);
        _Left(_Z) = _Nil, _Right(_Z) = _Nil;
        _Consval(&_Value(_Z), _V);
        ++_Size;
        if (_Y == _Head || _X != _Nil
            || key_compare(_Kfn()(_V), _Key(_Y)))
        {
            _Left(_Y) = _Z;
            if (_Y == _Head)
            {
                _Root() = _Z;
                _Rmost() = _Z;
            }
            else if (_Y == _Lmost())
                _Lmost() = _Z;
        }
        else
        {
            _Right(_Y) = _Z;
            if (_Y == _Rmost())
                _Rmost() = _Z;
        }
        for (_X = _Z; _X != _Root()
            && _Color(_Parent(_X)) == _Red; )
            if (_Parent(_X) == _Left(_Parent(_Parent(_X))))
            {
                _Y = _Right(_Parent(_Parent(_X)));
                if (_Color(_Y) == _Red)
                {
                    _Color(_Parent(_X)) = _Black;
                    _Color(_Y) = _Black;
                    _Color(_Parent(_Parent(_X))) = _Red;
                    _X = _Parent(_Parent(_X));
                }
                else
                {
                    if (_X == _Right(_Parent(_X)))
                    {
                        _X = _Parent(_X);
                        _Lrotate(_X);
                    }
                    _Color(_Parent(_X)) = _Black;
                    _Color(_Parent(_Parent(_X))) = _Red;
                    _Rrotate(_Parent(_Parent(_X)));
                }
            }
            else
            {
                _Y = _Left(_Parent(_Parent(_X)));
                if (_Color(_Y) == _Red)
                {
                    _Color(_Parent(_X)) = _Black;
                    _Color(_Y) = _Black;
                    _Color(_Parent(_Parent(_X))) = _Red;
                    _X = _Parent(_Parent(_X));
                }
                else
                {
                    if (_X == _Left(_Parent(_X)))
                    {
                        _X = _Parent(_X);
                        _Rrotate(_X);
                    }
                    _Color(_Parent(_X)) = _Black;
                    _Color(_Parent(_Parent(_X))) = _Red;
                    _Lrotate(_Parent(_Parent(_X)));
                }
            }
        _Color(_Root()) = _Black;
        return (iterator(_Z));
    }
    _Nodeptr _Lbound(const _K& _Kv) const
    {
        //_Lockit _Lk;
        _Nodeptr _X = _Root();
        _Nodeptr _Y = _Head;
        while (_X != _Nil)
            if (key_compare(_Key(_X), _Kv))
                _X = _Right(_X);
            else
                _Y = _X, _X = _Left(_X);
        return (_Y);
    }
    _Nodeptr& _Lmost()
    {
        return (_Left(_Head));
    }
    _Nodeptr& _Lmost() const
    {
        return (_Left(_Head));
    }
    void _Lrotate(_Nodeptr _X)
    {
        //_Lockit _Lk;
        _Nodeptr _Y = _Right(_X);
        _Right(_X) = _Left(_Y);
        if (_Left(_Y) != _Nil)
            _Parent(_Left(_Y)) = _X;
        _Parent(_Y) = _Parent(_X);
        if (_X == _Root())
            _Root() = _Y;
        else if (_X == _Left(_Parent(_X)))
            _Left(_Parent(_X)) = _Y;
        else
            _Right(_Parent(_X)) = _Y;
        _Left(_Y) = _X;
        _Parent(_X) = _Y;
    }
    static _Nodeptr _Max(_Nodeptr _P)
    {
        //_Lockit _Lk;
        while (_Right(_P) != _Nil)
            _P = _Right(_P);
        return (_P);
    }
    static _Nodeptr _Min(_Nodeptr _P)
    {
        //_Lockit _Lk;
        while (_Left(_P) != _Nil)
            _P = _Left(_P);
        return (_P);
    }
    _Nodeptr& _Rmost()
    {
        return (_Right(_Head));
    }
    _Nodeptr& _Rmost() const
    {
        return (_Right(_Head));
    }
    _Nodeptr& _Root()
    {
        return (_Parent(_Head));
    }
    _Nodeptr& _Root() const
    {
        return (_Parent(_Head));
    }
    void _Rrotate(_Nodeptr _X)
    {
        //_Lockit _Lk;
        _Nodeptr _Y = _Left(_X);
        _Left(_X) = _Right(_Y);
        if (_Right(_Y) != _Nil)
            _Parent(_Right(_Y)) = _X;
        _Parent(_Y) = _Parent(_X);
        if (_X == _Root())
            _Root() = _Y;
        else if (_X == _Right(_Parent(_X)))
            _Right(_Parent(_X)) = _Y;
        else
            _Left(_Parent(_X)) = _Y;
        _Right(_Y) = _X;
        _Parent(_X) = _Y;
    }
    _Nodeptr _Ubound(const _K& _Kv) const
    {
        //_Lockit _Lk;
        _Nodeptr _X = _Root();
        _Nodeptr _Y = _Head;
        while (_X != _Nil)
            if (key_compare(_Kv, _Key(_X)))
                _Y = _X, _X = _Left(_X);
            else
                _X = _Right(_X);
        return (_Y);
    }
    _Nodeptr _Buynode(_Nodeptr _Parg, _Redbl _Carg)
    {
        _Nodeptr _S = (_Nodeptr)allocator._Charalloc(
                                                    1 * sizeof (_Node));
        _Parent(_S) = _Parg;
        _Color(_S) = _Carg;
        return (_S);
    }
    void _Consval(_Tptr _P, const _Ty& _V)
    {
        _Construct(&*_P, _V);
    }
    void _Destval(_Tptr _P)
    {
        _Destroy(&*_P);
    }
    void _Freenode(_Nodeptr _S)
    {
        allocator.deallocate(_S, 1);
    }
    _A          allocator;
    _Pr         key_compare;
    _Nodeptr    _Head;
    bool        _Multi;
    size_type   _Size;
};

template<class _K, class _Ty, class _Kfn, class _Pr, class _A>
_Tree<_K, _Ty, _Kfn, _Pr, _A>::_Nodeptr
_Tree<_K, _Ty, _Kfn, _Pr, _A>::_Nil = 0;

template<class _K, class _Ty, class _Kfn, class _Pr, class _A>
size_t _Tree<_K, _Ty, _Kfn, _Pr, _A>::_Nilrefs = 0;

// tree TEMPLATE OPERATORS
template<class _K, class _Ty, class _Kfn,
class _Pr, class _A> inline
bool operator==(const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _X,
                const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _Y)
{
    return (_X.size() == _Y.size()
            && equal(_X.begin(), _X.end(), _Y.begin()));
}
template<class _K, class _Ty, class _Kfn,
class _Pr, class _A> inline
bool operator!=(const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _X,
                const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _Y)
{
    return (!(_X == _Y));
}
template<class _K, class _Ty, class _Kfn,
class _Pr, class _A> inline
bool operator<(const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _X,
               const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _Y)
{
    return (lexicographical_compare(_X.begin(), _X.end(),
                                    _Y.begin(), _Y.end()));
}
template<class _K, class _Ty, class _Kfn,
class _Pr, class _A> inline
bool operator>(const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _X,
               const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _Y)
{
    return (_Y < _X);
}
template<class _K, class _Ty, class _Kfn,
class _Pr, class _A> inline
bool operator<=(const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _X,
                const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _Y)
{
    return (!(_Y < _X));
}
template<class _K, class _Ty, class _Kfn,
class _Pr, class _A> inline
bool operator>=(const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _X,
                const _Tree<_K, _Ty, _Kfn, _Pr, _A>& _Y)
{
    return (!(_X < _Y));
}

_STD_END

#ifdef  _MSC_VER
#pragma pack(pop)
#endif  /* _MSC_VER */

#endif /* _STLTREE_H_ */

/*
 * Copyright (c) 1995 by P.J. Plauger.  ALL RIGHTS RESERVED.
 * Consult your license regarding permissions and restrictions.
 */

/*
 * This file is derived from software bearing the following
 * restrictions:
 *
 * Copyright (c) 1994
 * Hewlett-Packard Company
 *
 * Permission to use, copy, modify, distribute and sell this
 * software and its documentation for any purpose is hereby
 * granted without fee, provided that the above copyright notice
 * appear in all copies and that both that copyright notice and
 * this permission notice appear in supporting documentation.
 * Hewlett-Packard Company makes no representations about the
 * suitability of this software for any purpose. It is provided
 * "as is" without express or implied warranty.
 */
