Index: cpp_type_traits.h =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/cpp_type_traits.h,v retrieving revision 1.8 diff -c -3 -p -r1.8 cpp_type_traits.h *** cpp_type_traits.h 5 Jul 2003 04:05:34 -0000 1.8 --- cpp_type_traits.h 28 Jul 2003 17:37:02 -0000 *************** *** 39,44 **** --- 39,47 ---- #pragma GCC system_header + #include + #include + // // This file provides some compile-time information about various types. // These representations were designed, on purpose, to be constant-expressions *************** namespace std *** 326,332 **** }; }; ! } // namespace std #endif //_CPP_TYPE_TRAITS_H --- 329,390 ---- }; }; ! template ! struct __is_pod<_Tp*> ! { ! enum ! { ! _M_type = 1 ! }; ! }; ! ! // Primary template has maximum alignment ! template ! struct _Type_with_alignment ! { struct __attribute__((__aligned__)) _M_type {}; }; ! ! #define _GLIBCXX_TYPE_WITH_ALIGNMENT(_Align) \ ! template<> \ ! struct _Type_with_alignment<_Align> \ ! { struct __attribute__((__aligned__(_Align))) _M_type {}; } ! ! _GLIBCXX_TYPE_WITH_ALIGNMENT(1); ! _GLIBCXX_TYPE_WITH_ALIGNMENT(2); ! _GLIBCXX_TYPE_WITH_ALIGNMENT(4); ! _GLIBCXX_TYPE_WITH_ALIGNMENT(8); ! _GLIBCXX_TYPE_WITH_ALIGNMENT(16); ! #undef _GLIBCXX_TYPE_WITH_ALIGNMENT ! ! template ! struct _Basic_pod ! { ! union { ! char _M_bytes[_Size]; ! typename _Type_with_alignment<_Alignment>::_M_type _M_align; ! }; ! }; ! ! template::_M_type> ! struct _Store_as ! { typedef _Tp _M_type; }; ! ! template ! struct _Store_as<_Tp, true> ! { ! typedef _Basic_pod _M_type; ! }; ! ! } // namespace std ! ! template ! struct __type_traits > ! { ! typedef __true_type has_trivial_default_constructor; ! typedef __true_type has_trivial_copy_constructor; ! typedef __true_type has_trivial_assignment_operator; ! typedef __true_type has_trivial_destructor; ! typedef __true_type is_POD_type; ! }; #endif //_CPP_TYPE_TRAITS_H Index: stl_vector.h =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/stl_vector.h,v retrieving revision 1.40 diff -c -3 -p -r1.40 stl_vector.h *** stl_vector.h 14 Jul 2003 02:52:04 -0000 1.40 --- stl_vector.h 28 Jul 2003 17:37:02 -0000 *************** *** 64,69 **** --- 64,70 ---- #include #include #include + #include namespace std { *************** namespace std *** 163,168 **** --- 164,352 ---- this->_M_end_of_storage - this->_M_start); } }; + /** + * @if maint + * This class template performs the majority of the work for the + * %vector. It is separated from the actual vector class because the + * data type stored (_Tp) and manipulated here may be different from + * (but must be a POD type isomorphic to) the type the user + * specified. The derived %vector will jump through the necessary + * hoops to make this work, with the result being that we can share + * this code. + * @endif + */ + template + class _Vector_impl + : protected _Vector_base<_Tp, _Alloc> + { + typedef _Vector_base<_Tp, _Alloc> _Base; + + public: + typedef _Tp value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef __gnu_cxx::__normal_iterator + iterator; + typedef __gnu_cxx::__normal_iterator + const_iterator; + typedef size_t size_type; + 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; + using _Base::_M_finish; + using _Base::_M_end_of_storage; + + public: + // [23.2.4.1] construct/copy/destroy + explicit + _Vector_impl(const allocator_type& __a = allocator_type()) + : _Base(__a) { } + + _Vector_impl(size_type __n, const value_type& __value, + const allocator_type& __a) + : _Base(__n, __a) + { this->_M_finish = std::uninitialized_fill_n(this->_M_start, __n, + __value); } + _Vector_impl(const _Vector_impl& __x) + : _Base(__x.size(), __x.get_allocator()) + { this->_M_finish = std::uninitialized_copy(__x._M_start, __x._M_finish, + this->_M_start); } + + ~_Vector_impl() { std::_Destroy(this->_M_start, this->_M_finish); } + + _Vector_impl& + operator=(const _Vector_impl& __x); + + allocator_type + get_allocator() const { return _Base::get_allocator(); } + + // iterators + iterator + begin() { return iterator (this->_M_start); } + + const_iterator + begin() const { return const_iterator (this->_M_start); } + + iterator + end() { return iterator (this->_M_finish); } + + const_iterator + end() const { return const_iterator (this->_M_finish); } + + // [23.2.4.2] capacity + size_type + size() const { return size_type(this->_M_finish - this->_M_start); } + + size_type + max_size() const { return size_type(-1) / sizeof(value_type); } + + void + resize(size_type __new_size, const value_type& __x) + { + if (__new_size < size()) + erase(begin() + __new_size, end()); + else + _M_fill_insert(end(), __new_size - size(), __x); + } + + size_type + capacity() const + { return size_type(this->_M_end_of_storage - this->_M_start); } + + bool + empty() const { return this->_M_start == this->_M_finish; } + + void + reserve(size_type __n); + + // [23.2.4.3] modifiers + void + push_back(const value_type& __x) + { + if (this->_M_finish != this->_M_end_of_storage) + { + std::_Construct(this->_M_finish, __x); + ++this->_M_finish; + } + else + _M_insert_aux(end(), __x); + } + + void + pop_back() + { + --this->_M_finish; + std::_Destroy(this->_M_finish); + } + + iterator + insert(iterator __position, const value_type& __x); + + iterator + erase(iterator __position); + + iterator + erase(iterator __first, iterator __last); + + void + swap(_Vector_impl& __x) + { + std::swap(this->_M_start, __x._M_start); + std::swap(this->_M_finish, __x._M_finish); + std::swap(this->_M_end_of_storage, __x._M_end_of_storage); + } + + void + clear() { erase(begin(), end()); } + + protected: + /** + * @if maint + * Memory expansion handler. Uses the member allocation function to + * obtain @a n bytes of memory, and then copies [first,last) into it. + * @endif + */ + template + pointer + _M_allocate_and_copy(size_type __n, + _ForwardIterator __first, _ForwardIterator __last) + { + pointer __result = this->_M_allocate(__n); + try + { + std::uninitialized_copy(__first, __last, __result); + return __result; + } + catch(...) + { + _M_deallocate(__result, __n); + __throw_exception_again; + } + } + + // 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); + + // 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); + + // Called by insert(p,x) + void + _M_insert_aux(iterator __position, const value_type& __x); + }; /** * @brief A standard container which offers fixed time access to individual *************** namespace std *** 182,234 **** * and saves the user from worrying about memory and size allocation. * Subscripting ( @c [] ) access is also provided as with C-style arrays. */ ! template > ! class vector : protected _Vector_base<_Tp, _Alloc> { // Concept requirements. __glibcxx_class_requires(_Tp, _SGIAssignableConcept) ! ! typedef _Vector_base<_Tp, _Alloc> _Base; ! typedef vector<_Tp, _Alloc> vector_type; ! public: ! typedef _Tp value_type; ! typedef value_type* pointer; ! typedef const value_type* const_pointer; ! typedef __gnu_cxx::__normal_iterator iterator; ! typedef __gnu_cxx::__normal_iterator ! 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: ! /** @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; ! using _Base::_M_finish; ! using _Base::_M_end_of_storage; public: ! // [23.2.4.1] construct/copy/destroy // (assign() and get_allocator() are also listed in this section) /** * @brief Default constructor creates no elements. */ ! explicit ! vector(const allocator_type& __a = allocator_type()) ! : _Base(__a) { } ! /** * @brief Create a %vector with copies of an exemplar element. * @param n The number of elements to initially create. --- 366,451 ---- * and saves the user from worrying about memory and size allocation. * Subscripting ( @c [] ) access is also provided as with C-style arrays. */ ! template > ! class vector ! : public _Vector_impl::_M_type, ! typename _Allocator::template rebind< ! typename _Store_as<_Tp>::_M_type>::other> { // Concept requirements. __glibcxx_class_requires(_Tp, _SGIAssignableConcept) ! ! typedef typename _Store_as<_Tp>::_M_type _Stored; ! typedef typename _Allocator::template rebind<_Stored>::other _Base_alloc; ! typedef _Vector_impl<_Stored, _Base_alloc> _Base; ! ! typedef typename _Base::iterator _Base_iterator; ! public: ! typedef _Tp& reference; ! typedef const _Tp& const_reference; ! typedef _Tp* pointer; ! typedef const _Tp* const_pointer; ! ! typedef __gnu_cxx::__normal_iterator iterator; ! typedef __gnu_cxx::__normal_iterator const_iterator; ! ! typedef typename _Base::size_type size_type; ! typedef ptrdiff_t difference_type; ! ! typedef _Tp value_type; ! typedef _Allocator allocator_type; ! typedef std::reverse_iterator reverse_iterator; ! typedef std::reverse_iterator const_reverse_iterator; ! ! private: ! /* _M_stored converts from a form of value_type (e.g., a ! reference, pointer or iterator as the user sees it) to the ! corresponding stored type (e.g., as the base class sees ! it). Used to pass values to the implementation base class. */ ! _Stored& _M_stored(_Tp& __x) const ! { return reinterpret_cast<_Stored&>(__x); } ! ! const _Stored& _M_stored(const _Tp& __x) const ! { return reinterpret_cast(__x); } ! ! _Stored* _M_stored(_Tp* __x) const ! { return reinterpret_cast<_Stored*>(__x); } ! ! const _Stored* _M_stored(const _Tp* __x) const ! { return reinterpret_cast(__x); } ! ! _Base_iterator _M_stored(iterator __x) const ! { return _Base_iterator(_M_stored(__x.base())); } ! ! /* _M_value converts from a form of the stored data type (e.g., a ! reference, pointer or iterator as the implementation, well, ! stores sees it) to the corresponding value type type (e.g., as ! the user sees it). Used to pass values received back from the ! implementation base class to the user. */ ! _Tp& _M_value(_Stored& __x) const ! { return reinterpret_cast<_Tp&>(__x); } ! ! const _Tp& _M_value(const _Stored& __x) const ! { return reinterpret_cast(__x); } ! _Tp* _M_value(_Stored* __x) const ! { return reinterpret_cast<_Tp*>(__x); } ! ! const _Tp* _M_value(const _Stored* __x) const ! { return reinterpret_cast(__x); } ! ! iterator _M_value(_Base_iterator __x) const ! { return iterator(_M_value(__x.base())); } public: ! // 23.2.4.1 construct/copy/destroy: // (assign() and get_allocator() are also listed in this section) /** * @brief Default constructor creates no elements. */ ! explicit vector(const _Allocator& __a = _Allocator()) : _Base(__a) { } ! /** * @brief Create a %vector with copies of an exemplar element. * @param n The number of elements to initially create. *************** namespace std *** 236,246 **** * * This constructor fills the %vector with @a n copies of @a value. */ ! vector(size_type __n, const value_type& __value, ! const allocator_type& __a = allocator_type()) ! : _Base(__n, __a) ! { this->_M_finish = std::uninitialized_fill_n(this->_M_start, __n, __value); } ! /** * @brief Create a %vector with default elements. * @param n The number of elements to initially create. --- 453,464 ---- * * This constructor fills the %vector with @a n copies of @a value. */ ! explicit ! vector(size_type __n, const _Tp& __value, ! const _Allocator& __a = _Allocator()) ! : _Base(__n, _M_stored(__value), __a) ! { } ! /** * @brief Create a %vector with default elements. * @param n The number of elements to initially create. *************** namespace std *** 248,274 **** * This constructor fills the %vector with @a n copies of a * default-constructed element. */ ! explicit ! vector(size_type __n) ! : _Base(__n, allocator_type()) ! { this->_M_finish = std::uninitialized_fill_n(this->_M_start, ! __n, value_type()); } ! ! /** ! * @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. ! */ ! vector(const vector& __x) ! : _Base(__x.size(), __x.get_allocator()) ! { this->_M_finish = std::uninitialized_copy(__x.begin(), __x.end(), ! this->_M_start); ! } ! /** * @brief Builds a %vector from a range. * @param first An input iterator. --- 466,476 ---- * This constructor fills the %vector with @a n copies of a * default-constructed element. */ ! explicit ! vector(size_type __n) ! : _Base(__n, _M_stored(_Tp()), _Allocator()) ! { } ! /** * @brief Builds a %vector from a range. * @param first An input iterator. *************** namespace std *** 284,305 **** * copy constructor, and logN memory reallocations. */ 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_dispatch(__first, __last, _Integral()); } ! /** * The dtor only erases the elements, and note that if the elements * themselves are pointers, the pointed-to memory is not touched in any * way. Managing the pointer is the user's responsibilty. */ ! ~vector() { std::_Destroy(this->_M_start, this->_M_finish); } ! /** * @brief %Vector assignment operator. * @param x A %vector of identical element and allocator types. --- 486,517 ---- * copy constructor, and logN memory reallocations. */ template ! vector(_InputIterator __first, _InputIterator __last, ! const _Allocator& __a = _Allocator()) : _Base(__a) { typedef typename _Is_integer<_InputIterator>::_Integral _Integral; _M_initialize_dispatch(__first, __last, _Integral()); } ! ! /** ! * @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. ! */ ! vector(const vector<_Tp,_Allocator>& __x) : _Base(__x) { } ! /** * The dtor only erases the elements, and note that if the elements * themselves are pointers, the pointed-to memory is not touched in any * way. Managing the pointer is the user's responsibilty. */ ! ~vector() { } ! /** * @brief %Vector assignment operator. * @param x A %vector of identical element and allocator types. *************** namespace std *** 308,316 **** * @a x (for fast expansion) will not be copied. Unlike the * copy constructor, the allocator object is not copied. */ ! vector& ! operator=(const vector& __x); ! /** * @brief Assigns a given value to a %vector. * @param n Number of elements to be assigned. --- 520,532 ---- * @a x (for fast expansion) will not be copied. Unlike the * copy constructor, the allocator object is not copied. */ ! vector<_Tp,_Allocator>& ! operator=(const vector<_Tp,_Allocator>& __x) ! { ! static_cast<_Base&>(*this) = __x; ! return *this; ! } ! /** * @brief Assigns a given value to a %vector. * @param n Number of elements to be assigned. *************** namespace std *** 321,331 **** * %vector and that the resulting %vector'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 %vector. * @param first An input iterator. * @param last An input iterator. --- 537,547 ---- * %vector and that the resulting %vector's size is the same as * the number of elements assigned. Old data may be lost. */ ! void ! assign(size_type __n, const _Tp& __val) ! { this->_M_fill_assign(__n, _M_stored(__val)); } ! ! /** * @brief Assigns a range to a %vector. * @param first An input iterator. * @param last An input iterator. *************** namespace std *** 337,427 **** * that the resulting %vector'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 * %vector. Iteration is done in ordinary element order. */ ! iterator ! begin() { return iterator (this->_M_start); } ! /** * Returns a read-only (constant) iterator that points to the * first element in the %vector. Iteration is done in ordinary * element order. */ ! const_iterator ! begin() const { return const_iterator (this->_M_start); } ! /** * Returns a read/write iterator that points one past the last * element in the %vector. Iteration is done in ordinary * element order. */ ! iterator ! end() { return iterator (this->_M_finish); } ! /** * Returns a read-only (constant) iterator that points one past the last * element in the %vector. Iteration is done in ordinary element order. */ ! const_iterator ! end() const { return const_iterator (this->_M_finish); } ! /** * Returns a read/write reverse iterator that points to the * last element in the %vector. 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 %vector. 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 %vector. 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 %vector. Iteration * is done in reverse element order. */ ! const_reverse_iterator ! rend() const { return const_reverse_iterator(begin()); } ! ! // [23.2.4.2] capacity /** Returns the number of elements in the %vector. */ size_type ! size() const { return size_type(end() - begin()); } ! /** Returns the size() of the largest possible %vector. */ size_type ! max_size() const { return size_type(-1) / sizeof(value_type); } ! /** * @brief Resizes the %vector to the specified number of elements. * @param new_size Number of elements the %vector should contain. --- 553,650 ---- * that the resulting %vector's size is the same as the number * of elements assigned. Old data may be lost. */ ! template ! void ! assign(_InputIterator __first, _InputIterator __last) ! { 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 * %vector. Iteration is done in ordinary element order. */ ! iterator ! begin() ! { return iterator(_M_value(this->_M_start)); } ! /** * Returns a read-only (constant) iterator that points to the * first element in the %vector. Iteration is done in ordinary * element order. */ ! const_iterator ! begin() const ! { return const_iterator(_M_value(this->_M_start)); } ! /** * Returns a read/write iterator that points one past the last * element in the %vector. Iteration is done in ordinary * element order. */ ! iterator ! end() ! { return iterator(_M_value(this->_M_finish)); } ! /** * Returns a read-only (constant) iterator that points one past the last * element in the %vector. Iteration is done in ordinary element order. */ ! const_iterator ! end() const ! { return const_iterator(_M_value(this->_M_finish)); } ! /** * Returns a read/write reverse iterator that points to the * last element in the %vector. 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 %vector. 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 %vector. 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 %vector. Iteration * is done in reverse element order. */ ! const_reverse_iterator ! rend() const ! { return const_reverse_iterator(begin()); } ! ! // 23.2.4.2 capacity: /** Returns the number of elements in the %vector. */ size_type ! size() const { return _Base::size(); } ! /** Returns the size() of the largest possible %vector. */ size_type ! max_size() const { return _Base::max_size(); } ! /** * @brief Resizes the %vector to the specified number of elements. * @param new_size Number of elements the %vector should contain. *************** namespace std *** 433,447 **** * the %vector is extended and new elements are populated with * given data. */ ! void ! resize(size_type __new_size, const value_type& __x) ! { ! if (__new_size < size()) ! erase(begin() + __new_size, end()); ! else ! insert(end(), __new_size - size(), __x); ! } ! /** * @brief Resizes the %vector to the specified number of elements. * @param new_size Number of elements the %vector should contain. --- 656,665 ---- * the %vector is extended and new elements are populated with * given data. */ ! void ! resize(size_type __new_size, _Tp __x) ! { _Base::resize(__new_size, _M_stored(__x)); } ! /** * @brief Resizes the %vector to the specified number of elements. * @param new_size Number of elements the %vector should contain. *************** namespace std *** 452,458 **** * the %vector is extended and new elements are * default-constructed. */ ! void resize(size_type __new_size) { resize(__new_size, value_type()); } /** --- 670,676 ---- * the %vector is extended and new elements are * default-constructed. */ ! void resize(size_type __new_size) { resize(__new_size, value_type()); } /** *************** namespace std *** 460,475 **** * needing to allocate more memory. */ size_type ! capacity() const ! { return size_type(const_iterator(this->_M_end_of_storage) - begin()); } ! /** * 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. --- 678,692 ---- * needing to allocate more memory. */ size_type ! capacity() const { return _Base::capacity(); } ! /** * Returns true if the %vector is empty. (Thus begin() would * equal end().) */ bool ! empty() const { return _Base::capacity(); } ! /** * @brief Attempt to preallocate enough memory for specified number of * elements. *************** namespace std *** 488,496 **** * and copying of %vector data. */ void ! reserve(size_type __n); ! ! // element access /** * @brief Subscript access to the data contained in the %vector. * @param n The index of the element for which data should be accessed. --- 705,713 ---- * and copying of %vector data. */ void ! reserve(size_type __n) { _Base::reserve(__n); } ! ! // element access: /** * @brief Subscript access to the data contained in the %vector. * @param n The index of the element for which data should be accessed. *************** namespace std *** 517,533 **** */ const_reference operator[](size_type __n) const { return *(begin() + __n); } ! ! 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(__N("vector::_M_range_check")); ! } ! ! public: /** * @brief Provides access to the data contained in the %vector. * @param n The index of the element for which data should be --- 734,740 ---- */ const_reference operator[](size_type __n) const { return *(begin() + __n); } ! /** * @brief Provides access to the data contained in the %vector. * @param n The index of the element for which data should be *************** namespace std *** 583,590 **** */ const_reference back() const { return *(end() - 1); } ! ! // [23.2.4.3] modifiers /** * @brief Add data to the end of the %vector. * @param x Data to be added. --- 790,807 ---- */ const_reference back() const { return *(end() - 1); } ! ! 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(__N("vector::_M_range_check")); ! } ! ! public: ! // 23.2.4.3 modifiers: /** * @brief Add data to the end of the %vector. * @param x Data to be added. *************** namespace std *** 595,612 **** * done in constant time if the %vector has preallocated space * available. */ ! void ! push_back(const value_type& __x) ! { ! if (this->_M_finish != this->_M_end_of_storage) ! { ! std::_Construct(this->_M_finish, __x); ! ++this->_M_finish; ! } ! else ! _M_insert_aux(end(), __x); ! } ! /** * @brief Removes last element. * --- 812,820 ---- * done in constant time if the %vector has preallocated space * available. */ ! void ! push_back(const _Tp& __x) { _Base::push_back(_M_stored(__x)); } ! /** * @brief Removes last element. * *************** namespace std *** 615,627 **** * 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() ! { ! --this->_M_finish; ! std::_Destroy(this->_M_finish); ! } ! /** * @brief Inserts given value into %vector before specified iterator. * @param position An iterator into the %vector. --- 823,831 ---- * 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() { _Base::pop_back(); } ! /** * @brief Inserts given value into %vector before specified iterator. * @param position An iterator into the %vector. *************** namespace std *** 633,640 **** * could be expensive for a %vector and if it is frequently * used the user should consider using std::list. */ ! iterator ! insert(iterator __position, const value_type& __x); /** * @brief Inserts a number of copies of given data into the %vector. --- 837,845 ---- * could be expensive for a %vector and if it is frequently * used the user should consider using std::list. */ ! iterator ! insert(iterator __position, const _Tp& __x) ! { return _M_value(_Base::insert(_M_stored(__position), _M_stored(__x))); } /** * @brief Inserts a number of copies of given data into the %vector. *************** namespace std *** 649,659 **** * %vector and if it is frequently used the user should * consider using std::list. */ ! void ! insert(iterator __position, size_type __n, const value_type& __x) ! { _M_fill_insert(__position, __n, __x); } ! ! /** * @brief Inserts a range into the %vector. * @param position An iterator into the %vector. * @param first An input iterator. --- 854,864 ---- * %vector and if it is frequently used the user should * consider using std::list. */ ! void ! insert(iterator __position, size_type __n, const _Tp& __x) ! { this->_M_fill_insert(_M_stored(__position), __n, _M_stored(__x)); } ! ! /** * @brief Inserts a range into the %vector. * @param position An iterator into the %vector. * @param first An input iterator. *************** namespace std *** 667,681 **** * %vector and if it is frequently used the user should * consider using std::list. */ ! 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. --- 872,887 ---- * %vector and if it is frequently used the user should * consider using std::list. */ ! 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. *************** namespace std *** 691,699 **** * 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. --- 897,906 ---- * the pointed-to memory is not touched in any way. Managing * the pointer is the user's responsibilty. */ ! iterator ! erase(iterator __position) ! { return _M_value(_Base::erase(_M_stored(__position))); } ! /** * @brief Remove a range of elements. * @param first Iterator pointing to the first element to be erased. *************** namespace std *** 712,720 **** * 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); ! /** * @brief Swaps data with another %vector. * @param x A %vector of the same element and allocator types. --- 919,928 ---- * 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) ! { return _M_value(_Base::erase(_M_stored(__first), _M_stored(__last))); } ! /** * @brief Swaps data with another %vector. * @param x A %vector of the same element and allocator types. *************** namespace std *** 724,747 **** * Note that the global std::swap() function is specialized such that * std::swap(v1,v2) will feed to this function. */ ! void ! swap(vector& __x) ! { ! std::swap(this->_M_start, __x._M_start); ! std::swap(this->_M_finish, __x._M_finish); ! std::swap(this->_M_end_of_storage, __x._M_end_of_storage); ! } ! /** * 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()); } ! ! protected: /** * @if maint * Memory expansion handler. Uses the member allocation function to --- 932,952 ---- * Note that the global std::swap() function is specialized such that * std::swap(v1,v2) will feed to this function. */ ! void ! swap(vector<_Tp,_Allocator>& __x) ! { _Base::swap(__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::clear(); } ! ! protected: /** * @if maint * Memory expansion handler. Uses the member allocation function to *************** namespace std *** 753,759 **** _M_allocate_and_copy(size_type __n, _ForwardIterator __first, _ForwardIterator __last) { ! pointer __result = this->_M_allocate(__n); try { std::uninitialized_copy(__first, __last, __result); --- 958,964 ---- _M_allocate_and_copy(size_type __n, _ForwardIterator __first, _ForwardIterator __last) { ! pointer __result = _M_value(this->_M_allocate(__n)); try { std::uninitialized_copy(__first, __last, __result); *************** namespace std *** 761,795 **** } catch(...) { ! _M_deallocate(__result, __n); __throw_exception_again; } } ! ! // Internal constructor functions follow. ! // Called by the range constructor to implement [23.1.1]/9 template void _M_initialize_dispatch(_Integer __n, _Integer __value, __true_type) { ! this->_M_start = _M_allocate(__n); ! this->_M_end_of_storage = this->_M_start + __n; ! this->_M_finish = std::uninitialized_fill_n(this->_M_start, __n, __value); ! } // Called by the range constructor to implement [23.1.1]/9 template void _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, ! __false_type) { ! typedef typename iterator_traits<_InputIterator>::iterator_category ! _IterCategory; ! _M_range_initialize(__first, __last, _IterCategory()); ! } ! // Called by the second initialize_dispatch above template void --- 966,1000 ---- } catch(...) { ! this->_M_deallocate(_M_stored(__result), __n); __throw_exception_again; } } ! // Internal constructor functions follow. ! // Called by the range constructor to implement [23.1.1]/9 template void _M_initialize_dispatch(_Integer __n, _Integer __value, __true_type) { ! this->_M_start = _M_allocate(__n); ! this->_M_end_of_storage = this->_M_start + __n; ! this->_M_finish = std::uninitialized_fill_n(this->_M_start, __n, ! _M_stored(__value)); ! } // Called by the range constructor to implement [23.1.1]/9 template void _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, ! __false_type) { ! typedef typename iterator_traits<_InputIterator>::iterator_category ! _IterCategory; ! _M_range_initialize(__first, __last, _IterCategory()); ! } ! // Called by the second initialize_dispatch above template void *************** namespace std *** 809,819 **** size_type __n = std::distance(__first, __last); this->_M_start = this->_M_allocate(__n); this->_M_end_of_storage = this->_M_start + __n; ! this->_M_finish = std::uninitialized_copy(__first, __last, ! this->_M_start); } ! ! // Internal assign functions follow. The *_aux functions do the actual // assignment work for the range versions. --- 1014,1024 ---- size_type __n = std::distance(__first, __last); this->_M_start = this->_M_allocate(__n); this->_M_end_of_storage = this->_M_start + __n; ! this->_M_finish = ! _M_stored(std::uninitialized_copy(__first, __last, ! _M_value(this->_M_start))); } ! // Internal assign functions follow. The *_aux functions do the actual // assignment work for the range versions. *************** namespace std *** 822,835 **** 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) { typedef typename iterator_traits<_InputIterator>::iterator_category _IterCategory; --- 1027,1041 ---- void _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) { ! _Base::_M_fill_assign(static_cast(__n), ! _M_stored(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) { typedef typename iterator_traits<_InputIterator>::iterator_category _IterCategory; *************** namespace std *** 847,859 **** void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag); ! ! // 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 --- 1053,1059 ---- void _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag); ! // Internal insert functions follow. // Called by the range insert to implement [23.1.1]/9 *************** namespace std *** 862,869 **** _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val, __true_type) { ! _M_fill_insert(__pos, static_cast(__n), ! static_cast(__val)); } // Called by the range insert to implement [23.1.1]/9 --- 1062,1069 ---- _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val, __true_type) { ! _Base::_M_fill_insert(_M_stored(__pos), static_cast(__n), ! _M_stored(static_cast(__val))); } // Called by the range insert to implement [23.1.1]/9 *************** namespace std *** 888,905 **** void _M_range_insert(iterator __pos, _ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag); ! ! // 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); ! ! // Called by insert(p,x) ! void ! _M_insert_aux(iterator __position, const value_type& __x); ! }; ! ! /** * @brief Vector equality comparison. * @param x A %vector. --- 1088,1095 ---- void _M_range_insert(iterator __pos, _ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag); ! }; ! /** * @brief Vector equality comparison. * @param x A %vector. Index: vector.tcc =================================================================== RCS file: /cvs/gcc/gcc/libstdc++-v3/include/bits/vector.tcc,v retrieving revision 1.10 diff -c -3 -p -r1.10 vector.tcc *** vector.tcc 14 Jul 2003 02:52:04 -0000 1.10 --- vector.tcc 28 Jul 2003 17:37:02 -0000 *************** namespace std *** 65,71 **** { template void ! vector<_Tp,_Alloc>:: reserve(size_type __n) { if (__n > this->max_size()) --- 65,71 ---- { template void ! _Vector_impl<_Tp,_Alloc>:: reserve(size_type __n) { if (__n > this->max_size()) *************** namespace std *** 86,93 **** } template ! typename vector<_Tp,_Alloc>::iterator ! vector<_Tp,_Alloc>:: insert(iterator __position, const value_type& __x) { size_type __n = __position - begin(); --- 86,93 ---- } template ! typename _Vector_impl<_Tp,_Alloc>::iterator ! _Vector_impl<_Tp,_Alloc>:: insert(iterator __position, const value_type& __x) { size_type __n = __position - begin(); *************** namespace std *** 102,109 **** } template ! typename vector<_Tp,_Alloc>::iterator ! vector<_Tp,_Alloc>:: erase(iterator __position) { if (__position + 1 != end()) --- 102,109 ---- } template ! typename _Vector_impl<_Tp,_Alloc>::iterator ! _Vector_impl<_Tp,_Alloc>:: erase(iterator __position) { if (__position + 1 != end()) *************** namespace std *** 114,121 **** } template ! typename vector<_Tp,_Alloc>::iterator ! vector<_Tp,_Alloc>:: erase(iterator __first, iterator __last) { iterator __i(copy(__last, end(), __first)); --- 114,121 ---- } template ! typename _Vector_impl<_Tp,_Alloc>::iterator ! _Vector_impl<_Tp,_Alloc>:: erase(iterator __first, iterator __last) { iterator __i(copy(__last, end(), __first)); *************** namespace std *** 125,133 **** } template ! vector<_Tp,_Alloc>& ! vector<_Tp,_Alloc>:: ! operator=(const vector<_Tp,_Alloc>& __x) { if (&__x != this) { --- 125,133 ---- } template ! _Vector_impl<_Tp,_Alloc>& ! _Vector_impl<_Tp,_Alloc>:: ! operator=(const _Vector_impl<_Tp,_Alloc>& __x) { if (&__x != this) { *************** namespace std *** 158,169 **** template void ! vector<_Tp,_Alloc>:: _M_fill_assign(size_t __n, const value_type& __val) { if (__n > capacity()) { ! vector __tmp(__n, __val, get_allocator()); __tmp.swap(*this); } else if (__n > size()) --- 158,169 ---- template void ! _Vector_impl<_Tp,_Alloc>:: _M_fill_assign(size_t __n, const value_type& __val) { if (__n > capacity()) { ! _Vector_impl __tmp(__n, __val, get_allocator()); __tmp.swap(*this); } else if (__n > size()) *************** namespace std *** 198,230 **** { size_type __len = std::distance(__first, __last); ! if (__len > capacity()) { pointer __tmp(_M_allocate_and_copy(__len, __first, __last)); std::_Destroy(this->_M_start, this->_M_finish); ! _M_deallocate(this->_M_start, ! this->_M_end_of_storage - this->_M_start); ! this->_M_start = __tmp; this->_M_end_of_storage = this->_M_finish = this->_M_start + __len; } ! else if (size() >= __len) { ! iterator __new_finish(copy(__first, __last, this->_M_start)); std::_Destroy(__new_finish, end()); ! this->_M_finish = __new_finish.base(); } else { _ForwardIterator __mid = __first; ! std::advance(__mid, size()); ! std::copy(__first, __mid, this->_M_start); ! this->_M_finish = std::uninitialized_copy(__mid, __last, this->_M_finish); } } template void ! vector<_Tp,_Alloc>:: _M_insert_aux(iterator __position, const _Tp& __x) { if (this->_M_finish != this->_M_end_of_storage) --- 198,232 ---- { size_type __len = std::distance(__first, __last); ! if (__len > this->capacity()) { pointer __tmp(_M_allocate_and_copy(__len, __first, __last)); std::_Destroy(this->_M_start, this->_M_finish); ! this->_M_deallocate(this->_M_start, ! this->_M_end_of_storage - this->_M_start); ! this->_M_start = _M_stored(__tmp); this->_M_end_of_storage = this->_M_finish = this->_M_start + __len; } ! else if (this->size() >= __len) { ! iterator __new_finish(copy(__first, __last, _M_value(this->_M_start))); std::_Destroy(__new_finish, end()); ! this->_M_finish = _M_stored(__new_finish.base()); } else { _ForwardIterator __mid = __first; ! std::advance(__mid, this->size()); ! std::copy(__first, __mid, _M_value(this->_M_start)); ! this->_M_finish = ! _M_stored(std::uninitialized_copy(__mid, __last, ! _M_value(this->_M_finish))); } } template void ! _Vector_impl<_Tp,_Alloc>:: _M_insert_aux(iterator __position, const _Tp& __x) { if (this->_M_finish != this->_M_end_of_storage) *************** namespace std *** 269,321 **** } } - #ifdef _GLIBCXX_DEPRECATED - template - void - vector<_Tp,_Alloc>:: - _M_insert_aux(iterator __position) - { - if (_M_finish != _M_end_of_storage) - { - std::_Construct(_M_finish, *(_M_finish - 1)); - ++_M_finish; - std::copy_backward(__position, iterator(_M_finish - 2), - iterator(_M_finish - 1)); - *__position = value_type(); - } - else - { - const size_type __old_size = size(); - const size_type __len = __old_size != 0 ? 2 * __old_size : 1; - pointer __new_start = _M_allocate(__len); - pointer __new_finish = __new_start; - try - { - __new_finish = std::uninitialized_copy(iterator(_M_start), __position, - __new_start); - std::_Construct(__new_finish); - ++__new_finish; - __new_finish = std::uninitialized_copy(__position, iterator(_M_finish), - __new_finish); - } - catch(...) - { - std::_Destroy(__new_start,__new_finish); - _M_deallocate(__new_start,__len); - __throw_exception_again; - } - std::_Destroy(begin(), end()); - _M_deallocate(_M_start, _M_end_of_storage - _M_start); - _M_start = __new_start; - _M_finish = __new_finish; - _M_end_of_storage = __new_start + __len; - } - } - #endif - template void ! vector<_Tp,_Alloc>:: _M_fill_insert(iterator __position, size_type __n, const value_type& __x) { if (__n != 0) --- 271,279 ---- } } template void ! _Vector_impl<_Tp,_Alloc>:: _M_fill_insert(iterator __position, size_type __n, const value_type& __x) { if (__n != 0) *************** namespace std *** 401,407 **** if (size_type(this->_M_end_of_storage - this->_M_finish) >= __n) { const size_type __elems_after = end() - __position; ! iterator __old_finish(this->_M_finish); if (__elems_after > __n) { std::uninitialized_copy(this->_M_finish - __n, --- 359,365 ---- if (size_type(this->_M_end_of_storage - this->_M_finish) >= __n) { const size_type __elems_after = end() - __position; ! iterator __old_finish(_M_value(this->_M_finish)); if (__elems_after > __n) { std::uninitialized_copy(this->_M_finish - __n, *************** namespace std *** 415,454 **** { _ForwardIterator __mid = __first; std::advance(__mid, __elems_after); ! std::uninitialized_copy(__mid, __last, this->_M_finish); this->_M_finish += __n - __elems_after; ! std::uninitialized_copy(__position, __old_finish, this->_M_finish); this->_M_finish += __elems_after; std::copy(__first, __mid, __position); } } else { ! const size_type __old_size = size(); const size_type __len = __old_size + std::max(__old_size, __n); ! iterator __new_start(this->_M_allocate(__len)); iterator __new_finish(__new_start); try { ! __new_finish = std::uninitialized_copy(iterator(this->_M_start), ! __position, __new_start); __new_finish = std::uninitialized_copy(__first, __last, __new_finish); ! __new_finish = std::uninitialized_copy(__position, ! iterator(this->_M_finish), ! __new_finish); } catch(...) { ! std::_Destroy(__new_start,__new_finish); ! _M_deallocate(__new_start.base(), __len); __throw_exception_again; } std::_Destroy(this->_M_start, this->_M_finish); _M_deallocate(this->_M_start, this->_M_end_of_storage - this->_M_start); ! this->_M_start = __new_start.base(); ! this->_M_finish = __new_finish.base(); ! this->_M_end_of_storage = __new_start.base() + __len; } } } --- 373,415 ---- { _ForwardIterator __mid = __first; std::advance(__mid, __elems_after); ! std::uninitialized_copy(__mid, __last, _M_value(this->_M_finish)); this->_M_finish += __n - __elems_after; ! std::uninitialized_copy(__position, __old_finish, ! _M_value(this->_M_finish)); this->_M_finish += __elems_after; std::copy(__first, __mid, __position); } } else { ! const size_type __old_size = this->size(); const size_type __len = __old_size + std::max(__old_size, __n); ! iterator __new_start(_M_value(this->_M_allocate(__len))); iterator __new_finish(__new_start); try { ! __new_finish = ! std::uninitialized_copy(iterator(_M_value(this->_M_start)), ! __position, __new_start); __new_finish = std::uninitialized_copy(__first, __last, __new_finish); ! __new_finish = ! std::uninitialized_copy(__position, ! iterator(_M_value(this->_M_finish)), ! __new_finish); } catch(...) { ! std::_Destroy(_M_stored(__new_start),_M_stored(__new_finish)); ! _M_deallocate(_M_stored(__new_start.base()), __len); __throw_exception_again; } std::_Destroy(this->_M_start, this->_M_finish); _M_deallocate(this->_M_start, this->_M_end_of_storage - this->_M_start); ! this->_M_start = _M_stored(__new_start.base()); ! this->_M_finish = _M_stored(__new_finish.base()); ! this->_M_end_of_storage = this->_M_start + __len; } } }