From: Phil Edwards Date: Tue, 21 May 2002 20:41:06 +0000 (+0000) Subject: stl_vector.h: Reformat to follow C++STYLE. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e4c62b265dfd167efcecbbbc539cbdad28bbd80f;p=gcc.git stl_vector.h: Reformat to follow C++STYLE. 2002-05-21 Phil Edwards * include/bits/stl_vector.h: Reformat to follow C++STYLE. Doxygenate all public members. Reorder to follow 14882. (vector::push_back(void)): Remove previously-deprecated fn. (vector::insert(iterator), vector::_M_insert_aux(iterator)): Deprecate for removal in 3.3. From-SVN: r53696 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 0a24bd70597..c4a4fe1b28a 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,11 @@ +2002-05-21 Phil Edwards + + * include/bits/stl_vector.h: Reformat to follow C++STYLE. + Doxygenate all public members. Reorder to follow 14882. + (vector::push_back(void)): Remove previously-deprecated fn. + (vector::insert(iterator), vector::_M_insert_aux(iterator)): + Deprecate for removal in 3.3. + 2002-05-20 Phil Edwards * docs/html/faq/index.html (5.4): Recommend against -I options for diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h index 5e2ea54d913..7a23b49fdbf 100644 --- a/libstdc++-v3/include/bits/stl_vector.h +++ b/libstdc++-v3/include/bits/stl_vector.h @@ -65,22 +65,27 @@ #include #include +// Since this entire file is within namespace std, there's no reason to +// waste two spaces along the left column. Thus the leading indentation is +// slightly violated from here on. namespace std { -// The vector base class serves two purposes. First, its constructor -// and destructor allocate (but don't initialize) storage. This makes -// exception safety easier. Second, the base class encapsulates all of -// the differences between SGI-style allocators and standard-conforming -// allocators. - -// Base class for ordinary allocators. +/// @if maint Primary default version. @endif +/** + * @if maint + * See bits/stl_deque.h's _Deque_alloc_base for an explanation. + * @endif +*/ template -class _Vector_alloc_base { +class _Vector_alloc_base +{ public: typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type allocator_type; - allocator_type get_allocator() const { return _M_data_allocator; } + + allocator_type + get_allocator() const { return _M_data_allocator; } _Vector_alloc_base(const allocator_type& __a) : _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0) @@ -92,20 +97,24 @@ protected: _Tp* _M_finish; _Tp* _M_end_of_storage; - _Tp* _M_allocate(size_t __n) - { return _M_data_allocator.allocate(__n); } - void _M_deallocate(_Tp* __p, size_t __n) + _Tp* + _M_allocate(size_t __n) { return _M_data_allocator.allocate(__n); } + + void + _M_deallocate(_Tp* __p, size_t __n) { if (__p) _M_data_allocator.deallocate(__p, __n); } }; -// Specialization for allocators that have the property that we don't -// actually have to store an allocator object. +/// @if maint Specialization for instanceless allocators. @endif template -class _Vector_alloc_base<_Tp, _Allocator, true> { +class _Vector_alloc_base<_Tp, _Allocator, true> +{ public: typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type allocator_type; - allocator_type get_allocator() const { return allocator_type(); } + + allocator_type + get_allocator() const { return allocator_type(); } _Vector_alloc_base(const allocator_type&) : _M_start(0), _M_finish(0), _M_end_of_storage(0) @@ -117,12 +126,20 @@ protected: _Tp* _M_end_of_storage; typedef typename _Alloc_traits<_Tp, _Allocator>::_Alloc_type _Alloc_type; - _Tp* _M_allocate(size_t __n) - { return _Alloc_type::allocate(__n); } - void _M_deallocate(_Tp* __p, size_t __n) - { _Alloc_type::deallocate(__p, __n);} + + _Tp* + _M_allocate(size_t __n) { return _Alloc_type::allocate(__n); } + + void + _M_deallocate(_Tp* __p, size_t __n) { _Alloc_type::deallocate(__p, __n);} }; + +/** + * @if maint + * See bits/stl_deque.h's _Deque_base for an explanation. + * @endif +*/ template struct _Vector_base : public _Vector_alloc_base<_Tp, _Alloc, @@ -133,8 +150,11 @@ struct _Vector_base _Base; typedef typename _Base::allocator_type allocator_type; - _Vector_base(const allocator_type& __a) : _Base(__a) {} - _Vector_base(size_t __n, const allocator_type& __a) : _Base(__a) { + _Vector_base(const allocator_type& __a) + : _Base(__a) {} + _Vector_base(size_t __n, const allocator_type& __a) + : _Base(__a) + { _M_start = _M_allocate(__n); _M_finish = _M_start; _M_end_of_storage = _M_start + __n; @@ -157,10 +177,10 @@ struct _Vector_base * optional sequence requirements with the * %exception of @c push_front and @c pop_front. * - * In some terminology a vector can be described as a dynamic C-style array, + * In some terminology a %vector can be described as a dynamic C-style array, * it offers fast and efficient access to individual elements in any order * and saves the user from worrying about memory and size allocation. - * Subscripting ( [] ) access is also provided as with C-style arrays. + * Subscripting ( @c [] ) access is also provided as with C-style arrays. */ template > class vector : protected _Vector_base<_Tp, _Alloc> @@ -168,9 +188,9 @@ class vector : protected _Vector_base<_Tp, _Alloc> // concept requirements __glibcpp_class_requires(_Tp, _SGIAssignableConcept) -private: - typedef _Vector_base<_Tp, _Alloc> _Base; - typedef vector<_Tp, _Alloc> vector_type; + typedef _Vector_base<_Tp, _Alloc> _Base; + typedef vector<_Tp, _Alloc> vector_type; + public: typedef _Tp value_type; typedef value_type* pointer; @@ -178,18 +198,22 @@ public: typedef __gnu_cxx::__normal_iterator iterator; typedef __gnu_cxx::__normal_iterator const_iterator; + typedef reverse_iterator const_reverse_iterator; + typedef 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; - allocator_type get_allocator() const { return _Base::get_allocator(); } - - typedef reverse_iterator const_reverse_iterator; - typedef reverse_iterator reverse_iterator; + typedef typename _Base::allocator_type allocator_type; protected: + /** @if maint + * These two functions and three data members are all from the top-most + * base class, which varies depending on the type of %allocator. They + * should be pretty self-explanatory, as %vector uses a simple contiguous + * allocation scheme. + * @endif + */ using _Base::_M_allocate; using _Base::_M_deallocate; using _Base::_M_start; @@ -198,199 +222,318 @@ protected: protected: void _M_insert_aux(iterator __position, const _Tp& __x); +#ifdef _GLIBCPP_DEPRECATED void _M_insert_aux(iterator __position); +#endif public: + // [23.2.4.1] construct/copy/destroy + // (assign() and get_allocator() are also listed in this section) /** - * Returns a read/write iterator that points to the first element in the - * vector. Iteration is done in ordinary element order. + * @brief Default constructor creates no elements. */ - iterator begin() { return iterator (_M_start); } + explicit + vector(const allocator_type& __a = allocator_type()) + : _Base(__a) {} /** - * Returns a read-only (constant) iterator that points to the first element - * in the vector. Iteration is done in ordinary element order. + * @brief Create a %vector 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 %vector with @a n copies of @a value. */ - const_iterator begin() const - { return const_iterator (_M_start); } + vector(size_type __n, const _Tp& __value, + const allocator_type& __a = allocator_type()) + : _Base(__n, __a) + { _M_finish = uninitialized_fill_n(_M_start, __n, __value); } /** - * Returns a read/write iterator that points one past the last element in - * the vector. Iteration is done in ordinary element order. + * @brief Create a %vector with default elements. + * @param n The number of elements to initially create. + * + * This constructor fills the %vector with @a n copies of a + * default-constructed element. */ - iterator end() { return iterator (_M_finish); } + explicit + vector(size_type __n) + : _Base(__n, allocator_type()) + { _M_finish = uninitialized_fill_n(_M_start, __n, _Tp()); } /** - * Returns a read-only (constant) iterator that points one past the last - * element in the vector. Iteration is done in ordinary element order. + * @brief %Vector copy constructor. + * @param x A %vector of identical element and allocator types. + * + * The newly-created %vector uses a copy of the allocation object used + * by @a x. All the elements of @a x are copied, but any extra memory in + * @a x (for fast expansion) will not be copied. */ - const_iterator end() const { return const_iterator (_M_finish); } + vector(const vector<_Tp, _Alloc>& __x) + : _Base(__x.size(), __x.get_allocator()) + { _M_finish = uninitialized_copy(__x.begin(), __x.end(), _M_start); } /** - * Returns a read/write reverse iterator that points to the last element in - * the vector. Iteration is done in reverse element order. + * @brief Builds a %vector from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Creats a %vector consisting of copies of the elements from [first,last). + * + * If the iterators are forward, bidirectional, or random-access, then + * this will call the elements' copy constructor N times (where N is + * distance(first,last)) and do no memory reallocation. But if only + * input iterators are used, then this will do at most 2N calls to the + * copy constructor, and logN memory reallocations. */ - reverse_iterator rbegin() - { return reverse_iterator(end()); } + template + vector(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_initialize_aux(__first, __last, _Integral()); + } + +protected: + template + void + _M_initialize_aux(_Integer __n, _Integer __value, __true_type) + { + _M_start = _M_allocate(__n); + _M_end_of_storage = _M_start + __n; + _M_finish = uninitialized_fill_n(_M_start, __n, __value); + } + + template + void + _M_initialize_aux(_InputIterator __first,_InputIterator __last,__false_type) + { + typedef typename iterator_traits<_InputIterator>::iterator_category + _IterCategory; + _M_range_initialize(__first, __last, _IterCategory()); + } +public: /** - * Returns a read-only (constant) reverse iterator that points to the last - * element in the vector. Iteration is done in reverse element order. + * Creats a %vector consisting of copies of the elements from [first,last). + * + * The dtor 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. */ - const_reverse_iterator rbegin() const - { return const_reverse_iterator(end()); } + ~vector() { _Destroy(_M_start, _M_finish); } /** - * Returns a read/write reverse iterator that points to one before the - * first element in the vector. Iteration is done in reverse element - * order. + * @brief %Vector assignment operator. + * @param x A %vector of identical element and allocator types. + * + * All the elements of @a x are copied, but any extra memory in @a x (for + * fast expansion) will not be copied. Unlike the copy constructor, the + * allocator object is not copied. */ - reverse_iterator rend() - { return reverse_iterator(begin()); } + vector<_Tp, _Alloc>& + operator=(const vector<_Tp, _Alloc>& __x); /** - * Returns a read-only (constant) reverse iterator that points to one - * before the first element in the vector. Iteration is done in reverse - * element order. + * @brief Assigns a given value to a %vector. + * @param n Number of elements to be assigned. + * @param val Value to be assigned. + * + * This function fills a %vector with @a n copies of the given value. + * Note that the assignment completely changes the %vector and that the + * resulting %vector's size is the same as the number of elements assigned. + * Old data may be lost. */ - const_reverse_iterator rend() const - { return const_reverse_iterator(begin()); } - - /** Returns the number of elements in the vector. */ - size_type size() const - { return size_type(end() - begin()); } + void + assign(size_type __n, const _Tp& __val) { _M_fill_assign(__n, __val); } - /** Returns the size of the largest possible vector. */ - size_type max_size() const - { return size_type(-1) / sizeof(_Tp); } +protected: + void + _M_fill_assign(size_type __n, const _Tp& __val); +public: /** - * Returns the amount of memory that has been alocated for the current - * elements (?). + * @brief Assigns a range to a %vector. + * @param first An input iterator. + * @param last An input iterator. + * + * This function fills a %vector with copies of the elements in the + * range [first,last). + * + * Note that the assignment completely changes the %vector and that the + * resulting %vector's size is the same as the number of elements assigned. + * Old data may be lost. */ - size_type capacity() const - { return size_type(const_iterator(_M_end_of_storage) - begin()); } + template + void + assign(_InputIterator __first, _InputIterator __last) + { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } +protected: + template + void + _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { _M_fill_assign((size_type) __n, (_Tp) __val); } + + template + void + _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type) + { + typedef typename iterator_traits<_InputIter>::iterator_category + _IterCategory; + _M_assign_aux(__first, __last, _IterCategory()); + } + + template + void + _M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag); + + template + void + _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag); + +public: + /// Get a copy of the memory allocation object. + allocator_type + get_allocator() const { return _Base::get_allocator(); } + + // iterators /** - * Returns true if the vector is empty. (Thus begin() would equal end().) + * Returns a read/write iterator that points to the first element in the + * %vector. Iteration is done in ordinary element order. */ - bool empty() const - { return begin() == end(); } + iterator + begin() { return iterator (_M_start); } /** - * @brief Subscript access to the data contained in the vector. - * @param n The element for which data should be accessed. - * @return Read/write reference to data. - * - * This operator allows for easy, array-style, data access. - * Note that data access with this operator is unchecked and out_of_range - * lookups are not defined. (For checked lookups see at().) + * Returns a read-only (constant) iterator that points to the first element + * in the %vector. Iteration is done in ordinary element order. */ - reference operator[](size_type __n) { return *(begin() + __n); } + const_iterator + begin() const { return const_iterator (_M_start); } /** - * @brief Subscript access to the data contained in the vector. - * @param n The element for which data should be accessed. - * @return Read-only (constant) reference to data. - * - * This operator allows for easy, array-style, data access. - * Note that data access with this operator is unchecked and out_of_range - * lookups are not defined. (For checked lookups see at().) + * Returns a read/write iterator that points one past the last element in + * the %vector. Iteration is done in ordinary element order. */ - const_reference operator[](size_type __n) const { return *(begin() + __n); } - - void _M_range_check(size_type __n) const { - if (__n >= this->size()) - __throw_out_of_range("vector"); - } + iterator + end() { return iterator (_M_finish); } /** - * @brief Provides access to the data contained in the vector. - * @param n The element for which data should be accessed. - * @return Read/write reference to data. - * - * This function provides for safer data access. The parameter is first - * checked that it is in the range of the vector. The function throws - * out_of_range if the check fails. + * Returns a read-only (constant) iterator that points one past the last + * element in the %vector. Iteration is done in ordinary element order. */ - reference at(size_type __n) - { _M_range_check(__n); return (*this)[__n]; } + const_iterator + end() const { return const_iterator (_M_finish); } /** - * @brief Provides access to the data contained in the vector. - * @param n The element for which data should be accessed. - * @return Read-only (constant) reference to data. - * - * This function provides for safer data access. The parameter is first - * checked that it is in the range of the vector. The function throws - * out_of_range if the check fails. + * Returns a read/write reverse iterator that points to the last element in + * the %vector. Iteration is done in reverse element order. */ - const_reference at(size_type __n) const - { _M_range_check(__n); return (*this)[__n]; } - + reverse_iterator + rbegin() { return reverse_iterator(end()); } - explicit vector(const allocator_type& __a = allocator_type()) - : _Base(__a) {} + /** + * Returns a read-only (constant) reverse iterator that points to the last + * element in the %vector. Iteration is done in reverse element order. + */ + const_reverse_iterator + rbegin() const { return const_reverse_iterator(end()); } - vector(size_type __n, const _Tp& __value, - const allocator_type& __a = allocator_type()) - : _Base(__n, __a) - { _M_finish = uninitialized_fill_n(_M_start, __n, __value); } + /** + * Returns a read/write reverse iterator that points to one before the + * first element in the %vector. Iteration is done in reverse element + * order. + */ + reverse_iterator + rend() { return reverse_iterator(begin()); } - explicit vector(size_type __n) - : _Base(__n, allocator_type()) - { _M_finish = uninitialized_fill_n(_M_start, __n, _Tp()); } + /** + * Returns a read-only (constant) reverse iterator that points to one + * before the first element in the %vector. Iteration is done in reverse + * element order. + */ + const_reverse_iterator + rend() const { return const_reverse_iterator(begin()); } - vector(const vector<_Tp, _Alloc>& __x) - : _Base(__x.size(), __x.get_allocator()) - { _M_finish = uninitialized_copy(__x.begin(), __x.end(), _M_start); } + // [23.2.4.2] capacity + /** Returns the number of elements in the %vector. */ + size_type + size() const { return size_type(end() - begin()); } - // Check whether it's an integral type. If so, it's not an iterator. - template - vector(_InputIterator __first, _InputIterator __last, - const allocator_type& __a = allocator_type()) - : _Base(__a) - { - typedef typename _Is_integer<_InputIterator>::_Integral _Integral; - _M_initialize_aux(__first, __last, _Integral()); - } + /** Returns the size() of the largest possible %vector. */ + size_type + max_size() const { return size_type(-1) / sizeof(_Tp); } - template - void _M_initialize_aux(_Integer __n, _Integer __value, __true_type) - { - _M_start = _M_allocate(__n); - _M_end_of_storage = _M_start + __n; - _M_finish = uninitialized_fill_n(_M_start, __n, __value); - } + /** + * @brief Resizes the %vector to the specified number of elements. + * @param new_size Number of elements the %vector should contain. + * @param x Data with which new elements should be populated. + * + * This function will %resize the %vector to the specified number of + * elements. If the number is smaller than the %vector's current size the + * %vector is truncated, otherwise the %vector is extended and new elements + * are populated with given data. + */ + void + resize(size_type __new_size, const _Tp& __x) + { + if (__new_size < size()) + erase(begin() + __new_size, end()); + else + insert(end(), __new_size - size(), __x); + } - template - void - _M_initialize_aux(_InputIterator __first, _InputIterator __last, __false_type) - { - typedef typename iterator_traits<_InputIterator>::iterator_category _IterCategory; - _M_range_initialize(__first, __last, _IterCategory()); - } + /** + * @brief Resizes the %vector to the specified number of elements. + * @param new_size Number of elements the %vector should contain. + * + * This function will resize the %vector to the specified number of + * elements. If the number is smaller than the %vector's current size the + * %vector is truncated, otherwise the %vector is extended and new elements + * are default-constructed. + */ + void + resize(size_type __new_size) { resize(__new_size, _Tp()); } - ~vector() - { _Destroy(_M_start, _M_finish); } + /** + * Returns the total number of elements that the %vector can hold before + * needing to allocate more memory. + */ + size_type + capacity() const + { return size_type(const_iterator(_M_end_of_storage) - begin()); } - vector<_Tp, _Alloc>& operator=(const vector<_Tp, _Alloc>& __x); + /** + * Returns true if the %vector is empty. (Thus begin() would equal end().) + */ + bool + empty() const { return begin() == end(); } /** * @brief Attempt to preallocate enough memory for specified number of * elements. - * @param n Number of elements required + * @param n Number of elements required. + * @throw std::length_error If @a n exceeds @c max_size(). * - * This function attempts to reserve enough memory for the vector to hold + * This function attempts to reserve enough memory for the %vector to hold * the specified number of elements. If the number requested is more than - * max_size() length_error is thrown. + * max_size(), length_error is thrown. * * The advantage of this function is that if optimal code is a necessity - * and the user can determine the number of elements that will be required - * the user can reserve the memory and thus prevent a possible - * reallocation of memory and copy of vector data. + * and the user can determine the number of elements that will be required, + * the user can reserve the memory in %advance, and thus prevent a possible + * reallocation of memory and copying of %vector data. */ - void reserve(size_type __n) { + void + reserve(size_type __n) // FIXME should be out of class + { if (capacity() < __n) { const size_type __old_size = size(); pointer __tmp = _M_allocate_and_copy(__n, _M_start, _M_finish); @@ -402,88 +545,104 @@ public: } } - // assign(), a generalized assignment member function. Two - // versions: one that takes a count, and one that takes a range. - // The range version is a member template, so we dispatch on whether - // or not the type is an integer. - + // element access /** - * @brief Assigns a given value or range to a vector. - * @param n Number of elements to be assigned. - * @param val Value to be assigned. + * @brief Subscript access to the data contained in the %vector. + * @param n The index of the element for which data should be accessed. + * @return Read/write reference to data. * - * This function can be used to assign a range to a vector or fill it - * with a specified number of copies of the given value. - * Note that the assignment completely changes the vector and that the - * resulting vector's size is the same as the number of elements assigned. - * Old data may be lost. + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and out_of_range + * lookups are not defined. (For checked lookups see at().) */ - void assign(size_type __n, const _Tp& __val) { _M_fill_assign(__n, __val); } - void _M_fill_assign(size_type __n, const _Tp& __val); + reference + operator[](size_type __n) { return *(begin() + __n); } - template - void - assign(_InputIterator __first, _InputIterator __last) - { - typedef typename _Is_integer<_InputIterator>::_Integral _Integral; - _M_assign_dispatch(__first, __last, _Integral()); - } - - template - void - _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) - { _M_fill_assign((size_type) __n, (_Tp) __val); } + /** + * @brief Subscript access to the data contained in the %vector. + * @param n The index of the element for which data should be accessed. + * @return Read-only (constant) reference to data. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and out_of_range + * lookups are not defined. (For checked lookups see at().) + */ + const_reference + operator[](size_type __n) const { return *(begin() + __n); } - template - void - _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type) - { - typedef typename iterator_traits<_InputIter>::iterator_category _IterCategory; - _M_assign_aux(__first, __last, _IterCategory()); - } +protected: + /// @if maint Safety check used only from at(). @endif + void + _M_range_check(size_type __n) const + { + if (__n >= this->size()) + __throw_out_of_range("vector [] access out of range"); + } - template - void - _M_assign_aux(_InputIterator __first, _InputIterator __last, - input_iterator_tag); +public: + /** + * @brief Provides access to the data contained in the %vector. + * @param n The index of the element for which data should be accessed. + * @return Read/write reference to data. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter is first + * checked that it is in the range of the vector. The function throws + * out_of_range if the check fails. + */ + reference + at(size_type __n) { _M_range_check(__n); return (*this)[__n]; } - template - void - _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, - forward_iterator_tag); + /** + * @brief Provides access to the data contained in the %vector. + * @param n The index of the element for which data should be accessed. + * @return Read-only (constant) reference to data. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter is first + * checked that it is in the range of the vector. The function throws + * out_of_range if the check fails. + */ + const_reference + at(size_type __n) const { _M_range_check(__n); return (*this)[__n]; } /** * Returns a read/write reference to the data at the first element of the - * vector. + * %vector. */ - reference front() { return *begin(); } + reference + front() { return *begin(); } /** * Returns a read-only (constant) reference to the data at the first - * element of the vector. + * element of the %vector. */ - const_reference front() const { return *begin(); } + const_reference + front() const { return *begin(); } /** * Returns a read/write reference to the data at the last element of the - * vector. + * %vector. */ - reference back() { return *(end() - 1); } + reference + back() { return *(end() - 1); } /** - * Returns a read-only (constant) reference to the data at the first - * element of the vector. + * Returns a read-only (constant) reference to the data at the last + * element of the %vector. */ - const_reference back() const { return *(end() - 1); } + const_reference + back() const { return *(end() - 1); } + // [23.2.4.3] modifiers /** - * @brief Add data to the end of the vector. + * @brief Add data to the end of the %vector. * @param x Data to be added. * * This is a typical stack operation. The function creates an element at - * the end of the vector and assigns the given data to it. - * Due to the nature of a vector this operation can be done in constant - * time if the vector has preallocated space available. + * the end of the %vector and assigns the given data to it. + * Due to the nature of a %vector this operation can be done in constant + * time if the %vector has preallocated space available. */ void push_back(const _Tp& __x) @@ -496,43 +655,30 @@ public: _M_insert_aux(end(), __x); } -#ifdef _GLIBCPP_DEPRECATED /** - * Add an element to the end of the vector. The element is - * default-constructed. + * @brief Removes last element. * - * @note You must define _GLIBCPP_DEPRECATED to make this visible; see - * c++config.h. + * This is a typical stack operation. It shrinks the %vector by one. + * + * Note that no data is returned, and if the last element's data is + * needed, it should be retrieved before pop_back() is called. */ void - push_back() - { - if (_M_finish != _M_end_of_storage) { - _Construct(_M_finish); - ++_M_finish; - } - else - _M_insert_aux(end()); - } -#endif - - void - swap(vector<_Tp, _Alloc>& __x) + pop_back() { - std::swap(_M_start, __x._M_start); - std::swap(_M_finish, __x._M_finish); - std::swap(_M_end_of_storage, __x._M_end_of_storage); + --_M_finish; + _Destroy(_M_finish); } /** - * @brief Inserts given value into vector at specified element. - * @param position An iterator that points to the element where data - * should be inserted. + * @brief Inserts given value into %vector before specified iterator. + * @param position An iterator into the %vector. * @param x Data to be inserted. * @return An iterator that points to the inserted data. * - * This function will insert the given value into the specified location. - * Note that this kind of operation could be expensive for a vector and if + * This function will insert a copy of the given value before the specified + * location. + * Note that this kind of operation could be expensive for a %vector and if * it is frequently used the user should consider using std::list. */ iterator @@ -548,16 +694,21 @@ public: return begin() + __n; } +#ifdef _GLIBCPP_DEPRECATED /** - * @brief Inserts an empty element into the vector. - * @param position An iterator that points to the element where empty - * element should be inserted. - * @param x Data to be inserted. + * @brief Inserts an element into the %vector. + * @param position An iterator into the %vector. * @return An iterator that points to the inserted element. * - * This function will insert an empty element into the specified location. + * This function will insert a default-constructed element before the + * specified location. You should consider using insert(position,Tp()) + * instead. * Note that this kind of operation could be expensive for a vector and if * it is frequently used the user should consider using std::list. + * + * @note This was deprecated in 3.2 and will be removed in 3.3. You must + * define @c _GLIBCPP_DEPRECATED to make this visible in 3.2; see + * c++config.h. */ iterator insert(iterator __position) @@ -571,70 +722,78 @@ public: _M_insert_aux(iterator(__position)); return begin() + __n; } - - // Check whether it's an integral type. If so, it's not an iterator. - template - void - insert(iterator __pos, _InputIterator __first, _InputIterator __last) - { - typedef typename _Is_integer<_InputIterator>::_Integral _Integral; - _M_insert_dispatch(__pos, __first, __last, _Integral()); - } - - template - void - _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val, __true_type) - { _M_fill_insert(__pos, static_cast(__n), static_cast<_Tp>(__val)); } - - template - void - _M_insert_dispatch(iterator __pos, - _InputIterator __first, _InputIterator __last, - __false_type) - { - typedef typename iterator_traits<_InputIterator>::iterator_category _IterCategory; - _M_range_insert(__pos, __first, __last, _IterCategory()); - } +#endif /** - * @brief Inserts a number of copies of given data into the vector. - * @param position An iterator that points to the element where data - * should be inserted. - * @param n Amount of elements to be inserted. + * @brief Inserts a number of copies of given data into the %vector. + * @param position An iterator into the %vector. + * @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 - * into the specified location. + * before the location specified by @a position. * - * Note that this kind of operation could be expensive for a vector and if + * Note that this kind of operation could be expensive for a %vector and if * it is frequently used the user should consider using std::list. */ - 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); } - void _M_fill_insert (iterator __pos, size_type __n, const _Tp& __x); +protected: + void + _M_fill_insert (iterator __pos, size_type __n, const _Tp& __x); +public: /** - * @brief Removes last element from vector. + * @brief Inserts a range into the %vector. + * @param pos An iterator into the %vector. + * @param first An input iterator. + * @param last An input iterator. * - * This is a typical stack operation. It allows us to shrink the vector by - * one. + * This function will insert copies of the data in the range [first,last) + * into the %vector before the location specified by @a pos. * - * Note that no data is returned and if last element's data is needed it - * should be retrieved before pop_back() is called. + * Note that this kind of operation could be expensive for a %vector and if + * it is frequently used the user should consider using std::list. */ - void pop_back() { - --_M_finish; - _Destroy(_M_finish); - } + template + void + insert(iterator __pos, _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(__pos, __first, __last, _Integral()); + } +protected: + template + void + _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val, + __true_type) + { + _M_fill_insert(__pos, static_cast(__n), + static_cast<_Tp>(__val)); + } + + template + void + _M_insert_dispatch(iterator __pos, _InputIterator __first, + _InputIterator __last, __false_type) + { + typedef typename iterator_traits<_InputIterator>::iterator_category + _IterCategory; + _M_range_insert(__pos, __first, __last, _IterCategory()); + } + +public: /** - * @brief Remove element at given position + * @brief Remove element at given position. * @param position Iterator pointing to element to be erased. - * @return Doc Me! (Iterator pointing to new element at old location?) + * @return An iterator pointing to the next element (or end()). * * This function will erase the element at the given position and thus - * shorten the vector by one. + * shorten the %vector by one. * * Note This operation could be expensive and if it is frequently used the * user should consider using std::list. The user is also cautioned that @@ -642,7 +801,9 @@ public: * a pointer, the pointed-to memory is not touched in any way. Managing * the pointer is the user's responsibilty. */ - iterator erase(iterator __position) { + iterator + erase(iterator __position) + { if (__position + 1 != end()) copy(__position + 1, end(), __position); --_M_finish; @@ -651,13 +812,14 @@ public: } /** - * @brief Remove a range of elements from a vector. + * @brief Remove a range of elements. * @param first Iterator pointing to the first element to be erased. - * @param last Iterator pointing to the last element to be erased. - * @return Doc Me! (Iterator pointing to new element at old location?) + * @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 given range and shorten the - * vector accordingly. + * This function will erase the elements in the range [first,last) and + * shorten the %vector accordingly. * * Note This operation could be expensive and if it is frequently used the * user should consider using std::list. The user is also cautioned that @@ -665,7 +827,9 @@ public: * 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) { + iterator + erase(iterator __first, iterator __last) + { iterator __i(copy(__last, end(), __first)); _Destroy(__i, end()); _M_finish = _M_finish - (__last - __first); @@ -673,52 +837,43 @@ public: } /** - * @brief Resizes the vector to the specified number of elements. - * @param new_size Number of elements the vector should contain. - * @param x Data with which new elements should be populated. + * @brief Swaps data with another %vector. + * @param x A %vector of the same element and allocator types. * - * This function will resize the vector to the specified number of - * elements. If the number is smaller than the vector's current size the - * vector is truncated, otherwise the vector is extended and new elements - * are populated with given data. + * This exchanges the elements between two vectors in constant time. + * (Three pointers, so it should be quite fast.) + * Note that the global std::swap() function is specialized such that + * std::swap(v1,v2) will feed to this function. */ - void resize(size_type __new_size, const _Tp& __x) { - if (__new_size < size()) - erase(begin() + __new_size, end()); - else - insert(end(), __new_size - size(), __x); + void + swap(vector<_Tp, _Alloc>& __x) + { + std::swap(_M_start, __x._M_start); + std::swap(_M_finish, __x._M_finish); + std::swap(_M_end_of_storage, __x._M_end_of_storage); } /** - * @brief Resizes the vector to the specified number of elements. - * @param new_size Number of elements the vector should contain. - * - * This function will resize the vector to the specified number of - * elements. If the number is smaller than the vector's current size the - * vector is truncated, otherwise the vector is extended and new elements - * are left uninitialized. - */ - void resize(size_type __new_size) { resize(__new_size, _Tp()); } - - /** - * Erases all elements in vector. Note that this function only erases the + * 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() { erase(begin(), end()); } + void + clear() { erase(begin(), end()); } protected: - template - pointer _M_allocate_and_copy(size_type __n, _ForwardIterator __first, - _ForwardIterator __last) + pointer + _M_allocate_and_copy(size_type __n, _ForwardIterator __first, + _ForwardIterator __last) { pointer __result = _M_allocate(__n); - try { - uninitialized_copy(__first, __last, __result); - return __result; - } + try + { + uninitialized_copy(__first, __last, __result); + return __result; + } catch(...) { _M_deallocate(__result, __n); @@ -727,8 +882,9 @@ protected: } template - void _M_range_initialize(_InputIterator __first, - _InputIterator __last, input_iterator_tag) + void + _M_range_initialize(_InputIterator __first, + _InputIterator __last, input_iterator_tag) { for ( ; __first != __last; ++__first) push_back(*__first); @@ -756,6 +912,17 @@ protected: forward_iterator_tag); }; + +/** + * @brief Vector equality comparison. + * @param x A %vector. + * @param y A %vector of the same type as @a x. + * @return True iff the size and elements of the vectors are equal. + * + * This is an equivalence relation. It is linear in the size of the + * vectors. Vectors are considered equivalent if their sizes are equal, + * and if corresponding elements compare equal. +*/ template inline bool operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) @@ -764,6 +931,17 @@ operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) equal(__x.begin(), __x.end(), __y.begin()); } +/** + * @brief Vector ordering relation. + * @param x A %vector. + * @param y A %vector of the same type as @a x. + * @return True iff @a x is lexographically less than @a y. + * + * This is a total ordering relation. It is linear in the size of the + * vectors. The elements must be comparable with @c <. + * + * See std::lexographical_compare() for how the determination is made. +*/ template inline bool operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) @@ -772,36 +950,42 @@ operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) __y.begin(), __y.end()); } +/// See std::vector::swap(). template inline void swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y) { __x.swap(__y); } +/// Based on operator== template inline bool operator!=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { return !(__x == __y); } +/// Based on operator< template inline bool operator>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { return __y < __x; } +/// Based on operator< template inline bool operator<=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { return !(__y < __x); } +/// Based on operator< template inline bool operator>=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) { return !(__x < __y); } +// XXX begin tcc me template vector<_Tp,_Alloc>& vector<_Tp,_Alloc>::operator=(const vector<_Tp, _Alloc>& __x) @@ -919,6 +1103,7 @@ vector<_Tp, _Alloc>::_M_insert_aux(iterator __position, const _Tp& __x) } } +#ifdef _GLIBCPP_DEPRECATED template void vector<_Tp, _Alloc>::_M_insert_aux(iterator __position) @@ -956,6 +1141,7 @@ vector<_Tp, _Alloc>::_M_insert_aux(iterator __position) _M_end_of_storage = __new_start + __len; } } +#endif template void vector<_Tp, _Alloc>::_M_fill_insert(iterator __position, size_type __n, @@ -1078,6 +1264,3 @@ vector<_Tp, _Alloc>::_M_range_insert(iterator __position, #endif /* __GLIBCPP_INTERNAL_VECTOR_H */ -// Local Variables: -// mode:C++ -// End: