RB-tree节点和迭代器设计
RB-tree有红黑二色,并且拥有左右子节点,要实现泛型容器,迭代器的设计是关键。要考虑迭代器的类型、前进、后退、引用、成员访问等操作。
RB-tree迭代器属于双向迭代器,不可随机访问,较为特殊的是前进和后退操作,RB-tree迭代器的前进操作operator++()调用_Rb_tree_increment(),RB-tree的后退操作operator–()调用_Rb_tree_decrement();前进或后退完全依据二叉搜索树的节点排列规则。
//迭代器前进后退操作
struct __rb_tree_base_iterator
{
typedef __rb_tree_node_base::base_ptr base_ptr;
typedef bidirectional_iteraotr_tag iterator_category;
typedef ptrdiff_t difference_type;
base_ptr node; //迭代器指向的节点
void increment()
{
if(nood->right != 0) //如果有右子节点,找到右子节点的最左子节点
{
node = node->right; //向右走
while (node->left != 0) //一直往左子树走到底
node = node->left; //即是解答
}
else //如果没有右子节点,找到为左子节点的父节点
{
base_ptr y = node->parent; //令y为父节点
while (node == y->right) //如果当前节点是个右子节点
{
node = y; //一直上溯,直到节点不为右子节点为止
y = y->parent; //设置循环条件
} //循环结束,为左子节点的父节点找到,即node->parent
if (node->right != y) //正常情况下
node = y; //父节点为寻找的节点
//但在寻找根节点的下一节点,但根节点无右子节点时,node即为解答
} //根节点与头节点互为父节点,根节点无右子节点时,父节点右子节点为根节点
}
void decrement()
{ //头节点为end(),头节点的右子节点即mostright,指向整棵树的max节点
if (node->color == __rb_tree_red && node->parent->parent == node) //如果是红节点,且父节点的父节点等于自己,即头节点时
node = node->right; //头节点的右节点即为解答
else if (node->left != 0) //如果有左子节点,找到左子节点的最右子节点
{
base_ptr y = node->left; //令y为左子节点
while (y->right != 0) //一直往右子树走到底
y = y->right;
node = y; //最后即为答案
}
else //无左子节点时,找到为右子节点的父节点即可
{
base_ptr y = node->parent; //令y为父节点
while (node == y->left) //如果当前节点为左子节点
{
node = y; //一直上溯,直到节点不为左子节点为止
y = y->parent;
}
node = y; //循环结束,父节点即为寻找的上一节点
}
}
};
树状结构的各种操作,需要注意边界情况,根节点需要有特殊处理,RB-tree在实现中设计头节点header,header与root互为对方父节点。
插入新节点时,不但要依照RB-tree的规则调整,还要维护header头节点的正确性,头节点的父节点指向根节点,左子节点指向最小节点,右子节点指向最大节点。
namespace std _GLIBCXX_VISIBILITY(default)
{
enum _Rb_tree_color { _S_red = false, _S_black = true }; //颜色设置
struct _Rb_tree_node_base //base节点结构设计,父节点,左右子树,节点颜色
{
typedef _Rb_tree_node_base* _Base_ptr; //指针类型
typedef const _Rb_tree_node_base* _Const_Base_ptr; //const指针类型
_Rb_tree_color _M_color; //节点颜色,非红即黑
_Base_ptr _M_parent; //父节点
_Base_ptr _M_left; //左子节点
_Base_ptr _M_right; //右子节点
//以下省略const版本
static _Base_ptr //最小节点
_S_minimum(_Base_ptr __x) _GLIBCXX_NOEXCEPT
{
while (__x->_M_left != 0) __x = __x->_M_left; //一直向左走即找到最小值,二叉搜索树的特性
return __x;
}
static _Base_ptr //最大节点
_S_maximum(_Base_ptr __x) _GLIBCXX_NOEXCEPT
{
while (__x->_M_right != 0) __x = __x->_M_right; //一直向右走即找到最大值,二叉搜索树的特性
return __x;
}
}; //_Rb_tree_node_base
template<typename _Key_compare> //节点键值比较函数模板设计
struct _Rb_tree_key_compare //在比较函数上提供值初始化
{
_Key_compare _M_key_compare;
//以下省略构造函数
}; //_Rb_tree_key_compare
struct _Rb_tree_header //头节点设计
{ //头节点默认初始化及节点数管理
_Rb_tree_node_base _M_header; //头节点
size_t _M_node_count; //树的大小
_Rb_tree_header() _GLIBCXX_NOEXCEPT //默认构造函数
{
_M_header._M_color = _S_red; //头节点颜色为红,区分header与root
_M_reset(); //头节点初始化
}
_Rb_tree_header(_Rb_tree_header&& __x) noexcept //移动构造函数
{
if (__x._M_header._M_parent != nullptr) //头节点__x根节点不为空时
_M_move_data(__x); //头节点赋值为__x头节点
else //否则
{
_M_header._M_color = _S_red; //头节点颜色为红
_M_reset(); //置初始状态
}
}
void
_M_move_data(_Rb_tree_header& __from) //赋值为__from头节点
{
_M_header._M_color = __from._M_header._M_color;
_M_header._M_parent = __from._M_header._M_parent;
_M_header._M_left = __from._M_header._M_left;
_M_header._M_right = __from._M_header._M_right;
_M_header._M_parent->_M_parent = &_M_header;
_M_node_count = __from._M_node_count;
__from._M_reset(); //__from头节点置空
}
void
_M_reset() //头节点置初始状态
{
_M_header._M_parent = 0; //header的根节点为空
_M_header._M_left = &_M_header; //header的左子节点为自己
_M_header._M_right = &_M_header; //header的右子节点为自己
_M_node_count = 0; //节点数为0
}
}; //_Rb_tree_header
template<typename _Val> //节点结构设计,在_Rb_tree_node_base基础上增加节点值
struct _Rb_tree_node : public _Rb_tree_node_base
{
typedef _Rb_tree_node<_Val>* _Link_type; //节点指针类型
__gnu_cxx::__aligned_membuf<_Val> _M_storage; //节点值
_Val*
_M_valptr() //返回指向节点值的指针
{ return _M_storage._M_ptr(); }
const _Val*
_M_valptr() const //const版本
{ return _M_storage._M_ptr(); }
}; //_Rb_tree_node
//前进后退操作,省略const版本
_GLIBCXX_PURE _Rb_tree_node_base* //前进操作,前面有详细代码设计
_Rb_tree_increment(_Rb_tree_node_base* __x) throw ();
_GLIBCXX_PURE _Rb_tree_node_base* //后退
_Rb_tree_decrement(_Rb_tree_node_base* __x) throw ();
template<typename _Tp>
struct _Rb_tree_iterator //迭代器设计
{ //类型定义
typedef _Tp value_type; //数据类型
typedef _Tp& reference; //左值引用类型
typedef _Tp* pointer; //指针类型
typedef bidirectional_iterator_tag iterator_category; //迭代器类型,双向迭代器
typedef ptrdiff_t difference_type; //迭代器之间的距离
typedef _Rb_tree_iterator<_Tp> _Self;
typedef _Rb_tree_node_base::_Base_ptr _Base_ptr;
typedef _Rb_tree_node<_Tp>* _Link_type;
_Rb_tree_iterator() _GLIBCXX_NOEXCEPT //默认构造函数
: _M_node() { }
explicit
_Rb_tree_iterator(_Base_ptr __x) _GLIBCXX_NOEXCEPT
: _M_node(__x) { }
//运算符重载
reference //解引用运算符
operator*() const _GLIBCXX_NOEXCEPT //获取节点值
{ return *static_cast<_Link_type>(_M_node)->_M_valptr(); }
pointer //成员访问运算符
operator->() const _GLIBCXX_NOEXCEPT
{ return static_cast<_Link_type> (_M_node)->_M_valptr(); }
_Self& //前置递增运算符
operator++() _GLIBCXX_NOEXCEPT
{
_M_node = _Rb_tree_increment(_M_node);
return *this;
}
_Self //后置递增运算符
operator++(int) _GLIBCXX_NOEXCEPT
{
_Self __tmp = *this;
_M_node = _Rb_tree_increment(_M_node);
return __tmp;
}
_Self& //前置递减运算符
operator--() _GLIBCXX_NOEXCEPT
{
_M_node = _Rb_tree_decrement(_M_node);
return *this;
}
_Self //后置递减运算符
operator--(int) _GLIBCXX_NOEXCEPT
{
_Self __tmp = *this;
_M_node = _Rb_tree_decrement(_M_node);
return __tmp;
}
bool //相等比较运算符
operator==(const _Self& __x) const _GLIBCXX_NOEXCEPT
{ return _M_node == __x._M_node; } //使用节点相等运算符比较
bool //不等运算符
operator!=(const _Self& __x) const _GLIBCXX_NOEXCEPT
{ return _M_node != __x._M_node; } //使用节点不等运算符比较
_Base_ptr _M_node; //base节点对象,与容器产生连结关系
}; //_Rb_tree_iterator
//省略const_iterator设计
template<typename _Val> //迭代器相等比较运算符
inline bool
operator==(const _Rb_tree_iterator<_Val>& __x,
const _Rb_tree_const_iterator<_Val>& __y) _GLIBCXX_NOEXCEPT
{ return __x._M_node == __y._M_node; } //使用节点相等运算符比较
template<typename _Val> //迭代器不等比较运算符
inline bool
operator!=(const _Rb_tree_iterator<_Val>& __x,
const _Rb_tree_const_iterator<_Val>& __y) _GLIBCXX_NOEXCEPT
{ return __x._M_node != __y._M_node; } //使用节点不等运算符比较
void //树中插入节点并调整树平衡及颜色修改
_Rb_tree_insert_and_rebalance(const bool __insert_left,
_Rb_tree_node_base* __x,
_Rb_tree_node_base* __p,
_Rb_tree_node_base& __header) throw ();
_Rb_tree_node_base* //树中删除节点并调整树平衡及颜色修改
_Rb_tree_rebalance_for_erase(_Rb_tree_node_base* const __z,
_Rb_tree_node_base& __header) throw ();
//_Rb_tree设计
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc = allocator<_Val> > //_Compare为比较函数对象,比较节点值
class _Rb_tree
{
typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template
rebind<_Rb_tree_node<_Val> >::other _Node_allocator; //节点内存分配器,分配类型_Rb_tree_node<_Val>
typedef __gnu_cxx::__alloc_traits<_Node_allocator> _Alloc_traits; //节点内存分配器的属性
static_assert(__is_invocable<_Compare&, const _Key&, const _Key&>{},
"comparison object must be invocable with two arguments of key type");
protected: //类型定义
typedef _Rb_tree_node_base* _Base_ptr;
typedef const _Rb_tree_node_base* _Const_Base_ptr;
typedef _Rb_tree_node<_Val>* _Link_type;
typedef const _Rb_tree_node<_Val>* _Const_Link_type;
public: //类型定义
typedef _Key key_type;
typedef _Val value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef _Alloc allocator_type;
protected:
_Link_type
_M_get_node() //内存分配
{ return _Alloc_traits::allocate(_M_get_Node_allocator(), 1); }
void
_M_put_node(_Link_type __p) _GLIBCXX_NOEXCEPT //内存释放
{ _Alloc_traits::deallocate(_M_get_Node_allocator(), __p, 1); }
template<typename... _Args>
void //对象构造
_M_construct_node(_Link_type __node, _Args&&... __args)
{
__try
{
::new(__node) _Rb_tree_node<_Val>;
_Alloc_traits::construct(_M_get_Node_allocator(),
__node->_M_valptr(),
std::forward<_Args>(__args)...);
}
__catch(...)
{
__node->~_Rb_tree_node<_Val>();
_M_put_node(__node);
__throw_exception_again;
}
}
void
_M_destroy_node(_Link_type __p) noexcept //对象析构
{
_Alloc_traits::destroy(_M_get_Node_allocator(), __p->_M_valptr());
__p->~_Rb_tree_node<_Val>();
}
template<typename... _Args>
_Link_type
_M_create_node(_Args&&... __args) //内存分配及对象构造
{
_Link_type __tmp = _M_get_node(); //内存分配
_M_construct_node(__tmp, std::forward<_Args>(__args)...); //构造内容
return __tmp;
}
void
_M_drop_node(_Link_type __p) //对象析构及内存释放
{
_M_destroy_node(__p); //析构内容
_M_put_node(__p); //释放内存
}
template<typename _NodeGen> //复制一个节点,包括值和颜色
_Link_type
_M_clone_node(_Const_Link_type __x, _NodeGen& __node_gen)
{
_Link_type __tmp = __node_gen(*__x->_M_valptr());
__tmp->_M_color = __x->_M_color;
__tmp->_M_left = 0;
__tmp->_M_right = 0;
return __tmp;
}
protected:
template<typename _Key_compare,
bool /* _Is_pod_comparator */ = __is_pod(_Key_compare)>
struct _Rb_tree_impl //节点操作封装,内存分配,键值比较,头节点
: public _Node_allocator
, public _Rb_tree_key_compare<_Key_compare>
, public _Rb_tree_header
{
typedef _Rb_tree_key_compare<_Key_compare> _Base_key_compare; //_Key_compare节点键值比较函数
//以下省略构造函数
}; //_Rb_tree_impl
_Rb_tree_impl<_Compare> _M_impl;
protected:
//以下省略const返回
_Base_ptr&
_M_root() _GLIBCXX_NOEXCEPT //header的父节点即为根节点,header和root互为对方的父节点
{ return this->_M_impl._M_header._M_parent; }
_Base_ptr&
_M_leftmost() _GLIBCXX_NOEXCEPT //header左子节点
{ return this->_M_impl._M_header._M_left; }
_Base_ptr&
_M_rightmost() _GLIBCXX_NOEXCEPT //header右子节点
{ return this->_M_impl._M_header._M_right; }
_Link_type
_M_begin() _GLIBCXX_NOEXCEPT //头节点的父节点为起始节点
{ return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); }
_Base_ptr //尾后节点为header节点
_M_end() _GLIBCXX_NOEXCEPT
{ return &this->_M_impl._M_header; }
static const_reference //节点__x的值
_S_value(_Const_Link_type __x)
{ return *__x->_M_valptr(); }
static const _Key& //节点__x的键值
_S_key(_Const_Link_type __x)
{ return _KeyOfValue()(_S_value(__x)); }
static _Link_type //节点__x左子节点
_S_left(_Base_ptr __x) _GLIBCXX_NOEXCEPT
{ return static_cast<_Link_type>(__x->_M_left); }
static _Link_type //节点__x右子节点
_S_right(_Base_ptr __x) _GLIBCXX_NOEXCEPT
{ return static_cast<_Link_type>(__x->_M_right); }
static const_reference
_S_value(_Const_Base_ptr __x)
{ return *static_cast<_Const_Link_type>(__x)->_M_valptr(); }
static const _Key&
_S_key(_Const_Base_ptr __x)
{ return _KeyOfValue()(_S_value(__x)); }
static _Base_ptr //树中最小值
_S_minimum(_Base_ptr __x) _GLIBCXX_NOEXCEPT
{ return _Rb_tree_node_base::_S_minimum(__x); }
static _Base_ptr //树中最大值
_S_maximum(_Base_ptr __x) _GLIBCXX_NOEXCEPT
{ return _Rb_tree_node_base::_S_maximum(__x); }
public: //类型定义
typedef _Rb_tree_iterator<value_type> iterator; //迭代
typedef _Rb_tree_const_iterator<value_type> const_iterator; //const迭代器
typedef std::reverse_iterator<iterator> reverse_iterator; //反向迭代器
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
pair<_Base_ptr, _Base_ptr> //元素插入,节点键值不允许重复
_M_get_insert_unique_pos(const key_type& __k)
{
typedef pair<_Base_ptr, _Base_ptr> _Res;
_Link_type __x = _M_begin(); //从根节点开始
_Base_ptr __y = _M_end();
bool __comp = true;
while (__x != 0) //根节点往下,寻找合适插入点
{ //循环只做了小于比较,不小于时即为等于或大于情况,需要再次比较
__y = __x;
__comp = _M_impl._M_key_compare(__k, _S_key(__x)); //__k键值与__x键值比较
__x = __comp ? _S_left(__x) : _S_right(__x); //__k键值较小时往左,大于或等于时往右
} //while循环后,__y为插入点__x的父节点,__y必为叶节点
iterator __j = iterator(__y); //迭代器j指向插入点父节点
if (__comp) //上次比较为小于时,需区分全为小于和不全为小于情况
{
if (__j == begin()) //当一路比较均为小于情况直到最小节点时
return _Res(__x, __y); //节点可直接插入
else //当一路比较不全为小于情况时,需要增加与上一个键值比较情况
--__j; //__k键值小于__j键值,需大于__j前一个键值才可插入
} //迭代器++或--指向下一个大或上一个小的键值
//上次比较为大于或等于时,需增加比较去掉等于情况,及上次比较不全为小于需增加与上一个键值比较情况
if (_M_impl._M_key_compare(_S_key(__j._M_node), __k))
return _Res(__x, __y); //当比较以上两种情况小于成立时,节点可直接插入
return _Res(__j._M_node, 0); //否则节点不可插入
}
pair<_Base_ptr, _Base_ptr> //元素插入,节点键值允许重复
_M_get_insert_equal_pos(const key_type& __k)
{
typedef pair<_Base_ptr, _Base_ptr> _Res;
_Link_type __x = _M_begin(); //从根节点开始
_Base_ptr __y = _M_end();
while (__x != 0) //根节点往下,寻找合适插入点
{
__y = __x;
__x = _M_impl._M_key_compare(__k, _S_key(__x)) ?
_S_left(__x) : _S_right(__x);
}
return _Res(__x, __y);
}
private:
template<typename _Arg, typename _NodeGen>
iterator
_M_insert_(_Base_ptr __x, _Base_ptr __p, _Arg&& __v, _NodeGen& __node_gen)
{ //需另外处理__p为header,__v为左插入点__p为最左节点时
bool __insert_left = (__x != 0 || __p == _M_end() //__p为header时
|| _M_impl._M_key_compare(_KeyOfValue()(__v),
_S_key(__p))); //__v为左插入节点时
_Link_type __z = __node_gen(_GLIBCXX_FORWARD(_Arg, __v)); //新增节点
_Rb_tree_insert_and_rebalance(__insert_left, __z, __p,
this->_M_impl._M_header); //设定插入点颜色并调整树
++_M_impl._M_node_count; //节点数累加
return iterator(__z); //返回迭代器指向新增节点
}
public:
//构造函数与析构函数
_Rb_tree() = default;
_Rb_tree(const _Compare& __comp,
const allocator_type& __a = allocator_type())
: _M_impl(__comp, _Node_allocator(__a)) { }
_Rb_tree(const _Rb_tree& __x)
: _M_impl(__x._M_impl) { }
_Rb_tree(const allocator_type& __a)
: _M_impl(_Compare(), _Node_allocator(__a))
{ }
_Rb_tree(const _Rb_tree& __x, const allocator_type& __a)
: _M_impl(__x._M_impl._M_key_compare, _Node_allocator(__a))
{ }
_Rb_tree(_Rb_tree&&) = default;
_Rb_tree(_Rb_tree&& __x, const allocator_type& __a)
: _Rb_tree(std::move(__x), _Node_allocator(__a))
{ }
_Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a)
: _M_impl(__x._M_impl._M_key_compare, std::move(__a))
{ }
~_Rb_tree() _GLIBCXX_NOEXCEPT
{ _M_erase(_M_begin()); }
_Rb_tree&
operator=(const _Rb_tree& __x)
{
if (this != &__x)
{
// Note that _Key may be a constant type.
if (_Alloc_traits::_S_propagate_on_copy_assign())
{
auto& __this_alloc = this->_M_get_Node_allocator();
auto& __that_alloc = __x._M_get_Node_allocator();
if (!_Alloc_traits::_S_always_equal()
&& __this_alloc != __that_alloc)
{
// Replacement allocator cannot free existing storage, we need
// to erase nodes first.
clear();
std::__alloc_on_copy(__this_alloc, __that_alloc);
}
}
_Reuse_or_alloc_node __roan(*this);
_M_impl._M_reset();
_M_impl._M_key_compare = __x._M_impl._M_key_compare;
if (__x._M_root() != 0)
_M_root() = _M_copy(__x, __roan);
}
return *this;
}
_Compare
key_comp() const
{ return _M_impl._M_key_compare; }
//以下省略const返回
iterator
begin() _GLIBCXX_NOEXCEPT //树的起始节点为最左节点
{ return iterator(this->_M_impl._M_header._M_left); }
iterator
end() _GLIBCXX_NOEXCEPT //树的尾后节点为header节点
{ return iterator(&this->_M_impl._M_header); }
reverse_iterator
rbegin() _GLIBCXX_NOEXCEPT
{ return reverse_iterator(end()); }
reverse_iterator
rend() _GLIBCXX_NOEXCEPT
{ return reverse_iterator(begin()); }
bool
empty() const _GLIBCXX_NOEXCEPT //判断树是否为空
{ return _M_impl._M_node_count == 0; }
size_type
size() const _GLIBCXX_NOEXCEPT //树的节点数
{ return _M_impl._M_node_count; }
size_type
max_size() const _GLIBCXX_NOEXCEPT
{ return _Alloc_traits::max_size(_M_get_Node_allocator()); }
void
swap(_Rb_tree& __t) { }
public:
iterator
erase(const_iterator __position) { }
iterator
erase(iterator __position) { }
size_type
erase(const key_type& __x) { }
iterator
erase(const_iterator __first, const_iterator __last) { }
void
erase(const key_type* __first, const key_type* __last)
{
while (__first != __last)
erase(*__first++);
}
void
clear() _GLIBCXX_NOEXCEPT
{
_M_erase(_M_begin());
_M_impl._M_reset();
}
//find、lower_bound、upper_bound、equal_range,以下省略const返回
iterator
find(const key_type& __k) { }
size_type
count(const key_type& __k) const { }
iterator
lower_bound(const key_type& __k) { }
iterator
upper_bound(const key_type& __k) { }
pair<iterator, iterator>
equal_range(const key_type& __k) { }
_Rb_tree&
operator=(_Rb_tree&&) { }
//以下省略部分内容
}; //_Rb_tree
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
inline bool
operator==(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
{
return __x.size() == __y.size()
&& std::equal(__x.begin(), __x.end(), __y.begin());
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
inline bool
operator<(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
{
return std::lexicographical_compare(__x.begin(), __x.end(),
__y.begin(), __y.end());
}
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
inline bool
operator!=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
{ return !(__x == __y); }
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
inline bool
operator>(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
{ return __y < __x; }
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
inline bool
operator<=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
{ return !(__y < __x); }
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
inline bool
operator>=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
{ return !(__x < __y); }
template<typename _Key, typename _Val, typename _KeyOfValue,
typename _Compare, typename _Alloc>
inline void
swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y)
{ __x.swap(__y); }
} // namespace