/*************************************************************************** * * _tree.h - Declarations for the Standard Library tree classes * * This is an internal header file used to implement the C++ Standard * Library. It should never be #included directly by a program. * * $Id: _tree.h 648752 2008-04-16 17:01:56Z faridz $ * *************************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. * * Copyright 1994-2006 Rogue Wave Software. * *************************************************************************** * * 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. * **************************************************************************/ /*************************************************************************** * * Red-black tree class, designed for use in implementing 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 _RWSTD_RW_TREE_H_INCLUDED #define _RWSTD_RW_TREE_H_INCLUDED #ifndef _RWSTD_RW_ALGOBASE_H_INCLUDED # include #endif // _RWSTD_RW_ALGOBASE_H_INCLUDED #ifndef _RWSTD_RW_ITERATOR_H_INCLUDED # include #endif // _RWSTD_RW_ITERATOR_H_INCLUDED _RWSTD_NAMESPACE (__rw) { template struct __rw_rb_tree_node { enum _C_color_t { _C_red, _C_black }; typedef _Val& reference; typedef _Alloc allocator_type; typedef _RWSTD_REBIND (allocator_type, __rw_rb_tree_node) _C_node_alloc_t; typedef _RWSTD_REBIND (allocator_type, _Key) _C_key_alloc_t; typedef _TYPENAME _C_node_alloc_t::pointer _C_link_t; typedef _TYPENAME _C_key_alloc_t::const_reference _C_const_key_ref; _C_color_t _C_color; _C_link_t _C_parent; _C_link_t _C_child [2]; // left (0) and right (1) children _Val _C_value; static _C_link_t _C_minmax (_C_link_t __lnk, bool __do_max) { _RWSTD_ASSERT (_C_link_t () != __lnk); while (_C_link_t () != __lnk->_C_child [__do_max]) __lnk = __lnk->_C_child [__do_max]; return __lnk; } static _C_link_t _C_min (_C_link_t __lnk) { return _C_minmax (__lnk, false); } static _C_link_t _C_max (_C_link_t __lnk) { return _C_minmax (__lnk, true); } _C_const_key_ref _C_key () const { return _KeyOf ()(_C_value); } }; // iterator implements inorder traversal; i.e., nodes are visited // recursively in this order: left subtree, root, right subtree template class __rw_tree_iter : public _STD::iterator <_STD::bidirectional_iterator_tag, _TypeT, _DiffT, _Pointer, _Reference> { typedef _STD::iterator <_STD::bidirectional_iterator_tag, _TypeT, _DiffT, _Pointer, _Reference> _C_iter_base; public: typedef _TYPENAME _C_iter_base::value_type value_type; typedef _TYPENAME _C_iter_base::difference_type difference_type; typedef _TYPENAME _C_iter_base::pointer pointer; typedef _TYPENAME _C_iter_base::reference reference; typedef _TYPENAME _C_iter_base::iterator_category iterator_category; typedef _Node _C_node_t; typedef _TYPENAME _C_node_t::allocator_type allocator_type; typedef _TYPENAME _C_node_t::_C_link_t _C_link_t; typedef const value_type* const_pointer; typedef const value_type& const_reference; typedef __rw_tree_iter<_TypeT, _DiffT, value_type*, value_type&, _C_node_t> _C_iterator; _C_link_t _C_node; __rw_tree_iter () { /* empty */ } // no copy ctor other than the one below is defined // will use a compiler generated one if __rw_tree_iter != _C_iterator __rw_tree_iter (const _C_iterator &__rhs) : _C_node (__rhs._C_node) { } template __rw_tree_iter (const __rw_tree_iter<_TypeT, _DiffT, _Ptr, _Ref, _Node>& __rhs) : _C_node (__rhs._C_node) { } __rw_tree_iter (_C_link_t __lnk) : _C_node (__lnk) {} #ifdef SNI difference_type operator- (const __rw_tree_iter&) const { return 0; } #endif __rw_tree_iter& operator++ () { if (_C_link_t () != _C_node->_C_child [1]) { _C_node = _C_node_t::_C_min (_C_node->_C_child [1]); } else { _C_link_t __tmp = _C_node->_C_parent; while (_C_node == __tmp->_C_child [1]) { _C_node = __tmp; __tmp = __tmp->_C_parent; } if (_C_node->_C_child [1] != __tmp) _C_node = __tmp; } return *this; } __rw_tree_iter& operator-- () { if ( _C_node->_C_color == _C_node_t::_C_red && _C_node->_C_parent->_C_parent == _C_node) // // Check for header. // _C_node = _C_node->_C_child [1]; // Return rightmost. else if (_C_link_t () != _C_node->_C_child [0]) { _C_node = _C_node_t::_C_max (_C_node->_C_child [0]); } else { _C_link_t __tmp = _C_node->_C_parent; while (_C_node == __tmp->_C_child [0]) { _C_node = __tmp; __tmp = __tmp->_C_parent; } _C_node = __tmp; } return *this; } __rw_tree_iter operator++ (int) { __rw_tree_iter __tmp (*this); return ++*this, __tmp; } __rw_tree_iter operator-- (int) { __rw_tree_iter __tmp (*this); return --*this, __tmp; } reference operator* () const { return _C_node->_C_value; } _RWSTD_OPERATOR_ARROW (pointer operator-> () const); }; #define _RWSTD_TREE_ITER(n) \ __rw_tree_iter <_TypeT, _DiffT, _Ptr##n, _Ref##n, _Node> template inline bool operator== (const _RWSTD_TREE_ITER (1) &__lhs, const _RWSTD_TREE_ITER (2) &__rhs) { return __lhs._C_node == __rhs._C_node; } template inline bool operator!= (const _RWSTD_TREE_ITER (1) &__lhs, const _RWSTD_TREE_ITER (2) &__rhs) { return !(__lhs == __rhs); } #undef _RWSTD_TREE_ITER // for convenience #undef _ITER_NODE #define _ITER_NODE(it) (_ITER_BASE (it)._C_node) _EXPORT template class __rb_tree : private _Alloc { private: typedef __rw_rb_tree_node<_Alloc,_Val,_Key,_KeyOf> _C_node_t; typedef _RWSTD_ALLOC_TYPE (_Alloc,_Val) _C_val_alloc_t; typedef _TYPENAME _C_node_t::_C_key_alloc_t _C_key_alloc_t; typedef _TYPENAME _C_node_t::_C_node_alloc_t _C_node_alloc_t; typedef _TYPENAME _C_node_t::_C_link_t _C_link_t; public: typedef _Key key_type; typedef _Val value_type; typedef _Comp key_compare; typedef _Alloc allocator_type; typedef _TYPENAME _C_val_alloc_t::pointer pointer; typedef _TYPENAME _C_val_alloc_t::const_pointer const_pointer; typedef _TYPENAME allocator_type::size_type size_type; typedef _TYPENAME allocator_type::difference_type difference_type; typedef _TYPENAME _C_val_alloc_t::reference reference; typedef _TYPENAME _C_val_alloc_t::const_reference const_reference; private: typedef __rw_tree_iter _C_tree_iter; typedef __rw_tree_iter _C_tree_citer; public: #ifndef _RWSTD_NO_DEBUG_ITER typedef __rw_debug_iter <__rb_tree, _C_tree_iter, _C_tree_iter> iterator; typedef __rw_debug_iter <__rb_tree, _C_tree_citer, _C_tree_iter> const_iterator; iterator _C_make_iter (_C_link_t __node) { return iterator (*this, _C_tree_iter (__node)); } const_iterator _C_make_iter (_C_link_t __node) const { return const_iterator (*this, _C_tree_citer (__node)); } #else // if defined (_RWSTD_NO_DEBUG_ITER) typedef _C_tree_iter iterator; typedef _C_tree_citer const_iterator; iterator _C_make_iter (_C_link_t __node) { return iterator (__node); } const_iterator _C_make_iter (_C_link_t __node) const { return const_iterator (__node); } #endif // _RWSTD_NO_DEBUG_ITER private: #ifdef _RWSTD_NO_NESTED_CLASS_ACCESS // allow _C_node_buf access to __rb_tree's private type(s) // if the resolution of cwg issue 45 is not yet implemented struct _C_node_buf; friend struct _C_node_buf; #endif // _RWSTD_NO_NESTED_CLASS_ACCESS struct _C_node_buf { typedef _RWSTD_REBIND (allocator_type, _C_node_buf) _C_buf_alloc_t; typedef _TYPENAME _C_buf_alloc_t::pointer _C_buf_ptr_t; _C_buf_ptr_t _C_next_buffer; size_type size; _C_link_t _C_buffer; }; typedef _TYPENAME _C_node_buf::_C_buf_alloc_t _C_buf_alloc_t; typedef _TYPENAME _C_node_buf::_C_buf_ptr_t _C_buf_ptr_t; _C_buf_ptr_t _C_buf_list; _C_link_t _C_free_list; _C_link_t _C_next_avail; _C_link_t _C_last; void _C_add_new_buffer (); void _C_deallocate_buffers (); // // Return a node from the free list or new storage // _C_link_t _C_get_link () { _C_link_t __tmp = _C_free_list; _C_link_t __tmp2 = (void*)_C_free_list ? (_C_free_list = _RWSTD_STATIC_CAST (_C_link_t,(_C_free_list->_C_child [1])), __tmp) : (_C_next_avail == _C_last ? (_C_add_new_buffer (), _C_next_avail++) : _C_next_avail++); __tmp2->_C_parent = 0; __tmp2->_C_child [0] = 0; __tmp2->_C_child [1] = 0; __tmp2->_C_color = _C_node_t::_C_red; return __tmp2; } // // Return a node from the free list or new storage with // the _Val __v constructed on it. Every call to _C_get_node // must eventually be followed by a call to _C_put_node. // _C_link_t _C_get_node (const_reference __v) { _C_link_t __tmp2 = _C_get_link (); _TRY { _RWSTD_VALUE_ALLOC (_C_val_alloc_t, *this, construct (_RWSTD_VALUE_ALLOC (_C_val_alloc_t, *this, address (__tmp2->_C_value)), __v)); } _CATCH (...) { _C_put_node (__tmp2, false); _RETHROW; } return __tmp2; } _C_link_t _C_get_node () { return _C_get_link (); } // // Return a node to the free list and destroy the value in it. // void _C_put_node (_C_link_t __p, bool __destroy = true) { __p->_C_child [1] = _C_free_list; if (__destroy) { _RWSTD_VALUE_ALLOC (_C_val_alloc_t, *this, destroy (_RWSTD_VALUE_ALLOC (_C_val_alloc_t, *this, address (__p->_C_value)))); } _C_free_list = __p; } private: // _C_end is end() // tree root is _C_end->_C_parent // the leftmost node, i.e., begin(), is _C_end->_C_child [0] // the rightmost node, i.e., end() - 1, is _C_end->_C_child [1] // all three pointers are null (0) when the tree is empty // both child pointers of each leaf node are null (0) // the parent pointer of the root node points to *_C_end _C_link_t _C_end; size_type _C_size; // number of nodes key_compare _C_cmp; // comparison object public: #ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC typedef _STD::reverse_iterator const_reverse_iterator; typedef _STD::reverse_iterator reverse_iterator; #else // if defined (_RWSTD_NO_CLASS_PARTIAL_SPEC) typedef std::reverse_iterator const_reverse_iterator; typedef std::reverse_iterator reverse_iterator; #endif // _RWSTD_NO_CLASS_PARTIAL_SPEC private: iterator _C_insert (_C_link_t, _C_link_t, const value_type&); _C_link_t _C_copy (_C_link_t, _C_link_t); void _C_erase (_C_link_t); void _C_erase_leaf (_C_link_t); void _C_init () { _C_buf_list = 0; _C_free_list = _C_next_avail = _C_last = 0; _C_end = _C_get_node (); _C_end->_C_parent = 0; _C_end->_C_child [0] = _C_end->_C_child [1] = _C_end; } public: __rb_tree (const key_compare& = key_compare (), const allocator_type& = allocator_type ()); template __rb_tree (_InputIter __first, _InputIter __last, const key_compare &__cmp, const allocator_type &__alloc, bool __dup) : allocator_type (__alloc), _C_buf_list (0), _C_end (0), _C_size (0), _C_cmp (__cmp) { _C_init (); _TRY { insert (__first, __last, __dup); } _CATCH (...) { _C_deallocate_buffers (); _RETHROW; } } __rb_tree (const __rb_tree&); ~__rb_tree (); __rb_tree& operator= (const __rb_tree&); key_compare key_comp () const { return _C_cmp; } _C_val_alloc_t get_allocator () const { return _C_val_alloc_t (*this); } iterator begin () { return _C_make_iter (_C_end->_C_child [0]); } const_iterator begin () const { return _C_make_iter (_C_end->_C_child [0]); } iterator end () { return _C_make_iter (_C_end); } const_iterator end () const { return _C_make_iter (_C_end); } reverse_iterator rbegin () { return reverse_iterator (end ()); } reverse_iterator rend () { return reverse_iterator (begin ()); } const_reverse_iterator rbegin () const { return const_reverse_iterator (end ()); } const_reverse_iterator rend () const { return const_reverse_iterator (begin ()); } bool empty () const { return 0 == _C_size; } size_type size () const { return _C_size; } size_type max_size () const { return _C_node_alloc_t (*this).max_size (); } void swap (__rb_tree &__rhs) { if (get_allocator () == __rhs.get_allocator ()) { _STD::swap (_C_buf_list, __rhs._C_buf_list); _STD::swap (_C_free_list, __rhs._C_free_list); _STD::swap (_C_next_avail, __rhs._C_next_avail); _STD::swap (_C_last, __rhs._C_last); _STD::swap (_C_end, __rhs._C_end); _STD::swap (_C_size, __rhs._C_size); _STD::swap (_C_cmp, __rhs._C_cmp); } else { __rb_tree __tmp = *this; *this = __rhs; __rhs = __tmp; } } void _C_insert (const value_type&, _STD::pair&, bool); _STD::pair insert (const value_type &__val, bool __dup) { _STD::pair __ret; return _C_insert (__val, __ret, __dup), __ret; } iterator insert (iterator, const value_type&, bool); template void insert (_Iterator __first, _Iterator __last, bool __dup) { for (; __first != __last; ++__first) insert (*__first, __dup); } iterator erase (iterator); size_type erase (const key_type&); iterator erase (iterator, iterator); // MSVC 6.0 thinks S is the same as S... #if !defined (_MSC_VER) || _MSC_VER > 1300 // map and set's iterator may be defined to be tree::const_iterator iterator insert (const_iterator __it, const value_type &__x, bool __dup) { return insert (_C_make_iter (_ITER_NODE (__it)), __x, __dup); } // map and set's iterator may be defined to be tree::const_iterator iterator erase (const_iterator __it) { return erase (_C_make_iter (_ITER_NODE (__it))); } // map and set's iterator may be defined to be tree::const_iterator iterator erase (const_iterator __first, const_iterator __last) { return erase (_C_make_iter (_ITER_NODE (__first)), _C_make_iter (_ITER_NODE (__last))); } #endif // _MSC_VER <= 1300 void erase (const key_type*, const key_type*); void clear () { erase (begin (), end ()); } iterator find (const key_type&); const_iterator find (const key_type& __key) const { return _RWSTD_CONST_CAST (__rb_tree*, this)->find (__key); } size_type count (const key_type&) const; iterator lower_bound (const key_type&); const_iterator lower_bound (const key_type& __key) const { return _RWSTD_CONST_CAST (__rb_tree*, this)->lower_bound (__key); } iterator upper_bound (const key_type&); const_iterator upper_bound (const key_type& __key) const { return _RWSTD_CONST_CAST (__rb_tree*, this)->upper_bound (__key); } _STD::pair equal_range (const key_type&); _STD::pair equal_range (const key_type& __key) const { _STD::pair __tmp = _RWSTD_CONST_CAST (__rb_tree*, this)->equal_range (__key); return _STD::pair (__tmp.first, __tmp.second); } #ifndef _RWSTD_NO_OPTIMIZE_SPEED void _C_rol (_C_link_t); void _C_ror (_C_link_t); #else // if defined (_RWSTD_NO_OPTIMIZE_SPEED) void _C_rotate (_C_link_t, bool); #endif // _RWSTD_NO_OPTIMIZE_SPEED size_type _C_level (const_iterator) const; // depth guaranteed to be <= 2 * log2(size() + 1) size_type _C_depth (const_iterator, size_type* = 0) const; size_type _C_depth () const { return _C_depth (_C_make_iter (_C_end->_C_parent)); } }; template inline bool operator== (const __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>& __lhs, const __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>& __rhs) { return __lhs.size () == __rhs.size () && _STD::equal (__lhs.begin (), __lhs.end (), __rhs.begin ()); } template inline bool operator< (const __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>& __lhs, const __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>& __rhs) { return _STD::lexicographical_compare (__lhs.begin (), __lhs.end (), __rhs.begin (), __rhs.end ()); } template inline void __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>:: _C_erase_leaf (_C_link_t __lnk) { // remove a leaf node from the tree const _C_link_t __parent = __lnk->_C_parent; if (__parent == _C_end) { _C_end->_C_parent = 0; _C_end->_C_child [0] = _C_end->_C_child [1] = __parent; } #ifndef _RWSTD_NO_OPTIMIZE_SPEED else if (__parent->_C_child [0] == __lnk) { __parent->_C_child [0] = 0; if (_C_end->_C_child [0] == __lnk) _C_end->_C_child [0] = __parent; } else { __parent->_C_child [1] = 0; if (_C_end->_C_child [1] == __lnk) _C_end->_C_child [1] = __parent; } #else // if !defined (_RWSTD_NO_OPTIMIZE_SPEED) else { const bool __right = __parent->_C_child [0] != __lnk; __parent->_C_child [__right] = 0; if (_C_end->_C_child [__right] == __lnk) _C_end->_C_child [__right] = __parent; } #endif // _RWSTD_NO_OPTIMIZE_SPEED } #ifndef _RWSTD_NO_OPTIMIZE_SPEED template inline void __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>:: _C_rol (_C_link_t __lnk) { _RWSTD_ASSERT (_C_link_t () != __lnk); _C_link_t __tmp = __lnk->_C_child [1]; __lnk->_C_child [1] = __tmp->_C_child [0]; if (_C_link_t () != __tmp->_C_child [0]) __tmp->_C_child [0]->_C_parent = __lnk; __tmp->_C_parent = __lnk->_C_parent; if (__lnk == _C_end->_C_parent) _C_end->_C_parent = __tmp; else if (__lnk == __lnk->_C_parent->_C_child [0]) __lnk->_C_parent->_C_child [0] = __tmp; else __lnk->_C_parent->_C_child [1] = __tmp; __tmp->_C_child [0] = __lnk; __lnk->_C_parent = __tmp; } template inline void __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>:: _C_ror (_C_link_t __lnk) { _RWSTD_ASSERT (_C_link_t () != __lnk); _C_link_t __tmp = __lnk->_C_child [0]; __lnk->_C_child [0] = __tmp->_C_child [1]; if (_C_link_t () != __tmp->_C_child [1]) __tmp->_C_child [1]->_C_parent = __lnk; __tmp->_C_parent = __lnk->_C_parent; if (__lnk == _C_end->_C_parent) _C_end->_C_parent = __tmp; else if (__lnk == __lnk->_C_parent->_C_child [1]) __lnk->_C_parent->_C_child [1] = __tmp; else __lnk->_C_parent->_C_child [0] = __tmp; __tmp->_C_child [1] = __lnk; __lnk->_C_parent = __tmp; } #else // if defined (_RWSTD_NO_OPTIMIZE_SPEED) template inline void __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>:: _C_rotate (_C_link_t __lnk, bool __right) { _RWSTD_ASSERT (_C_link_t () != __lnk); _C_link_t __tmp = __lnk->_C_child [!__right]; __lnk->_C_child [!__right] = __tmp->_C_child [__right]; if (_C_link_t () != __tmp->_C_child [__right]) __tmp->_C_child [__right]->_C_parent = __lnk; __tmp->_C_parent = __lnk->_C_parent; if (__lnk == _C_end->_C_parent) _C_end->_C_parent = __tmp; else { const bool __rt = __lnk == __lnk->_C_parent->_C_child [1]; __lnk->_C_parent->_C_child [__rt] = __tmp; } __tmp->_C_child [__right] = __lnk; __lnk->_C_parent = __tmp; } #endif // _RWSTD_NO_OPTIMIZE_SPEED template inline void __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>:: erase (const _Key* __first, const _Key* __last) { for (; __first != __last; ++__first) erase (*__first); } template inline _TYPENAME __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::size_type __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>:: count (const _Key& __k) const { _STD::pair __p = equal_range (__k); size_type __n = _DISTANCE (__p.first, __p.second, size_type); return __n; } #define _RWSTD_RB_TREE_ITER \ _TYPENAME __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>::iterator template inline _STD::pair<_RWSTD_RB_TREE_ITER , _RWSTD_RB_TREE_ITER > __rb_tree<_Key, _Val, _KeyOf, _Comp, _Alloc>:: equal_range (const _Key& __k) { return _STD::pair(lower_bound (__k), upper_bound(__k)); } #undef _RWSTD_RB_TREE_ITER } // namespace __rw #ifdef _RWSTD_NO_IMPLICIT_INCLUSION # include #endif #endif // _RWSTD_RW_TREE_H_INCLUDED