[multiple changes]

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.

From-SVN: r75515
This commit is contained in:
Benjamin Kosnik 2004-01-07 20:55:06 +00:00
parent 85b58ca564
commit e135a038d3
12 changed files with 667 additions and 378 deletions

View File

@ -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

View File

@ -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*;

View File

@ -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 */

View File

@ -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
@ -85,78 +95,30 @@ namespace __gnu_norm
};
/**
* @if maint
* @brief Common part of 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.
* @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; }
bool
operator==(const _List_iterator_base& __x) const
{ return _M_node == __x._M_node; }
bool
operator!=(const _List_iterator_base& __x) const
{ return _M_node != __x._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.
*
* @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_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 _List_iterator<_Tp> _Self;
typedef _List_node<_Tp> _Node;
typedef _Tp value_type;
typedef _Ptr pointer;
typedef _Ref reference;
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(_Node* __x)
: _List_iterator_base(__x) { }
_List_iterator() { }
_List_iterator(const iterator& __x)
: _List_iterator_base(__x._M_node) { }
_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
@ -164,12 +126,92 @@ namespace __gnu_norm
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;
}
_Self
operator++(int)
{
_Self __tmp = *this;
_M_node = _M_node->_M_next;
return __tmp;
}
_Self&
operator--()
{
_M_node = _M_node->_M_prev;
return *this;
}
_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::const_iterator.
*
* @if maint
* All the functions are op overloads.
* @endif
*/
template<typename _Tp>
struct _List_const_iterator
{
typedef _List_const_iterator<_Tp> _Self;
typedef const _List_node<_Tp> _Node;
typedef _List_iterator<_Tp> 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_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 &static_cast<_Node*>(_M_node)->_M_data; }
_Self&
operator++()
{
_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 */

View File

@ -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>
template<typename _Tp>
struct _Rb_tree_const_iterator
{
typedef _Tp value_type;
typedef const _Tp& reference;
typedef const _Tp* pointer;
typedef _Rb_tree_iterator<_Tp> iterator;
typedef bidirectional_iterator_tag iterator_category;
typedef ptrdiff_t difference_type;
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, _Ref, _Ptr>& __x,
const _Rb_tree_iterator<_Val, _Ref, _Ptr>& __y)
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, const _Val&, const _Val*>& __x,
const _Rb_tree_iterator<_Val, _Val&, _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)
{ return __x._M_node == __y._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 _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; }
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)

View File

@ -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;

View File

@ -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 \

View File

@ -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)

141
libstdc++-v3/src/list.cc Normal file
View File

@ -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

View File

@ -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)
{

View File

@ -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 }

View File

@ -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 }