diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index d98e25b5ef614605504dbd37284f9dbd8cacd5b9..efbd7c78368b50e82d9b26c34d71c4570dd918c8 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,43 @@ +2004-01-07 Gawain Bolton <gp.bolton@computer.org> + + * include/bits/stl_list.h: + * include/bits/list.tc: + * src/list.cc: + Performance enhancements for destructor, push_front(), + push_back(), pop_front(), pop_back(), sort() + Eliminated static_casts where possible. + Moved code out of header files into new src/list.cc + implementation file for library where possible. + Remove inheritance from iterator class and create separate + classes for non-constant and constant iterators. + * include/bits/stl_tree.h (_Rb_tree class): + * src/tree.cc: + Only erase contents in destructor. + Eliminate unnecessary initialization in assignment operator. + Optimize for the nominal case by not checking whether + container is empty in clear(). + Re-order test in _M_insert() to improve performance. + Move initialization of new node's left & right pointers to + src/tree.cc to where new node's colour is initialized + and to reduce the amount of inline code. + Use _M_leftmost() and _M_end() to improve readability where + appropriate. + Create separate classes for non-constant and constant + iterators to clarify code, avoid extra template parameters and + casting away constness. + +2004-01-07 Benjamin Kosnik <bkoz@redhat.com> + + * src/Makefile.am (sources): Add list.cc, tree.cc. + * src/stl_tree.cc: Move to... + * src/tree.cc: ...here. + * src/list.cc: Add. + * config/linker-map.gnu: Tweaks. + * testsuite/23_containers/map/operators/1_neg.cc: Add excess errors. + * testsuite/23_containers/set/operators/1_neg.cc: Add excess errors. + + * bits/stl_vector.h: Column wrap comments. + 2004-01-07 Loren J. Rittle <ljrittle@acm.org> (re-open) PR libstdc++/12658 diff --git a/libstdc++-v3/config/linker-map.gnu b/libstdc++-v3/config/linker-map.gnu index 7931953705811d4f9b7074bece71b8b937dac199..2d46e884888e3edfe6b58d585f23725f11f0db7f 100644 --- a/libstdc++-v3/config/linker-map.gnu +++ b/libstdc++-v3/config/linker-map.gnu @@ -112,13 +112,15 @@ GLIBCXX_3.4 { _ZSt9has_facet*; # _Rb_tree + _ZSt18_Rb_tree_decrementPKSt18_Rb_tree_node_base; _ZSt18_Rb_tree_decrementPSt18_Rb_tree_node_base; + _ZSt18_Rb_tree_incrementPKSt18_Rb_tree_node_base; _ZSt18_Rb_tree_incrementPSt18_Rb_tree_node_base; - _ZSt18_Rb_tree_rebalancePSt18_Rb_tree_node_baseRS0_; _ZSt20_Rb_tree_black_countPKSt18_Rb_tree_node_baseS1_; _ZSt20_Rb_tree_rotate_leftPSt18_Rb_tree_node_baseRS0_; _ZSt21_Rb_tree_rotate_rightPSt18_Rb_tree_node_baseRS0_; _ZSt28_Rb_tree_rebalance_for_erasePSt18_Rb_tree_node_baseRS_; + _ZSt29_Rb_tree_insert_and_rebalancebPSt18_Rb_tree_node_baseS0_RS_; # std::__codecvt_abstract_base* _ZNStSt23__codecvt_abstract_base*; diff --git a/libstdc++-v3/include/bits/list.tcc b/libstdc++-v3/include/bits/list.tcc index a4f7c18dffa5638881af3baf6b0dbf6564e8eaba..2b50518e44e4268f05ea7e3e21777cde722d6fff 100644 --- a/libstdc++-v3/include/bits/list.tcc +++ b/libstdc++-v3/include/bits/list.tcc @@ -77,45 +77,6 @@ namespace __gnu_norm std::_Destroy(&__tmp->_M_data); _M_put_node(__tmp); } - this->_M_node._M_next = &this->_M_node; - this->_M_node._M_prev = &this->_M_node; - } - - template<typename _Tp, typename _Alloc> - void list<_Tp, _Alloc>:: - swap(list<_Tp, _Alloc>& __x) - { - if ( this->_M_node._M_next == &this->_M_node ) - { - if ( __x._M_node._M_next != &__x._M_node ) - { - this->_M_node._M_next = __x._M_node._M_next; - this->_M_node._M_prev = __x._M_node._M_prev; - - this->_M_node._M_prev->_M_next = &this->_M_node; - this->_M_node._M_next->_M_prev = this->_M_node._M_prev->_M_next; - __x._M_node._M_next = __x._M_node._M_prev = &__x._M_node; - } - } - else if ( __x._M_node._M_next == &__x._M_node ) - { - __x._M_node._M_next = this->_M_node._M_next; - __x._M_node._M_prev = this->_M_node._M_prev; - - __x._M_node._M_prev->_M_next = &__x._M_node; - __x._M_node._M_next->_M_prev = __x._M_node._M_prev->_M_next; - this->_M_node._M_next = this->_M_node._M_prev = &this->_M_node; - } - else - { - std::swap(this->_M_node._M_next,__x._M_node._M_next); - std::swap(this->_M_node._M_prev,__x._M_node._M_prev); - - this->_M_node._M_prev->_M_next = &this->_M_node; - this->_M_node._M_next->_M_prev = this->_M_node._M_prev->_M_next; - __x._M_node._M_prev->_M_next = &__x._M_node; - __x._M_node._M_next->_M_prev = __x._M_node._M_prev->_M_next; - } } template<typename _Tp, typename _Alloc> @@ -124,10 +85,7 @@ namespace __gnu_norm insert(iterator __position, const value_type& __x) { _Node* __tmp = _M_create_node(__x); - __tmp->_M_next = __position._M_node; - __tmp->_M_prev = __position._M_node->_M_prev; - __position._M_node->_M_prev->_M_next = __tmp; - __position._M_node->_M_prev = __tmp; + __tmp->hook(__position._M_node); return __tmp; } @@ -136,14 +94,9 @@ namespace __gnu_norm list<_Tp,_Alloc>:: erase(iterator __position) { - _List_node_base* __next_node = __position._M_node->_M_next; - _List_node_base* __prev_node = __position._M_node->_M_prev; - _Node* __n = static_cast<_Node*>(__position._M_node); - __prev_node->_M_next = __next_node; - __next_node->_M_prev = __prev_node; - std::_Destroy(&__n->_M_data); - _M_put_node(__n); - return iterator(static_cast<_Node*>(__next_node)); + iterator __ret = __position._M_node->_M_next; + _M_erase(__position); + return __ret; } template<typename _Tp, typename _Alloc> @@ -226,7 +179,7 @@ namespace __gnu_norm iterator __next = __first; ++__next; if (*__first == __value) - erase(__first); + _M_erase(__first); __first = __next; } } @@ -243,7 +196,7 @@ namespace __gnu_norm while (++__next != __last) { if (*__first == *__next) - erase(__next); + _M_erase(__next); else __first = __next; __next = __first; @@ -277,19 +230,6 @@ namespace __gnu_norm } } - // FIXME put this somewhere else - inline void - __List_base_reverse(_List_node_base* __p) - { - _List_node_base* __tmp = __p; - do - { - std::swap(__tmp->_M_next, __tmp->_M_prev); - __tmp = __tmp->_M_prev; // Old next node is now prev. - } - while (__tmp != __p); - } - template<typename _Tp, typename _Alloc> void list<_Tp,_Alloc>:: @@ -300,24 +240,28 @@ namespace __gnu_norm && this->_M_node._M_next->_M_next != &this->_M_node) { list __carry; - list __counter[64]; - int __fill = 0; - while (!empty()) + list __tmp[64]; + list * __fill = &__tmp[0]; + list * __counter; + + do { __carry.splice(__carry.begin(), *this, begin()); - int __i = 0; - while(__i < __fill && !__counter[__i].empty()) + + for(__counter = &__tmp[0]; + (__counter != __fill) && !__counter->empty(); + ++__counter) { - __counter[__i].merge(__carry); - __carry.swap(__counter[__i++]); + __counter->merge(__carry); + __carry.swap(*__counter); } - __carry.swap(__counter[__i]); - if (__i == __fill) ++__fill; - } - - for (int __i = 1; __i < __fill; ++__i) - __counter[__i].merge(__counter[__i-1]); - swap(__counter[__fill-1]); + __carry.swap(*__counter); + if (__counter == __fill) ++__fill; + } while ( !empty() ); + + for (__counter = &__tmp[1]; __counter != __fill; ++__counter) + __counter->merge( *(__counter-1) ); + swap( *(__fill-1) ); } } @@ -333,7 +277,7 @@ namespace __gnu_norm { iterator __next = __first; ++__next; - if (__pred(*__first)) erase(__first); + if (__pred(*__first)) _M_erase(__first); __first = __next; } } @@ -351,7 +295,7 @@ namespace __gnu_norm while (++__next != __last) { if (__binary_pred(*__first, *__next)) - erase(__next); + _M_erase(__next); else __first = __next; __next = __first; @@ -397,26 +341,31 @@ namespace __gnu_norm this->_M_node._M_next->_M_next != &this->_M_node) { list __carry; - list __counter[64]; - int __fill = 0; - while (!empty()) + list __tmp[64]; + list * __fill = &__tmp[0]; + list * __counter; + + do { __carry.splice(__carry.begin(), *this, begin()); - int __i = 0; - while(__i < __fill && !__counter[__i].empty()) + + for(__counter = &__tmp[0]; + (__counter != __fill) && !__counter->empty(); + ++__counter) { - __counter[__i].merge(__carry, __comp); - __carry.swap(__counter[__i++]); + __counter->merge(__carry, __comp); + __carry.swap(*__counter); } - __carry.swap(__counter[__i]); - if (__i == __fill) ++__fill; - } - - for (int __i = 1; __i < __fill; ++__i) - __counter[__i].merge(__counter[__i-1], __comp); - swap(__counter[__fill-1]); + __carry.swap(*__counter); + if (__counter == __fill) ++__fill; + } while ( !empty() ); + + for (__counter = &__tmp[1]; __counter != __fill; ++__counter) + __counter->merge( *(__counter-1), __comp ); + swap( *(__fill-1) ); } } } // namespace __gnu_norm #endif /* _LIST_TCC */ + diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h index a9513f1656a01e07feec86fe20d1b280fa27dfb8..fca21e9ed0cccd3e5bfeb41c06c182b3a0365b7f 100644 --- a/libstdc++-v3/include/bits/stl_list.h +++ b/libstdc++-v3/include/bits/stl_list.h @@ -1,6 +1,6 @@ // List implementation -*- C++ -*- -// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004 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 @@ -75,6 +75,16 @@ namespace __gnu_norm { _List_node_base* _M_next; ///< Self-explanatory _List_node_base* _M_prev; ///< Self-explanatory + + static void swap(_List_node_base& __x, + _List_node_base& __y); + + void transfer(_List_node_base * const __first, + _List_node_base * const __last); + + void reverse(); + void hook(_List_node_base * const __position); + void unhook(); }; /// @if maint An actual node in the %list. @endif @@ -86,90 +96,122 @@ namespace __gnu_norm /** - * @if maint - * @brief Common part of a list::iterator. + * @brief A list::iterator. * - * A simple type to walk a doubly-linked list. All operations here - * should be self-explanatory after taking any decent introductory - * data structures course. + * @if maint + * All the functions are op overloads. * @endif */ - struct _List_iterator_base - { - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef bidirectional_iterator_tag iterator_category; - - /// The only member points to the %list element. - _List_node_base* _M_node; - - _List_iterator_base(_List_node_base* __x) - : _M_node(__x) { } - - _List_iterator_base() { } - - /// Walk the %list forward. - void - _M_incr() - { _M_node = _M_node->_M_next; } - - /// Walk the %list backward. - void - _M_decr() - { _M_node = _M_node->_M_prev; } + template<typename _Tp> + struct _List_iterator + { + typedef _List_iterator<_Tp> _Self; + typedef _List_node<_Tp> _Node; + + typedef ptrdiff_t difference_type; + typedef bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Tp* pointer; + typedef _Tp& reference; + + _List_iterator() { } + + _List_iterator(_List_node_base* __x) + : _M_node(__x) { } + + // Must downcast from List_node_base to _List_node to get to _M_data. + reference + operator*() const + { return static_cast<_Node*>(_M_node)->_M_data; } + + pointer + operator->() const + { return &static_cast<_Node*>(_M_node)->_M_data; } + + _Self& + operator++() + { + _M_node = _M_node->_M_next; + return *this; + } - bool - operator==(const _List_iterator_base& __x) const - { return _M_node == __x._M_node; } + _Self + operator++(int) + { + _Self __tmp = *this; + _M_node = _M_node->_M_next; + return __tmp; + } + + _Self& + operator--() + { + _M_node = _M_node->_M_prev; + return *this; + } - bool - operator!=(const _List_iterator_base& __x) const - { return _M_node != __x._M_node; } - }; + _Self + operator--(int) + { + _Self __tmp = *this; + _M_node = _M_node->_M_prev; + 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; } + + // The only member points to the %list element. + _List_node_base* _M_node; + }; /** - * @brief A list::iterator. - * - * In addition to being used externally, a list holds one of these - * internally, pointing to the sequence of data. + * @brief A list::const_iterator. * * @if maint * All the functions are op overloads. * @endif */ - template<typename _Tp, typename _Ref, typename _Ptr> - struct _List_iterator : public _List_iterator_base + template<typename _Tp> + struct _List_const_iterator { - typedef _List_iterator<_Tp,_Tp&,_Tp*> iterator; - typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; - typedef _List_iterator<_Tp,_Ref,_Ptr> _Self; - - typedef _Tp value_type; - typedef _Ptr pointer; - typedef _Ref reference; - typedef _List_node<_Tp> _Node; + typedef _List_const_iterator<_Tp> _Self; + typedef const _List_node<_Tp> _Node; + typedef _List_iterator<_Tp> iterator; - _List_iterator(_Node* __x) - : _List_iterator_base(__x) { } - - _List_iterator() { } + typedef ptrdiff_t difference_type; + typedef bidirectional_iterator_tag iterator_category; + typedef _Tp value_type; + typedef const _Tp* pointer; + typedef const _Tp& reference; - _List_iterator(const iterator& __x) - : _List_iterator_base(__x._M_node) { } - - // Must downcast from List_node_base to _List_node to get to _M_data. + _List_const_iterator() { } + + _List_const_iterator(const _List_node_base* __x) + : _M_node(__x) { } + + _List_const_iterator(const iterator& __x) + : _M_node(__x._M_node) { } + + // Must downcast from List_node_base to _List_node to get to + // _M_data. reference operator*() const { return static_cast<_Node*>(_M_node)->_M_data; } pointer operator->() const - { return &(operator*()); } + { return &static_cast<_Node*>(_M_node)->_M_data; } _Self& operator++() { - this->_M_incr(); + _M_node = _M_node->_M_next; return *this; } @@ -177,26 +219,50 @@ namespace __gnu_norm operator++(int) { _Self __tmp = *this; - this->_M_incr(); + _M_node = _M_node->_M_next; return __tmp; } _Self& operator--() { - this->_M_decr(); + _M_node = _M_node->_M_prev; return *this; } - + _Self operator--(int) { _Self __tmp = *this; - this->_M_decr(); - return __tmp; + _M_node = _M_node->_M_prev; + 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; } + + // The only member points to the %list element. + const _List_node_base* _M_node; }; + template<typename _Val> + inline bool + operator==(const _List_iterator<_Val>& __x, + const _List_const_iterator<_Val>& __y) + { return __x._M_node == __y._M_node; } + + template<typename _Val> + inline bool + operator!=(const _List_iterator<_Val>& __x, + const _List_const_iterator<_Val>& __y) + { return __x._M_node != __y._M_node; } + + /** * @if maint * See bits/stl_deque.h's _Deque_base for an explanation. @@ -242,10 +308,7 @@ namespace __gnu_norm _List_base(const allocator_type& __a) : _Node_Alloc_type(__a) - { - this->_M_node._M_next = &this->_M_node; - this->_M_node._M_prev = &this->_M_node; - } + { _M_init(); } // This is what actually destroys the list. ~_List_base() @@ -253,6 +316,13 @@ namespace __gnu_norm void _M_clear(); + + void + _M_init() + { + this->_M_node._M_next = &this->_M_node; + this->_M_node._M_prev = &this->_M_node; + } }; @@ -313,8 +383,8 @@ namespace __gnu_norm typedef _Tp value_type; typedef value_type* pointer; typedef const value_type* const_pointer; - typedef _List_iterator<_Tp,_Tp&,_Tp*> iterator; - typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; + typedef _List_iterator<_Tp> iterator; + typedef _List_const_iterator<_Tp> const_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; typedef std::reverse_iterator<iterator> reverse_iterator; typedef value_type& reference; @@ -511,7 +581,7 @@ namespace __gnu_norm * %list. Iteration is done in ordinary element order. */ iterator - begin() { return static_cast<_Node*>(this->_M_node._M_next); } + begin() { return this->_M_node._M_next; } /** * Returns a read-only (constant) iterator that points to the @@ -519,7 +589,7 @@ namespace __gnu_norm * element order. */ const_iterator - begin() const { return static_cast<_Node*>(this->_M_node._M_next); } + begin() const { return this->_M_node._M_next; } /** * Returns a read/write iterator that points one past the last @@ -527,7 +597,7 @@ namespace __gnu_norm * order. */ iterator - end() { return static_cast<_Node*>(&this->_M_node); } + end() { return &this->_M_node; } /** * Returns a read-only (constant) iterator that points one past @@ -535,8 +605,7 @@ namespace __gnu_norm * element order. */ const_iterator - end() const - { return const_cast<_Node*>(static_cast<const _Node*>(&this->_M_node)); } + end() const { return &this->_M_node; } /** * Returns a read/write reverse iterator that points to the last @@ -653,7 +722,7 @@ namespace __gnu_norm * references. */ void - push_front(const value_type& __x) { this->insert(begin(), __x); } + push_front(const value_type& __x) { this->_M_insert(begin(), __x); } /** * @brief Removes first element. @@ -668,7 +737,7 @@ namespace __gnu_norm * called. */ void - pop_front() { this->erase(begin()); } + pop_front() { this->_M_erase(begin()); } /** * @brief Add data to the end of the %list. @@ -681,7 +750,7 @@ namespace __gnu_norm * references. */ void - push_back(const value_type& __x) { this->insert(end(), __x); } + push_back(const value_type& __x) { this->_M_insert(end(), __x); } /** * @brief Removes last element. @@ -695,11 +764,7 @@ namespace __gnu_norm * is needed, it should be retrieved before pop_back() is called. */ void - pop_back() - { - iterator __tmp = end(); - this->erase(--__tmp); - } + pop_back() { this->_M_erase(this->_M_node._M_prev); } /** * @brief Inserts given value into %list before specified iterator. @@ -797,7 +862,7 @@ namespace __gnu_norm erase(iterator __first, iterator __last) { while (__first != __last) - erase(__first++); + __first = erase(__first); return __last; } @@ -811,7 +876,7 @@ namespace __gnu_norm * function. */ void - swap(list& __x); + swap(list& __x) { _List_node_base::swap(this->_M_node,__x._M_node); } /** * Erases all the elements. Note that this function only erases @@ -820,7 +885,11 @@ namespace __gnu_norm * Managing the pointer is the user's responsibilty. */ void - clear() { _Base::_M_clear(); } + clear() + { + _Base::_M_clear(); + _Base::_M_init(); + } // [23.2.2.4] list operations /** @@ -968,7 +1037,7 @@ namespace __gnu_norm * Reverse the order of elements in the list in linear time. */ void - reverse() { __List_base_reverse(&this->_M_node); } + reverse() { this->_M_node.reverse(); } /** * @brief Sort the elements. @@ -1033,7 +1102,7 @@ namespace __gnu_norm __false_type) { for ( ; __first != __last; ++__first) - insert(__pos, *__first); + _M_insert(__pos, *__first); } // Called by insert(p,n,x), and the range insert when it turns out @@ -1042,7 +1111,7 @@ namespace __gnu_norm _M_fill_insert(iterator __pos, size_type __n, const value_type& __x) { for ( ; __n > 0; --__n) - insert(__pos, __x); + _M_insert(__pos, __x); } @@ -1050,19 +1119,26 @@ namespace __gnu_norm void _M_transfer(iterator __position, iterator __first, iterator __last) { - if (__position != __last) - { - // Remove [first, last) from its old position. - __last._M_node->_M_prev->_M_next = __position._M_node; - __first._M_node->_M_prev->_M_next = __last._M_node; - __position._M_node->_M_prev->_M_next = __first._M_node; - - // Splice [first, last) into its new position. - _List_node_base* __tmp = __position._M_node->_M_prev; - __position._M_node->_M_prev = __last._M_node->_M_prev; - __last._M_node->_M_prev = __first._M_node->_M_prev; - __first._M_node->_M_prev = __tmp; - } + __position._M_node->transfer(__first._M_node,__last._M_node); + } + + // Inserts new element at position given and with value given. + void + _M_insert(iterator __position, const value_type& __x) + { + _Node* __tmp = _M_create_node(__x); + + __tmp->hook(__position._M_node); + } + + // Erases element at position given. + void + _M_erase(iterator __position) + { + __position._M_node->unhook(); + _Node* __n = static_cast<_Node*>(__position._M_node); + std::_Destroy(&__n->_M_data); + _M_put_node(__n); } }; @@ -1146,3 +1222,4 @@ namespace __gnu_norm } // namespace __gnu_norm #endif /* _LIST_H */ + diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h index d0739e10a57bc0cd56ccb58debf9626a8c92f764..81428b28876768e0bb5cd3c7c946c102d0ae281f 100644 --- a/libstdc++-v3/include/bits/stl_tree.h +++ b/libstdc++-v3/include/bits/stl_tree.h @@ -141,36 +141,34 @@ namespace std _Rb_tree_node_base* _Rb_tree_increment(_Rb_tree_node_base* __x); + const _Rb_tree_node_base* + _Rb_tree_increment(const _Rb_tree_node_base* __x); + _Rb_tree_node_base* _Rb_tree_decrement(_Rb_tree_node_base* __x); - template<typename _Val, typename _Ref, typename _Ptr> + const _Rb_tree_node_base* + _Rb_tree_decrement(const _Rb_tree_node_base* __x); + + template<typename _Tp> 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_node_base::_Base_ptr _Base_ptr; + 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<_Val, _Ref, _Ptr> _Self; - typedef _Rb_tree_node<_Val>* _Link_type; - typedef const _Rb_tree_node<_Val>* _Const_Link_type; + 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() {} _Rb_tree_iterator(_Link_type __x) : _M_node(__x) {} - _Rb_tree_iterator(_Const_Link_type __x) - : _M_node(const_cast<_Link_type>(__x)) {} - - _Rb_tree_iterator(const iterator& __it) - : _M_node(__it._M_node) {} - reference operator*() const { return static_cast<_Link_type>(_M_node)->_M_value_field; } @@ -209,53 +207,115 @@ namespace std 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<typename _Val, typename _Ref, typename _Ptr> - 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<typename _Tp> + struct _Rb_tree_const_iterator + { + typedef _Tp value_type; + typedef const _Tp& reference; + typedef const _Tp* pointer; - template<typename _Val> - 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<typename _Val> - 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<typename _Val, typename _Ref, typename _Ptr> - 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; + + _Rb_tree_const_iterator() {} + + _Rb_tree_const_iterator(_Link_type __x) + : _M_node(__x) {} + + _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++() + { + _M_node = _Rb_tree_increment(_M_node); + return *this; + } + + _Self + operator++(int) + { + _Self __tmp = *this; + _M_node = _Rb_tree_increment(_M_node); + return __tmp; + } + + _Self& + operator--() + { + _M_node = _Rb_tree_decrement(_M_node); + return *this; + } + + _Self + operator--(int) + { + _Self __tmp = *this; + _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<typename _Val> 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; } + operator==(const _Rb_tree_iterator<_Val>& __x, + const _Rb_tree_const_iterator<_Val>& __y) + { return __x._M_node == __y._M_node; } template<typename _Val> inline bool - operator!=(const _Rb_tree_iterator<_Val, _Val&, _Val*>& __x, - const _Rb_tree_iterator<_Val, const _Val&, const _Val*>& __y) + operator!=(const _Rb_tree_iterator<_Val>& __x, + const _Rb_tree_const_iterator<_Val>& __y) { return __x._M_node != __y._M_node; } void - _Rb_tree_rotate_left(_Rb_tree_node_base* const __x, _Rb_tree_node_base*& __root); + _Rb_tree_rotate_left(_Rb_tree_node_base* const __x, + _Rb_tree_node_base*& __root); void - _Rb_tree_rotate_right(_Rb_tree_node_base* const __x, _Rb_tree_node_base*& __root); + _Rb_tree_rotate_right(_Rb_tree_node_base* const __x, + _Rb_tree_node_base*& __root); void - _Rb_tree_rebalance(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root); + _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_node_base* _Rb_tree_rebalance_for_erase(_Rb_tree_node_base* const __z, @@ -407,12 +467,11 @@ namespace std { return _Rb_tree_node_base::_S_maximum(__x); } public: - typedef _Rb_tree_iterator<value_type, reference, pointer> iterator; - typedef _Rb_tree_iterator<value_type, const_reference, const_pointer> - const_iterator; + typedef _Rb_tree_iterator<value_type> iterator; + typedef _Rb_tree_const_iterator<value_type> const_iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; - typedef std::reverse_iterator<iterator> reverse_iterator; private: iterator @@ -461,7 +520,7 @@ namespace std _M_node_count = __x._M_node_count; } - ~_Rb_tree() { clear(); } + ~_Rb_tree() { _M_erase(_M_begin()); } _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& operator=(const _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>& __x); @@ -550,18 +609,15 @@ namespace std void erase(const key_type* __first, const key_type* __last); - void - clear() + void + clear() { - if (_M_node_count != 0) - { - _M_erase(_M_begin()); - _M_leftmost() = _M_end(); - _M_root() = 0; - _M_rightmost() = _M_end(); - _M_node_count = 0; - } - } + _M_erase(_M_begin()); + _M_leftmost() = _M_end(); + _M_root() = 0; + _M_rightmost() = _M_end(); + _M_node_count = 0; + } // Set operations. iterator @@ -661,15 +717,8 @@ namespace std { // 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_end(); - _M_rightmost() = _M_end(); - } - else + if (__x._M_root() != 0) { _M_root() = _M_copy(__x._M_begin(), _M_end()); _M_leftmost() = _S_minimum(_M_root()); @@ -684,38 +733,15 @@ namespace std typename _Compare, typename _Alloc> 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) + _M_insert(_Base_ptr __x, _Base_ptr __p, const _Val& __v) { - _Link_type __x = static_cast<_Link_type>(__x_); - _Link_type __y = static_cast<_Link_type>(__y_); - _Link_type __z; - - if (__y == &this->_M_header || __x != 0 || - _M_key_compare(_KeyOfValue()(__v), _S_key(__y))) - { - __z = _M_create_node(__v); - __y->_M_left = __z; // also makes _M_leftmost() = __z - // when __y == &_M_header - if (__y == &this->_M_header) - { - _M_root() = __z; - _M_rightmost() = __z; - } - else if (__y == _M_leftmost()) - _M_leftmost() = __z; // maintain _M_leftmost() pointing to min node - } - else - { - __z = _M_create_node(__v); - __y->_M_right = __z; - // Maintain _M_rightmost() pointing to max node. - if (__y == _M_rightmost()) - _M_rightmost() = __z; - } - __z->_M_parent = __y; - __z->_M_left = 0; - __z->_M_right = 0; - _Rb_tree_rebalance(__z, this->_M_header._M_parent); + _Link_type __z = _M_create_node(__v); + bool __insert_left; + + __insert_left = __x != 0 || __p == _M_end() || + _M_key_compare(_KeyOfValue()(__v), _S_key(__p)); + + _Rb_tree_insert_and_rebalance(__insert_left, __z, __p, this->_M_header); ++_M_node_count; return iterator(__z); } @@ -816,7 +842,7 @@ namespace std _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: insert_unique(iterator __position, const _Val& __v) { - if (__position._M_node == this->_M_header._M_left) + if (__position._M_node == _M_leftmost()) { // begin() if (size() > 0 && @@ -826,7 +852,7 @@ namespace std else return insert_unique(__v).first; } - else if (__position._M_node == &this->_M_header) + else if (__position._M_node == _M_end()) { // end() if (_M_key_compare(_S_key(_M_rightmost()), _KeyOfValue()(__v))) @@ -858,7 +884,7 @@ namespace std _Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>:: insert_equal(iterator __position, const _Val& __v) { - if (__position._M_node == this->_M_header._M_left) + if (__position._M_node == _M_leftmost()) { // begin() if (size() > 0 && @@ -868,7 +894,7 @@ namespace std else return insert_equal(__v); } - else if (__position._M_node == &this->_M_header) + else if (__position._M_node == _M_end()) { // end() if (!_M_key_compare(_KeyOfValue()(__v), _S_key(_M_rightmost()))) @@ -1168,8 +1194,8 @@ namespace std { if (_M_node_count == 0 || begin() == end()) return _M_node_count == 0 && begin() == end() && - this->_M_header._M_left == &this->_M_header && - this->_M_header._M_right == &this->_M_header; + this->_M_header._M_left == _M_end() && + this->_M_header._M_right == _M_end(); unsigned int __len = _Rb_tree_black_count(_M_leftmost(), _M_root()); for (const_iterator __it = begin(); __it != end(); ++__it) diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h index de9c1a341b9aa3de0bf0514b33afa655f8e369ee..83d13ad028ea96e4c7741e8cb6c6977b3e7bdaf6 100644 --- a/libstdc++-v3/include/bits/stl_vector.h +++ b/libstdc++-v3/include/bits/stl_vector.h @@ -112,8 +112,8 @@ namespace __gnu_norm /** - * @brief A standard container which offers fixed time access to individual - * elements in any order. + * @brief A standard container which offers fixed time access to + * individual elements in any order. * * @ingroup Containers * @ingroup Sequences @@ -124,10 +124,11 @@ namespace __gnu_norm * <a href="tables.html#68">optional sequence requirements</a> with the * %exception of @c push_front and @c pop_front. * - * In some terminology a %vector can be described as a dynamic C-style array, - * it offers fast and efficient access to individual elements in any order - * and saves the user from worrying about memory and size allocation. - * Subscripting ( @c [] ) access is also provided as with C-style arrays. + * In some terminology a %vector can be described as a dynamic + * C-style array, it offers fast and efficient access to individual + * elements in any order and saves the user from worrying about + * memory and size allocation. Subscripting ( @c [] ) access is + * also provided as with C-style arrays. */ template<typename _Tp, typename _Alloc = allocator<_Tp> > class vector : protected _Vector_base<_Tp, _Alloc> @@ -185,7 +186,8 @@ namespace __gnu_norm vector(size_type __n, const value_type& __value, const allocator_type& __a = allocator_type()) : _Base(__n, __a) - { this->_M_finish = std::uninitialized_fill_n(this->_M_start, __n, __value); } + { this->_M_finish = std::uninitialized_fill_n(this->_M_start, + __n, __value); } /** * @brief Create a %vector with default elements. @@ -223,11 +225,12 @@ namespace __gnu_norm * Create a %vector consisting of copies of the elements from * [first,last). * - * If the iterators are forward, bidirectional, or random-access, then - * this will call the elements' copy constructor N times (where N is - * distance(first,last)) and do no memory reallocation. But if only - * input iterators are used, then this will do at most 2N calls to the - * copy constructor, and logN memory reallocations. + * If the iterators are forward, bidirectional, or + * random-access, then this will call the elements' copy + * constructor N times (where N is distance(first,last)) and do + * no memory reallocation. But if only input iterators are + * used, then this will do at most 2N calls to the copy + * constructor, and logN memory reallocations. */ template<typename _InputIterator> vector(_InputIterator __first, _InputIterator __last, @@ -240,9 +243,10 @@ namespace __gnu_norm } /** - * The dtor only erases the elements, and note that if the elements - * themselves are pointers, the pointed-to memory is not touched in any - * way. Managing the pointer is the user's responsibilty. + * The dtor only erases the elements, and note that if the + * elements themselves are pointers, the pointed-to memory is + * not touched in any way. Managing the pointer is the user's + * responsibilty. */ ~vector() { std::_Destroy(this->_M_start, this->_M_finish); } @@ -297,8 +301,9 @@ namespace __gnu_norm // iterators /** - * Returns a read/write iterator that points to the first element in the - * %vector. Iteration is done in ordinary element order. + * Returns a read/write iterator that points to the first + * element in the %vector. Iteration is done in ordinary + * element order. */ iterator begin() { return iterator (this->_M_start); } @@ -320,8 +325,9 @@ namespace __gnu_norm end() { return iterator (this->_M_finish); } /** - * Returns a read-only (constant) iterator that points one past the last - * element in the %vector. Iteration is done in ordinary element order. + * Returns a read-only (constant) iterator that points one past + * the last element in the %vector. Iteration is done in + * ordinary element order. */ const_iterator end() const { return const_iterator (this->_M_finish); } @@ -343,9 +349,9 @@ namespace __gnu_norm rbegin() const { return const_reverse_iterator(end()); } /** - * Returns a read/write reverse iterator that points to one before the - * first element in the %vector. Iteration is done in reverse element - * order. + * Returns a read/write reverse iterator that points to one + * before the first element in the %vector. Iteration is done + * in reverse element order. */ reverse_iterator rend() { return reverse_iterator(begin()); } @@ -401,8 +407,8 @@ namespace __gnu_norm resize(size_type __new_size) { resize(__new_size, value_type()); } /** - * Returns the total number of elements that the %vector can hold before - * needing to allocate more memory. + * Returns the total number of elements that the %vector can + * hold before needing to allocate more memory. */ size_type capacity() const @@ -438,7 +444,8 @@ namespace __gnu_norm // element access /** * @brief Subscript access to the data contained in the %vector. - * @param n The index of the element for which data should be accessed. + * @param n The index of the element for which data should be + * accessed. * @return Read/write reference to data. * * This operator allows for easy, array-style, data access. @@ -480,9 +487,9 @@ namespace __gnu_norm * @return Read/write reference to data. * @throw std::out_of_range If @a n is an invalid index. * - * This function provides for safer data access. The parameter is first - * checked that it is in the range of the vector. The function throws - * out_of_range if the check fails. + * This function provides for safer data access. The parameter + * is first checked that it is in the range of the vector. The + * function throws out_of_range if the check fails. */ reference at(size_type __n) { _M_range_check(__n); return (*this)[__n]; } @@ -516,15 +523,15 @@ namespace __gnu_norm front() const { return *begin(); } /** - * Returns a read/write reference to the data at the last element of the - * %vector. + * Returns a read/write reference to the data at the last + * element of the %vector. */ reference back() { return *(end() - 1); } /** - * Returns a read-only (constant) reference to the data at the last - * element of the %vector. + * Returns a read-only (constant) reference to the data at the + * last element of the %vector. */ const_reference back() const { return *(end() - 1); } @@ -557,8 +564,9 @@ namespace __gnu_norm * * This is a typical stack operation. It shrinks the %vector by one. * - * Note that no data is returned, and if the last element's data is - * needed, it should be retrieved before pop_back() is called. + * Note that no data is returned, and if the last element's + * data is needed, it should be retrieved before pop_back() is + * called. */ void pop_back() @@ -614,7 +622,8 @@ namespace __gnu_norm */ template<typename _InputIterator> void - insert(iterator __position, _InputIterator __first, _InputIterator __last) + insert(iterator __position, _InputIterator __first, + _InputIterator __last) { // Check whether it's an integral type. If so, it's not an iterator. typedef typename _Is_integer<_InputIterator>::_Integral _Integral; @@ -721,7 +730,8 @@ namespace __gnu_norm { this->_M_start = _M_allocate(__n); this->_M_end_of_storage = this->_M_start + __n; - this->_M_finish = std::uninitialized_fill_n(this->_M_start, __n, __value); + this->_M_finish = std::uninitialized_fill_n(this->_M_start, + __n, __value); } // Called by the range constructor to implement [23.1.1]/9 @@ -774,7 +784,8 @@ namespace __gnu_norm // Called by the range assign to implement [23.1.1]/9 template<typename _InputIterator> void - _M_assign_dispatch(_InputIterator __first, _InputIterator __last, __false_type) + _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) { typedef typename iterator_traits<_InputIterator>::iterator_category _IterCategory; diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am index a0d0187c7cf437c88d101973bc5b4bfcec3834dc..3b4f67501c51d96d1c0f1fc2e3bd13bd4b21410b 100644 --- a/libstdc++-v3/src/Makefile.am +++ b/libstdc++-v3/src/Makefile.am @@ -104,13 +104,14 @@ sources = \ ios_init.cc \ ios_locale.cc \ limits.cc \ + list.cc \ locale.cc \ locale_init.cc \ locale_facets.cc \ localename.cc \ stdexcept.cc \ - stl_tree.cc \ strstream.cc \ + tree.cc \ allocator-inst.cc \ concept-inst.cc \ fstream-inst.cc \ diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in index 3f1d41bd9e3ad9fbff7b8575390a596621d1ce75..d6cc47cbb8884dc0ff83df6016da71cb56617ede 100644 --- a/libstdc++-v3/src/Makefile.in +++ b/libstdc++-v3/src/Makefile.in @@ -260,13 +260,14 @@ sources = \ ios_init.cc \ ios_locale.cc \ limits.cc \ + list.cc \ locale.cc \ locale_init.cc \ locale_facets.cc \ localename.cc \ stdexcept.cc \ - stl_tree.cc \ strstream.cc \ + tree.cc \ allocator-inst.cc \ concept-inst.cc \ fstream-inst.cc \ @@ -361,13 +362,13 @@ am__objects_1 = codecvt_members.lo collate_members.lo ctype_members.lo \ am__objects_2 = basic_file.lo c++locale.lo am__objects_3 = codecvt.lo complex_io.lo ctype.lo debug.lo demangle.lo \ functexcept.lo globals_locale.lo globals_io.lo ios.lo \ - ios_failure.lo ios_init.lo ios_locale.lo limits.lo locale.lo \ - locale_init.lo locale_facets.lo localename.lo stdexcept.lo \ - stl_tree.lo strstream.lo allocator-inst.lo concept-inst.lo \ - fstream-inst.lo ext-inst.lo io-inst.lo istream-inst.lo \ - locale-inst.lo locale-misc-inst.lo misc-inst.lo ostream-inst.lo \ - sstream-inst.lo streambuf-inst.lo string-inst.lo \ - valarray-inst.lo wlocale-inst.lo wstring-inst.lo \ + ios_failure.lo ios_init.lo ios_locale.lo limits.lo list.lo \ + locale.lo locale_init.lo locale_facets.lo localename.lo \ + stdexcept.lo strstream.lo tree.lo allocator-inst.lo \ + concept-inst.lo fstream-inst.lo ext-inst.lo io-inst.lo \ + istream-inst.lo locale-inst.lo locale-misc-inst.lo misc-inst.lo \ + ostream-inst.lo sstream-inst.lo streambuf-inst.lo \ + string-inst.lo valarray-inst.lo wlocale-inst.lo wstring-inst.lo \ $(am__objects_1) $(am__objects_2) am_libstdc___la_OBJECTS = $(am__objects_3) libstdc___la_OBJECTS = $(am_libstdc___la_OBJECTS) diff --git a/libstdc++-v3/src/list.cc b/libstdc++-v3/src/list.cc new file mode 100644 index 0000000000000000000000000000000000000000..2be2d7131938b752984c62653a37771502e0a113 --- /dev/null +++ b/libstdc++-v3/src/list.cc @@ -0,0 +1,141 @@ +// std::list utilities implementation -*- C++ -*- + +// Copyright (C) 2003 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) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// 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. + +// 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. + +/* + * + * 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. + * + * + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * 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. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + */ + +#include <list> + +namespace __gnu_norm +{ + void + _List_node_base::swap(_List_node_base& __x, _List_node_base& __y) + { + if ( __x._M_next != &__x ) + { + if ( __y._M_next != &__y ) + { + // Both __x and __y are not empty. + std::swap(__x._M_next,__y._M_next); + std::swap(__x._M_prev,__y._M_prev); + __x._M_next->_M_prev = __x._M_prev->_M_next = &__x; + __y._M_next->_M_prev = __y._M_prev->_M_next = &__y; + } + else + { + // __x is not empty, __y is empty. + __y._M_next = __x._M_next; + __y._M_prev = __x._M_prev; + __y._M_next->_M_prev = __y._M_prev->_M_next = &__y; + __x._M_next = __x._M_prev = &__x; + } + } + else if ( __y._M_next != &__y ) + { + // __x is empty, __y is not empty. + __x._M_next = __y._M_next; + __x._M_prev = __y._M_prev; + __x._M_next->_M_prev = __x._M_prev->_M_next = &__x; + __y._M_next = __y._M_prev = &__y; + } + } + + void + _List_node_base::transfer(_List_node_base * const __first, + _List_node_base * const __last) + { + if (this != __last) + { + // Remove [first, last) from its old position. + __last->_M_prev->_M_next = this; + __first->_M_prev->_M_next = __last; + this->_M_prev->_M_next = __first; + + // Splice [first, last) into its new position. + _List_node_base* const __tmp = this->_M_prev; + this->_M_prev = __last->_M_prev; + __last->_M_prev = __first->_M_prev; + __first->_M_prev = __tmp; + } + } + + void + _List_node_base::reverse() + { + _List_node_base* __tmp = this; + do + { + std::swap(__tmp->_M_next, __tmp->_M_prev); + __tmp = __tmp->_M_prev; // Old next node is now prev. + } + while (__tmp != this); + } + + void + _List_node_base::hook(_List_node_base * const __position) + { + this->_M_next = __position; + this->_M_prev = __position->_M_prev; + __position->_M_prev->_M_next = this; + __position->_M_prev = this; + } + + void + _List_node_base::unhook() + { + _List_node_base* const __next_node = this->_M_next; + _List_node_base* const __prev_node = this->_M_prev; + __prev_node->_M_next = __next_node; + __next_node->_M_prev = __prev_node; + } +} // namespace __gnu_norm + diff --git a/libstdc++-v3/src/stl_tree.cc b/libstdc++-v3/src/tree.cc similarity index 88% rename from libstdc++-v3/src/stl_tree.cc rename to libstdc++-v3/src/tree.cc index eac141f0f79049b6d1c2c1216dde365eea35064c..0cef30c104e9c64ffb3277622079f9f1d287e06f 100644 --- a/libstdc++-v3/src/stl_tree.cc +++ b/libstdc++-v3/src/tree.cc @@ -82,6 +82,12 @@ namespace std return __x; } + const _Rb_tree_node_base* + _Rb_tree_increment(const _Rb_tree_node_base* __x) + { + return _Rb_tree_increment(const_cast<_Rb_tree_node_base*>(__x)); + } + _Rb_tree_node_base* _Rb_tree_decrement(_Rb_tree_node_base* __x) { @@ -108,6 +114,12 @@ namespace std return __x; } + const _Rb_tree_node_base* + _Rb_tree_decrement(const _Rb_tree_node_base* __x) + { + return _Rb_tree_decrement(const_cast<_Rb_tree_node_base*>(__x)); + } + void _Rb_tree_rotate_left(_Rb_tree_node_base* const __x, _Rb_tree_node_base*& __root) @@ -151,10 +163,43 @@ namespace std } void - _Rb_tree_rebalance(_Rb_tree_node_base* __x, _Rb_tree_node_base*& __root) + _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_node_base *& __root = __header._M_parent; + + // Initialize fields in new node to insert. + __x->_M_parent = __p; + __x->_M_left = 0; + __x->_M_right = 0; __x->_M_color = _S_red; + // Insert. + // Make new node child of parent and maintain root, leftmost and + // rightmost nodes. + // N.B. First node is always inserted left. + if (__insert_left) + { + __p->_M_left = __x; // also makes leftmost = __x when __p == &__header + + if (__p == &__header) + { + __header._M_parent = __x; + __header._M_right = __x; + } + else if (__p == __header._M_left) + __header._M_left = __x; // maintain leftmost pointing to min node + } + else + { + __p->_M_right = __x; + + if (__p == __header._M_right) + __header._M_right = __x; // maintain rightmost pointing to max node + } + // Rebalance. while (__x != __root && __x->_M_parent->_M_color == _S_red) { diff --git a/libstdc++-v3/testsuite/23_containers/map/operators/1_neg.cc b/libstdc++-v3/testsuite/23_containers/map/operators/1_neg.cc index f105f9b91a5733db9e04de63a4fef2fe13e31c85..84302328b4d3031349e4fd2dd653c151c08966c9 100644 --- a/libstdc++-v3/testsuite/23_containers/map/operators/1_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/map/operators/1_neg.cc @@ -1,6 +1,6 @@ -// 2000-09-07 bgarcia@laurelnetworks.com +// { dg-do compile } -// Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2000, 2001, 2002, 2004 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 @@ -19,12 +19,11 @@ // USA. // 23.3.4 template class multiset negative tests +// 2000-09-07 bgarcia@laurelnetworks.com #include <map> #include <string> -// { dg-do compile } - // libstdc++/86: map & set iterator comparisons are not type-safe void test01() { @@ -42,8 +41,5 @@ void test01() test &= itr == mapByName.end(); // { dg-error "no" } } -int main() -{ - test01(); - return 0; -} +// { dg-error "candidates are" "" { target *-*-* } 212 } +// { dg-error "candidates are" "" { target *-*-* } 216 } diff --git a/libstdc++-v3/testsuite/23_containers/set/operators/1_neg.cc b/libstdc++-v3/testsuite/23_containers/set/operators/1_neg.cc index 0c620a18b9d699c39bf66e99c41a3ad0f7c4633a..e178b8c3918a5f28f30c972bdf66869d088c9544 100644 --- a/libstdc++-v3/testsuite/23_containers/set/operators/1_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/set/operators/1_neg.cc @@ -1,6 +1,6 @@ -// 2000-09-07 bgarcia@laurelnetworks.com +// { dg-do compile } -// Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2000, 2001, 2002, 2004 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 @@ -19,14 +19,13 @@ // USA. // 23.3.4 template class multiset negative tests +// 2000-09-07 bgarcia@laurelnetworks.com #include <set> #include <string> -// { dg-do compile } - // libstdc++/86: map & set iterator comparisons are not type-safe -int main(void) +void test01() { bool test __attribute__((unused)) = true; @@ -38,6 +37,7 @@ int main(void) // NB: it's not setByIndex!! test &= itr != setByName.end(); // { dg-error "no" } test &= itr == setByName.end(); // { dg-error "no" } - - return 0; } + +// { dg-error "candidates are" "" { target *-*-* } 285 } +// { dg-error "candidates are" "" { target *-*-* } 289 }