Commit 1fc61093 by Stephen M. Webb Committed by Benjamin Kosnik

list_capacity.cc: New file.


2001-11-22  Stephen M. Webb  <stephen@bregmasoft.com>

        * testsuite/23_containers/list_capacity.cc: New file.
        * testsuite/23_containers/list_ctor.cc: New file.
        * testsuite/23_containers/list_modifiers.cc: New file.
        * testsuite/23_containers/list_operators.cc: New file.

2001-11-22  Stephen M. Webb  <stephen@bregmasoft.com>

	* include/bits/stl_list.h: Reformatted according to C++STYLE rules.
	(size): Replaced nonstandard distance() call with the standard one.
	(transfer): Uglified to _M_transfer.

From-SVN: r47277
parent 60f4621c
2001-11-22 Stephen M. Webb <stephen@bregmasoft.com>
* testsuite/23_containers/list_capacity.cc: New file.
* testsuite/23_containers/list_ctor.cc: New file.
* testsuite/23_containers/list_modifiers.cc: New file.
* testsuite/23_containers/list_operators.cc: New file.
2001-11-22 Stephen M. Webb <stephen@bregmasoft.com>
* include/bits/stl_list.h: Reformatted according to C++STYLE rules.
(size): Replaced nonstandard distance() call with the standard one.
(transfer): Uglified to _M_transfer.
2001-11-21 Paolo Carlini <pcarlini@unitus.it> 2001-11-21 Paolo Carlini <pcarlini@unitus.it>
PR libstdc++/4548 PR libstdc++/4548
......
...@@ -66,39 +66,53 @@ ...@@ -66,39 +66,53 @@
namespace std namespace std
{ {
struct _List_node_base { struct _List_node_base
{
_List_node_base* _M_next; _List_node_base* _M_next;
_List_node_base* _M_prev; _List_node_base* _M_prev;
}; };
template <class _Tp> template<typename _Tp>
struct _List_node : public _List_node_base { struct _List_node : public _List_node_base
{
_Tp _M_data; _Tp _M_data;
}; };
struct _List_iterator_base { struct _List_iterator_base
{
typedef size_t size_type; typedef size_t size_type;
typedef ptrdiff_t difference_type; typedef ptrdiff_t difference_type;
typedef bidirectional_iterator_tag iterator_category; typedef bidirectional_iterator_tag iterator_category;
_List_node_base* _M_node; _List_node_base* _M_node;
_List_iterator_base(_List_node_base* __x) : _M_node(__x) {} _List_iterator_base(_List_node_base* __x)
_List_iterator_base() {} : _M_node(__x)
{ }
void _M_incr() { _M_node = _M_node->_M_next; } _List_iterator_base()
void _M_decr() { _M_node = _M_node->_M_prev; } { }
bool operator==(const _List_iterator_base& __x) const { void
return _M_node == __x._M_node; _M_incr()
} { _M_node = _M_node->_M_next; }
bool operator!=(const _List_iterator_base& __x) const {
return _M_node != __x._M_node; void
} _M_decr()
}; { _M_node = _M_node->_M_prev; }
template<class _Tp, class _Ref, class _Ptr> bool
struct _List_iterator : public _List_iterator_base { 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; }
};
template<typename _Tp, typename _Ref, typename _Ptr>
struct _List_iterator : public _List_iterator_base
{
typedef _List_iterator<_Tp,_Tp&,_Tp*> iterator; typedef _List_iterator<_Tp,_Tp&,_Tp*> iterator;
typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
typedef _List_iterator<_Tp,_Ref,_Ptr> _Self; typedef _List_iterator<_Tp,_Ref,_Ptr> _Self;
...@@ -108,136 +122,169 @@ struct _List_iterator : public _List_iterator_base { ...@@ -108,136 +122,169 @@ struct _List_iterator : public _List_iterator_base {
typedef _Ref reference; typedef _Ref reference;
typedef _List_node<_Tp> _Node; typedef _List_node<_Tp> _Node;
_List_iterator(_Node* __x) : _List_iterator_base(__x) {} _List_iterator(_Node* __x)
_List_iterator() {} : _List_iterator_base(__x)
_List_iterator(const iterator& __x) : _List_iterator_base(__x._M_node) {} { }
_List_iterator()
{ }
_List_iterator(const iterator& __x)
: _List_iterator_base(__x._M_node)
{ }
reference operator*() const { return ((_Node*) _M_node)->_M_data; } reference
pointer operator->() const { return &(operator*()); } operator*() const
{ return ((_Node*) _M_node)->_M_data; }
_Self& operator++() { pointer
operator->() const
{ return &(operator*()); }
_Self&
operator++()
{
this->_M_incr(); this->_M_incr();
return *this; return *this;
} }
_Self operator++(int) {
_Self
operator++(int)
{
_Self __tmp = *this; _Self __tmp = *this;
this->_M_incr(); this->_M_incr();
return __tmp; return __tmp;
} }
_Self& operator--() {
_Self&
operator--()
{
this->_M_decr(); this->_M_decr();
return *this; return *this;
} }
_Self operator--(int) {
_Self
operator--(int)
{
_Self __tmp = *this; _Self __tmp = *this;
this->_M_decr(); this->_M_decr();
return __tmp; return __tmp;
} }
}; };
// Base class that encapsulates details of allocators. Three cases: // Base class that encapsulates details of allocators. Three cases:
// an ordinary standard-conforming allocator, a standard-conforming // an ordinary standard-conforming allocator, a standard-conforming
// allocator with no non-static data, and an SGI-style allocator. // allocator with no non-static data, and an SGI-style allocator.
// This complexity is necessary only because we're worrying about backward // This complexity is necessary only because we're worrying about backward
// compatibility and because we want to avoid wasting storage on an // compatibility and because we want to avoid wasting storage on an
// allocator instance if it isn't necessary. // allocator instance if it isn't necessary.
// Base for general standard-conforming allocators. // Base for general standard-conforming allocators.
template <class _Tp, class _Allocator, bool _IsStatic> template<typename _Tp, typename _Allocator, bool _IsStatic>
class _List_alloc_base { class _List_alloc_base
public: {
public:
typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
allocator_type; allocator_type;
allocator_type get_allocator() const { return _Node_allocator; }
_List_alloc_base(const allocator_type& __a) : _Node_allocator(__a) {} allocator_type
get_allocator() const
{ return _Node_allocator; }
_List_alloc_base(const allocator_type& __a)
: _Node_allocator(__a)
{ }
protected: protected:
_List_node<_Tp>* _M_get_node() _List_node<_Tp>*
_M_get_node()
{ return _Node_allocator.allocate(1); } { return _Node_allocator.allocate(1); }
void _M_put_node(_List_node<_Tp>* __p)
void
_M_put_node(_List_node<_Tp>* __p)
{ _Node_allocator.deallocate(__p, 1); } { _Node_allocator.deallocate(__p, 1); }
protected: protected:
typename _Alloc_traits<_List_node<_Tp>, _Allocator>::allocator_type typename _Alloc_traits<_List_node<_Tp>, _Allocator>::allocator_type
_Node_allocator; _Node_allocator;
_List_node<_Tp>* _M_node; _List_node<_Tp>* _M_node;
}; };
// Specialization for instanceless allocators. // Specialization for instanceless allocators.
template <class _Tp, class _Allocator> template<typename _Tp, typename _Allocator>
class _List_alloc_base<_Tp, _Allocator, true> { class _List_alloc_base<_Tp, _Allocator, true>
public: {
public:
typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
allocator_type; allocator_type;
allocator_type get_allocator() const { return allocator_type(); }
_List_alloc_base(const allocator_type&) {} allocator_type
get_allocator() const
{ return allocator_type(); }
protected: _List_alloc_base(const allocator_type&)
{ }
protected:
typedef typename _Alloc_traits<_List_node<_Tp>, _Allocator>::_Alloc_type typedef typename _Alloc_traits<_List_node<_Tp>, _Allocator>::_Alloc_type
_Alloc_type; _Alloc_type;
_List_node<_Tp>* _M_get_node() { return _Alloc_type::allocate(1); }
void _M_put_node(_List_node<_Tp>* __p) { _Alloc_type::deallocate(__p, 1); }
protected: _List_node<_Tp>*
_M_get_node()
{ return _Alloc_type::allocate(1); }
void
_M_put_node(_List_node<_Tp>* __p)
{ _Alloc_type::deallocate(__p, 1); }
protected:
_List_node<_Tp>* _M_node; _List_node<_Tp>* _M_node;
}; };
template <class _Tp, class _Alloc> template<typename _Tp, typename _Alloc>
class _List_base class _List_base
: public _List_alloc_base<_Tp, _Alloc, : public _List_alloc_base<_Tp, _Alloc,
_Alloc_traits<_Tp, _Alloc>::_S_instanceless> _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
{ {
public: public:
typedef _List_alloc_base<_Tp, _Alloc, typedef _List_alloc_base<_Tp, _Alloc,
_Alloc_traits<_Tp, _Alloc>::_S_instanceless> _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
_Base; _Base;
typedef typename _Base::allocator_type allocator_type; typedef typename _Base::allocator_type allocator_type;
_List_base(const allocator_type& __a) : _Base(__a) { _List_base(const allocator_type& __a)
: _Base(__a)
{
_M_node = _M_get_node(); _M_node = _M_get_node();
_M_node->_M_next = _M_node; _M_node->_M_next = _M_node;
_M_node->_M_prev = _M_node; _M_node->_M_prev = _M_node;
} }
~_List_base() {
~_List_base()
{
clear(); clear();
_M_put_node(_M_node); _M_put_node(_M_node);
} }
void clear(); void clear();
}; };
template <class _Tp, class _Alloc>
void
_List_base<_Tp,_Alloc>::clear()
{
_List_node<_Tp>* __cur = (_List_node<_Tp>*) _M_node->_M_next;
while (__cur != _M_node) {
_List_node<_Tp>* __tmp = __cur;
__cur = (_List_node<_Tp>*) __cur->_M_next;
_Destroy(&__tmp->_M_data);
_M_put_node(__tmp);
}
_M_node->_M_next = _M_node;
_M_node->_M_prev = _M_node;
}
template <class _Tp, class _Alloc = allocator<_Tp> > template<typename _Tp, typename _Alloc = allocator<_Tp> >
class list : protected _List_base<_Tp, _Alloc> class list : protected _List_base<_Tp, _Alloc>
{ {
// concept requirements // concept requirements
__glibcpp_class_requires(_Tp, _SGIAssignableConcept) __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
typedef _List_base<_Tp, _Alloc> _Base; typedef _List_base<_Tp, _Alloc> _Base;
protected: protected:
typedef void* _Void_pointer; typedef void* _Void_pointer;
public: public:
typedef _Tp value_type; typedef _Tp value_type;
typedef value_type* pointer; typedef value_type* pointer;
typedef const value_type* const_pointer; typedef const value_type* const_pointer;
...@@ -248,22 +295,21 @@ public: ...@@ -248,22 +295,21 @@ public:
typedef ptrdiff_t difference_type; typedef ptrdiff_t difference_type;
typedef typename _Base::allocator_type allocator_type; typedef typename _Base::allocator_type allocator_type;
allocator_type get_allocator() const { return _Base::get_allocator(); }
public:
typedef _List_iterator<_Tp,_Tp&,_Tp*> iterator; typedef _List_iterator<_Tp,_Tp&,_Tp*> iterator;
typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
typedef reverse_iterator<const_iterator> const_reverse_iterator; typedef reverse_iterator<const_iterator> const_reverse_iterator;
typedef reverse_iterator<iterator> reverse_iterator; typedef reverse_iterator<iterator> reverse_iterator;
protected: protected:
using _Base::_M_node; using _Base::_M_node;
using _Base::_M_put_node; using _Base::_M_put_node;
using _Base::_M_get_node; using _Base::_M_get_node;
protected: protected:
_Node* _M_create_node(const _Tp& __x) _Node*
_M_create_node(const _Tp& __x)
{ {
_Node* __p = _M_get_node(); _Node* __p = _M_get_node();
try { try {
...@@ -277,7 +323,8 @@ protected: ...@@ -277,7 +323,8 @@ protected:
return __p; return __p;
} }
_Node* _M_create_node() _Node*
_M_create_node()
{ {
_Node* __p = _M_get_node(); _Node* __p = _M_get_node();
try { try {
...@@ -291,41 +338,83 @@ protected: ...@@ -291,41 +338,83 @@ protected:
return __p; return __p;
} }
public: public:
explicit list(const allocator_type& __a = allocator_type()) : _Base(__a) {} allocator_type
get_allocator() const
{ return _Base::get_allocator(); }
explicit
list(const allocator_type& __a = allocator_type())
: _Base(__a)
{ }
iterator
begin()
{ return static_cast<_Node*>(_M_node->_M_next); }
iterator begin() { return (_Node*)(_M_node->_M_next); } const_iterator
const_iterator begin() const { return (_Node*)(_M_node->_M_next); } begin() const
{ return static_cast<_Node*>(_M_node->_M_next); }
iterator end() { return _M_node; } iterator
const_iterator end() const { return _M_node; } end()
{ return _M_node; }
reverse_iterator rbegin() const_iterator
end() const
{ return _M_node; }
reverse_iterator
rbegin()
{ return reverse_iterator(end()); } { return reverse_iterator(end()); }
const_reverse_iterator rbegin() const
const_reverse_iterator
rbegin() const
{ return const_reverse_iterator(end()); } { return const_reverse_iterator(end()); }
reverse_iterator rend() reverse_iterator
rend()
{ return reverse_iterator(begin()); } { return reverse_iterator(begin()); }
const_reverse_iterator rend() const
const_reverse_iterator
rend() const
{ return const_reverse_iterator(begin()); } { return const_reverse_iterator(begin()); }
bool empty() const { return _M_node->_M_next == _M_node; } bool
size_type size() const { empty() const
size_type __result = 0; { return _M_node->_M_next == _M_node; }
distance(begin(), end(), __result);
return __result; size_type
} size() const
size_type max_size() const { return size_type(-1); } { return distance(begin(), end()); }
reference front() { return *begin(); } size_type
const_reference front() const { return *begin(); } max_size() const
reference back() { return *(--end()); } { return size_type(-1); }
const_reference back() const { return *(--end()); }
void swap(list<_Tp, _Alloc>& __x) { std::swap(_M_node, __x._M_node); } reference
front()
{ return *begin(); }
iterator insert(iterator __position, const _Tp& __x) { const_reference
front() const
{ return *begin(); }
reference
back()
{ return *(--end()); }
const_reference
back() const
{ return *(--end()); }
void
swap(list<_Tp, _Alloc>& __x)
{ std::swap(_M_node, __x._M_node); }
iterator
insert(iterator __position, const _Tp& __x)
{
_Node* __tmp = _M_create_node(__x); _Node* __tmp = _M_create_node(__x);
__tmp->_M_next = __position._M_node; __tmp->_M_next = __position._M_node;
__tmp->_M_prev = __position._M_node->_M_prev; __tmp->_M_prev = __position._M_node->_M_prev;
...@@ -333,105 +422,155 @@ public: ...@@ -333,105 +422,155 @@ public:
__position._M_node->_M_prev = __tmp; __position._M_node->_M_prev = __tmp;
return __tmp; return __tmp;
} }
iterator insert(iterator __position) { return insert(__position, _Tp()); }
// Check whether it's an integral type. If so, it's not an iterator. iterator
template<class _Integer> insert(iterator __position)
void _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, { return insert(__position, _Tp()); }
__true_type) {
_M_fill_insert(__pos, (size_type) __n, (_Tp) __x);
}
template <class _InputIterator> // Check whether it's an integral type. If so, it's not an iterator.
void _M_insert_dispatch(iterator __pos, template<typename _Integer>
void
_M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, __true_type)
{ _M_fill_insert(__pos, (size_type) __n, (_Tp) __x); }
template<typename _InputIterator>
void
_M_insert_dispatch(iterator __pos,
_InputIterator __first, _InputIterator __last, _InputIterator __first, _InputIterator __last,
__false_type); __false_type);
template <class _InputIterator> template<typename _InputIterator>
void insert(iterator __pos, _InputIterator __first, _InputIterator __last) { void
insert(iterator __pos, _InputIterator __first, _InputIterator __last)
{
typedef typename _Is_integer<_InputIterator>::_Integral _Integral; typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
_M_insert_dispatch(__pos, __first, __last, _Integral()); _M_insert_dispatch(__pos, __first, __last, _Integral());
} }
void insert(iterator __pos, size_type __n, const _Tp& __x) void
insert(iterator __pos, size_type __n, const _Tp& __x)
{ _M_fill_insert(__pos, __n, __x); } { _M_fill_insert(__pos, __n, __x); }
void _M_fill_insert(iterator __pos, size_type __n, const _Tp& __x);
void push_front(const _Tp& __x) { insert(begin(), __x); } void
void push_front() {insert(begin());} _M_fill_insert(iterator __pos, size_type __n, const _Tp& __x);
void push_back(const _Tp& __x) { insert(end(), __x); }
void push_back() {insert(end());} void
push_front(const _Tp& __x)
{ insert(begin(), __x); }
iterator erase(iterator __position) { void
push_front()
{ insert(begin()); }
void
push_back(const _Tp& __x)
{ insert(end(), __x); }
void
push_back()
{ insert(end()); }
iterator
erase(iterator __position)
{
_List_node_base* __next_node = __position._M_node->_M_next; _List_node_base* __next_node = __position._M_node->_M_next;
_List_node_base* __prev_node = __position._M_node->_M_prev; _List_node_base* __prev_node = __position._M_node->_M_prev;
_Node* __n = (_Node*) __position._M_node; _Node* __n = static_cast<_Node*>(__position._M_node);
__prev_node->_M_next = __next_node; __prev_node->_M_next = __next_node;
__next_node->_M_prev = __prev_node; __next_node->_M_prev = __prev_node;
_Destroy(&__n->_M_data); _Destroy(&__n->_M_data);
_M_put_node(__n); _M_put_node(__n);
return iterator((_Node*) __next_node); return iterator(static_cast<_Node*>(__next_node));
} }
iterator erase(iterator __first, iterator __last);
void clear() { _Base::clear(); }
void resize(size_type __new_size, const _Tp& __x); iterator
void resize(size_type __new_size) { this->resize(__new_size, _Tp()); } erase(iterator __first, iterator __last);
void
clear()
{ _Base::clear(); }
void pop_front() { erase(begin()); } void
void pop_back() { resize(size_type __new_size, const _Tp& __x);
void
resize(size_type __new_size)
{ this->resize(__new_size, _Tp()); }
void
pop_front()
{ erase(begin()); }
void
pop_back()
{
iterator __tmp = end(); iterator __tmp = end();
erase(--__tmp); erase(--__tmp);
} }
list(size_type __n, const _Tp& __value, list(size_type __n, const _Tp& __value,
const allocator_type& __a = allocator_type()) const allocator_type& __a = allocator_type())
: _Base(__a) : _Base(__a)
{ insert(begin(), __n, __value); } { insert(begin(), __n, __value); }
explicit list(size_type __n)
explicit
list(size_type __n)
: _Base(allocator_type()) : _Base(allocator_type())
{ insert(begin(), __n, _Tp()); } { insert(begin(), __n, _Tp()); }
// We don't need any dispatching tricks here, because insert does all of // We don't need any dispatching tricks here, because insert does all of
// that anyway. // that anyway.
template <class _InputIterator> template<typename _InputIterator>
list(_InputIterator __first, _InputIterator __last, list(_InputIterator __first, _InputIterator __last,
const allocator_type& __a = allocator_type()) const allocator_type& __a = allocator_type())
: _Base(__a) : _Base(__a)
{ insert(begin(), __first, __last); } { insert(begin(), __first, __last); }
list(const list<_Tp, _Alloc>& __x) : _Base(__x.get_allocator()) list(const list<_Tp, _Alloc>& __x)
: _Base(__x.get_allocator())
{ insert(begin(), __x.begin(), __x.end()); } { insert(begin(), __x.begin(), __x.end()); }
~list() { } ~list()
{ }
list<_Tp, _Alloc>& operator=(const list<_Tp, _Alloc>& __x); list<_Tp, _Alloc>&
operator=(const list<_Tp, _Alloc>& __x);
public: public:
// assign(), a generalized assignment member function. Two // assign(), a generalized assignment member function. Two
// versions: one that takes a count, and one that takes a range. // versions: one that takes a count, and one that takes a range.
// The range version is a member template, so we dispatch on whether // The range version is a member template, so we dispatch on whether
// or not the type is an integer. // or not the type is an integer.
void assign(size_type __n, const _Tp& __val) { _M_fill_assign(__n, __val); } void
assign(size_type __n, const _Tp& __val)
{ _M_fill_assign(__n, __val); }
void _M_fill_assign(size_type __n, const _Tp& __val); void
_M_fill_assign(size_type __n, const _Tp& __val);
template <class _InputIterator> template<typename _InputIterator>
void assign(_InputIterator __first, _InputIterator __last) { void
assign(_InputIterator __first, _InputIterator __last)
{
typedef typename _Is_integer<_InputIterator>::_Integral _Integral; typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
_M_assign_dispatch(__first, __last, _Integral()); _M_assign_dispatch(__first, __last, _Integral());
} }
template <class _Integer> template<typename _Integer>
void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) void
_M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
{ _M_fill_assign((size_type) __n, (_Tp) __val); } { _M_fill_assign((size_type) __n, (_Tp) __val); }
template <class _InputIterator> template<typename _InputIterator>
void _M_assign_dispatch(_InputIterator __first, _InputIterator __last, void
_M_assign_dispatch(_InputIterator __first, _InputIterator __last,
__false_type); __false_type);
protected: protected:
void transfer(iterator __position, iterator __first, iterator __last) { void
_M_transfer(iterator __position, iterator __first, iterator __last)
{
if (__position != __last) { if (__position != __last) {
// Remove [first, last) from its old position. // Remove [first, last) from its old position.
__last._M_node->_M_prev->_M_next = __position._M_node; __last._M_node->_M_prev->_M_next = __position._M_node;
...@@ -446,37 +585,66 @@ protected: ...@@ -446,37 +585,66 @@ protected:
} }
} }
public: public:
void splice(iterator __position, list& __x) { void
splice(iterator __position, list& __x)
{
if (!__x.empty()) if (!__x.empty())
this->transfer(__position, __x.begin(), __x.end()); this->_M_transfer(__position, __x.begin(), __x.end());
} }
void splice(iterator __position, list&, iterator __i) {
void
splice(iterator __position, list&, iterator __i)
{
iterator __j = __i; iterator __j = __i;
++__j; ++__j;
if (__position == __i || __position == __j) return; if (__position == __i || __position == __j) return;
this->transfer(__position, __i, __j); this->_M_transfer(__position, __i, __j);
} }
void splice(iterator __position, list&, iterator __first, iterator __last) {
void
splice(iterator __position, list&, iterator __first, iterator __last)
{
if (__first != __last) if (__first != __last)
this->transfer(__position, __first, __last); this->_M_transfer(__position, __first, __last);
} }
void remove(const _Tp& __value);
void unique(); void
void merge(list& __x); remove(const _Tp& __value);
void reverse();
void sort(); void
unique();
template <class _Predicate> void remove_if(_Predicate);
template <class _BinaryPredicate> void unique(_BinaryPredicate); void
template <class _StrictWeakOrdering> void merge(list&, _StrictWeakOrdering); merge(list& __x);
template <class _StrictWeakOrdering> void sort(_StrictWeakOrdering);
}; void
reverse();
template <class _Tp, class _Alloc>
inline bool void
operator==(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) sort();
{
template<typename _Predicate>
void
remove_if(_Predicate);
template<typename _BinaryPredicate>
void
unique(_BinaryPredicate);
template<typename _StrictWeakOrdering>
void
merge(list&, _StrictWeakOrdering);
template<typename _StrictWeakOrdering>
void
sort(_StrictWeakOrdering);
};
template<typename _Tp, typename _Alloc>
inline bool
operator==(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
{
typedef typename list<_Tp,_Alloc>::const_iterator const_iterator; typedef typename list<_Tp,_Alloc>::const_iterator const_iterator;
const_iterator __end1 = __x.end(); const_iterator __end1 = __x.end();
const_iterator __end2 = __y.end(); const_iterator __end2 = __y.end();
...@@ -488,78 +656,90 @@ operator==(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) ...@@ -488,78 +656,90 @@ operator==(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
++__i2; ++__i2;
} }
return __i1 == __end1 && __i2 == __end2; return __i1 == __end1 && __i2 == __end2;
} }
template <class _Tp, class _Alloc> template<typename _Tp, typename _Alloc>
inline bool operator<(const list<_Tp,_Alloc>& __x, inline bool
const list<_Tp,_Alloc>& __y) operator<(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
{ {
return lexicographical_compare(__x.begin(), __x.end(), return lexicographical_compare(__x.begin(), __x.end(),
__y.begin(), __y.end()); __y.begin(), __y.end());
} }
template <class _Tp, class _Alloc> template<typename _Tp, typename _Alloc>
inline bool operator!=(const list<_Tp,_Alloc>& __x, inline bool
const list<_Tp,_Alloc>& __y) { operator!=(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
return !(__x == __y); { return !(__x == __y); }
}
template<typename _Tp, typename _Alloc>
template <class _Tp, class _Alloc> inline bool
inline bool operator>(const list<_Tp,_Alloc>& __x, operator>(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
const list<_Tp,_Alloc>& __y) { { return __y < __x; }
return __y < __x;
} template<typename _Tp, typename _Alloc>
inline bool
template <class _Tp, class _Alloc> operator<=(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
inline bool operator<=(const list<_Tp,_Alloc>& __x, { return !(__y < __x); }
const list<_Tp,_Alloc>& __y) {
return !(__y < __x); template<typename _Tp, typename _Alloc>
} inline bool
operator>=(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y)
template <class _Tp, class _Alloc> { return !(__x < __y); }
inline bool operator>=(const list<_Tp,_Alloc>& __x,
const list<_Tp,_Alloc>& __y) { template<typename _Tp, typename _Alloc>
return !(__x < __y); inline void
} swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)
{ __x.swap(__y); }
template <class _Tp, class _Alloc>
inline void
swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y)
{
__x.swap(__y);
}
template <class _Tp, class _Alloc> template <class _InputIter> // move these to stl_list.tcc
void
list<_Tp, _Alloc>::_M_insert_dispatch(iterator __position, template<typename _Tp, typename _Alloc>
_InputIter __first, _InputIter __last, void _List_base<_Tp,_Alloc>::
clear()
{
_List_node<_Tp>* __cur = static_cast<_List_node<_Tp>*>(_M_node->_M_next);
while (__cur != _M_node) {
_List_node<_Tp>* __tmp = __cur;
__cur = static_cast<_List_node<_Tp>*>(__cur->_M_next);
_Destroy(&__tmp->_M_data);
_M_put_node(__tmp);
}
_M_node->_M_next = _M_node;
_M_node->_M_prev = _M_node;
}
template<typename _Tp, typename _Alloc>
template <typename _InputIter>
void list<_Tp, _Alloc>::
_M_insert_dispatch(iterator __position, _InputIter __first, _InputIter __last,
__false_type) __false_type)
{ {
for ( ; __first != __last; ++__first) for ( ; __first != __last; ++__first)
insert(__position, *__first); insert(__position, *__first);
}
template <class _Tp, class _Alloc> }
void
list<_Tp, _Alloc>::_M_fill_insert(iterator __position, template<typename _Tp, typename _Alloc>
size_type __n, const _Tp& __x) void list<_Tp, _Alloc>::
{ _M_fill_insert(iterator __position, size_type __n, const _Tp& __x)
{
for ( ; __n > 0; --__n) for ( ; __n > 0; --__n)
insert(__position, __x); insert(__position, __x);
} }
template <class _Tp, class _Alloc> template<typename _Tp, typename _Alloc>
typename list<_Tp,_Alloc>::iterator list<_Tp, _Alloc>::erase(iterator __first, typename list<_Tp,_Alloc>::iterator list<_Tp, _Alloc>::
iterator __last) erase(iterator __first, iterator __last)
{ {
while (__first != __last) while (__first != __last)
erase(__first++); erase(__first++);
return __last; return __last;
} }
template <class _Tp, class _Alloc> template<typename _Tp, typename _Alloc>
void list<_Tp, _Alloc>::resize(size_type __new_size, const _Tp& __x) void list<_Tp, _Alloc>::
{ resize(size_type __new_size, const _Tp& __x)
{
iterator __i = begin(); iterator __i = begin();
size_type __len = 0; size_type __len = 0;
for ( ; __i != end() && __len < __new_size; ++__i, ++__len) for ( ; __i != end() && __len < __new_size; ++__i, ++__len)
...@@ -568,11 +748,12 @@ void list<_Tp, _Alloc>::resize(size_type __new_size, const _Tp& __x) ...@@ -568,11 +748,12 @@ void list<_Tp, _Alloc>::resize(size_type __new_size, const _Tp& __x)
erase(__i, end()); erase(__i, end());
else // __i == end() else // __i == end()
insert(end(), __new_size - __len, __x); insert(end(), __new_size - __len, __x);
} }
template <class _Tp, class _Alloc> template<typename _Tp, typename _Alloc>
list<_Tp, _Alloc>& list<_Tp, _Alloc>::operator=(const list<_Tp, _Alloc>& __x) list<_Tp, _Alloc>& list<_Tp, _Alloc>::
{ operator=(const list<_Tp, _Alloc>& __x)
{
if (this != &__x) { if (this != &__x) {
iterator __first1 = begin(); iterator __first1 = begin();
iterator __last1 = end(); iterator __last1 = end();
...@@ -586,10 +767,11 @@ list<_Tp, _Alloc>& list<_Tp, _Alloc>::operator=(const list<_Tp, _Alloc>& __x) ...@@ -586,10 +767,11 @@ list<_Tp, _Alloc>& list<_Tp, _Alloc>::operator=(const list<_Tp, _Alloc>& __x)
insert(__last1, __first2, __last2); insert(__last1, __first2, __last2);
} }
return *this; return *this;
} }
template <class _Tp, class _Alloc> template<typename _Tp, typename _Alloc>
void list<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val) { void list<_Tp, _Alloc>::
_M_fill_assign(size_type __n, const _Tp& __val) {
iterator __i = begin(); iterator __i = begin();
for ( ; __i != end() && __n > 0; ++__i, --__n) for ( ; __i != end() && __n > 0; ++__i, --__n)
*__i = __val; *__i = __val;
...@@ -597,13 +779,13 @@ void list<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val) { ...@@ -597,13 +779,13 @@ void list<_Tp, _Alloc>::_M_fill_assign(size_type __n, const _Tp& __val) {
insert(end(), __n, __val); insert(end(), __n, __val);
else else
erase(__i, end()); erase(__i, end());
} }
template <class _Tp, class _Alloc> template <class _InputIter> template<typename _Tp, typename _Alloc>
void template <typename _InputIter>
list<_Tp, _Alloc>::_M_assign_dispatch(_InputIter __first2, _InputIter __last2, void list<_Tp, _Alloc>::
__false_type) _M_assign_dispatch(_InputIter __first2, _InputIter __last2, __false_type)
{ {
iterator __first1 = begin(); iterator __first1 = begin();
iterator __last1 = end(); iterator __last1 = end();
for ( ; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2) for ( ; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2)
...@@ -612,11 +794,12 @@ list<_Tp, _Alloc>::_M_assign_dispatch(_InputIter __first2, _InputIter __last2, ...@@ -612,11 +794,12 @@ list<_Tp, _Alloc>::_M_assign_dispatch(_InputIter __first2, _InputIter __last2,
erase(__first1, __last1); erase(__first1, __last1);
else else
insert(__last1, __first2, __last2); insert(__last1, __first2, __last2);
} }
template <class _Tp, class _Alloc> template<typename _Tp, typename _Alloc>
void list<_Tp, _Alloc>::remove(const _Tp& __value) void list<_Tp, _Alloc>::
{ remove(const _Tp& __value)
{
iterator __first = begin(); iterator __first = begin();
iterator __last = end(); iterator __last = end();
while (__first != __last) { while (__first != __last) {
...@@ -625,11 +808,12 @@ void list<_Tp, _Alloc>::remove(const _Tp& __value) ...@@ -625,11 +808,12 @@ void list<_Tp, _Alloc>::remove(const _Tp& __value)
if (*__first == __value) erase(__first); if (*__first == __value) erase(__first);
__first = __next; __first = __next;
} }
} }
template <class _Tp, class _Alloc> template<typename _Tp, typename _Alloc>
void list<_Tp, _Alloc>::unique() void list<_Tp, _Alloc>::
{ unique()
{
iterator __first = begin(); iterator __first = begin();
iterator __last = end(); iterator __last = end();
if (__first == __last) return; if (__first == __last) return;
...@@ -641,11 +825,12 @@ void list<_Tp, _Alloc>::unique() ...@@ -641,11 +825,12 @@ void list<_Tp, _Alloc>::unique()
__first = __next; __first = __next;
__next = __first; __next = __first;
} }
} }
template <class _Tp, class _Alloc> template<typename _Tp, typename _Alloc>
void list<_Tp, _Alloc>::merge(list<_Tp, _Alloc>& __x) void list<_Tp, _Alloc>::
{ merge(list<_Tp, _Alloc>& __x)
{
iterator __first1 = begin(); iterator __first1 = begin();
iterator __last1 = end(); iterator __last1 = end();
iterator __first2 = __x.begin(); iterator __first2 = __x.begin();
...@@ -653,32 +838,33 @@ void list<_Tp, _Alloc>::merge(list<_Tp, _Alloc>& __x) ...@@ -653,32 +838,33 @@ void list<_Tp, _Alloc>::merge(list<_Tp, _Alloc>& __x)
while (__first1 != __last1 && __first2 != __last2) while (__first1 != __last1 && __first2 != __last2)
if (*__first2 < *__first1) { if (*__first2 < *__first1) {
iterator __next = __first2; iterator __next = __first2;
transfer(__first1, __first2, ++__next); _M_transfer(__first1, __first2, ++__next);
__first2 = __next; __first2 = __next;
} }
else else
++__first1; ++__first1;
if (__first2 != __last2) transfer(__last1, __first2, __last2); if (__first2 != __last2) _M_transfer(__last1, __first2, __last2);
} }
inline void __List_base_reverse(_List_node_base* __p) inline void
{ __List_base_reverse(_List_node_base* __p)
{
_List_node_base* __tmp = __p; _List_node_base* __tmp = __p;
do { do {
std::swap(__tmp->_M_next, __tmp->_M_prev); std::swap(__tmp->_M_next, __tmp->_M_prev);
__tmp = __tmp->_M_prev; // Old next node is now prev. __tmp = __tmp->_M_prev; // Old next node is now prev.
} while (__tmp != __p); } while (__tmp != __p);
} }
template <class _Tp, class _Alloc> template<typename _Tp, typename _Alloc>
inline void list<_Tp, _Alloc>::reverse() inline void list<_Tp, _Alloc>::
{ reverse()
__List_base_reverse(this->_M_node); { __List_base_reverse(this->_M_node); }
}
template <class _Tp, class _Alloc> template<typename _Tp, typename _Alloc>
void list<_Tp, _Alloc>::sort() void list<_Tp, _Alloc>::
{ sort()
{
// Do nothing if the list has length 0 or 1. // Do nothing if the list has length 0 or 1.
if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node) { if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node) {
list<_Tp, _Alloc> __carry; list<_Tp, _Alloc> __carry;
...@@ -699,11 +885,13 @@ void list<_Tp, _Alloc>::sort() ...@@ -699,11 +885,13 @@ void list<_Tp, _Alloc>::sort()
__counter[__i].merge(__counter[__i-1]); __counter[__i].merge(__counter[__i-1]);
swap(__counter[__fill-1]); swap(__counter[__fill-1]);
} }
} }
template <class _Tp, class _Alloc> template <class _Predicate> template<typename _Tp, typename _Alloc>
void list<_Tp, _Alloc>::remove_if(_Predicate __pred) template <typename _Predicate>
{ void list<_Tp, _Alloc>::
remove_if(_Predicate __pred)
{
iterator __first = begin(); iterator __first = begin();
iterator __last = end(); iterator __last = end();
while (__first != __last) { while (__first != __last) {
...@@ -712,11 +900,13 @@ void list<_Tp, _Alloc>::remove_if(_Predicate __pred) ...@@ -712,11 +900,13 @@ void list<_Tp, _Alloc>::remove_if(_Predicate __pred)
if (__pred(*__first)) erase(__first); if (__pred(*__first)) erase(__first);
__first = __next; __first = __next;
} }
} }
template <class _Tp, class _Alloc> template <class _BinaryPredicate> template<typename _Tp, typename _Alloc>
void list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred) template <typename _BinaryPredicate>
{ void list<_Tp, _Alloc>::
unique(_BinaryPredicate __binary_pred)
{
iterator __first = begin(); iterator __first = begin();
iterator __last = end(); iterator __last = end();
if (__first == __last) return; if (__first == __last) return;
...@@ -728,12 +918,13 @@ void list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred) ...@@ -728,12 +918,13 @@ void list<_Tp, _Alloc>::unique(_BinaryPredicate __binary_pred)
__first = __next; __first = __next;
__next = __first; __next = __first;
} }
} }
template <class _Tp, class _Alloc> template <class _StrictWeakOrdering> template<typename _Tp, typename _Alloc>
void list<_Tp, _Alloc>::merge(list<_Tp, _Alloc>& __x, template <typename _StrictWeakOrdering>
_StrictWeakOrdering __comp) void list<_Tp, _Alloc>::
{ merge(list<_Tp, _Alloc>& __x, _StrictWeakOrdering __comp)
{
iterator __first1 = begin(); iterator __first1 = begin();
iterator __last1 = end(); iterator __last1 = end();
iterator __first2 = __x.begin(); iterator __first2 = __x.begin();
...@@ -741,17 +932,19 @@ void list<_Tp, _Alloc>::merge(list<_Tp, _Alloc>& __x, ...@@ -741,17 +932,19 @@ void list<_Tp, _Alloc>::merge(list<_Tp, _Alloc>& __x,
while (__first1 != __last1 && __first2 != __last2) while (__first1 != __last1 && __first2 != __last2)
if (__comp(*__first2, *__first1)) { if (__comp(*__first2, *__first1)) {
iterator __next = __first2; iterator __next = __first2;
transfer(__first1, __first2, ++__next); _M_transfer(__first1, __first2, ++__next);
__first2 = __next; __first2 = __next;
} }
else else
++__first1; ++__first1;
if (__first2 != __last2) transfer(__last1, __first2, __last2); if (__first2 != __last2) _M_transfer(__last1, __first2, __last2);
} }
template <class _Tp, class _Alloc> template <class _StrictWeakOrdering> template<typename _Tp, typename _Alloc>
void list<_Tp, _Alloc>::sort(_StrictWeakOrdering __comp) template <typename _StrictWeakOrdering>
{ void list<_Tp, _Alloc>::
sort(_StrictWeakOrdering __comp)
{
// Do nothing if the list has length 0 or 1. // Do nothing if the list has length 0 or 1.
if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node) { if (_M_node->_M_next != _M_node && _M_node->_M_next->_M_next != _M_node) {
list<_Tp, _Alloc> __carry; list<_Tp, _Alloc> __carry;
...@@ -772,12 +965,13 @@ void list<_Tp, _Alloc>::sort(_StrictWeakOrdering __comp) ...@@ -772,12 +965,13 @@ void list<_Tp, _Alloc>::sort(_StrictWeakOrdering __comp)
__counter[__i].merge(__counter[__i-1], __comp); __counter[__i].merge(__counter[__i-1], __comp);
swap(__counter[__fill-1]); swap(__counter[__fill-1]);
} }
} }
} // namespace std } // namespace std
#endif /* __SGI_STL_INTERNAL_LIST_H */ #endif /* __SGI_STL_INTERNAL_LIST_H */
// vi:set ts=2 sw=2:
// Local Variables: // Local Variables:
// mode:C++ // mode:C++
// End: // End:
// Copyright (C) 2001 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 Pred 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.
// 23.2.2.2 list capacity [lib.list.capacity]
#include <list>
#include <testsuite_hooks.h>
bool test = true;
// This test verifies the following.
//
// 23.2.2 bool empty() const
// 23.2.2 size_type size() const
// 23.2.2 iterator begin()
// 23.2.2 iterator end()
// 23.2.2.3 void push_back(const T&)
// 23.2.2 size_type max_size() const
// 23.2.2.2 void resize(size_type s, T c = T())
//
void
test01()
{
std::list<int> list0101;
VERIFY(list0101.empty());
VERIFY(list0101.size() == 0);
list0101.push_back(1);
VERIFY(!list0101.empty());
VERIFY(list0101.size() == 1);
list0101.resize(3, 2);
VERIFY(!list0101.empty());
VERIFY(list0101.size() == 3);
std::list<int>::iterator i = list0101.begin();
VERIFY(*i == 1); ++i;
VERIFY(*i == 2); ++i;
VERIFY(*i == 2); ++i;
VERIFY(i == list0101.end());
list0101.resize(0);
VERIFY(list0101.empty());
VERIFY(list0101.size() == 0);
}
int
main(int argc, char* argv[])
{
test01();
return !test;
}
// vi:set sw=2 ts=2:
// Copyright (C) 2001 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.
// 23.2.2.1 list constructors, copy, and assignment
#include <list>
#include <testsuite_hooks.h>
bool test = true;
// A nontrivial type.
template<typename T>
struct A { };
// Another nontrivial type
struct B { };
// A nontrivial type convertible from an int
struct C {
C(int i) : i_(i) { }
bool operator==(const C& rhs) { return i_ == rhs.i_; }
int i_;
};
// Default constructor, basic properties
//
// This test verifies the following.
// 23.2.2.1 explicit list(const a& = Allocator())
// 23.1 (7) iterator behaviour of empty containers
// 23.2.2 iterator begin()
// 23.2.2 iterator end()
// 23.2.2 size_type size() const
// 23.2.2 existence of required typedefs
//
void
test01()
{
std::list< A<B> > list0101;
VERIFY(list0101.begin() == list0101.end());
VERIFY(list0101.size() == 0);
// check type definitions -- will fail compile if missing
typedef std::list< A<B> >::reference reference;
typedef std::list< A<B> >::const_reference const_reference;
typedef std::list< A<B> >::iterator iterator;
typedef std::list< A<B> >::const_iterator const_iterator;
typedef std::list< A<B> >::size_type size_type;
typedef std::list< A<B> >::difference_type difference_type;
typedef std::list< A<B> >::value_type value_type;
typedef std::list< A<B> >::allocator_type allocator_type;
typedef std::list< A<B> >::pointer pointer;
typedef std::list< A<B> >::const_pointer const_pointer;
typedef std::list< A<B> >::reverse_iterator reverse_iterator;
typedef std::list< A<B> >::const_reverse_iterator const_reverse_iterator;
// allocator checks?
}
// Fill constructor
//
// This test verifies the following.
// 23.2.2.1 explicit list(size_type n, const T& v = T(), const a& = Allocator())
// 23.2.2 const_iterator begin() const
// 23.2.2 const_iterator end() const
// 23.2.2 size_type size() const
//
void
test02()
{
const int LIST_SIZE = 5;
const int INIT_VALUE = 7;
int count;
std::list<int>::const_iterator i;
// nontrivial value_type
std::list< A<B> > list0201(LIST_SIZE);
// default value
std::list<int> list0202(LIST_SIZE);
for (i = list0202.begin(), count = 0;
i != list0202.end();
++i, ++count)
VERIFY(*i == 0);
VERIFY(count == LIST_SIZE);
VERIFY(list0202.size() == LIST_SIZE);
// explicit value
std::list<int> list0203(LIST_SIZE, INIT_VALUE);
for (i = list0203.begin(), count = 0;
i != list0203.end();
++i, ++count)
VERIFY(*i == INIT_VALUE);
VERIFY(count == LIST_SIZE);
VERIFY(list0203.size() == LIST_SIZE);
}
// Fill constructor disguised as a range constructor
void
test02D()
{
const int LIST_SIZE = 5;
const int INIT_VALUE = 7;
int count = 0;
std::list<C> list0204(LIST_SIZE, INIT_VALUE);
std::list<C>::iterator i = list0204.begin();
for (; i != list0204.end(); ++i, ++count)
VERIFY(*i == INIT_VALUE);
VERIFY(count == LIST_SIZE);
VERIFY(list0204.size() == LIST_SIZE);
}
// Range constructor
//
// This test verifies the following.
// 23.2.2.1 template list(InputIterator f, InputIterator l, const Allocator& a = Allocator())
// 23.2.2 const_iterator begin() const
// 23.2.2 const_iterator end() const
// 23.2.2 size_type size() const
//
void
test03()
{
const int A[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};
const int N = sizeof(A) / sizeof(int);
int count;
std::list<int>::const_iterator i;
// construct from a dissimilar range
std::list<int> list0301(A, A + N);
for (i = list0301.begin(), count = 0;
i != list0301.end();
++i, ++count)
VERIFY(*i == A[count]);
VERIFY(count == N);
VERIFY(list0301.size() == N);
// construct from a similar range
std::list<int> list0302(list0301.begin(), list0301.end());
for (i = list0302.begin(), count = 0;
i != list0302.end();
++i, ++count)
VERIFY(*i == A[count]);
VERIFY(count == N);
VERIFY(list0302.size() == N);
}
// Copy constructor
//
// This test verifies the following.
// 23.2.2.1 list(const list& x)
// 23.2.2 reverse_iterator rbegin()
// 23.2.2 reverse_iterator rend()
// 23.2.2 size_type size() const
//
void
test04()
{
const int A[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};
const int N = sizeof(A) / sizeof(int);
int count;
std::list<int>::reverse_iterator i;
std::list<int> list0401(A, A + N);
std::list<int> list0402(list0401);
for (i = list0401.rbegin(), count = N - 1;
i != list0401.rend();
++i, --count)
VERIFY(*i == A[count]);
VERIFY(count == -1);
VERIFY(list0401.size() == N);
}
// Range assign
//
// This test verifies the following.
// 23.2.2.1 void assign(InputIterator f, InputIterator l)
// 23.2.2 const_iterator begin() const
// 23.2.2 const_iterator end() const
// 23.2.2 size_type size() const
//
void
test05()
{
const int A[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};
const int B[] = {101, 102, 103, 104, 105};
const int N = sizeof(A) / sizeof(int);
const int M = sizeof(B) / sizeof(int);
int count;
std::list<int>::const_iterator i;
std::list<int> list0501;
// make it bigger
list0501.assign(A, A + N);
for (i = list0501.begin(), count = 0;
i != list0501.end();
++i, ++count)
VERIFY(*i == A[count]);
VERIFY(count == N);
VERIFY(list0501.size() == N);
// make it smaller
list0501.assign(B, B + M);
for (i = list0501.begin(), count = 0;
i != list0501.end();
++i, ++count)
VERIFY(*i == B[count]);
VERIFY(count == M);
VERIFY(list0501.size() == M);
}
// Fill assign
//
// This test verifies the following.
// 23.2.2.1 void assign(size_type n, const T& v)
// 23.2.2 const_iterator begin() const
// 23.2.2 const_iterator end() const
// 23.2.2 size_type size() const
//
void
test06()
{
const int BIG_LIST_SIZE = 11;
const int BIG_INIT_VALUE = 7;
const int SMALL_LIST_SIZE = 5;
const int SMALL_INIT_VALUE = 17;
int count;
std::list<int>::const_iterator i;
std::list<int> list0601;
VERIFY(list0601.size() == 0);
// make it bigger
list0601.assign(BIG_LIST_SIZE, BIG_INIT_VALUE);
for (i = list0601.begin(), count = 0;
i != list0601.end();
++i, ++count)
VERIFY(*i == BIG_INIT_VALUE);
VERIFY(count == BIG_LIST_SIZE);
VERIFY(list0601.size() == BIG_LIST_SIZE);
// make it shrink
list0601.assign(SMALL_LIST_SIZE, SMALL_INIT_VALUE);
for (i = list0601.begin(), count = 0;
i != list0601.end();
++i, ++count)
VERIFY(*i == SMALL_INIT_VALUE);
VERIFY(count == SMALL_LIST_SIZE);
VERIFY(list0601.size() == SMALL_LIST_SIZE);
}
// Fill Assignment disguised as a Range Assignment
void
test06D()
{
const int LIST_SIZE = 5;
const int INIT_VALUE = 7;
int count = 0;
std::list<C> list0604;
VERIFY(list0604.size() == 0);
list0604.assign(LIST_SIZE, INIT_VALUE);
std::list<C>::iterator i = list0604.begin();
for (; i != list0604.end(); ++i, ++count)
VERIFY(*i == INIT_VALUE);
VERIFY(count == LIST_SIZE);
VERIFY(list0604.size() == LIST_SIZE);
}
// Assignment operator
//
// This test verifies the following.
// 23.2.2 operator=(const list& x)
// 23.2.2 iterator begin()
// 23.2.2 iterator end()
// 23.2.2 size_type size() const
// 23.2.2 bool operator==(const list& x, const list& y)
//
void
test07()
{
const int A[] = {701, 702, 703, 704, 705};
const int N = sizeof(A) / sizeof(int);
int count;
std::list<int>::iterator i;
std::list<int> list0701(A, A + N);
VERIFY(list0701.size() == N);
std::list<int> list0702;
VERIFY(list0702.size() == 0);
list0702 = list0701;
VERIFY(list0702.size() == N);
for (i = list0702.begin(), count = 0;
i != list0702.end();
++i, ++count)
VERIFY(*i == A[count]);
VERIFY(count == N);
VERIFY(list0702 == list0701);
}
int main()
{
test01();
test02();
test02D();
test03();
test04();
test05();
test06();
test06D();
test07();
return !test;
}
// vi:set sw=2 ts=2:
// Copyright (C) 2001 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 Pred 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.
// 23.2.2.3 list modifiers [lib.list.modifiers]
#include <list>
#include <testsuite_hooks.h>
bool test = true;
// Here's a class with nontrivial ctor/dtor that provides
// the ability to track the number of copy ctors and dtors
// and will throw on demand during copy.
class T
{
public:
// default constructor
T(int anId, bool throwOnDemand = false)
: itsId(anId), willThrow(throwOnDemand)
{ }
// copy constructor
T(const T& rhs)
: itsId(rhs.id()), willThrow(rhs.willThrow)
{
++itsCopyCount;
if (willThrow)
throw "exception";
}
~T()
{ ++itsDtorCount; }
int
id() const
{ return itsId; }
private:
const int itsId;
const bool willThrow;
public:
static void
reset()
{ itsCopyCount = 0; itsDtorCount = 0; }
static int
copyCount()
{ return itsCopyCount; }
static int
dtorCount()
{ return itsDtorCount; }
private:
static int itsCopyCount;
static int itsDtorCount;
};
int T::itsCopyCount = 0;
int T::itsDtorCount = 0;
// This test verifies the following.
//
// 23.2.2.3 void push_front(const T& x)
// 23.2.2.3 void push_back(const T& x)
// 23.2.2.3 (1) iterator and reference non-invalidation
// 23.2.2.3 (1) exception effects
// 23.2.2.3 (2) complexity requirements
//
// 23.2.2.3 void pop_front()
// 23.2.2.3 void pop_back()
// 23.2.2.3 (3) iterator and reference non-invalidation
// 23.2.2.3 (5) complexity requirements
//
// 23.2.2 const_iterator begin() const
// 23.2.2 iterator end()
// 23.2.2 const_reverse_iterator rbegin() const
// 23.2.2 _reference front()
// 23.2.2 const_reference front() const
// 23.2.2 reference back()
// 23.2.2 const_reference back() const
//
void
test01()
{
std::list<T> list0101;
std::list<T>::const_iterator i;
std::list<T>::const_reverse_iterator j;
std::list<T>::iterator k;
T::reset();
list0101.push_back(T(1)); // list should be [1]
VERIFY(list0101.size() == 1);
VERIFY(T::copyCount() == 1);
k = list0101.end();
--k;
VERIFY(k->id() == 1);
VERIFY(k->id() == list0101.front().id());
VERIFY(k->id() == list0101.back().id());
list0101.push_front(T(2)); // list should be [2 1]
VERIFY(list0101.size() == 2);
VERIFY(T::copyCount() == 2);
VERIFY(k->id() == 1);
list0101.push_back(T(3)); // list should be [2 1 3]
VERIFY(list0101.size() == 3);
VERIFY(T::copyCount() == 3);
VERIFY(k->id() == 1);
try
{
list0101.push_back(T(4, true));
VERIFY(("no exception thrown", false));
}
catch (...)
{
VERIFY(list0101.size() == 3);
VERIFY(T::copyCount() == 4);
}
i = list0101.begin();
VERIFY(i->id() == 2);
VERIFY(i->id() == list0101.front().id());
j = list0101.rbegin();
VERIFY(j->id() == 3);
VERIFY(j->id() == list0101.back().id());
++i;
VERIFY(i->id() == 1);
++j;
VERIFY(j->id() == 1);
T::reset();
list0101.pop_back(); // list should be [2 1]
VERIFY(list0101.size() == 2);
VERIFY(T::dtorCount() == 1);
VERIFY(i->id() == 1);
VERIFY(j->id() == 1);
VERIFY(k->id() == 1);
list0101.pop_front(); // list should be [1]
VERIFY(list0101.size() == 1);
VERIFY(T::dtorCount() == 2);
VERIFY(i->id() == 1);
VERIFY(j->id() == 1);
VERIFY(k->id() == 1);
}
// general single insert/erase + swap
void
test02()
{
std::list<T> list0201;
T::reset();
list0201.insert(list0201.begin(), T(1)); // list should be [1]
VERIFY(list0201.size() == 1);
VERIFY(T::copyCount() == 1);
list0201.insert(list0201.end(), T(2)); // list should be [1 2]
VERIFY(list0201.size() == 2);
VERIFY(T::copyCount() == 2);
std::list<T>::iterator i = list0201.begin();
std::list<T>::const_iterator j = i;
VERIFY(i->id() == 1); ++i;
VERIFY(i->id() == 2);
list0201.insert(i, T(3)); // list should be [1 3 2]
VERIFY(list0201.size() == 3);
VERIFY(T::copyCount() == 3);
std::list<T>::const_iterator k = i;
VERIFY(i->id() == 2); --i;
VERIFY(i->id() == 3); --i;
VERIFY(i->id() == 1);
VERIFY(j->id() == 1);
++i; // will point to '3'
T::reset();
list0201.erase(i); // should be [1 2]
VERIFY(list0201.size() == 2);
VERIFY(T::dtorCount() == 1);
VERIFY(k->id() == 2);
VERIFY(j->id() == 1);
std::list<T> list0202;
T::reset();
VERIFY(list0202.size() == 0);
VERIFY(T::copyCount() == 0);
VERIFY(T::dtorCount() == 0);
// member swap
list0202.swap(list0201);
VERIFY(list0201.size() == 0);
VERIFY(list0202.size() == 2);
VERIFY(T::copyCount() == 0);
VERIFY(T::dtorCount() == 0);
// specialized swap
swap(list0201, list0202);
VERIFY(list0201.size() == 2);
VERIFY(list0202.size() == 0);
VERIFY(T::copyCount() == 0);
VERIFY(T::dtorCount() == 0);
}
// range and fill insert/erase + clear
// missing: o fill insert disguised as a range insert in all its variants
// o exception effects
void
test03()
{
std::list<T> list0301;
T::reset();
// fill insert at beginning of list / empty list
list0301.insert(list0301.begin(), 3, T(11)); // should be [11 11 11]
VERIFY(list0301.size() == 3);
VERIFY(T::copyCount() == 3);
// save iterators to verify post-insert validity
std::list<T>::iterator b = list0301.begin();
std::list<T>::iterator m = list0301.end(); --m;
std::list<T>::iterator e = list0301.end();
// fill insert at end of list
T::reset();
list0301.insert(list0301.end(), 3, T(13)); // should be [11 11 11 13 13 13]
VERIFY(list0301.size() == 6);
VERIFY(T::copyCount() == 3);
VERIFY(b == list0301.begin() && b->id() == 11);
VERIFY(e == list0301.end());
VERIFY(m->id() == 11);
// fill insert in the middle of list
++m;
T::reset();
list0301.insert(m, 3, T(12)); // should be [11 11 11 12 12 12 13 13 13]
VERIFY(list0301.size() == 9);
VERIFY(T::copyCount() == 3);
VERIFY(b == list0301.begin() && b->id() == 11);
VERIFY(e == list0301.end());
VERIFY(m->id() == 13);
// single erase
T::reset();
m = list0301.erase(m); // should be [11 11 11 12 12 12 13 13]
VERIFY(list0301.size() == 8);
VERIFY(T::dtorCount() == 1);
VERIFY(b == list0301.begin() && b->id() == 11);
VERIFY(e == list0301.end());
VERIFY(m->id() == 13);
// range erase
T::reset();
m = list0301.erase(list0301.begin(), m); // should be [13 13]
VERIFY(list0301.size() == 2);
VERIFY(T::dtorCount() == 6);
VERIFY(m->id() == 13);
// range fill at beginning
const int A[] = {321, 322, 333};
const int N = sizeof(A) / sizeof(int);
T::reset();
b = list0301.begin();
list0301.insert(b, A, A + N); // should be [321 322 333 13 13]
VERIFY(list0301.size() == 5);
VERIFY(T::copyCount() == 3);
VERIFY(m->id() == 13);
// range fill at end
T::reset();
list0301.insert(e, A, A + N); // should be [321 322 333 13 13 321 322 333]
VERIFY(list0301.size() == 8);
VERIFY(T::copyCount() == 3);
VERIFY(e == list0301.end());
VERIFY(m->id() == 13);
// range fill in middle
T::reset();
list0301.insert(m, A, A + N);
VERIFY(list0301.size() == 11);
VERIFY(T::copyCount() == 3);
VERIFY(e == list0301.end());
VERIFY(m->id() == 13);
T::reset();
list0301.clear();
VERIFY(list0301.size() == 0);
VERIFY(T::dtorCount() == 11);
VERIFY(e == list0301.end());
}
main(int argc, char* argv[])
{
test01();
test02();
test03();
return !test;
}
// vi:set sw=2 ts=2:
// Copyright (C) 2001 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 Pred 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.
// 23.2.2.4 list operations [lib.list.ops]
#include <list>
#include <testsuite_hooks.h>
bool test = true;
// splice(p, x) + remove + reverse
void
test01()
{
const int K = 417;
const int A[] = {1, 2, 3, 4, 5};
const int B[] = {K, K, K, K, K};
const int N = sizeof(A) / sizeof(int);
const int M = sizeof(B) / sizeof(int);
std::list<int> list0101(A, A + N);
std::list<int> list0102(B, B + M);
std::list<int>::iterator p = list0101.begin();
VERIFY(list0101.size() == N);
VERIFY(list0102.size() == M);
++p;
list0101.splice(p, list0102); // [1 K K K K K 2 3 4 5]
VERIFY(list0101.size() == N + M);
VERIFY(list0102.size() == 0);
// remove range from middle
list0101.remove(K);
VERIFY(list0101.size() == N);
// remove first element
list0101.remove(1);
VERIFY(list0101.size() == N - 1);
// remove last element
list0101.remove(5);
VERIFY(list0101.size() == N - 2);
// reverse
list0101.reverse();
p = list0101.begin();
VERIFY(*p == 4); ++p;
VERIFY(*p == 3); ++p;
VERIFY(*p == 2); ++p;
VERIFY(p == list0101.end());
}
// splice(p, x, i) + remove_if + operator==
void
test02()
{
const int A[] = {1, 2, 3, 4, 5};
const int B[] = {2, 1, 3, 4, 5};
const int C[] = {1, 3, 4, 5, 2};
const int N = sizeof(A) / sizeof(int);
std::list<int> list0201(A, A + N);
std::list<int> list0202(A, A + N);
std::list<int> list0203(B, B + N);
std::list<int> list0204(C, C + N);
std::list<int>::iterator i = list0201.begin();
// result should be unchanged
list0201.splice(list0201.begin(), list0201, i);
VERIFY(list0201 == list0202);
// result should be [2 1 3 4 5]
++i;
list0201.splice(list0201.begin(), list0201, i);
VERIFY(list0201 != list0202);
VERIFY(list0201 == list0203);
// result should be [1 3 4 5 2]
list0201.splice(list0201.end(), list0201, i);
VERIFY(list0201 == list0204);
}
// splice(p, x, f, l) + sort + merge + unique
void
test03()
{
const int A[] = {103, 203, 603, 303, 403, 503};
const int B[] = {417, 417, 417, 417, 417};
const int E[] = {103, 417, 417, 203, 603, 303, 403, 503};
const int F[] = {103, 203, 303, 403, 417, 417, 503, 603};
const int C[] = {103, 203, 303, 403, 417, 417, 417, 417, 417, 503, 603};
const int D[] = {103, 203, 303, 403, 417, 503, 603};
const int N = sizeof(A) / sizeof(int);
const int M = sizeof(B) / sizeof(int);
const int P = sizeof(C) / sizeof(int);
const int Q = sizeof(D) / sizeof(int);
const int R = sizeof(E) / sizeof(int);
std::list<int> list0301(A, A + N);
std::list<int> list0302(B, B + M);
std::list<int> list0303(C, C + P);
std::list<int> list0304(D, D + Q);
std::list<int> list0305(E, E + R);
std::list<int> list0306(F, F + R);
std::list<int>::iterator p = list0301.begin();
std::list<int>::iterator q = list0302.begin();
++p; ++q; ++q;
list0301.splice(p, list0302, list0302.begin(), q);
VERIFY(list0301 == list0305);
VERIFY(list0301.size() == N + 2);
VERIFY(list0302.size() == M - 2);
list0301.sort();
VERIFY(list0301 == list0306);
list0301.merge(list0302);
VERIFY(list0301.size() == N + M);
VERIFY(list0302.size() == 0);
VERIFY(list0301 == list0303);
list0301.unique();
VERIFY(list0301 == list0304);
}
// A comparison predicate to order by rightmost digit. Tracks call counts for
// performance checks.
struct CompLastLt
{
bool operator()(const int x, const int y) { ++itsCount; return x % 10 < y % 10; }
static int count() { return itsCount; }
static void reset() { itsCount = 0; }
static int itsCount;
};
int CompLastLt::itsCount;
struct CompLastEq
{
bool operator()(const int x, const int y) { ++itsCount; return x % 10 == y % 10; }
static int count() { return itsCount; }
static void reset() { itsCount = 0; }
static int itsCount;
};
int CompLastEq::itsCount;
// sort(pred) + merge(pred) + unique(pred)
// also checks performance requirements
void
test04()
{
const int A[] = {1, 2, 3, 4, 5, 6};
const int B[] = {12, 15, 13, 14, 11};
const int C[] = {11, 12, 13, 14, 15};
const int D[] = {1, 11, 2, 12, 3, 13, 4, 14, 5, 15, 6};
const int N = sizeof(A) / sizeof(int);
const int M = sizeof(B) / sizeof(int);
const int Q = sizeof(D) / sizeof(int);
std::list<int> list0401(A, A + N);
std::list<int> list0402(B, B + M);
std::list<int> list0403(C, C + M);
std::list<int> list0404(D, D + Q);
std::list<int> list0405(A, A + N);
// sort B
CompLastLt lt;
CompLastLt::reset();
list0402.sort(lt);
VERIFY(list0402 == list0403);
CompLastLt::reset();
list0401.merge(list0402, lt);
VERIFY(list0401 == list0404);
VERIFY(lt.count() <= (N + M - 1));
CompLastEq eq;
CompLastEq::reset();
list0401.unique(eq);
VERIFY(list0401 == list0405);
VERIFY(eq.count() == (N + M - 1));
}
main(int argc, char* argv[])
{
test01();
test02();
test03();
test04();
return !test;
}
// vi:set sw=2 ts=2:
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment