From 4d54539c8fa94d78298746efe4a18e909a440457 Mon Sep 17 00:00:00 2001 From: Benjamin Kosnik Date: Thu, 18 Dec 2003 20:23:04 +0000 Subject: [PATCH] stl_list.h: Formatting tweaks. 2003-12-18 Benjamin Kosnik * include/bits/stl_list.h: Formatting tweaks. * include/bits/list.tcc: Same. From-SVN: r74795 --- libstdc++-v3/ChangeLog | 5 + libstdc++-v3/include/bits/list.tcc | 30 +- libstdc++-v3/include/bits/stl_list.h | 1645 +++++++++++++------------- 3 files changed, 849 insertions(+), 831 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 3d9f85e979d..faba7f1f964 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,8 @@ +2003-12-18 Benjamin Kosnik + + * include/bits/stl_list.h: Formatting tweaks. + * include/bits/list.tcc: Same. + 2003-12-18 Matt Austern * include/bits/demangle.h: Fix allocator type correctness, diff --git a/libstdc++-v3/include/bits/list.tcc b/libstdc++-v3/include/bits/list.tcc index 283b0ac6838..a4f7c18dffa 100644 --- a/libstdc++-v3/include/bits/list.tcc +++ b/libstdc++-v3/include/bits/list.tcc @@ -66,7 +66,7 @@ namespace __gnu_norm template void _List_base<_Tp,_Alloc>:: - __clear() + _M_clear() { typedef _List_node<_Tp> _Node; _Node* __cur = static_cast<_Node*>(this->_M_node._M_next); @@ -92,7 +92,8 @@ namespace __gnu_norm this->_M_node._M_next = __x._M_node._M_next; this->_M_node._M_prev = __x._M_node._M_prev; - this->_M_node._M_next->_M_prev = this->_M_node._M_prev->_M_next = &this->_M_node; + 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; } } @@ -101,7 +102,8 @@ namespace __gnu_norm __x._M_node._M_next = this->_M_node._M_next; __x._M_node._M_prev = this->_M_node._M_prev; - __x._M_node._M_next->_M_prev = __x._M_node._M_prev->_M_next = &__x._M_node; + __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 @@ -109,8 +111,10 @@ namespace __gnu_norm 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_next->_M_prev = this->_M_node._M_prev->_M_next = &this->_M_node; - __x._M_node._M_next->_M_prev = __x._M_node._M_prev->_M_next = &__x._M_node; + 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; } } @@ -196,11 +200,13 @@ namespace __gnu_norm template void list<_Tp,_Alloc>:: - _M_assign_dispatch(_InputIterator __first2, _InputIterator __last2, __false_type) + _M_assign_dispatch(_InputIterator __first2, _InputIterator __last2, + __false_type) { iterator __first1 = begin(); iterator __last1 = end(); - for (; __first1 != __last1 && __first2 != __last2; ++__first1, ++__first2) + for (; __first1 != __last1 && __first2 != __last2; + ++__first1, ++__first2) *__first1 = *__first2; if (__first2 == __last2) erase(__first1, __last1); @@ -276,10 +282,12 @@ namespace __gnu_norm __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); + do + { + std::swap(__tmp->_M_next, __tmp->_M_prev); + __tmp = __tmp->_M_prev; // Old next node is now prev. + } + while (__tmp != __p); } template diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h index 8fd2f71026e..a9513f1656a 100644 --- a/libstdc++-v3/include/bits/stl_list.h +++ b/libstdc++-v3/include/bits/stl_list.h @@ -80,9 +80,9 @@ namespace __gnu_norm /// @if maint An actual node in the %list. @endif template struct _List_node : public _List_node_base - { - _Tp _M_data; ///< User's data. - }; + { + _Tp _M_data; ///< User's data. + }; /** @@ -104,11 +104,9 @@ namespace __gnu_norm _List_node_base* _M_node; _List_iterator_base(_List_node_base* __x) - : _M_node(__x) - { } + : _M_node(__x) { } - _List_iterator_base() - { } + _List_iterator_base() { } /// Walk the %list forward. void @@ -141,127 +139,126 @@ namespace __gnu_norm */ template struct _List_iterator : public _List_iterator_base - { - 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; - - _List_iterator(_Node* __x) - : _List_iterator_base(__x) - { } - - _List_iterator() - { } - - _List_iterator(const iterator& __x) - : _List_iterator_base(__x._M_node) - { } - - reference - operator*() const - { return static_cast<_Node*>(_M_node)->_M_data; } - // Must downcast from List_node_base to _List_node to get to _M_data. - - pointer - operator->() const - { return &(operator*()); } - - _Self& - operator++() { - this->_M_incr(); - return *this; - } + 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; + + _List_iterator(_Node* __x) + : _List_iterator_base(__x) { } - _Self - operator++(int) - { - _Self __tmp = *this; - this->_M_incr(); + _List_iterator() { } + + _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. + reference + operator*() const + { return static_cast<_Node*>(_M_node)->_M_data; } + + pointer + operator->() const + { return &(operator*()); } + + _Self& + operator++() + { + this->_M_incr(); + return *this; + } + + _Self + operator++(int) + { + _Self __tmp = *this; + this->_M_incr(); + return __tmp; + } + + _Self& + operator--() + { + this->_M_decr(); + return *this; + } + + _Self + operator--(int) + { + _Self __tmp = *this; + this->_M_decr(); return __tmp; - } - - _Self& - operator--() - { - this->_M_decr(); - return *this; - } - - _Self - operator--(int) - { - _Self __tmp = *this; - this->_M_decr(); - return __tmp; - } - }; + } + }; /** * @if maint * See bits/stl_deque.h's _Deque_base for an explanation. * @endif */ - template + template class _List_base : public _Alloc::template rebind<_List_node<_Tp> >::other - { - protected: - // NOTA BENE - // The stored instance is not actually of "allocator_type"'s type. - // Instead we rebind the type to Allocator>, which - // according to [20.1.5]/4 should probably be the same. - // List_node is not the same size as Tp (it's two pointers - // larger), and specializations on Tp may go unused because - // List_node is being bound instead. - // - // We put this to the test in the constructors and in get_allocator, - // where we use conversions between allocator_type and - // _Node_Alloc_type. The conversion is required by table 32 in [20.1.5]. - typedef typename _Alloc::template rebind<_List_node<_Tp> >::other + { + protected: + // NOTA BENE + // The stored instance is not actually of "allocator_type"'s + // type. Instead we rebind the type to + // Allocator>, which according to [20.1.5]/4 + // should probably be the same. List_node is not the same + // size as Tp (it's two pointers larger), and specializations on + // Tp may go unused because List_node is being bound + // instead. + // + // We put this to the test in the constructors and in + // get_allocator, where we use conversions between + // allocator_type and _Node_Alloc_type. The conversion is + // required by table 32 in [20.1.5]. + typedef typename _Alloc::template rebind<_List_node<_Tp> >::other _Node_Alloc_type; - _List_node<_Tp>* - _M_get_node() - { return _Node_Alloc_type::allocate(1); } + _List_node_base _M_node; - void - _M_put_node(_List_node<_Tp>* __p) - { _Node_Alloc_type::deallocate(__p, 1); } + _List_node<_Tp>* + _M_get_node() + { return _Node_Alloc_type::allocate(1); } + + void + _M_put_node(_List_node<_Tp>* __p) + { _Node_Alloc_type::deallocate(__p, 1); } - _List_node_base _M_node; public: - typedef _Alloc allocator_type; - allocator_type get_allocator() const + typedef _Alloc allocator_type; - { return allocator_type(*static_cast(this)); } + allocator_type + get_allocator() const + { return allocator_type(*static_cast(this)); } - _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; - } + _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; + } - // This is what actually destroys the list. - ~_List_base() - { - __clear(); - } - - void - __clear(); - }; + // This is what actually destroys the list. + ~_List_base() + { _M_clear(); } + + void + _M_clear(); + }; /** - * @brief A standard container with linear time access to elements, and - * fixed time insertion/deletion at any point in the sequence. + * @brief A standard container with linear time access to elements, + * and fixed time insertion/deletion at any point in the sequence. * * @ingroup Containers * @ingroup Sequences @@ -306,761 +303,768 @@ namespace __gnu_norm */ template > class list : protected _List_base<_Tp, _Alloc> - { - // concept requirements - __glibcxx_class_requires(_Tp, _SGIAssignableConcept) - - typedef _List_base<_Tp, _Alloc> _Base; - - public: - 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 std::reverse_iterator const_reverse_iterator; - typedef std::reverse_iterator reverse_iterator; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef typename _Base::allocator_type allocator_type; - - protected: - // Note that pointers-to-_Node's can be ctor-converted to iterator types. - typedef _List_node<_Tp> _Node; - - /** @if maint - * One data member plus two memory-handling functions. If the _Alloc - * type requires separate instances, then one of those will also be - * included, accumulated from the topmost parent. - * @endif - */ - using _Base::_M_node; - using _Base::_M_put_node; - using _Base::_M_get_node; - - /** - * @if maint - * @param x An instance of user data. - * - * Allocates space for a new node and constructs a copy of @a x in it. - * @endif - */ - _Node* - _M_create_node(const value_type& __x) { - _Node* __p = this->_M_get_node(); - try { - std::_Construct(&__p->_M_data, __x); - } - catch(...) + // concept requirements + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + + typedef _List_base<_Tp, _Alloc> _Base; + + public: + 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 std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef typename _Base::allocator_type allocator_type; + + protected: + // Note that pointers-to-_Node's can be ctor-converted to + // iterator types. + typedef _List_node<_Tp> _Node; + + /** @if maint + * One data member plus two memory-handling functions. If the + * _Alloc type requires separate instances, then one of those + * will also be included, accumulated from the topmost parent. + * @endif + */ + using _Base::_M_node; + using _Base::_M_put_node; + using _Base::_M_get_node; + + /** + * @if maint + * @param x An instance of user data. + * + * Allocates space for a new node and constructs a copy of @a x in it. + * @endif + */ + _Node* + _M_create_node(const value_type& __x) { - _M_put_node(__p); - __throw_exception_again; + _Node* __p = this->_M_get_node(); + try + { + std::_Construct(&__p->_M_data, __x); + } + catch(...) + { + _M_put_node(__p); + __throw_exception_again; + } + return __p; } - return __p; - } - /** - * @if maint - * Allocates space for a new node and default-constructs a new instance - * of @c value_type in it. - * @endif - */ - _Node* - _M_create_node() - { - _Node* __p = this->_M_get_node(); - try { - std::_Construct(&__p->_M_data); - } - catch(...) + /** + * @if maint + * Allocates space for a new node and default-constructs a new + * instance of @c value_type in it. + * @endif + */ + _Node* + _M_create_node() { - _M_put_node(__p); - __throw_exception_again; + _Node* __p = this->_M_get_node(); + try + { + std::_Construct(&__p->_M_data); + } + catch(...) + { + _M_put_node(__p); + __throw_exception_again; + } + return __p; } - return __p; - } + + public: + // [23.2.2.1] construct/copy/destroy + // (assign() and get_allocator() are also listed in this section) + /** + * @brief Default constructor creates no elements. + */ + explicit + list(const allocator_type& __a = allocator_type()) + : _Base(__a) { } - public: - // [23.2.2.1] construct/copy/destroy - // (assign() and get_allocator() are also listed in this section) - /** - * @brief Default constructor creates no elements. - */ - explicit - list(const allocator_type& __a = allocator_type()) - : _Base(__a) { } - - /** - * @brief Create a %list with copies of an exemplar element. - * @param n The number of elements to initially create. - * @param value An element to copy. - * - * This constructor fills the %list with @a n copies of @a value. - */ - list(size_type __n, const value_type& __value, - const allocator_type& __a = allocator_type()) + /** + * @brief Create a %list with copies of an exemplar element. + * @param n The number of elements to initially create. + * @param value An element to copy. + * + * This constructor fills the %list with @a n copies of @a value. + */ + list(size_type __n, const value_type& __value, + const allocator_type& __a = allocator_type()) : _Base(__a) { this->insert(begin(), __n, __value); } - /** - * @brief Create a %list with default elements. - * @param n The number of elements to initially create. - * - * This constructor fills the %list with @a n copies of a - * default-constructed element. - */ - explicit - list(size_type __n) + /** + * @brief Create a %list with default elements. + * @param n The number of elements to initially create. + * + * This constructor fills the %list with @a n copies of a + * default-constructed element. + */ + explicit + list(size_type __n) : _Base(allocator_type()) { this->insert(begin(), __n, value_type()); } - /** - * @brief %List copy constructor. - * @param x A %list of identical element and allocator types. - * - * The newly-created %list uses a copy of the allocation object used - * by @a x. - */ - list(const list& __x) + /** + * @brief %List copy constructor. + * @param x A %list of identical element and allocator types. + * + * The newly-created %list uses a copy of the allocation object used + * by @a x. + */ + list(const list& __x) : _Base(__x.get_allocator()) { this->insert(begin(), __x.begin(), __x.end()); } + + /** + * @brief Builds a %list from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %list consisting of copies of the elements from + * [@a first,@a last). This is linear in N (where N is + * distance(@a first,@a last)). + * + * @if maint + * We don't need any dispatching tricks here, because insert does all of + * that anyway. + * @endif + */ + template + list(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { this->insert(begin(), __first, __last); } - /** - * @brief Builds a %list from a range. - * @param first An input iterator. - * @param last An input iterator. - * - * Create a %list consisting of copies of the elements from - * [@a first,@a last). This is linear in N (where N is - * distance(@a first,@a last)). - * - * @if maint - * We don't need any dispatching tricks here, because insert does all of - * that anyway. - * @endif - */ - template - list(_InputIterator __first, _InputIterator __last, - const allocator_type& __a = allocator_type()) - : _Base(__a) - { this->insert(begin(), __first, __last); } + /** + * No explicit dtor needed as the _Base dtor takes care of + * things. The _Base 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. + */ - /** - * No explicit dtor needed as the _Base dtor takes care of - * things. The _Base 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. - */ - - /** - * @brief %List assignment operator. - * @param x A %list of identical element and allocator types. - * - * All the elements of @a x are copied, but unlike the copy - * constructor, the allocator object is not copied. - */ - list& - operator=(const list& __x); - - /** - * @brief Assigns a given value to a %list. - * @param n Number of elements to be assigned. - * @param val Value to be assigned. - * - * This function fills a %list with @a n copies of the given - * value. Note that the assignment completely changes the %list - * and that the resulting %list's size is the same as the number - * of elements assigned. Old data may be lost. - */ - void - assign(size_type __n, const value_type& __val) - { _M_fill_assign(__n, __val); } - - /** - * @brief Assigns a range to a %list. - * @param first An input iterator. - * @param last An input iterator. - * - * This function fills a %list with copies of the elements in the - * range [@a first,@a last). - * - * Note that the assignment completely changes the %list and that the - * resulting %list's size is the same as the number of elements assigned. - * Old data may be lost. - */ - template + /** + * @brief %List assignment operator. + * @param x A %list of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy + * constructor, the allocator object is not copied. + */ + list& + operator=(const list& __x); + + /** + * @brief Assigns a given value to a %list. + * @param n Number of elements to be assigned. + * @param val Value to be assigned. + * + * This function fills a %list with @a n copies of the given + * value. Note that the assignment completely changes the %list + * and that the resulting %list's size is the same as the number + * of elements assigned. Old data may be lost. + */ void - assign(_InputIterator __first, _InputIterator __last) + assign(size_type __n, const value_type& __val) + { _M_fill_assign(__n, __val); } + + /** + * @brief Assigns a range to a %list. + * @param first An input iterator. + * @param last An input iterator. + * + * This function fills a %list with copies of the elements in the + * range [@a first,@a last). + * + * Note that the assignment completely changes the %list and + * that the resulting %list's size is the same as the number of + * elements assigned. Old data may be lost. + */ + template + void + assign(_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; + _M_assign_dispatch(__first, __last, _Integral()); + } + + /// Get a copy of the memory allocation object. + allocator_type + get_allocator() const { return _Base::get_allocator(); } + + // iterators + /** + * Returns a read/write iterator that points to the first element in the + * %list. Iteration is done in ordinary element order. + */ + iterator + begin() { return static_cast<_Node*>(this->_M_node._M_next); } + + /** + * Returns a read-only (constant) iterator that points to the + * first element in the %list. Iteration is done in ordinary + * element order. + */ + const_iterator + begin() const { return static_cast<_Node*>(this->_M_node._M_next); } + + /** + * Returns a read/write iterator that points one past the last + * element in the %list. Iteration is done in ordinary element + * order. + */ + iterator + end() { return static_cast<_Node*>(&this->_M_node); } + + /** + * Returns a read-only (constant) iterator that points one past + * the last element in the %list. Iteration is done in ordinary + * element order. + */ + const_iterator + end() const + { return const_cast<_Node*>(static_cast(&this->_M_node)); } + + /** + * Returns a read/write reverse iterator that points to the last + * element in the %list. Iteration is done in reverse element + * order. + */ + reverse_iterator + rbegin() { return reverse_iterator(end()); } + + /** + * Returns a read-only (constant) reverse iterator that points to + * the last element in the %list. Iteration is done in reverse + * element order. + */ + const_reverse_iterator + rbegin() const { return const_reverse_iterator(end()); } + + /** + * Returns a read/write reverse iterator that points to one + * before the first element in the %list. Iteration is done in + * reverse element order. + */ + reverse_iterator + rend() { return reverse_iterator(begin()); } + + /** + * Returns a read-only (constant) reverse iterator that points to one + * before the first element in the %list. Iteration is done in reverse + * element order. + */ + const_reverse_iterator + rend() const + { return const_reverse_iterator(begin()); } + + // [23.2.2.2] capacity + /** + * Returns true if the %list is empty. (Thus begin() would equal + * end().) + */ + bool + empty() const { return this->_M_node._M_next == &this->_M_node; } + + /** Returns the number of elements in the %list. */ + size_type + size() const { return std::distance(begin(), end()); } + + /** Returns the size() of the largest possible %list. */ + size_type + max_size() const { return size_type(-1); } + + /** + * @brief Resizes the %list to the specified number of elements. + * @param new_size Number of elements the %list should contain. + * @param x Data with which new elements should be populated. + * + * This function will %resize the %list to the specified number + * of elements. If the number is smaller than the %list's + * current size the %list is truncated, otherwise the %list is + * extended and new elements are populated with given data. + */ + void + resize(size_type __new_size, const value_type& __x); + + /** + * @brief Resizes the %list to the specified number of elements. + * @param new_size Number of elements the %list should contain. + * + * This function will resize the %list to the specified number of + * elements. If the number is smaller than the %list's current + * size the %list is truncated, otherwise the %list is extended + * and new elements are default-constructed. + */ + void + resize(size_type __new_size) { this->resize(__new_size, value_type()); } + + // element access + /** + * Returns a read/write reference to the data at the first + * element of the %list. + */ + reference + front() { return *begin(); } + + /** + * Returns a read-only (constant) reference to the data at the first + * element of the %list. + */ + const_reference + front() const { return *begin(); } + + /** + * Returns a read/write reference to the data at the last element + * of the %list. + */ + reference + back() { return *(--end()); } + + /** + * Returns a read-only (constant) reference to the data at the last + * element of the %list. + */ + const_reference + back() const { return *(--end()); } + + // [23.2.2.3] modifiers + /** + * @brief Add data to the front of the %list. + * @param x Data to be added. + * + * This is a typical stack operation. The function creates an + * element at the front of the %list and assigns the given data + * to it. Due to the nature of a %list this operation can be + * done in constant time, and does not invalidate iterators and + * references. + */ + void + push_front(const value_type& __x) { this->insert(begin(), __x); } + + /** + * @brief Removes first element. + * + * This is a typical stack operation. It shrinks the %list by + * one. Due to the nature of a %list this operation can be done + * in constant time, and only invalidates iterators/references to + * the element being removed. + * + * Note that no data is returned, and if the first element's data + * is needed, it should be retrieved before pop_front() is + * called. + */ + void + pop_front() { this->erase(begin()); } + + /** + * @brief Add data to the end of the %list. + * @param x Data to be added. + * + * This is a typical stack operation. The function creates an + * element at the end of the %list and assigns the given data to + * it. Due to the nature of a %list this operation can be done + * in constant time, and does not invalidate iterators and + * references. + */ + void + push_back(const value_type& __x) { this->insert(end(), __x); } + + /** + * @brief Removes last element. + * + * This is a typical stack operation. It shrinks the %list by + * one. Due to the nature of a %list this operation can be done + * in constant time, and only invalidates iterators/references to + * the element being removed. + * + * 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() { - // Check whether it's an integral type. If so, it's not an iterator. - typedef typename _Is_integer<_InputIterator>::_Integral _Integral; - _M_assign_dispatch(__first, __last, _Integral()); + iterator __tmp = end(); + this->erase(--__tmp); + } + + /** + * @brief Inserts given value into %list before specified iterator. + * @param position An iterator into the %list. + * @param x Data to be inserted. + * @return An iterator that points to the inserted data. + * + * This function will insert a copy of the given value before + * the specified location. Due to the nature of a %list this + * operation can be done in constant time, and does not + * invalidate iterators and references. + */ + iterator + insert(iterator __position, const value_type& __x); + + /** + * @brief Inserts a number of copies of given data into the %list. + * @param position An iterator into the %list. + * @param n Number of elements to be inserted. + * @param x Data to be inserted. + * + * This function will insert a specified number of copies of the + * given data before the location specified by @a position. + * + * Due to the nature of a %list this operation can be done in + * constant time, and does not invalidate iterators and + * references. + */ + void + insert(iterator __position, size_type __n, const value_type& __x) + { _M_fill_insert(__position, __n, __x); } + + /** + * @brief Inserts a range into the %list. + * @param position An iterator into the %list. + * @param first An input iterator. + * @param last An input iterator. + * + * This function will insert copies of the data in the range [@a + * first,@a last) into the %list before the location specified by + * @a position. + * + * Due to the nature of a %list this operation can be done in + * constant time, and does not invalidate iterators and + * references. + */ + template + void + 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; + _M_insert_dispatch(__position, __first, __last, _Integral()); + } + + /** + * @brief Remove element at given position. + * @param position Iterator pointing to element to be erased. + * @return An iterator pointing to the next element (or end()). + * + * This function will erase the element at the given position and thus + * shorten the %list by one. + * + * Due to the nature of a %list this operation can be done in + * constant time, and only invalidates iterators/references to + * the element being removed. The user is also cautioned that + * this function only erases the element, and that if the element + * is itself a pointer, the pointed-to memory is not touched in + * any way. Managing the pointer is the user's responsibilty. + */ + iterator + erase(iterator __position); + + /** + * @brief Remove a range of elements. + * @param first Iterator pointing to the first element to be erased. + * @param last Iterator pointing to one past the last element to be + * erased. + * @return An iterator pointing to the element pointed to by @a last + * prior to erasing (or end()). + * + * This function will erase the elements in the range @a + * [first,last) and shorten the %list accordingly. + * + * Due to the nature of a %list this operation can be done in + * constant time, and only invalidates iterators/references to + * the element being removed. The user is also cautioned that + * this function only erases the elements, and 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. + */ + iterator + erase(iterator __first, iterator __last) + { + while (__first != __last) + erase(__first++); + return __last; } - /// Get a copy of the memory allocation object. - allocator_type - get_allocator() const { return _Base::get_allocator(); } - - // iterators - /** - * Returns a read/write iterator that points to the first element in the - * %list. Iteration is done in ordinary element order. - */ - iterator - begin() { return static_cast<_Node*>(this->_M_node._M_next); } - - /** - * Returns a read-only (constant) iterator that points to the - * first element in the %list. Iteration is done in ordinary - * element order. - */ - const_iterator - begin() const { return static_cast<_Node*>(this->_M_node._M_next); } - - /** - * Returns a read/write iterator that points one past the last - * element in the %list. Iteration is done in ordinary element - * order. - */ - iterator - end() { return static_cast<_Node*>(&this->_M_node); } - - /** - * Returns a read-only (constant) iterator that points one past - * the last element in the %list. Iteration is done in ordinary - * element order. - */ - const_iterator - end() const - { return const_cast<_Node *>(static_cast(&this->_M_node)); } - - /** - * Returns a read/write reverse iterator that points to the last - * element in the %list. Iteration is done in reverse element - * order. - */ - reverse_iterator - rbegin() { return reverse_iterator(end()); } - - /** - * Returns a read-only (constant) reverse iterator that points to - * the last element in the %list. Iteration is done in reverse - * element order. - */ - const_reverse_iterator - rbegin() const { return const_reverse_iterator(end()); } - - /** - * Returns a read/write reverse iterator that points to one - * before the first element in the %list. Iteration is done in - * reverse element order. - */ - reverse_iterator - rend() { return reverse_iterator(begin()); } - - /** - * Returns a read-only (constant) reverse iterator that points to one - * before the first element in the %list. Iteration is done in reverse - * element order. - */ - const_reverse_iterator - rend() const - { return const_reverse_iterator(begin()); } - - // [23.2.2.2] capacity - /** - * Returns true if the %list is empty. (Thus begin() would equal - * end().) - */ - bool - empty() const { return this->_M_node._M_next == &this->_M_node; } - - /** Returns the number of elements in the %list. */ - size_type - size() const { return std::distance(begin(), end()); } - - /** Returns the size() of the largest possible %list. */ - size_type - max_size() const { return size_type(-1); } - - /** - * @brief Resizes the %list to the specified number of elements. - * @param new_size Number of elements the %list should contain. - * @param x Data with which new elements should be populated. - * - * This function will %resize the %list to the specified number - * of elements. If the number is smaller than the %list's - * current size the %list is truncated, otherwise the %list is - * extended and new elements are populated with given data. - */ - void - resize(size_type __new_size, const value_type& __x); - - /** - * @brief Resizes the %list to the specified number of elements. - * @param new_size Number of elements the %list should contain. - * - * This function will resize the %list to the specified number of - * elements. If the number is smaller than the %list's current - * size the %list is truncated, otherwise the %list is extended - * and new elements are default-constructed. - */ - void - resize(size_type __new_size) { this->resize(__new_size, value_type()); } - - // element access - /** - * Returns a read/write reference to the data at the first element of the - * %list. - */ - reference - front() { return *begin(); } - - /** - * Returns a read-only (constant) reference to the data at the first - * element of the %list. - */ - const_reference - front() const { return *begin(); } - - /** - * Returns a read/write reference to the data at the last element - * of the %list. - */ - reference - back() { return *(--end()); } - - /** - * Returns a read-only (constant) reference to the data at the last - * element of the %list. - */ - const_reference - back() const { return *(--end()); } - - // [23.2.2.3] modifiers - /** - * @brief Add data to the front of the %list. - * @param x Data to be added. - * - * This is a typical stack operation. The function creates an - * element at the front of the %list and assigns the given data - * to it. Due to the nature of a %list this operation can be - * done in constant time, and does not invalidate iterators and - * references. - */ - void - push_front(const value_type& __x) { this->insert(begin(), __x); } - - /** - * @brief Removes first element. - * - * This is a typical stack operation. It shrinks the %list by - * one. Due to the nature of a %list this operation can be done - * in constant time, and only invalidates iterators/references to - * the element being removed. - * - * Note that no data is returned, and if the first element's data - * is needed, it should be retrieved before pop_front() is - * called. - */ - void - pop_front() { this->erase(begin()); } - - /** - * @brief Add data to the end of the %list. - * @param x Data to be added. - * - * This is a typical stack operation. The function creates an - * element at the end of the %list and assigns the given data to - * it. Due to the nature of a %list this operation can be done - * in constant time, and does not invalidate iterators and - * references. - */ - void - push_back(const value_type& __x) { this->insert(end(), __x); } - - /** - * @brief Removes last element. - * - * This is a typical stack operation. It shrinks the %list by - * one. Due to the nature of a %list this operation can be done - * in constant time, and only invalidates iterators/references to - * the element being removed. - * - * 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() - { - iterator __tmp = end(); - this->erase(--__tmp); - } - - /** - * @brief Inserts given value into %list before specified iterator. - * @param position An iterator into the %list. - * @param x Data to be inserted. - * @return An iterator that points to the inserted data. - * - * This function will insert a copy of the given value before the - * specified location. Due to the nature of a %list this - * operation can be done in constant time, and does not - * invalidate iterators and references. - */ - iterator - insert(iterator __position, const value_type& __x); - - /** - * @brief Inserts a number of copies of given data into the %list. - * @param position An iterator into the %list. - * @param n Number of elements to be inserted. - * @param x Data to be inserted. - * - * This function will insert a specified number of copies of the - * given data before the location specified by @a position. - * - * Due to the nature of a %list this operation can be done in - * constant time, and does not invalidate iterators and - * references. - */ - void - insert(iterator __position, size_type __n, const value_type& __x) - { _M_fill_insert(__position, __n, __x); } - - /** - * @brief Inserts a range into the %list. - * @param position An iterator into the %list. - * @param first An input iterator. - * @param last An input iterator. - * - * This function will insert copies of the data in the range [@a - * first,@a last) into the %list before the location specified by - * @a position. - * - * Due to the nature of a %list this operation can be done in constant - * time, and does not invalidate iterators and references. - */ - template + /** + * @brief Swaps data with another %list. + * @param x A %list of the same element and allocator types. + * + * This exchanges the elements between two lists in constant + * time. Note that the global std::swap() function is + * specialized such that std::swap(l1,l2) will feed to this + * function. + */ void - insert(iterator __position, _InputIterator __first, - _InputIterator __last) + swap(list& __x); + + /** + * Erases all the elements. Note that this function only erases + * the elements, and 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. + */ + void + clear() { _Base::_M_clear(); } + + // [23.2.2.4] list operations + /** + * @brief Insert contents of another %list. + * @param position Iterator referencing the element to insert before. + * @param x Source list. + * + * The elements of @a x are inserted in constant time in front of + * the element referenced by @a position. @a x becomes an empty + * list. + */ + void + splice(iterator __position, list& __x) { - // Check whether it's an integral type. If so, it's not an iterator. - typedef typename _Is_integer<_InputIterator>::_Integral _Integral; - _M_insert_dispatch(__position, __first, __last, _Integral()); + if (!__x.empty()) + this->_M_transfer(__position, __x.begin(), __x.end()); } - /** - * @brief Remove element at given position. - * @param position Iterator pointing to element to be erased. - * @return An iterator pointing to the next element (or end()). - * - * This function will erase the element at the given position and thus - * shorten the %list by one. - * - * Due to the nature of a %list this operation can be done in - * constant time, and only invalidates iterators/references to - * the element being removed. The user is also cautioned that - * this function only erases the element, and that if the element - * is itself a pointer, the pointed-to memory is not touched in - * any way. Managing the pointer is the user's responsibilty. - */ - iterator - erase(iterator __position); + /** + * @brief Insert element from another %list. + * @param position Iterator referencing the element to insert before. + * @param x Source list. + * @param i Iterator referencing the element to move. + * + * Removes the element in list @a x referenced by @a i and + * inserts it into the current list before @a position. + */ + void + splice(iterator __position, list&, iterator __i) + { + iterator __j = __i; + ++__j; + if (__position == __i || __position == __j) return; + this->_M_transfer(__position, __i, __j); + } - /** - * @brief Remove a range of elements. - * @param first Iterator pointing to the first element to be erased. - * @param last Iterator pointing to one past the last element to be - * erased. - * @return An iterator pointing to the element pointed to by @a last - * prior to erasing (or end()). - * - * This function will erase the elements in the range @a - * [first,last) and shorten the %list accordingly. - * - * Due to the nature of a %list this operation can be done in - * constant time, and only invalidates iterators/references to - * the element being removed. The user is also cautioned that - * this function only erases the elements, and 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. - */ - iterator - erase(iterator __first, iterator __last) - { - while (__first != __last) - erase(__first++); - return __last; - } + /** + * @brief Insert range from another %list. + * @param position Iterator referencing the element to insert before. + * @param x Source list. + * @param first Iterator referencing the start of range in x. + * @param last Iterator referencing the end of range in x. + * + * Removes elements in the range [first,last) and inserts them + * before @a position in constant time. + * + * Undefined if @a position is in [first,last). + */ + void + splice(iterator __position, list&, iterator __first, iterator __last) + { + if (__first != __last) + this->_M_transfer(__position, __first, __last); + } - /** - * @brief Swaps data with another %list. - * @param x A %list of the same element and allocator types. - * - * This exchanges the elements between two lists in constant - * time. Note that the global std::swap() function is - * specialized such that std::swap(l1,l2) will feed to this - * function. - */ - void - swap(list& __x); + /** + * @brief Remove all elements equal to value. + * @param value The value to remove. + * + * Removes every element in the list equal to @a value. + * Remaining elements stay in list order. Note that this + * function only erases the elements, and 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. + */ + void + remove(const _Tp& __value); - /** - * Erases all the elements. Note that this function only erases - * the elements, and 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. - */ - void - clear() { _Base::__clear(); } - - // [23.2.2.4] list operations - /** - * @brief Insert contents of another %list. - * @param position Iterator referencing the element to insert before. - * @param x Source list. - * - * The elements of @a x are inserted in constant time in front of - * the element referenced by @a position. @a x becomes an empty - * list. - */ - void - splice(iterator __position, list& __x) - { - if (!__x.empty()) - this->_M_transfer(__position, __x.begin(), __x.end()); - } - - /** - * @brief Insert element from another %list. - * @param position Iterator referencing the element to insert before. - * @param x Source list. - * @param i Iterator referencing the element to move. - * - * Removes the element in list @a x referenced by @a i and - * inserts it into the current list before @a position. - */ - void - splice(iterator __position, list&, iterator __i) - { - iterator __j = __i; - ++__j; - if (__position == __i || __position == __j) return; - this->_M_transfer(__position, __i, __j); - } - - /** - * @brief Insert range from another %list. - * @param position Iterator referencing the element to insert before. - * @param x Source list. - * @param first Iterator referencing the start of range in x. - * @param last Iterator referencing the end of range in x. - * - * Removes elements in the range [first,last) and inserts them - * before @a position in constant time. - * - * Undefined if @a position is in [first,last). - */ - void - splice(iterator __position, list&, iterator __first, iterator __last) - { - if (__first != __last) - this->_M_transfer(__position, __first, __last); - } - - /** - * @brief Remove all elements equal to value. - * @param value The value to remove. - * - * Removes every element in the list equal to @a value. - * Remaining elements stay in list order. Note that this - * function only erases the elements, and 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. - */ - void - remove(const _Tp& __value); - - /** - * @brief Remove all elements satisfying a predicate. - * @param Predicate Unary predicate function or object. - * - * Removes every element in the list for which the predicate - * returns true. Remaining elements stay in list order. Note - * that this function only erases the elements, and 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. - */ - template + /** + * @brief Remove all elements satisfying a predicate. + * @param Predicate Unary predicate function or object. + * + * Removes every element in the list for which the predicate + * returns true. Remaining elements stay in list order. Note + * that this function only erases the elements, and 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. + */ + template void remove_if(_Predicate); - /** - * @brief Remove consecutive duplicate elements. - * - * For each consecutive set of elements with the same value, - * remove all but the first one. Remaining elements stay in list - * order. Note that this function only erases the elements, and - * 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. - */ - void - unique(); - - /** - * @brief Remove consecutive elements satisfying a predicate. - * @param BinaryPredicate Binary predicate function or object. - * - * For each consecutive set of elements [first,last) that satisfy - * predicate(first,i) where i is an iterator in [first,last), - * remove all but the first one. Remaining elements stay in list - * order. Note that this function only erases the elements, and - * 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. - */ - template + /** + * @brief Remove consecutive duplicate elements. + * + * For each consecutive set of elements with the same value, + * remove all but the first one. Remaining elements stay in + * list order. Note that this function only erases the + * elements, and 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. + */ void - unique(_BinaryPredicate); + unique(); - /** - * @brief Merge sorted lists. - * @param x Sorted list to merge. - * - * Assumes that both @a x and this list are sorted according to - * operator<(). Merges elements of @a x into this list in sorted - * order, leaving @a x empty when complete. Elements in this - * list precede elements in @a x that are equal. - */ - void - merge(list& __x); + /** + * @brief Remove consecutive elements satisfying a predicate. + * @param BinaryPredicate Binary predicate function or object. + * + * For each consecutive set of elements [first,last) that + * satisfy predicate(first,i) where i is an iterator in + * [first,last), remove all but the first one. Remaining + * elements stay in list order. Note that this function only + * erases the elements, and 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. + */ + template + void + unique(_BinaryPredicate); - /** - * @brief Merge sorted lists according to comparison function. - * @param x Sorted list to merge. - * @param StrictWeakOrdering Comparison function definining sort order. - * - * Assumes that both @a x and this list are sorted according to - * StrictWeakOrdering. Merges elements of @a x into this list in - * sorted order, leaving @a x empty when complete. Elements in - * this list precede elements in @a x that are equivalent - * according to StrictWeakOrdering(). - */ - template + /** + * @brief Merge sorted lists. + * @param x Sorted list to merge. + * + * Assumes that both @a x and this list are sorted according to + * operator<(). Merges elements of @a x into this list in + * sorted order, leaving @a x empty when complete. Elements in + * this list precede elements in @a x that are equal. + */ void - merge(list&, _StrictWeakOrdering); + merge(list& __x); - /** - * @brief Reverse the elements in list. - * - * Reverse the order of elements in the list in linear time. - */ - void - reverse() { __List_base_reverse(&this->_M_node); } + /** + * @brief Merge sorted lists according to comparison function. + * @param x Sorted list to merge. + * @param StrictWeakOrdering Comparison function definining + * sort order. + * + * Assumes that both @a x and this list are sorted according to + * StrictWeakOrdering. Merges elements of @a x into this list + * in sorted order, leaving @a x empty when complete. Elements + * in this list precede elements in @a x that are equivalent + * according to StrictWeakOrdering(). + */ + template + void + merge(list&, _StrictWeakOrdering); - /** - * @brief Sort the elements. - * - * Sorts the elements of this list in NlogN time. Equivalent - * elements remain in list order. - */ - void - sort(); - - /** - * @brief Sort the elements according to comparison function. - * - * Sorts the elements of this list in NlogN time. Equivalent - * elements remain in list order. - */ - template + /** + * @brief Reverse the elements in list. + * + * Reverse the order of elements in the list in linear time. + */ void - sort(_StrictWeakOrdering); + reverse() { __List_base_reverse(&this->_M_node); } - protected: - // Internal assign functions follow. - - // Called by the range assign to implement [23.1.1]/9 - template + /** + * @brief Sort the elements. + * + * Sorts the elements of this list in NlogN time. Equivalent + * elements remain in list order. + */ void - _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + sort(); + + /** + * @brief Sort the elements according to comparison function. + * + * Sorts the elements of this list in NlogN time. Equivalent + * elements remain in list order. + */ + template + void + sort(_StrictWeakOrdering); + + protected: + // Internal assign functions follow. + + // Called by the range assign to implement [23.1.1]/9 + template + void + _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { + _M_fill_assign(static_cast(__n), + static_cast(__val)); + } + + // Called by the range assign to implement [23.1.1]/9 + template + void + _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type); + + // Called by assign(n,t), and the range assign when it turns out + // to be the same thing. + void + _M_fill_assign(size_type __n, const value_type& __val); + + + // Internal insert functions follow. + + // Called by the range insert to implement [23.1.1]/9 + template + void + _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, + __true_type) + { + _M_fill_insert(__pos, static_cast(__n), + static_cast(__x)); + } + + // Called by the range insert to implement [23.1.1]/9 + template + void + _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type) + { + for ( ; __first != __last; ++__first) + insert(__pos, *__first); + } + + // Called by insert(p,n,x), and the range insert when it turns out + // to be the same thing. + void + _M_fill_insert(iterator __pos, size_type __n, const value_type& __x) { - _M_fill_assign(static_cast(__n), - static_cast(__val)); + for ( ; __n > 0; --__n) + insert(__pos, __x); } - - // Called by the range assign to implement [23.1.1]/9 - template + + + // Moves the elements from [first,last) before position. void - _M_assign_dispatch(_InputIterator __first, _InputIterator __last, - __false_type); - - // Called by assign(n,t), and the range assign when it turns out - // to be the same thing. - void - _M_fill_assign(size_type __n, const value_type& __val); - - - // Internal insert functions follow. - - // Called by the range insert to implement [23.1.1]/9 - template - void - _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __x, - __true_type) + _M_transfer(iterator __position, iterator __first, iterator __last) { - _M_fill_insert(__pos, static_cast(__n), - static_cast(__x)); + 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; + } } - - // Called by the range insert to implement [23.1.1]/9 - template - void - _M_insert_dispatch(iterator __pos, - _InputIterator __first, _InputIterator __last, - __false_type) - { - for ( ; __first != __last; ++__first) - insert(__pos, *__first); - } - - // Called by insert(p,n,x), and the range insert when it turns out - // to be the same thing. - void - _M_fill_insert(iterator __pos, size_type __n, const value_type& __x) - { - for ( ; __n > 0; --__n) - insert(__pos, __x); - } - - - // Moves the elements from [first,last) before position. - 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; - } - } - }; + }; /** @@ -1074,7 +1078,7 @@ namespace __gnu_norm * equal, and if corresponding elements compare equal. */ template - inline bool + inline bool operator==(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) { typedef typename list<_Tp,_Alloc>::const_iterator const_iterator; @@ -1083,9 +1087,10 @@ namespace __gnu_norm const_iterator __i1 = __x.begin(); const_iterator __i2 = __y.begin(); - while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) { - ++__i1; - ++__i2; + while (__i1 != __end1 && __i2 != __end2 && *__i1 == *__i2) + { + ++__i1; + ++__i2; } return __i1 == __end1 && __i2 == __end2; }