X-Git-Url: https://oss.titaniummirror.com/gitweb?a=blobdiff_plain;f=libstdc%2B%2B-v3%2Finclude%2Fbits%2Fstl_tree.h;fp=libstdc%2B%2B-v3%2Finclude%2Fbits%2Fstl_tree.h;h=2e567360039cb114cba16a64ca3633bc4b2fea7e;hb=6fed43773c9b0ce596dca5686f37ac3fc0fa11c0;hp=d2ae142e9265c7be01e9a43b59506547ddd89197;hpb=27b11d56b743098deb193d510b337ba22dc52e5c;p=msp430-gcc.git diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h index d2ae142e..2e567360 100644 --- a/libstdc++-v3/include/bits/stl_tree.h +++ b/libstdc++-v3/include/bits/stl_tree.h @@ -1,11 +1,12 @@ // RB tree implementation -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 +// Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library 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 2, or (at your option) +// Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, @@ -13,19 +14,14 @@ // 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 library; see the file COPYING. If not, write to the Free -// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, -// USA. +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. -// As a special exception, you may use this file as part of a free software -// library without restriction. Specifically, if other files instantiate -// templates or use macros or inline functions from this file, or you compile -// this file and link it with other files to produce an executable, this -// file does not by itself cause the resulting executable to be covered by -// the GNU General Public License. This exception does not however -// invalidate any other reasons why the executable file might be covered by -// the GNU General Public License. +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . /* * @@ -60,60 +56,71 @@ * You should not attempt to use it directly. */ -#ifndef __GLIBCPP_INTERNAL_TREE_H -#define __GLIBCPP_INTERNAL_TREE_H - -/* - -Red-black tree class, designed for use in implementing STL -associative containers (set, multiset, map, and multimap). The -insertion and deletion algorithms are based on those in Cormen, -Leiserson, and Rivest, Introduction to Algorithms (MIT Press, 1990), -except that - -(1) the header cell is maintained with links not only to the root -but also to the leftmost node of the tree, to enable constant time -begin(), and to the rightmost node of the tree, to enable linear time -performance when used with the generic set algorithms (set_union, -etc.); - -(2) when a node being deleted has two children its successor node is -relinked into its place, rather than copied, so that the only -iterators invalidated are those referring to the deleted node. - -*/ +#ifndef _STL_TREE_H +#define _STL_TREE_H 1 #include -#include -#include +#include #include - -namespace std -{ - enum _Rb_tree_color { _M_red = false, _M_black = true }; +#include + +_GLIBCXX_BEGIN_NAMESPACE(std) + + // Red-black tree class, designed for use in implementing STL + // associative containers (set, multiset, map, and multimap). The + // insertion and deletion algorithms are based on those in Cormen, + // Leiserson, and Rivest, Introduction to Algorithms (MIT Press, + // 1990), except that + // + // (1) the header cell is maintained with links not only to the root + // but also to the leftmost node of the tree, to enable constant + // time begin(), and to the rightmost node of the tree, to enable + // linear time performance when used with the generic set algorithms + // (set_union, etc.) + // + // (2) when a node being deleted has two children its successor node + // is relinked into its place, rather than copied, so that the only + // iterators invalidated are those referring to the deleted node. + + enum _Rb_tree_color { _S_red = false, _S_black = true }; struct _Rb_tree_node_base { typedef _Rb_tree_node_base* _Base_ptr; - - _Rb_tree_color _M_color; - _Base_ptr _M_parent; - _Base_ptr _M_left; - _Base_ptr _M_right; - - static _Base_ptr + typedef const _Rb_tree_node_base* _Const_Base_ptr; + + _Rb_tree_color _M_color; + _Base_ptr _M_parent; + _Base_ptr _M_left; + _Base_ptr _M_right; + + static _Base_ptr _S_minimum(_Base_ptr __x) { while (__x->_M_left != 0) __x = __x->_M_left; return __x; } - static _Base_ptr + static _Const_Base_ptr + _S_minimum(_Const_Base_ptr __x) + { + while (__x->_M_left != 0) __x = __x->_M_left; + return __x; + } + + static _Base_ptr _S_maximum(_Base_ptr __x) { while (__x->_M_right != 0) __x = __x->_M_right; return __x; } + + static _Const_Base_ptr + _S_maximum(_Const_Base_ptr __x) + { + while (__x->_M_right != 0) __x = __x->_M_right; + return __x; + } }; template @@ -121,476 +128,206 @@ namespace std { typedef _Rb_tree_node<_Val>* _Link_type; _Val _M_value_field; + +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + template + _Rb_tree_node(_Args&&... __args) + : _Rb_tree_node_base(), + _M_value_field(std::forward<_Args>(__args)...) { } +#endif }; - - struct _Rb_tree_base_iterator - { - typedef _Rb_tree_node_base::_Base_ptr _Base_ptr; - typedef bidirectional_iterator_tag iterator_category; - typedef ptrdiff_t difference_type; - _Base_ptr _M_node; + _Rb_tree_node_base* + _Rb_tree_increment(_Rb_tree_node_base* __x); - void - _M_increment() - { - if (_M_node->_M_right != 0) - { - _M_node = _M_node->_M_right; - while (_M_node->_M_left != 0) - _M_node = _M_node->_M_left; - } - else - { - _Base_ptr __y = _M_node->_M_parent; - while (_M_node == __y->_M_right) - { - _M_node = __y; - __y = __y->_M_parent; - } - if (_M_node->_M_right != __y) - _M_node = __y; - } - } + const _Rb_tree_node_base* + _Rb_tree_increment(const _Rb_tree_node_base* __x); - void - _M_decrement() - { - if (_M_node->_M_color == _M_red - && _M_node->_M_parent->_M_parent == _M_node) - _M_node = _M_node->_M_right; - else if (_M_node->_M_left != 0) - { - _Base_ptr __y = _M_node->_M_left; - while (__y->_M_right != 0) - __y = __y->_M_right; - _M_node = __y; - } - else - { - _Base_ptr __y = _M_node->_M_parent; - while (_M_node == __y->_M_left) - { - _M_node = __y; - __y = __y->_M_parent; - } - _M_node = __y; - } - } - }; + _Rb_tree_node_base* + _Rb_tree_decrement(_Rb_tree_node_base* __x); + + const _Rb_tree_node_base* + _Rb_tree_decrement(const _Rb_tree_node_base* __x); - template - struct _Rb_tree_iterator : public _Rb_tree_base_iterator + template + struct _Rb_tree_iterator { - typedef _Val value_type; - typedef _Ref reference; - typedef _Ptr pointer; - typedef _Rb_tree_iterator<_Val, _Val&, _Val*> iterator; - typedef _Rb_tree_iterator<_Val, const _Val&, const _Val*> - const_iterator; - typedef _Rb_tree_iterator<_Val, _Ref, _Ptr> _Self; - typedef _Rb_tree_node<_Val>* _Link_type; - - _Rb_tree_iterator() {} - _Rb_tree_iterator(_Link_type __x) { _M_node = __x; } - _Rb_tree_iterator(const iterator& __it) { _M_node = __it._M_node; } + typedef _Tp value_type; + typedef _Tp& reference; + typedef _Tp* pointer; - reference - operator*() const { return _Link_type(_M_node)->_M_value_field; } + typedef bidirectional_iterator_tag iterator_category; + typedef ptrdiff_t difference_type; - pointer - operator->() const { return &(operator*()); } + typedef _Rb_tree_iterator<_Tp> _Self; + typedef _Rb_tree_node_base::_Base_ptr _Base_ptr; + typedef _Rb_tree_node<_Tp>* _Link_type; - _Self& - operator++() - { - _M_increment(); - return *this; + _Rb_tree_iterator() + : _M_node() { } + + explicit + _Rb_tree_iterator(_Link_type __x) + : _M_node(__x) { } + + reference + operator*() const + { return static_cast<_Link_type>(_M_node)->_M_value_field; } + + pointer + operator->() const + { return &static_cast<_Link_type>(_M_node)->_M_value_field; } + + _Self& + operator++() + { + _M_node = _Rb_tree_increment(_M_node); + return *this; } - _Self - operator++(int) + _Self + operator++(int) { _Self __tmp = *this; - _M_increment(); + _M_node = _Rb_tree_increment(_M_node); return __tmp; } - - _Self& - operator--() { _M_decrement(); return *this; } - _Self - operator--(int) + _Self& + operator--() + { + _M_node = _Rb_tree_decrement(_M_node); + return *this; + } + + _Self + operator--(int) { _Self __tmp = *this; - _M_decrement(); + _M_node = _Rb_tree_decrement(_M_node); return __tmp; } + + bool + operator==(const _Self& __x) const + { return _M_node == __x._M_node; } + + bool + operator!=(const _Self& __x) const + { return _M_node != __x._M_node; } + + _Base_ptr _M_node; }; - template - inline bool - operator==(const _Rb_tree_iterator<_Val, _Ref, _Ptr>& __x, - const _Rb_tree_iterator<_Val, _Ref, _Ptr>& __y) - { return __x._M_node == __y._M_node; } + template + struct _Rb_tree_const_iterator + { + typedef _Tp value_type; + typedef const _Tp& reference; + typedef const _Tp* pointer; - template - inline bool - operator==(const _Rb_tree_iterator<_Val, const _Val&, const _Val*>& __x, - const _Rb_tree_iterator<_Val, _Val&, _Val*>& __y) - { return __x._M_node == __y._M_node; } + typedef _Rb_tree_iterator<_Tp> iterator; - template - inline bool - operator==(const _Rb_tree_iterator<_Val, _Val&, _Val*>& __x, - const _Rb_tree_iterator<_Val, const _Val&, const _Val*>& __y) - { return __x._M_node == __y._M_node; } + typedef bidirectional_iterator_tag iterator_category; + typedef ptrdiff_t difference_type; - template - inline bool - operator!=(const _Rb_tree_iterator<_Val, _Ref, _Ptr>& __x, - const _Rb_tree_iterator<_Val, _Ref, _Ptr>& __y) - { return __x._M_node != __y._M_node; } + typedef _Rb_tree_const_iterator<_Tp> _Self; + typedef _Rb_tree_node_base::_Const_Base_ptr _Base_ptr; + typedef const _Rb_tree_node<_Tp>* _Link_type; - template - inline bool - operator!=(const _Rb_tree_iterator<_Val, const _Val&, const _Val*>& __x, - const _Rb_tree_iterator<_Val, _Val&, _Val*>& __y) - { return __x._M_node != __y._M_node; } + _Rb_tree_const_iterator() + : _M_node() { } - template - inline bool - operator!=(const _Rb_tree_iterator<_Val, _Val&, _Val*>& __x, - const _Rb_tree_iterator<_Val, const _Val&, const _Val*>& __y) - { return __x._M_node != __y._M_node; } + explicit + _Rb_tree_const_iterator(_Link_type __x) + : _M_node(__x) { } - inline void - _Rb_tree_rotate_left(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root) - { - _Rb_tree_node_base* __y = __x->_M_right; - __x->_M_right = __y->_M_left; - if (__y->_M_left !=0) - __y->_M_left->_M_parent = __x; - __y->_M_parent = __x->_M_parent; - - if (__x == __root) - __root = __y; - else if (__x == __x->_M_parent->_M_left) - __x->_M_parent->_M_left = __y; - else - __x->_M_parent->_M_right = __y; - __y->_M_left = __x; - __x->_M_parent = __y; - } - - inline void - _Rb_tree_rotate_right(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root) - { - _Rb_tree_node_base* __y = __x->_M_left; - __x->_M_left = __y->_M_right; - if (__y->_M_right != 0) - __y->_M_right->_M_parent = __x; - __y->_M_parent = __x->_M_parent; - - if (__x == __root) - __root = __y; - else if (__x == __x->_M_parent->_M_right) - __x->_M_parent->_M_right = __y; - else - __x->_M_parent->_M_left = __y; - __y->_M_right = __x; - __x->_M_parent = __y; - } - - inline void - _Rb_tree_rebalance(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root) - { - __x->_M_color = _M_red; - while (__x != __root - && __x->_M_parent->_M_color == _M_red) + _Rb_tree_const_iterator(const iterator& __it) + : _M_node(__it._M_node) { } + + reference + operator*() const + { return static_cast<_Link_type>(_M_node)->_M_value_field; } + + pointer + operator->() const + { return &static_cast<_Link_type>(_M_node)->_M_value_field; } + + _Self& + operator++() { - if (__x->_M_parent == __x->_M_parent->_M_parent->_M_left) - { - _Rb_tree_node_base* __y = __x->_M_parent->_M_parent->_M_right; - if (__y && __y->_M_color == _M_red) - { - __x->_M_parent->_M_color = _M_black; - __y->_M_color = _M_black; - __x->_M_parent->_M_parent->_M_color = _M_red; - __x = __x->_M_parent->_M_parent; - } - else - { - if (__x == __x->_M_parent->_M_right) - { - __x = __x->_M_parent; - _Rb_tree_rotate_left(__x, __root); - } - __x->_M_parent->_M_color = _M_black; - __x->_M_parent->_M_parent->_M_color = _M_red; - _Rb_tree_rotate_right(__x->_M_parent->_M_parent, __root); - } - } - else - { - _Rb_tree_node_base* __y = __x->_M_parent->_M_parent->_M_left; - if (__y && __y->_M_color == _M_red) - { - __x->_M_parent->_M_color = _M_black; - __y->_M_color = _M_black; - __x->_M_parent->_M_parent->_M_color = _M_red; - __x = __x->_M_parent->_M_parent; - } - else - { - if (__x == __x->_M_parent->_M_left) - { - __x = __x->_M_parent; - _Rb_tree_rotate_right(__x, __root); - } - __x->_M_parent->_M_color = _M_black; - __x->_M_parent->_M_parent->_M_color = _M_red; - _Rb_tree_rotate_left(__x->_M_parent->_M_parent, __root); - } - } + _M_node = _Rb_tree_increment(_M_node); + return *this; } - __root->_M_color = _M_black; - } - - inline _Rb_tree_node_base* - _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* __z, - _Rb_tree_node_base*& __root, - _Rb_tree_node_base*& __leftmost, - _Rb_tree_node_base*& __rightmost) - { - _Rb_tree_node_base* __y = __z; - _Rb_tree_node_base* __x = 0; - _Rb_tree_node_base* __x_parent = 0; - if (__y->_M_left == 0) // __z has at most one non-null child. y == z. - __x = __y->_M_right; // __x might be null. - else - if (__y->_M_right == 0) // __z has exactly one non-null child. y == z. - __x = __y->_M_left; // __x is not null. - else - { - // __z has two non-null children. Set __y to - __y = __y->_M_right; // __z's successor. __x might be null. - while (__y->_M_left != 0) - __y = __y->_M_left; - __x = __y->_M_right; - } - if (__y != __z) + + _Self + operator++(int) { - // relink y in place of z. y is z's successor - __z->_M_left->_M_parent = __y; - __y->_M_left = __z->_M_left; - if (__y != __z->_M_right) - { - __x_parent = __y->_M_parent; - if (__x) __x->_M_parent = __y->_M_parent; - __y->_M_parent->_M_left = __x; // __y must be a child of _M_left - __y->_M_right = __z->_M_right; - __z->_M_right->_M_parent = __y; - } - else - __x_parent = __y; - if (__root == __z) - __root = __y; - else if (__z->_M_parent->_M_left == __z) - __z->_M_parent->_M_left = __y; - else - __z->_M_parent->_M_right = __y; - __y->_M_parent = __z->_M_parent; - std::swap(__y->_M_color, __z->_M_color); - __y = __z; - // __y now points to node to be actually deleted - } - else - { // __y == __z - __x_parent = __y->_M_parent; - if (__x) - __x->_M_parent = __y->_M_parent; - if (__root == __z) - __root = __x; - else - if (__z->_M_parent->_M_left == __z) - __z->_M_parent->_M_left = __x; - else - __z->_M_parent->_M_right = __x; - if (__leftmost == __z) - if (__z->_M_right == 0) // __z->_M_left must be null also - __leftmost = __z->_M_parent; - // makes __leftmost == _M_header if __z == __root - else - __leftmost = _Rb_tree_node_base::_S_minimum(__x); - if (__rightmost == __z) - if (__z->_M_left == 0) // __z->_M_right must be null also - __rightmost = __z->_M_parent; - // makes __rightmost == _M_header if __z == __root - else // __x == __z->_M_left - __rightmost = _Rb_tree_node_base::_S_maximum(__x); - } - if (__y->_M_color != _M_red) - { - while (__x != __root && (__x == 0 || __x->_M_color == _M_black)) - if (__x == __x_parent->_M_left) - { - _Rb_tree_node_base* __w = __x_parent->_M_right; - if (__w->_M_color == _M_red) - { - __w->_M_color = _M_black; - __x_parent->_M_color = _M_red; - _Rb_tree_rotate_left(__x_parent, __root); - __w = __x_parent->_M_right; - } - if ((__w->_M_left == 0 || - __w->_M_left->_M_color == _M_black) && - (__w->_M_right == 0 || - __w->_M_right->_M_color == _M_black)) - { - __w->_M_color = _M_red; - __x = __x_parent; - __x_parent = __x_parent->_M_parent; - } - else - { - if (__w->_M_right == 0 - || __w->_M_right->_M_color == _M_black) - { - if (__w->_M_left) __w->_M_left->_M_color = _M_black; - __w->_M_color = _M_red; - _Rb_tree_rotate_right(__w, __root); - __w = __x_parent->_M_right; - } - __w->_M_color = __x_parent->_M_color; - __x_parent->_M_color = _M_black; - if (__w->_M_right) - __w->_M_right->_M_color = _M_black; - _Rb_tree_rotate_left(__x_parent, __root); - break; - } - } - else - { - // same as above, with _M_right <-> _M_left. - _Rb_tree_node_base* __w = __x_parent->_M_left; - if (__w->_M_color == _M_red) - { - __w->_M_color = _M_black; - __x_parent->_M_color = _M_red; - _Rb_tree_rotate_right(__x_parent, __root); - __w = __x_parent->_M_left; - } - if ((__w->_M_right == 0 || - __w->_M_right->_M_color == _M_black) && - (__w->_M_left == 0 || - __w->_M_left->_M_color == _M_black)) - { - __w->_M_color = _M_red; - __x = __x_parent; - __x_parent = __x_parent->_M_parent; - } - else - { - if (__w->_M_left == 0 || __w->_M_left->_M_color == _M_black) - { - if (__w->_M_right) __w->_M_right->_M_color = _M_black; - __w->_M_color = _M_red; - _Rb_tree_rotate_left(__w, __root); - __w = __x_parent->_M_left; - } - __w->_M_color = __x_parent->_M_color; - __x_parent->_M_color = _M_black; - if (__w->_M_left) - __w->_M_left->_M_color = _M_black; - _Rb_tree_rotate_right(__x_parent, __root); - break; - } - } - if (__x) __x->_M_color = _M_black; + _Self __tmp = *this; + _M_node = _Rb_tree_increment(_M_node); + return __tmp; } - return __y; - } - - // Base class to encapsulate the differences between old SGI-style - // allocators and standard-conforming allocators. In order to avoid - // having an empty base class, we arbitrarily move one of rb_tree's - // data members into the base class. - // _Base for general standard-conforming allocators. - template - class _Rb_tree_alloc_base - { - public: - typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type; - - allocator_type - get_allocator() const { return _M_node_allocator; } + _Self& + operator--() + { + _M_node = _Rb_tree_decrement(_M_node); + return *this; + } - _Rb_tree_alloc_base(const allocator_type& __a) - : _M_node_allocator(__a), _M_header(0) {} + _Self + operator--(int) + { + _Self __tmp = *this; + _M_node = _Rb_tree_decrement(_M_node); + return __tmp; + } - protected: - typename _Alloc_traits<_Rb_tree_node<_Tp>, _Alloc>::allocator_type - _M_node_allocator; + bool + operator==(const _Self& __x) const + { return _M_node == __x._M_node; } - _Rb_tree_node<_Tp>* _M_header; - - _Rb_tree_node<_Tp>* - _M_get_node() { return _M_node_allocator.allocate(1); } + bool + operator!=(const _Self& __x) const + { return _M_node != __x._M_node; } - void - _M_put_node(_Rb_tree_node<_Tp>* __p) - { _M_node_allocator.deallocate(__p, 1); } + _Base_ptr _M_node; }; - // Specialization for instanceless allocators. - template - class _Rb_tree_alloc_base<_Tp, _Alloc, true> - { - public: - typedef typename _Alloc_traits<_Tp, _Alloc>::allocator_type allocator_type; - allocator_type get_allocator() const { return allocator_type(); } - - _Rb_tree_alloc_base(const allocator_type&) : _M_header(0) {} + template + inline bool + operator==(const _Rb_tree_iterator<_Val>& __x, + const _Rb_tree_const_iterator<_Val>& __y) + { return __x._M_node == __y._M_node; } - protected: - _Rb_tree_node<_Tp>* _M_header; - - typedef typename _Alloc_traits<_Rb_tree_node<_Tp>, _Alloc>::_Alloc_type - _Alloc_type; - - _Rb_tree_node<_Tp>* - _M_get_node() { return _Alloc_type::allocate(1); } + template + inline bool + operator!=(const _Rb_tree_iterator<_Val>& __x, + const _Rb_tree_const_iterator<_Val>& __y) + { return __x._M_node != __y._M_node; } - void - _M_put_node(_Rb_tree_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); } - }; - - template - struct _Rb_tree_base : public _Rb_tree_alloc_base<_Tp, _Alloc, - _Alloc_traits<_Tp, _Alloc>::_S_instanceless> - { - typedef _Rb_tree_alloc_base<_Tp, - _Alloc, _Alloc_traits<_Tp, _Alloc>::_S_instanceless> _Base; - typedef typename _Base::allocator_type allocator_type; + 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); - _Rb_tree_base(const allocator_type& __a) - : _Base(__a) { _M_header = _M_get_node(); } - ~_Rb_tree_base() { _M_put_node(_M_header); } - }; + _Rb_tree_node_base* + _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* const __z, + _Rb_tree_node_base& __header); - template > - class _Rb_tree : protected _Rb_tree_base<_Val, _Alloc> + class _Rb_tree { - typedef _Rb_tree_base<_Val, _Alloc> _Base; - + typedef typename _Alloc::template rebind<_Rb_tree_node<_Val> >::other + _Node_allocator; + protected: typedef _Rb_tree_node_base* _Base_ptr; - typedef _Rb_tree_node<_Val> _Rb_tree_node; - + typedef const _Rb_tree_node_base* _Const_Base_ptr; + public: typedef _Key key_type; typedef _Val value_type; @@ -598,34 +335,83 @@ namespace std typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; - typedef _Rb_tree_node* _Link_type; + typedef _Rb_tree_node<_Val>* _Link_type; + typedef const _Rb_tree_node<_Val>* _Const_Link_type; typedef size_t size_type; typedef ptrdiff_t difference_type; + typedef _Alloc allocator_type; + + _Node_allocator& + _M_get_Node_allocator() + { return *static_cast<_Node_allocator*>(&this->_M_impl); } - typedef typename _Base::allocator_type allocator_type; - allocator_type get_allocator() const { return _Base::get_allocator(); } - + const _Node_allocator& + _M_get_Node_allocator() const + { return *static_cast(&this->_M_impl); } + + allocator_type + get_allocator() const + { return allocator_type(_M_get_Node_allocator()); } + protected: - using _Base::_M_get_node; - using _Base::_M_put_node; - using _Base::_M_header; - + _Link_type + _M_get_node() + { return _M_impl._Node_allocator::allocate(1); } + + void + _M_put_node(_Link_type __p) + { _M_impl._Node_allocator::deallocate(__p, 1); } + +#ifndef __GXX_EXPERIMENTAL_CXX0X__ _Link_type _M_create_node(const value_type& __x) { _Link_type __tmp = _M_get_node(); - try - { _Construct(&__tmp->_M_value_field, __x); } - catch(...) + __try + { get_allocator().construct(&__tmp->_M_value_field, __x); } + __catch(...) { - _M_put_node(__tmp); - __throw_exception_again; + _M_put_node(__tmp); + __throw_exception_again; } return __tmp; } - - _Link_type - _M_clone_node(_Link_type __x) + + void + _M_destroy_node(_Link_type __p) + { + get_allocator().destroy(&__p->_M_value_field); + _M_put_node(__p); + } +#else + template + _Link_type + _M_create_node(_Args&&... __args) + { + _Link_type __tmp = _M_get_node(); + __try + { + _M_get_Node_allocator().construct(__tmp, + std::forward<_Args>(__args)...); + } + __catch(...) + { + _M_put_node(__tmp); + __throw_exception_again; + } + return __tmp; + } + + void + _M_destroy_node(_Link_type __p) + { + _M_get_Node_allocator().destroy(__p); + _M_put_node(__p); + } +#endif + + _Link_type + _M_clone_node(_Const_Link_type __x) { _Link_type __tmp = _M_create_node(__x->_M_value_field); __tmp->_M_color = __x->_M_color; @@ -634,829 +420,1076 @@ namespace std return __tmp; } - void - destroy_node(_Link_type __p) - { - _Destroy(&__p->_M_value_field); - _M_put_node(__p); - } + protected: + template + struct _Rb_tree_impl : public _Node_allocator + { + _Key_compare _M_key_compare; + _Rb_tree_node_base _M_header; + size_type _M_node_count; // Keeps track of size of tree. + + _Rb_tree_impl() + : _Node_allocator(), _M_key_compare(), _M_header(), + _M_node_count(0) + { _M_initialize(); } + + _Rb_tree_impl(const _Key_compare& __comp, const _Node_allocator& __a) + : _Node_allocator(__a), _M_key_compare(__comp), _M_header(), + _M_node_count(0) + { _M_initialize(); } + + private: + void + _M_initialize() + { + this->_M_header._M_color = _S_red; + this->_M_header._M_parent = 0; + this->_M_header._M_left = &this->_M_header; + this->_M_header._M_right = &this->_M_header; + } + }; - size_type _M_node_count; // keeps track of size of tree - _Compare _M_key_compare; + _Rb_tree_impl<_Compare> _M_impl; + + protected: + _Base_ptr& + _M_root() + { return this->_M_impl._M_header._M_parent; } - _Link_type& - _M_root() const { return (_Link_type&) _M_header->_M_parent; } + _Const_Base_ptr + _M_root() const + { return this->_M_impl._M_header._M_parent; } - _Link_type& - _M_leftmost() const { return (_Link_type&) _M_header->_M_left; } + _Base_ptr& + _M_leftmost() + { return this->_M_impl._M_header._M_left; } - _Link_type& - _M_rightmost() const { return (_Link_type&) _M_header->_M_right; } + _Const_Base_ptr + _M_leftmost() const + { return this->_M_impl._M_header._M_left; } - static _Link_type& - _S_left(_Link_type __x) { return (_Link_type&)(__x->_M_left); } + _Base_ptr& + _M_rightmost() + { return this->_M_impl._M_header._M_right; } - static _Link_type& - _S_right(_Link_type __x) { return (_Link_type&)(__x->_M_right); } + _Const_Base_ptr + _M_rightmost() const + { return this->_M_impl._M_header._M_right; } - static _Link_type& - _S_parent(_Link_type __x) { return (_Link_type&)(__x->_M_parent); } + _Link_type + _M_begin() + { return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); } - static reference - _S_value(_Link_type __x) { return __x->_M_value_field; } + _Const_Link_type + _M_begin() const + { + return static_cast<_Const_Link_type> + (this->_M_impl._M_header._M_parent); + } - static const _Key& - _S_key(_Link_type __x) { return _KeyOfValue()(_S_value(__x)); } + _Link_type + _M_end() + { return static_cast<_Link_type>(&this->_M_impl._M_header); } - static _Rb_tree_color& - _S_color(_Link_type __x) { return __x->_M_color; } + _Const_Link_type + _M_end() const + { return static_cast<_Const_Link_type>(&this->_M_impl._M_header); } - static _Link_type& - _S_left(_Base_ptr __x) { return (_Link_type&)(__x->_M_left); } + static const_reference + _S_value(_Const_Link_type __x) + { return __x->_M_value_field; } - static _Link_type& - _S_right(_Base_ptr __x) { return (_Link_type&)(__x->_M_right); } + static const _Key& + _S_key(_Const_Link_type __x) + { return _KeyOfValue()(_S_value(__x)); } - static _Link_type& - _S_parent(_Base_ptr __x) { return (_Link_type&)(__x->_M_parent); } + static _Link_type + _S_left(_Base_ptr __x) + { return static_cast<_Link_type>(__x->_M_left); } - static reference - _S_value(_Base_ptr __x) { return ((_Link_type)__x)->_M_value_field; } + static _Const_Link_type + _S_left(_Const_Base_ptr __x) + { return static_cast<_Const_Link_type>(__x->_M_left); } - static const _Key& - _S_key(_Base_ptr __x) { return _KeyOfValue()(_S_value(_Link_type(__x)));} + static _Link_type + _S_right(_Base_ptr __x) + { return static_cast<_Link_type>(__x->_M_right); } - static _Rb_tree_color& - _S_color(_Base_ptr __x) { return (_Link_type(__x)->_M_color); } + static _Const_Link_type + _S_right(_Const_Base_ptr __x) + { return static_cast<_Const_Link_type>(__x->_M_right); } - static _Link_type - _S_minimum(_Link_type __x) - { return (_Link_type) _Rb_tree_node_base::_S_minimum(__x); } + static const_reference + _S_value(_Const_Base_ptr __x) + { return static_cast<_Const_Link_type>(__x)->_M_value_field; } - static _Link_type - _S_maximum(_Link_type __x) - { return (_Link_type) _Rb_tree_node_base::_S_maximum(__x); } + static const _Key& + _S_key(_Const_Base_ptr __x) + { return _KeyOfValue()(_S_value(__x)); } + + static _Base_ptr + _S_minimum(_Base_ptr __x) + { return _Rb_tree_node_base::_S_minimum(__x); } + + static _Const_Base_ptr + _S_minimum(_Const_Base_ptr __x) + { return _Rb_tree_node_base::_S_minimum(__x); } + + static _Base_ptr + _S_maximum(_Base_ptr __x) + { return _Rb_tree_node_base::_S_maximum(__x); } + + static _Const_Base_ptr + _S_maximum(_Const_Base_ptr __x) + { return _Rb_tree_node_base::_S_maximum(__x); } public: - typedef _Rb_tree_iterator iterator; - typedef _Rb_tree_iterator - const_iterator; + typedef _Rb_tree_iterator iterator; + typedef _Rb_tree_const_iterator const_iterator; - typedef reverse_iterator const_reverse_iterator; - typedef reverse_iterator reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; private: - iterator - _M_insert(_Base_ptr __x, _Base_ptr __y, const value_type& __v); + iterator + _M_insert_(_Const_Base_ptr __x, _Const_Base_ptr __y, + const value_type& __v); - _Link_type - _M_copy(_Link_type __x, _Link_type __p); + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 233. Insertion hints in associative containers. + iterator + _M_insert_lower(_Base_ptr __x, _Base_ptr __y, const value_type& __v); + + iterator + _M_insert_equal_lower(const value_type& __x); + + _Link_type + _M_copy(_Const_Link_type __x, _Link_type __p); - void + void _M_erase(_Link_type __x); + iterator + _M_lower_bound(_Link_type __x, _Link_type __y, + const _Key& __k); + + const_iterator + _M_lower_bound(_Const_Link_type __x, _Const_Link_type __y, + const _Key& __k) const; + + iterator + _M_upper_bound(_Link_type __x, _Link_type __y, + const _Key& __k); + + const_iterator + _M_upper_bound(_Const_Link_type __x, _Const_Link_type __y, + const _Key& __k) const; + public: // allocation/deallocation - _Rb_tree() - : _Base(allocator_type()), _M_node_count(0), _M_key_compare() - { _M_empty_initialize(); } - - _Rb_tree(const _Compare& __comp) - : _Base(allocator_type()), _M_node_count(0), _M_key_compare(__comp) - { _M_empty_initialize(); } + _Rb_tree() { } - _Rb_tree(const _Compare& __comp, const allocator_type& __a) - : _Base(__a), _M_node_count(0), _M_key_compare(__comp) - { _M_empty_initialize(); } + _Rb_tree(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_impl(__comp, __a) { } - _Rb_tree(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x) - : _Base(__x.get_allocator()), _M_node_count(0), - _M_key_compare(__x._M_key_compare) - { - if (__x._M_root() == 0) - _M_empty_initialize(); - else + _Rb_tree(const _Rb_tree& __x) + : _M_impl(__x._M_impl._M_key_compare, __x._M_get_Node_allocator()) + { + if (__x._M_root() != 0) { - _S_color(_M_header) = _M_red; - _M_root() = _M_copy(__x._M_root(), _M_header); + _M_root() = _M_copy(__x._M_begin(), _M_end()); _M_leftmost() = _S_minimum(_M_root()); _M_rightmost() = _S_maximum(_M_root()); + _M_impl._M_node_count = __x._M_impl._M_node_count; } - _M_node_count = __x._M_node_count; } - ~_Rb_tree() { clear(); } +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + _Rb_tree(_Rb_tree&& __x); +#endif - _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& - operator=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x); + ~_Rb_tree() + { _M_erase(_M_begin()); } - private: - void _M_empty_initialize() - { - _S_color(_M_header) = _M_red; // used to distinguish header from - // __root, in iterator.operator++ - _M_root() = 0; - _M_leftmost() = _M_header; - _M_rightmost() = _M_header; - } + _Rb_tree& + operator=(const _Rb_tree& __x); - public: // Accessors. - _Compare - key_comp() const { return _M_key_compare; } + _Compare + key_comp() const + { return _M_impl._M_key_compare; } - iterator - begin() { return _M_leftmost(); } + iterator + begin() + { + return iterator(static_cast<_Link_type> + (this->_M_impl._M_header._M_left)); + } - const_iterator - begin() const { return _M_leftmost(); } + const_iterator + begin() const + { + return const_iterator(static_cast<_Const_Link_type> + (this->_M_impl._M_header._M_left)); + } - iterator - end() { return _M_header; } + iterator + end() + { return iterator(static_cast<_Link_type>(&this->_M_impl._M_header)); } - const_iterator - end() const { return _M_header; } + const_iterator + end() const + { + return const_iterator(static_cast<_Const_Link_type> + (&this->_M_impl._M_header)); + } - reverse_iterator - rbegin() { return reverse_iterator(end()); } + reverse_iterator + rbegin() + { return reverse_iterator(end()); } - const_reverse_iterator - rbegin() const { return const_reverse_iterator(end()); } + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(end()); } - reverse_iterator - rend() { return reverse_iterator(begin()); } + reverse_iterator + rend() + { return reverse_iterator(begin()); } - const_reverse_iterator - rend() const { return const_reverse_iterator(begin()); } - - bool - empty() const { return _M_node_count == 0; } + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } - size_type - size() const { return _M_node_count; } + bool + empty() const + { return _M_impl._M_node_count == 0; } - size_type - max_size() const { return size_type(-1); } + size_type + size() const + { return _M_impl._M_node_count; } + + size_type + max_size() const + { return _M_get_Node_allocator().max_size(); } + + void +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + swap(_Rb_tree&& __t); +#else + swap(_Rb_tree& __t); +#endif - void - swap(_Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __t) - { - std::swap(_M_header, __t._M_header); - std::swap(_M_node_count, __t._M_node_count); - std::swap(_M_key_compare, __t._M_key_compare); - } - // Insert/erase. - pair - insert_unique(const value_type& __x); + pair + _M_insert_unique(const value_type& __x); - iterator - insert_equal(const value_type& __x); + iterator + _M_insert_equal(const value_type& __x); - iterator - insert_unique(iterator __position, const value_type& __x); + iterator + _M_insert_unique_(const_iterator __position, const value_type& __x); - iterator - insert_equal(iterator __position, const value_type& __x); + iterator + _M_insert_equal_(const_iterator __position, const value_type& __x); template - void - insert_unique(_InputIterator __first, _InputIterator __last); + void + _M_insert_unique(_InputIterator __first, _InputIterator __last); template - void - insert_equal(_InputIterator __first, _InputIterator __last); + void + _M_insert_equal(_InputIterator __first, _InputIterator __last); - void + void erase(iterator __position); - size_type + void + erase(const_iterator __position); + + size_type erase(const key_type& __x); - void + void erase(iterator __first, iterator __last); - void + void + erase(const_iterator __first, const_iterator __last); + + void erase(const key_type* __first, const key_type* __last); - void - clear() + void + clear() { - if (_M_node_count != 0) - { - _M_erase(_M_root()); - _M_leftmost() = _M_header; - _M_root() = 0; - _M_rightmost() = _M_header; - _M_node_count = 0; - } - } + _M_erase(_M_begin()); + _M_leftmost() = _M_end(); + _M_root() = 0; + _M_rightmost() = _M_end(); + _M_impl._M_node_count = 0; + } // Set operations. - iterator - find(const key_type& __x); + iterator + find(const key_type& __k); - const_iterator - find(const key_type& __x) const; + const_iterator + find(const key_type& __k) const; - size_type - count(const key_type& __x) const; + size_type + count(const key_type& __k) const; - iterator - lower_bound(const key_type& __x); + iterator + lower_bound(const key_type& __k) + { return _M_lower_bound(_M_begin(), _M_end(), __k); } - const_iterator - lower_bound(const key_type& __x) const; + const_iterator + lower_bound(const key_type& __k) const + { return _M_lower_bound(_M_begin(), _M_end(), __k); } - iterator - upper_bound(const key_type& __x); + iterator + upper_bound(const key_type& __k) + { return _M_upper_bound(_M_begin(), _M_end(), __k); } - const_iterator - upper_bound(const key_type& __x) const; + const_iterator + upper_bound(const key_type& __k) const + { return _M_upper_bound(_M_begin(), _M_end(), __k); } - pair - equal_range(const key_type& __x); + pair + equal_range(const key_type& __k); - pair - equal_range(const key_type& __x) const; + pair + equal_range(const key_type& __k) const; // Debugging. - bool + bool __rb_verify() const; }; - template - inline bool - operator==(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, - const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + 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() && - equal(__x.begin(), __x.end(), __y.begin()); + return __x.size() == __y.size() + && std::equal(__x.begin(), __x.end(), __y.begin()); } - template - inline bool - operator<(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, - const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + inline bool + operator<(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, + const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) { - return lexicographical_compare(__x.begin(), __x.end(), - __y.begin(), __y.end()); + return std::lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); } - template - inline bool - operator!=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, - const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + 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 - inline bool - operator>(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, - const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + 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 - inline bool - operator<=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, - const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) - { return !(__y < __x); } + 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 - inline bool - operator>=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, - const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) - { return !(__x < __y); } + 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 - inline void - swap(_Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x, - _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __y) + inline void + swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x, + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __y) { __x.swap(__y); } - template - _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& - _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: - operator=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x) + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _Rb_tree(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&& __x) + : _M_impl(__x._M_impl._M_key_compare, __x._M_get_Node_allocator()) { - if (this != &__x) + if (__x._M_root() != 0) + { + _M_root() = __x._M_root(); + _M_leftmost() = __x._M_leftmost(); + _M_rightmost() = __x._M_rightmost(); + _M_root()->_M_parent = _M_end(); + + __x._M_root() = 0; + __x._M_leftmost() = __x._M_end(); + __x._M_rightmost() = __x._M_end(); + + this->_M_impl._M_node_count = __x._M_impl._M_node_count; + __x._M_impl._M_node_count = 0; + } + } +#endif + + template + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + operator=(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x) + { + if (this != &__x) { // Note that _Key may be a constant type. clear(); - _M_node_count = 0; - _M_key_compare = __x._M_key_compare; - if (__x._M_root() == 0) - { - _M_root() = 0; - _M_leftmost() = _M_header; - _M_rightmost() = _M_header; - } - else + _M_impl._M_key_compare = __x._M_impl._M_key_compare; + if (__x._M_root() != 0) { - _M_root() = _M_copy(__x._M_root(), _M_header); + _M_root() = _M_copy(__x._M_begin(), _M_end()); _M_leftmost() = _S_minimum(_M_root()); _M_rightmost() = _S_maximum(_M_root()); - _M_node_count = __x._M_node_count; + _M_impl._M_node_count = __x._M_impl._M_node_count; } } return *this; } - template - typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator - _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: - _M_insert(_Base_ptr __x_, _Base_ptr __y_, const _Val& __v) + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_insert_(_Const_Base_ptr __x, _Const_Base_ptr __p, const _Val& __v) { - _Link_type __x = (_Link_type) __x_; - _Link_type __y = (_Link_type) __y_; - _Link_type __z; - - if (__y == _M_header || __x != 0 || - _M_key_compare(_KeyOfValue()(__v), _S_key(__y))) + bool __insert_left = (__x != 0 || __p == _M_end() + || _M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(__p))); + + _Link_type __z = _M_create_node(__v); + + _Rb_tree_insert_and_rebalance(__insert_left, __z, + const_cast<_Base_ptr>(__p), + this->_M_impl._M_header); + ++_M_impl._M_node_count; + return iterator(__z); + } + + template + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_insert_lower(_Base_ptr __x, _Base_ptr __p, const _Val& __v) + { + bool __insert_left = (__x != 0 || __p == _M_end() + || !_M_impl._M_key_compare(_S_key(__p), + _KeyOfValue()(__v))); + + _Link_type __z = _M_create_node(__v); + + _Rb_tree_insert_and_rebalance(__insert_left, __z, __p, + this->_M_impl._M_header); + ++_M_impl._M_node_count; + return iterator(__z); + } + + template + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_insert_equal_lower(const _Val& __v) + { + _Link_type __x = _M_begin(); + _Link_type __y = _M_end(); + while (__x != 0) + { + __y = __x; + __x = !_M_impl._M_key_compare(_S_key(__x), _KeyOfValue()(__v)) ? + _S_left(__x) : _S_right(__x); + } + return _M_insert_lower(__x, __y, __v); + } + + template + typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type + _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>:: + _M_copy(_Const_Link_type __x, _Link_type __p) + { + // Structural copy. __x and __p must be non-null. + _Link_type __top = _M_clone_node(__x); + __top->_M_parent = __p; + + __try + { + if (__x->_M_right) + __top->_M_right = _M_copy(_S_right(__x), __top); + __p = __top; + __x = _S_left(__x); + + while (__x != 0) + { + _Link_type __y = _M_clone_node(__x); + __p->_M_left = __y; + __y->_M_parent = __p; + if (__x->_M_right) + __y->_M_right = _M_copy(_S_right(__x), __y); + __p = __y; + __x = _S_left(__x); + } + } + __catch(...) + { + _M_erase(__top); + __throw_exception_again; + } + return __top; + } + + template + void + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_erase(_Link_type __x) + { + // Erase without rebalancing. + while (__x != 0) + { + _M_erase(_S_right(__x)); + _Link_type __y = _S_left(__x); + _M_destroy_node(__x); + __x = __y; + } + } + + template + typename _Rb_tree<_Key, _Val, _KeyOfValue, + _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_lower_bound(_Link_type __x, _Link_type __y, + const _Key& __k) + { + while (__x != 0) + if (!_M_impl._M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + return iterator(__y); + } + + template + typename _Rb_tree<_Key, _Val, _KeyOfValue, + _Compare, _Alloc>::const_iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_lower_bound(_Const_Link_type __x, _Const_Link_type __y, + const _Key& __k) const + { + while (__x != 0) + if (!_M_impl._M_key_compare(_S_key(__x), __k)) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + return const_iterator(__y); + } + + template + typename _Rb_tree<_Key, _Val, _KeyOfValue, + _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_upper_bound(_Link_type __x, _Link_type __y, + const _Key& __k) + { + while (__x != 0) + if (_M_impl._M_key_compare(__k, _S_key(__x))) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + return iterator(__y); + } + + template + typename _Rb_tree<_Key, _Val, _KeyOfValue, + _Compare, _Alloc>::const_iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_upper_bound(_Const_Link_type __x, _Const_Link_type __y, + const _Key& __k) const + { + while (__x != 0) + if (_M_impl._M_key_compare(__k, _S_key(__x))) + __y = __x, __x = _S_left(__x); + else + __x = _S_right(__x); + return const_iterator(__y); + } + + template + pair::iterator, + typename _Rb_tree<_Key, _Val, _KeyOfValue, + _Compare, _Alloc>::iterator> + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + equal_range(const _Key& __k) + { + _Link_type __x = _M_begin(); + _Link_type __y = _M_end(); + while (__x != 0) { - __z = _M_create_node(__v); - _S_left(__y) = __z; // also makes _M_leftmost() = __z - // when __y == _M_header - if (__y == _M_header) + if (_M_impl._M_key_compare(_S_key(__x), __k)) + __x = _S_right(__x); + else if (_M_impl._M_key_compare(__k, _S_key(__x))) + __y = __x, __x = _S_left(__x); + else { - _M_root() = __z; - _M_rightmost() = __z; + _Link_type __xu(__x), __yu(__y); + __y = __x, __x = _S_left(__x); + __xu = _S_right(__xu); + return pair(_M_lower_bound(__x, __y, __k), + _M_upper_bound(__xu, __yu, __k)); } - else if (__y == _M_leftmost()) - _M_leftmost() = __z; // maintain _M_leftmost() pointing to min node } - else + return pair(iterator(__y), + iterator(__y)); + } + + template + pair::const_iterator, + typename _Rb_tree<_Key, _Val, _KeyOfValue, + _Compare, _Alloc>::const_iterator> + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + equal_range(const _Key& __k) const + { + _Const_Link_type __x = _M_begin(); + _Const_Link_type __y = _M_end(); + while (__x != 0) { - __z = _M_create_node(__v); - _S_right(__y) = __z; - // Maintain _M_rightmost() pointing to max node. - if (__y == _M_rightmost()) - _M_rightmost() = __z; + if (_M_impl._M_key_compare(_S_key(__x), __k)) + __x = _S_right(__x); + else if (_M_impl._M_key_compare(__k, _S_key(__x))) + __y = __x, __x = _S_left(__x); + else + { + _Const_Link_type __xu(__x), __yu(__y); + __y = __x, __x = _S_left(__x); + __xu = _S_right(__xu); + return pair(_M_lower_bound(__x, __y, __k), + _M_upper_bound(__xu, __yu, __k)); + } } - _S_parent(__z) = __y; - _S_left(__z) = 0; - _S_right(__z) = 0; - _Rb_tree_rebalance(__z, _M_header->_M_parent); - ++_M_node_count; - return iterator(__z); + return pair(const_iterator(__y), + const_iterator(__y)); } - template - typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator - _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: - insert_equal(const _Val& __v) + void + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&& __t) +#else + swap(_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __t) +#endif { - _Link_type __y = _M_header; - _Link_type __x = _M_root(); - while (__x != 0) + if (_M_root() == 0) { - __y = __x; - __x = _M_key_compare(_KeyOfValue()(__v), _S_key(__x)) ? - _S_left(__x) : _S_right(__x); + if (__t._M_root() != 0) + { + _M_root() = __t._M_root(); + _M_leftmost() = __t._M_leftmost(); + _M_rightmost() = __t._M_rightmost(); + _M_root()->_M_parent = _M_end(); + + __t._M_root() = 0; + __t._M_leftmost() = __t._M_end(); + __t._M_rightmost() = __t._M_end(); + } + } + else if (__t._M_root() == 0) + { + __t._M_root() = _M_root(); + __t._M_leftmost() = _M_leftmost(); + __t._M_rightmost() = _M_rightmost(); + __t._M_root()->_M_parent = __t._M_end(); + + _M_root() = 0; + _M_leftmost() = _M_end(); + _M_rightmost() = _M_end(); } - return _M_insert(__x, __y, __v); + else + { + std::swap(_M_root(),__t._M_root()); + std::swap(_M_leftmost(),__t._M_leftmost()); + std::swap(_M_rightmost(),__t._M_rightmost()); + + _M_root()->_M_parent = _M_end(); + __t._M_root()->_M_parent = __t._M_end(); + } + // No need to swap header's color as it does not change. + std::swap(this->_M_impl._M_node_count, __t._M_impl._M_node_count); + std::swap(this->_M_impl._M_key_compare, __t._M_impl._M_key_compare); + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 431. Swapping containers with unequal allocators. + std::__alloc_swap<_Node_allocator>:: + _S_do_it(_M_get_Node_allocator(), __t._M_get_Node_allocator()); } - template - pair::iterator, - bool> - _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: - insert_unique(const _Val& __v) + pair::iterator, bool> + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_insert_unique(const _Val& __v) { - _Link_type __y = _M_header; - _Link_type __x = _M_root(); + _Link_type __x = _M_begin(); + _Link_type __y = _M_end(); bool __comp = true; - while (__x != 0) + while (__x != 0) { __y = __x; - __comp = _M_key_compare(_KeyOfValue()(__v), _S_key(__x)); + __comp = _M_impl._M_key_compare(_KeyOfValue()(__v), _S_key(__x)); __x = __comp ? _S_left(__x) : _S_right(__x); } - iterator __j = iterator(__y); + iterator __j = iterator(__y); if (__comp) - if (__j == begin()) - return pair(_M_insert(__x, __y, __v), true); - else - --__j; - if (_M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__v))) - return pair(_M_insert(__x, __y, __v), true); - return pair(__j, false); + { + if (__j == begin()) + return pair(_M_insert_(__x, __y, __v), true); + else + --__j; + } + if (_M_impl._M_key_compare(_S_key(__j._M_node), _KeyOfValue()(__v))) + return pair(_M_insert_(__x, __y, __v), true); + return pair(__j, false); } - - template - typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: - insert_unique(iterator __position, const _Val& __v) + _M_insert_equal(const _Val& __v) { - if (__position._M_node == _M_header->_M_left) - { - // begin() - if (size() > 0 && - _M_key_compare(_KeyOfValue()(__v), _S_key(__position._M_node))) - return _M_insert(__position._M_node, __position._M_node, __v); - // first argument just needs to be non-null - else - return insert_unique(__v).first; - } - else if (__position._M_node == _M_header) - { - // end() - if (_M_key_compare(_S_key(_M_rightmost()), _KeyOfValue()(__v))) - return _M_insert(0, _M_rightmost(), __v); + _Link_type __x = _M_begin(); + _Link_type __y = _M_end(); + while (__x != 0) + { + __y = __x; + __x = _M_impl._M_key_compare(_KeyOfValue()(__v), _S_key(__x)) ? + _S_left(__x) : _S_right(__x); + } + return _M_insert_(__x, __y, __v); + } + + template + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_insert_unique_(const_iterator __position, const _Val& __v) + { + // end() + if (__position._M_node == _M_end()) + { + if (size() > 0 + && _M_impl._M_key_compare(_S_key(_M_rightmost()), + _KeyOfValue()(__v))) + return _M_insert_(0, _M_rightmost(), __v); else - return insert_unique(__v).first; - } - else + return _M_insert_unique(__v).first; + } + else if (_M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(__position._M_node))) { - iterator __before = __position; - --__before; - if (_M_key_compare(_S_key(__before._M_node), _KeyOfValue()(__v)) - && _M_key_compare(_KeyOfValue()(__v),_S_key(__position._M_node))) + // First, try before... + const_iterator __before = __position; + if (__position._M_node == _M_leftmost()) // begin() + return _M_insert_(_M_leftmost(), _M_leftmost(), __v); + else if (_M_impl._M_key_compare(_S_key((--__before)._M_node), + _KeyOfValue()(__v))) { if (_S_right(__before._M_node) == 0) - return _M_insert(0, __before._M_node, __v); + return _M_insert_(0, __before._M_node, __v); else - return _M_insert(__position._M_node, __position._M_node, __v); - // first argument just needs to be non-null - } + return _M_insert_(__position._M_node, + __position._M_node, __v); + } else - return insert_unique(__v).first; + return _M_insert_unique(__v).first; } + else if (_M_impl._M_key_compare(_S_key(__position._M_node), + _KeyOfValue()(__v))) + { + // ... then try after. + const_iterator __after = __position; + if (__position._M_node == _M_rightmost()) + return _M_insert_(0, _M_rightmost(), __v); + else if (_M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key((++__after)._M_node))) + { + if (_S_right(__position._M_node) == 0) + return _M_insert_(0, __position._M_node, __v); + else + return _M_insert_(__after._M_node, __after._M_node, __v); + } + else + return _M_insert_unique(__v).first; + } + else + // Equivalent keys. + return iterator(static_cast<_Link_type> + (const_cast<_Base_ptr>(__position._M_node))); } - template - typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator - _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: - insert_equal(iterator __position, const _Val& __v) + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + _M_insert_equal_(const_iterator __position, const _Val& __v) { - if (__position._M_node == _M_header->_M_left) - { - // begin() - if (size() > 0 && - !_M_key_compare(_S_key(__position._M_node), _KeyOfValue()(__v))) - return _M_insert(__position._M_node, __position._M_node, __v); - // first argument just needs to be non-null - else - return insert_equal(__v); - } - else if (__position._M_node == _M_header) + // end() + if (__position._M_node == _M_end()) { - // end() - if (!_M_key_compare(_KeyOfValue()(__v), _S_key(_M_rightmost()))) - return _M_insert(0, _M_rightmost(), __v); + if (size() > 0 + && !_M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key(_M_rightmost()))) + return _M_insert_(0, _M_rightmost(), __v); else - return insert_equal(__v); - } - else + return _M_insert_equal(__v); + } + else if (!_M_impl._M_key_compare(_S_key(__position._M_node), + _KeyOfValue()(__v))) { - iterator __before = __position; - --__before; - if (!_M_key_compare(_KeyOfValue()(__v), _S_key(__before._M_node)) - && !_M_key_compare(_S_key(__position._M_node), - _KeyOfValue()(__v))) + // First, try before... + const_iterator __before = __position; + if (__position._M_node == _M_leftmost()) // begin() + return _M_insert_(_M_leftmost(), _M_leftmost(), __v); + else if (!_M_impl._M_key_compare(_KeyOfValue()(__v), + _S_key((--__before)._M_node))) { if (_S_right(__before._M_node) == 0) - return _M_insert(0, __before._M_node, __v); + return _M_insert_(0, __before._M_node, __v); else - return _M_insert(__position._M_node, __position._M_node, __v); - // first argument just needs to be non-null - } + return _M_insert_(__position._M_node, + __position._M_node, __v); + } else - return insert_equal(__v); + return _M_insert_equal(__v); + } + else + { + // ... then try after. + const_iterator __after = __position; + if (__position._M_node == _M_rightmost()) + return _M_insert_(0, _M_rightmost(), __v); + else if (!_M_impl._M_key_compare(_S_key((++__after)._M_node), + _KeyOfValue()(__v))) + { + if (_S_right(__position._M_node) == 0) + return _M_insert_(0, __position._M_node, __v); + else + return _M_insert_(__after._M_node, __after._M_node, __v); + } + else + return _M_insert_equal_lower(__v); } } - template template - void - _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc>:: - insert_equal(_II __first, _II __last) + void + _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>:: + _M_insert_unique(_II __first, _II __last) { - for ( ; __first != __last; ++__first) - insert_equal(*__first); + for (; __first != __last; ++__first) + _M_insert_unique_(end(), *__first); } - template + template template - void - _Rb_tree<_Key,_Val,_KoV,_Cmp,_Alloc>:: - insert_unique(_II __first, _II __last) - { - for ( ; __first != __last; ++__first) - insert_unique(*__first); - } + void + _Rb_tree<_Key, _Val, _KoV, _Cmp, _Alloc>:: + _M_insert_equal(_II __first, _II __last) + { + for (; __first != __last; ++__first) + _M_insert_equal_(end(), *__first); + } - template - inline void - _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::erase(iterator __position) + inline void + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + erase(iterator __position) { - _Link_type __y = - (_Link_type) _Rb_tree_rebalance_for_erase(__position._M_node, - _M_header->_M_parent, - _M_header->_M_left, - _M_header->_M_right); - destroy_node(__y); - --_M_node_count; + _Link_type __y = + static_cast<_Link_type>(_Rb_tree_rebalance_for_erase + (__position._M_node, + this->_M_impl._M_header)); + _M_destroy_node(__y); + --_M_impl._M_node_count; } - template - typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::size_type - _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::erase(const _Key& __x) + inline void + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + erase(const_iterator __position) { - pair __p = equal_range(__x); - size_type __n = distance(__p.first, __p.second); - erase(__p.first, __p.second); - return __n; + _Link_type __y = + static_cast<_Link_type>(_Rb_tree_rebalance_for_erase + (const_cast<_Base_ptr>(__position._M_node), + this->_M_impl._M_header)); + _M_destroy_node(__y); + --_M_impl._M_node_count; } - template - typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::_Link_type - _Rb_tree<_Key,_Val,_KoV,_Compare,_Alloc>:: - _M_copy(_Link_type __x, _Link_type __p) + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + erase(const _Key& __x) { - // Structural copy. __x and __p must be non-null. - _Link_type __top = _M_clone_node(__x); - __top->_M_parent = __p; - - try - { - if (__x->_M_right) - __top->_M_right = _M_copy(_S_right(__x), __top); - __p = __top; - __x = _S_left(__x); - - while (__x != 0) - { - _Link_type __y = _M_clone_node(__x); - __p->_M_left = __y; - __y->_M_parent = __p; - if (__x->_M_right) - __y->_M_right = _M_copy(_S_right(__x), __y); - __p = __y; - __x = _S_left(__x); - } - } - catch(...) - { - _M_erase(__top); - __throw_exception_again; - } - return __top; + pair __p = equal_range(__x); + const size_type __old_size = size(); + erase(__p.first, __p.second); + return __old_size - size(); } - template - void - _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::_M_erase(_Link_type __x) + void + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + erase(iterator __first, iterator __last) { - // Erase without rebalancing. - while (__x != 0) - { - _M_erase(_S_right(__x)); - _Link_type __y = _S_left(__x); - destroy_node(__x); - __x = __y; - } + if (__first == begin() && __last == end()) + clear(); + else + while (__first != __last) + erase(__first++); } - template - void - _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: - erase(iterator __first, iterator __last) + void + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + erase(const_iterator __first, const_iterator __last) { if (__first == begin() && __last == end()) clear(); else - while (__first != __last) erase(__first++); + while (__first != __last) + erase(__first++); } - template - void - _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: - erase(const _Key* __first, const _Key* __last) - { - while (__first != __last) - erase(*__first++); + void + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + erase(const _Key* __first, const _Key* __last) + { + while (__first != __last) + erase(*__first++); } - template - typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator - _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::find(const _Key& __k) + typename _Rb_tree<_Key, _Val, _KeyOfValue, + _Compare, _Alloc>::iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: + find(const _Key& __k) { - _Link_type __y = _M_header; // Last node which is not less than __k. - _Link_type __x = _M_root(); // Current node. - - while (__x != 0) - if (!_M_key_compare(_S_key(__x), __k)) - __y = __x, __x = _S_left(__x); - else - __x = _S_right(__x); - - iterator __j = iterator(__y); - return (__j == end() || _M_key_compare(__k, _S_key(__j._M_node))) ? - end() : __j; + iterator __j = _M_lower_bound(_M_begin(), _M_end(), __k); + return (__j == end() + || _M_impl._M_key_compare(__k, + _S_key(__j._M_node))) ? end() : __j; } - - template - typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::const_iterator - _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + typename _Rb_tree<_Key, _Val, _KeyOfValue, + _Compare, _Alloc>::const_iterator + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: find(const _Key& __k) const { - _Link_type __y = _M_header; // Last node which is not less than __k. - _Link_type __x = _M_root(); // Current node. - - while (__x != 0) - { - if (!_M_key_compare(_S_key(__x), __k)) - __y = __x, __x = _S_left(__x); - else - __x = _S_right(__x); - } - const_iterator __j = const_iterator(__y); - return (__j == end() || _M_key_compare(__k, _S_key(__j._M_node))) ? - end() : __j; + const_iterator __j = _M_lower_bound(_M_begin(), _M_end(), __k); + return (__j == end() + || _M_impl._M_key_compare(__k, + _S_key(__j._M_node))) ? end() : __j; } - template - typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::size_type - _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: + typename _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::size_type + _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: count(const _Key& __k) const { pair __p = equal_range(__k); - size_type __n = distance(__p.first, __p.second); + const size_type __n = std::distance(__p.first, __p.second); return __n; } - template - typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator - _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: - lower_bound(const _Key& __k) - { - _Link_type __y = _M_header; /* Last node which is not less than __k. */ - _Link_type __x = _M_root(); /* Current node. */ - - while (__x != 0) - if (!_M_key_compare(_S_key(__x), __k)) - __y = __x, __x = _S_left(__x); - else - __x = _S_right(__x); - - return iterator(__y); - } - - template - typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::const_iterator - _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: - lower_bound(const _Key& __k) const - { - _Link_type __y = _M_header; /* Last node which is not less than __k. */ - _Link_type __x = _M_root(); /* Current node. */ - - while (__x != 0) - if (!_M_key_compare(_S_key(__x), __k)) - __y = __x, __x = _S_left(__x); - else - __x = _S_right(__x); - - return const_iterator(__y); - } + unsigned int + _Rb_tree_black_count(const _Rb_tree_node_base* __node, + const _Rb_tree_node_base* __root); - template - typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator - _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: - upper_bound(const _Key& __k) + bool + _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::__rb_verify() const { - _Link_type __y = _M_header; /* Last node which is greater than __k. */ - _Link_type __x = _M_root(); /* Current node. */ - - while (__x != 0) - if (_M_key_compare(__k, _S_key(__x))) - __y = __x, __x = _S_left(__x); - else - __x = _S_right(__x); - - return iterator(__y); - } + if (_M_impl._M_node_count == 0 || begin() == end()) + return _M_impl._M_node_count == 0 && begin() == end() + && this->_M_impl._M_header._M_left == _M_end() + && this->_M_impl._M_header._M_right == _M_end(); - template - typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::const_iterator - _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: - upper_bound(const _Key& __k) const - { - _Link_type __y = _M_header; /* Last node which is greater than __k. */ - _Link_type __x = _M_root(); /* Current node. */ - - while (__x != 0) - if (_M_key_compare(__k, _S_key(__x))) - __y = __x, __x = _S_left(__x); - else - __x = _S_right(__x); - - return const_iterator(__y); - } + unsigned int __len = _Rb_tree_black_count(_M_leftmost(), _M_root()); + for (const_iterator __it = begin(); __it != end(); ++__it) + { + _Const_Link_type __x = static_cast<_Const_Link_type>(__it._M_node); + _Const_Link_type __L = _S_left(__x); + _Const_Link_type __R = _S_right(__x); - template - inline - pair::iterator, - typename _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator> - _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: - equal_range(const _Key& __k) - { return pair(lower_bound(__k), upper_bound(__k)); } + if (__x->_M_color == _S_red) + if ((__L && __L->_M_color == _S_red) + || (__R && __R->_M_color == _S_red)) + return false; - template - inline - pair::const_iterator, - typename _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc>::const_iterator> - _Rb_tree<_Key, _Val, _KoV, _Compare, _Alloc> - ::equal_range(const _Key& __k) const - { - return pair(lower_bound(__k), - upper_bound(__k)); - } + if (__L && _M_impl._M_key_compare(_S_key(__x), _S_key(__L))) + return false; + if (__R && _M_impl._M_key_compare(_S_key(__R), _S_key(__x))) + return false; - inline int - __black_count(_Rb_tree_node_base* __node, _Rb_tree_node_base* __root) - { - if (__node == 0) - return 0; - int __sum = 0; - do - { - if (__node->_M_color == _M_black) - ++__sum; - if (__node == __root) - break; - __node = __node->_M_parent; - } - while (1); - return __sum; - } - - template - bool - _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::__rb_verify() const - { - if (_M_node_count == 0 || begin() == end()) - return _M_node_count == 0 && begin() == end() && - _M_header->_M_left == _M_header && _M_header->_M_right == _M_header; - - int __len = __black_count(_M_leftmost(), _M_root()); - for (const_iterator __it = begin(); __it != end(); ++__it) - { - _Link_type __x = (_Link_type) __it._M_node; - _Link_type __L = _S_left(__x); - _Link_type __R = _S_right(__x); - - if (__x->_M_color == _M_red) - if ((__L && __L->_M_color == _M_red) - || (__R && __R->_M_color == _M_red)) + if (!__L && !__R && _Rb_tree_black_count(__x, _M_root()) != __len) return false; - - if (__L && _M_key_compare(_S_key(__x), _S_key(__L))) - return false; - if (__R && _M_key_compare(_S_key(__R), _S_key(__x))) - return false; - - if (!__L && !__R && __black_count(__x, _M_root()) != __len) - return false; - } - - if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root())) - return false; - if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root())) - return false; - return true; + } + + if (_M_leftmost() != _Rb_tree_node_base::_S_minimum(_M_root())) + return false; + if (_M_rightmost() != _Rb_tree_node_base::_S_maximum(_M_root())) + return false; + return true; } -} // namespace std -#endif +_GLIBCXX_END_NAMESPACE + +#endif