+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
_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*;
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>
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;
}
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>
iterator __next = __first;
++__next;
if (*__first == __value)
- erase(__first);
+ _M_erase(__first);
__first = __next;
}
}
while (++__next != __last)
{
if (*__first == *__next)
- erase(__next);
+ _M_erase(__next);
else
__first = __next;
__next = __first;
}
}
- // 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>::
&& 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) );
}
}
{
iterator __next = __first;
++__next;
- if (__pred(*__first)) erase(__first);
+ if (__pred(*__first)) _M_erase(__first);
__first = __next;
}
}
while (++__next != __last)
{
if (__binary_pred(*__first, *__next))
- erase(__next);
+ _M_erase(__next);
else
__first = __next;
__next = __first;
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 */
+
// 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
{
_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
/**
- * @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;
}
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.
_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()
void
_M_clear();
+
+ void
+ _M_init()
+ {
+ this->_M_node._M_next = &this->_M_node;
+ this->_M_node._M_prev = &this->_M_node;
+ }
};
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;
* %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
* 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
* 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
* 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
* 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.
* called.
*/
void
- pop_front() { this->erase(begin()); }
+ pop_front() { this->_M_erase(begin()); }
/**
* @brief Add data to the end of the %list.
* 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.
* 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.
erase(iterator __first, iterator __last)
{
while (__first != __last)
- erase(__first++);
+ __first = erase(__first);
return __last;
}
* 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
* 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
/**
* 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.
__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
_M_fill_insert(iterator __pos, size_type __n, const value_type& __x)
{
for ( ; __n > 0; --__n)
- insert(__pos, __x);
+ _M_insert(__pos, __x);
}
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);
}
};
} // namespace __gnu_norm
#endif /* _LIST_H */
+
_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; }
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,
{ 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
_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);
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
{
// 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());
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);
}
_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 &&
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)))
_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 &&
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())))
{
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)
/**
- * @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
* <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>
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.
* 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,
}
/**
- * 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); }
// 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); }
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); }
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()); }
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
// 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.
* @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]; }
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); }
*
* 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()
*/
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;
{
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
// 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;
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 \
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 \
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)
--- /dev/null
+// 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
+
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)
{
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)
}
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)
{
-// 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
// 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()
{
test &= itr == mapByName.end(); // { dg-error "no" }
}
-int main()
-{
- test01();
- return 0;
-}
+// { dg-error "candidates are" "" { target *-*-* } 212 }
+// { dg-error "candidates are" "" { target *-*-* } 216 }
-// 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
// 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;
// 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 }