[multiple changes]
[gcc.git] / libstdc++-v3 / include / bits / stl_vector.h
1 // Vector implementation -*- C++ -*-
2
3 // Copyright (C) 2001, 2002 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 2, or (at your option)
9 // any later version.
10
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING. If not, write to the Free
18 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 // USA.
20
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
29
30 /*
31 *
32 * Copyright (c) 1994
33 * Hewlett-Packard Company
34 *
35 * Permission to use, copy, modify, distribute and sell this software
36 * and its documentation for any purpose is hereby granted without fee,
37 * provided that the above copyright notice appear in all copies and
38 * that both that copyright notice and this permission notice appear
39 * in supporting documentation. Hewlett-Packard Company makes no
40 * representations about the suitability of this software for any
41 * purpose. It is provided "as is" without express or implied warranty.
42 *
43 *
44 * Copyright (c) 1996
45 * Silicon Graphics Computer Systems, Inc.
46 *
47 * Permission to use, copy, modify, distribute and sell this software
48 * and its documentation for any purpose is hereby granted without fee,
49 * provided that the above copyright notice appear in all copies and
50 * that both that copyright notice and this permission notice appear
51 * in supporting documentation. Silicon Graphics makes no
52 * representations about the suitability of this software for any
53 * purpose. It is provided "as is" without express or implied warranty.
54 */
55
56 /** @file stl_vector.h
57 * This is an internal header file, included by other library headers.
58 * You should not attempt to use it directly.
59 */
60
61 #ifndef __GLIBCPP_INTERNAL_VECTOR_H
62 #define __GLIBCPP_INTERNAL_VECTOR_H
63
64 #include <bits/stl_iterator_base_funcs.h>
65 #include <bits/functexcept.h>
66 #include <bits/concept_check.h>
67
68 namespace std
69 {
70
71 // The vector base class serves two purposes. First, its constructor
72 // and destructor allocate (but don't initialize) storage. This makes
73 // exception safety easier. Second, the base class encapsulates all of
74 // the differences between SGI-style allocators and standard-conforming
75 // allocators.
76
77 // Base class for ordinary allocators.
78 template <class _Tp, class _Allocator, bool _IsStatic>
79 class _Vector_alloc_base {
80 public:
81 typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
82 allocator_type;
83 allocator_type get_allocator() const { return _M_data_allocator; }
84
85 _Vector_alloc_base(const allocator_type& __a)
86 : _M_data_allocator(__a), _M_start(0), _M_finish(0), _M_end_of_storage(0)
87 {}
88
89 protected:
90 allocator_type _M_data_allocator;
91 _Tp* _M_start;
92 _Tp* _M_finish;
93 _Tp* _M_end_of_storage;
94
95 _Tp* _M_allocate(size_t __n)
96 { return _M_data_allocator.allocate(__n); }
97 void _M_deallocate(_Tp* __p, size_t __n)
98 { if (__p) _M_data_allocator.deallocate(__p, __n); }
99 };
100
101 // Specialization for allocators that have the property that we don't
102 // actually have to store an allocator object.
103 template <class _Tp, class _Allocator>
104 class _Vector_alloc_base<_Tp, _Allocator, true> {
105 public:
106 typedef typename _Alloc_traits<_Tp, _Allocator>::allocator_type
107 allocator_type;
108 allocator_type get_allocator() const { return allocator_type(); }
109
110 _Vector_alloc_base(const allocator_type&)
111 : _M_start(0), _M_finish(0), _M_end_of_storage(0)
112 {}
113
114 protected:
115 _Tp* _M_start;
116 _Tp* _M_finish;
117 _Tp* _M_end_of_storage;
118
119 typedef typename _Alloc_traits<_Tp, _Allocator>::_Alloc_type _Alloc_type;
120 _Tp* _M_allocate(size_t __n)
121 { return _Alloc_type::allocate(__n); }
122 void _M_deallocate(_Tp* __p, size_t __n)
123 { _Alloc_type::deallocate(__p, __n);}
124 };
125
126 template <class _Tp, class _Alloc>
127 struct _Vector_base
128 : public _Vector_alloc_base<_Tp, _Alloc,
129 _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
130 {
131 typedef _Vector_alloc_base<_Tp, _Alloc,
132 _Alloc_traits<_Tp, _Alloc>::_S_instanceless>
133 _Base;
134 typedef typename _Base::allocator_type allocator_type;
135
136 _Vector_base(const allocator_type& __a) : _Base(__a) {}
137 _Vector_base(size_t __n, const allocator_type& __a) : _Base(__a) {
138 _M_start = _M_allocate(__n);
139 _M_finish = _M_start;
140 _M_end_of_storage = _M_start + __n;
141 }
142
143 ~_Vector_base() { _M_deallocate(_M_start, _M_end_of_storage - _M_start); }
144 };
145
146
147 /**
148 * @brief A standard container which offers fixed time access to individual
149 * elements in any order.
150 *
151 * @ingroup Containers
152 * @ingroup Sequences
153 *
154 * Meets the requirements of a <a href="tables.html#65">container</a>, a
155 * <a href="tables.html#66">reversible container</a>, and a
156 * <a href="tables.html#67">sequence</a>, including the
157 * <a href="tables.html#68">optional sequence requirements</a> with the
158 * %exception of @c push_front and @c pop_front.
159 *
160 * In some terminology a vector can be described as a dynamic C-style array,
161 * it offers fast and efficient access to individual elements in any order
162 * and saves the user from worrying about memory and size allocation.
163 * Subscripting ( [] ) access is also provided as with C-style arrays.
164 */
165 template <class _Tp, class _Alloc = allocator<_Tp> >
166 class vector : protected _Vector_base<_Tp, _Alloc>
167 {
168 // concept requirements
169 __glibcpp_class_requires(_Tp, _SGIAssignableConcept)
170
171 private:
172 typedef _Vector_base<_Tp, _Alloc> _Base;
173 typedef vector<_Tp, _Alloc> vector_type;
174 public:
175 typedef _Tp value_type;
176 typedef value_type* pointer;
177 typedef const value_type* const_pointer;
178 typedef __gnu_cxx::__normal_iterator<pointer, vector_type> iterator;
179 typedef __gnu_cxx::__normal_iterator<const_pointer, vector_type>
180 const_iterator;
181 typedef value_type& reference;
182 typedef const value_type& const_reference;
183 typedef size_t size_type;
184 typedef ptrdiff_t difference_type;
185
186 typedef typename _Base::allocator_type allocator_type;
187 allocator_type get_allocator() const { return _Base::get_allocator(); }
188
189 typedef reverse_iterator<const_iterator> const_reverse_iterator;
190 typedef reverse_iterator<iterator> reverse_iterator;
191
192 protected:
193 using _Base::_M_allocate;
194 using _Base::_M_deallocate;
195 using _Base::_M_start;
196 using _Base::_M_finish;
197 using _Base::_M_end_of_storage;
198
199 protected:
200 void _M_insert_aux(iterator __position, const _Tp& __x);
201 void _M_insert_aux(iterator __position);
202
203 public:
204 /**
205 * Returns a read/write iterator that points to the first element in the
206 * vector. Iteration is done in ordinary element order.
207 */
208 iterator begin() { return iterator (_M_start); }
209
210 /**
211 * Returns a read-only (constant) iterator that points to the first element
212 * in the vector. Iteration is done in ordinary element order.
213 */
214 const_iterator begin() const
215 { return const_iterator (_M_start); }
216
217 /**
218 * Returns a read/write iterator that points one past the last element in
219 * the vector. Iteration is done in ordinary element order.
220 */
221 iterator end() { return iterator (_M_finish); }
222
223 /**
224 * Returns a read-only (constant) iterator that points one past the last
225 * element in the vector. Iteration is done in ordinary element order.
226 */
227 const_iterator end() const { return const_iterator (_M_finish); }
228
229 /**
230 * Returns a read/write reverse iterator that points to the last element in
231 * the vector. Iteration is done in reverse element order.
232 */
233 reverse_iterator rbegin()
234 { return reverse_iterator(end()); }
235
236 /**
237 * Returns a read-only (constant) reverse iterator that points to the last
238 * element in the vector. Iteration is done in reverse element order.
239 */
240 const_reverse_iterator rbegin() const
241 { return const_reverse_iterator(end()); }
242
243 /**
244 * Returns a read/write reverse iterator that points to one before the
245 * first element in the vector. Iteration is done in reverse element
246 * order.
247 */
248 reverse_iterator rend()
249 { return reverse_iterator(begin()); }
250
251 /**
252 * Returns a read-only (constant) reverse iterator that points to one
253 * before the first element in the vector. Iteration is done in reverse
254 * element order.
255 */
256 const_reverse_iterator rend() const
257 { return const_reverse_iterator(begin()); }
258
259 /** Returns the number of elements in the vector. */
260 size_type size() const
261 { return size_type(end() - begin()); }
262
263 /** Returns the size of the largest possible vector. */
264 size_type max_size() const
265 { return size_type(-1) / sizeof(_Tp); }
266
267 /**
268 * Returns the amount of memory that has been alocated for the current
269 * elements (?).
270 */
271 size_type capacity() const
272 { return size_type(const_iterator(_M_end_of_storage) - begin()); }
273
274 /**
275 * Returns true if the vector is empty. (Thus begin() would equal end().)
276 */
277 bool empty() const
278 { return begin() == end(); }
279
280 /**
281 * @brief Subscript access to the data contained in the vector.
282 * @param n The element for which data should be accessed.
283 * @return Read/write reference to data.
284 *
285 * This operator allows for easy, array-style, data access.
286 * Note that data access with this operator is unchecked and out_of_range
287 * lookups are not defined. (For checked lookups see at().)
288 */
289 reference operator[](size_type __n) { return *(begin() + __n); }
290
291 /**
292 * @brief Subscript access to the data contained in the vector.
293 * @param n The element for which data should be accessed.
294 * @return Read-only (constant) reference to data.
295 *
296 * This operator allows for easy, array-style, data access.
297 * Note that data access with this operator is unchecked and out_of_range
298 * lookups are not defined. (For checked lookups see at().)
299 */
300 const_reference operator[](size_type __n) const { return *(begin() + __n); }
301
302 void _M_range_check(size_type __n) const {
303 if (__n >= this->size())
304 __throw_out_of_range("vector");
305 }
306
307 /**
308 * @brief Provides access to the data contained in the vector.
309 * @param n The element for which data should be accessed.
310 * @return Read/write reference to data.
311 *
312 * This function provides for safer data access. The parameter is first
313 * checked that it is in the range of the vector. The function throws
314 * out_of_range if the check fails.
315 */
316 reference at(size_type __n)
317 { _M_range_check(__n); return (*this)[__n]; }
318
319 /**
320 * @brief Provides access to the data contained in the vector.
321 * @param n The element for which data should be accessed.
322 * @return Read-only (constant) reference to data.
323 *
324 * This function provides for safer data access. The parameter is first
325 * checked that it is in the range of the vector. The function throws
326 * out_of_range if the check fails.
327 */
328 const_reference at(size_type __n) const
329 { _M_range_check(__n); return (*this)[__n]; }
330
331
332 explicit vector(const allocator_type& __a = allocator_type())
333 : _Base(__a) {}
334
335 vector(size_type __n, const _Tp& __value,
336 const allocator_type& __a = allocator_type())
337 : _Base(__n, __a)
338 { _M_finish = uninitialized_fill_n(_M_start, __n, __value); }
339
340 explicit vector(size_type __n)
341 : _Base(__n, allocator_type())
342 { _M_finish = uninitialized_fill_n(_M_start, __n, _Tp()); }
343
344 vector(const vector<_Tp, _Alloc>& __x)
345 : _Base(__x.size(), __x.get_allocator())
346 { _M_finish = uninitialized_copy(__x.begin(), __x.end(), _M_start); }
347
348 // Check whether it's an integral type. If so, it's not an iterator.
349 template <class _InputIterator>
350 vector(_InputIterator __first, _InputIterator __last,
351 const allocator_type& __a = allocator_type())
352 : _Base(__a)
353 {
354 typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
355 _M_initialize_aux(__first, __last, _Integral());
356 }
357
358 template <class _Integer>
359 void _M_initialize_aux(_Integer __n, _Integer __value, __true_type)
360 {
361 _M_start = _M_allocate(__n);
362 _M_end_of_storage = _M_start + __n;
363 _M_finish = uninitialized_fill_n(_M_start, __n, __value);
364 }
365
366 template<class _InputIterator>
367 void
368 _M_initialize_aux(_InputIterator __first, _InputIterator __last, __false_type)
369 {
370 typedef typename iterator_traits<_InputIterator>::iterator_category _IterCategory;
371 _M_range_initialize(__first, __last, _IterCategory());
372 }
373
374 ~vector()
375 { _Destroy(_M_start, _M_finish); }
376
377 vector<_Tp, _Alloc>& operator=(const vector<_Tp, _Alloc>& __x);
378
379 /**
380 * @brief Attempt to preallocate enough memory for specified number of
381 * elements.
382 * @param n Number of elements required
383 *
384 * This function attempts to reserve enough memory for the vector to hold
385 * the specified number of elements. If the number requested is more than
386 * max_size() length_error is thrown.
387 *
388 * The advantage of this function is that if optimal code is a necessity
389 * and the user can determine the number of elements that will be required
390 * the user can reserve the memory and thus prevent a possible
391 * reallocation of memory and copy of vector data.
392 */
393 void reserve(size_type __n) {
394 if (capacity() < __n) {
395 const size_type __old_size = size();
396 pointer __tmp = _M_allocate_and_copy(__n, _M_start, _M_finish);
397 _Destroy(_M_start, _M_finish);
398 _M_deallocate(_M_start, _M_end_of_storage - _M_start);
399 _M_start = __tmp;
400 _M_finish = __tmp + __old_size;
401 _M_end_of_storage = _M_start + __n;
402 }
403 }
404
405 // assign(), a generalized assignment member function. Two
406 // versions: one that takes a count, and one that takes a range.
407 // The range version is a member template, so we dispatch on whether
408 // or not the type is an integer.
409
410 /**
411 * @brief Assigns a given value or range to a vector.
412 * @param n Number of elements to be assigned.
413 * @param val Value to be assigned.
414 *
415 * This function can be used to assign a range to a vector or fill it
416 * with a specified number of copies of the given value.
417 * Note that the assignment completely changes the vector and that the
418 * resulting vector's size is the same as the number of elements assigned.
419 * Old data may be lost.
420 */
421 void assign(size_type __n, const _Tp& __val) { _M_fill_assign(__n, __val); }
422 void _M_fill_assign(size_type __n, const _Tp& __val);
423
424 template<class _InputIterator>
425 void
426 assign(_InputIterator __first, _InputIterator __last)
427 {
428 typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
429 _M_assign_dispatch(__first, __last, _Integral());
430 }
431
432 template<class _Integer>
433 void
434 _M_assign_dispatch(_Integer __n, _Integer __val, __true_type)
435 { _M_fill_assign((size_type) __n, (_Tp) __val); }
436
437 template<class _InputIter>
438 void
439 _M_assign_dispatch(_InputIter __first, _InputIter __last, __false_type)
440 {
441 typedef typename iterator_traits<_InputIter>::iterator_category _IterCategory;
442 _M_assign_aux(__first, __last, _IterCategory());
443 }
444
445 template <class _InputIterator>
446 void
447 _M_assign_aux(_InputIterator __first, _InputIterator __last,
448 input_iterator_tag);
449
450 template <class _ForwardIterator>
451 void
452 _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
453 forward_iterator_tag);
454
455 /**
456 * Returns a read/write reference to the data at the first element of the
457 * vector.
458 */
459 reference front() { return *begin(); }
460
461 /**
462 * Returns a read-only (constant) reference to the data at the first
463 * element of the vector.
464 */
465 const_reference front() const { return *begin(); }
466
467 /**
468 * Returns a read/write reference to the data at the last element of the
469 * vector.
470 */
471 reference back() { return *(end() - 1); }
472
473 /**
474 * Returns a read-only (constant) reference to the data at the first
475 * element of the vector.
476 */
477 const_reference back() const { return *(end() - 1); }
478
479 /**
480 * @brief Add data to the end of the vector.
481 * @param x Data to be added.
482 *
483 * This is a typical stack operation. The function creates an element at
484 * the end of the vector and assigns the given data to it.
485 * Due to the nature of a vector this operation can be done in constant
486 * time if the vector has preallocated space available.
487 */
488 void
489 push_back(const _Tp& __x)
490 {
491 if (_M_finish != _M_end_of_storage) {
492 _Construct(_M_finish, __x);
493 ++_M_finish;
494 }
495 else
496 _M_insert_aux(end(), __x);
497 }
498
499 #ifdef _GLIBCPP_DEPRECATED
500 /**
501 * Add an element to the end of the vector. The element is
502 * default-constructed.
503 *
504 * @note You must define _GLIBCPP_DEPRECATED to make this visible; see
505 * c++config.h.
506 */
507 void
508 push_back()
509 {
510 if (_M_finish != _M_end_of_storage) {
511 _Construct(_M_finish);
512 ++_M_finish;
513 }
514 else
515 _M_insert_aux(end());
516 }
517 #endif
518
519 void
520 swap(vector<_Tp, _Alloc>& __x)
521 {
522 std::swap(_M_start, __x._M_start);
523 std::swap(_M_finish, __x._M_finish);
524 std::swap(_M_end_of_storage, __x._M_end_of_storage);
525 }
526
527 /**
528 * @brief Inserts given value into vector at specified element.
529 * @param position An iterator that points to the element where data
530 * should be inserted.
531 * @param x Data to be inserted.
532 * @return An iterator that points to the inserted data.
533 *
534 * This function will insert the given value into the specified location.
535 * Note that this kind of operation could be expensive for a vector and if
536 * it is frequently used the user should consider using std::list.
537 */
538 iterator
539 insert(iterator __position, const _Tp& __x)
540 {
541 size_type __n = __position - begin();
542 if (_M_finish != _M_end_of_storage && __position == end()) {
543 _Construct(_M_finish, __x);
544 ++_M_finish;
545 }
546 else
547 _M_insert_aux(iterator(__position), __x);
548 return begin() + __n;
549 }
550
551 /**
552 * @brief Inserts an empty element into the vector.
553 * @param position An iterator that points to the element where empty
554 * element should be inserted.
555 * @param x Data to be inserted.
556 * @return An iterator that points to the inserted element.
557 *
558 * This function will insert an empty element into the specified location.
559 * Note that this kind of operation could be expensive for a vector and if
560 * it is frequently used the user should consider using std::list.
561 */
562 iterator
563 insert(iterator __position)
564 {
565 size_type __n = __position - begin();
566 if (_M_finish != _M_end_of_storage && __position == end()) {
567 _Construct(_M_finish);
568 ++_M_finish;
569 }
570 else
571 _M_insert_aux(iterator(__position));
572 return begin() + __n;
573 }
574
575 // Check whether it's an integral type. If so, it's not an iterator.
576 template<class _InputIterator>
577 void
578 insert(iterator __pos, _InputIterator __first, _InputIterator __last)
579 {
580 typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
581 _M_insert_dispatch(__pos, __first, __last, _Integral());
582 }
583
584 template <class _Integer>
585 void
586 _M_insert_dispatch(iterator __pos, _Integer __n, _Integer __val, __true_type)
587 { _M_fill_insert(__pos, static_cast<size_type>(__n), static_cast<_Tp>(__val)); }
588
589 template<class _InputIterator>
590 void
591 _M_insert_dispatch(iterator __pos,
592 _InputIterator __first, _InputIterator __last,
593 __false_type)
594 {
595 typedef typename iterator_traits<_InputIterator>::iterator_category _IterCategory;
596 _M_range_insert(__pos, __first, __last, _IterCategory());
597 }
598
599 /**
600 * @brief Inserts a number of copies of given data into the vector.
601 * @param position An iterator that points to the element where data
602 * should be inserted.
603 * @param n Amount of elements to be inserted.
604 * @param x Data to be inserted.
605 *
606 * This function will insert a specified number of copies of the given data
607 * into the specified location.
608 *
609 * Note that this kind of operation could be expensive for a vector and if
610 * it is frequently used the user should consider using std::list.
611 */
612 void insert (iterator __pos, size_type __n, const _Tp& __x)
613 { _M_fill_insert(__pos, __n, __x); }
614
615 void _M_fill_insert (iterator __pos, size_type __n, const _Tp& __x);
616
617 /**
618 * @brief Removes last element from vector.
619 *
620 * This is a typical stack operation. It allows us to shrink the vector by
621 * one.
622 *
623 * Note that no data is returned and if last element's data is needed it
624 * should be retrieved before pop_back() is called.
625 */
626 void pop_back() {
627 --_M_finish;
628 _Destroy(_M_finish);
629 }
630
631 /**
632 * @brief Remove element at given position
633 * @param position Iterator pointing to element to be erased.
634 * @return Doc Me! (Iterator pointing to new element at old location?)
635 *
636 * This function will erase the element at the given position and thus
637 * shorten the vector by one.
638 *
639 * Note This operation could be expensive and if it is frequently used the
640 * user should consider using std::list. The user is also cautioned that
641 * this function only erases the element, and that if the element is itself
642 * a pointer, the pointed-to memory is not touched in any way. Managing
643 * the pointer is the user's responsibilty.
644 */
645 iterator erase(iterator __position) {
646 if (__position + 1 != end())
647 copy(__position + 1, end(), __position);
648 --_M_finish;
649 _Destroy(_M_finish);
650 return __position;
651 }
652
653 /**
654 * @brief Remove a range of elements from a vector.
655 * @param first Iterator pointing to the first element to be erased.
656 * @param last Iterator pointing to the last element to be erased.
657 * @return Doc Me! (Iterator pointing to new element at old location?)
658 *
659 * This function will erase the elements in the given range and shorten the
660 * vector accordingly.
661 *
662 * Note This operation could be expensive and if it is frequently used the
663 * user should consider using std::list. The user is also cautioned that
664 * this function only erases the elements, and that if the elements
665 * themselves are pointers, the pointed-to memory is not touched in any
666 * way. Managing the pointer is the user's responsibilty.
667 */
668 iterator erase(iterator __first, iterator __last) {
669 iterator __i(copy(__last, end(), __first));
670 _Destroy(__i, end());
671 _M_finish = _M_finish - (__last - __first);
672 return __first;
673 }
674
675 /**
676 * @brief Resizes the vector to the specified number of elements.
677 * @param new_size Number of elements the vector should contain.
678 * @param x Data with which new elements should be populated.
679 *
680 * This function will resize the vector to the specified number of
681 * elements. If the number is smaller than the vector's current size the
682 * vector is truncated, otherwise the vector is extended and new elements
683 * are populated with given data.
684 */
685 void resize(size_type __new_size, const _Tp& __x) {
686 if (__new_size < size())
687 erase(begin() + __new_size, end());
688 else
689 insert(end(), __new_size - size(), __x);
690 }
691
692 /**
693 * @brief Resizes the vector to the specified number of elements.
694 * @param new_size Number of elements the vector should contain.
695 *
696 * This function will resize the vector to the specified number of
697 * elements. If the number is smaller than the vector's current size the
698 * vector is truncated, otherwise the vector is extended and new elements
699 * are left uninitialized.
700 */
701 void resize(size_type __new_size) { resize(__new_size, _Tp()); }
702
703 /**
704 * Erases all elements in vector. Note that this function only erases the
705 * elements, and that if the elements themselves are pointers, the
706 * pointed-to memory is not touched in any way. Managing the pointer is
707 * the user's responsibilty.
708 */
709 void clear() { erase(begin(), end()); }
710
711 protected:
712
713 template <class _ForwardIterator>
714 pointer _M_allocate_and_copy(size_type __n, _ForwardIterator __first,
715 _ForwardIterator __last)
716 {
717 pointer __result = _M_allocate(__n);
718 try {
719 uninitialized_copy(__first, __last, __result);
720 return __result;
721 }
722 catch(...)
723 {
724 _M_deallocate(__result, __n);
725 __throw_exception_again;
726 }
727 }
728
729 template <class _InputIterator>
730 void _M_range_initialize(_InputIterator __first,
731 _InputIterator __last, input_iterator_tag)
732 {
733 for ( ; __first != __last; ++__first)
734 push_back(*__first);
735 }
736
737 // This function is only called by the constructor.
738 template <class _ForwardIterator>
739 void _M_range_initialize(_ForwardIterator __first,
740 _ForwardIterator __last, forward_iterator_tag)
741 {
742 size_type __n = distance(__first, __last);
743 _M_start = _M_allocate(__n);
744 _M_end_of_storage = _M_start + __n;
745 _M_finish = uninitialized_copy(__first, __last, _M_start);
746 }
747
748 template <class _InputIterator>
749 void _M_range_insert(iterator __pos,
750 _InputIterator __first, _InputIterator __last,
751 input_iterator_tag);
752
753 template <class _ForwardIterator>
754 void _M_range_insert(iterator __pos,
755 _ForwardIterator __first, _ForwardIterator __last,
756 forward_iterator_tag);
757 };
758
759 template <class _Tp, class _Alloc>
760 inline bool
761 operator==(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
762 {
763 return __x.size() == __y.size() &&
764 equal(__x.begin(), __x.end(), __y.begin());
765 }
766
767 template <class _Tp, class _Alloc>
768 inline bool
769 operator<(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y)
770 {
771 return lexicographical_compare(__x.begin(), __x.end(),
772 __y.begin(), __y.end());
773 }
774
775 template <class _Tp, class _Alloc>
776 inline void swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y)
777 {
778 __x.swap(__y);
779 }
780
781 template <class _Tp, class _Alloc>
782 inline bool
783 operator!=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) {
784 return !(__x == __y);
785 }
786
787 template <class _Tp, class _Alloc>
788 inline bool
789 operator>(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) {
790 return __y < __x;
791 }
792
793 template <class _Tp, class _Alloc>
794 inline bool
795 operator<=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) {
796 return !(__y < __x);
797 }
798
799 template <class _Tp, class _Alloc>
800 inline bool
801 operator>=(const vector<_Tp, _Alloc>& __x, const vector<_Tp, _Alloc>& __y) {
802 return !(__x < __y);
803 }
804
805 template <class _Tp, class _Alloc>
806 vector<_Tp,_Alloc>&
807 vector<_Tp,_Alloc>::operator=(const vector<_Tp, _Alloc>& __x)
808 {
809 if (&__x != this) {
810 const size_type __xlen = __x.size();
811 if (__xlen > capacity()) {
812 pointer __tmp = _M_allocate_and_copy(__xlen, __x.begin(), __x.end());
813 _Destroy(_M_start, _M_finish);
814 _M_deallocate(_M_start, _M_end_of_storage - _M_start);
815 _M_start = __tmp;
816 _M_end_of_storage = _M_start + __xlen;
817 }
818 else if (size() >= __xlen) {
819 iterator __i(copy(__x.begin(), __x.end(), begin()));
820 _Destroy(__i, end());
821 }
822 else {
823 copy(__x.begin(), __x.begin() + size(), _M_start);
824 uninitialized_copy(__x.begin() + size(), __x.end(), _M_finish);
825 }
826 _M_finish = _M_start + __xlen;
827 }
828 return *this;
829 }
830
831 template <class _Tp, class _Alloc>
832 void vector<_Tp, _Alloc>::_M_fill_assign(size_t __n, const value_type& __val)
833 {
834 if (__n > capacity()) {
835 vector<_Tp, _Alloc> __tmp(__n, __val, get_allocator());
836 __tmp.swap(*this);
837 }
838 else if (__n > size()) {
839 fill(begin(), end(), __val);
840 _M_finish = uninitialized_fill_n(_M_finish, __n - size(), __val);
841 }
842 else
843 erase(fill_n(begin(), __n, __val), end());
844 }
845
846 template <class _Tp, class _Alloc> template <class _InputIter>
847 void vector<_Tp, _Alloc>::_M_assign_aux(_InputIter __first, _InputIter __last,
848 input_iterator_tag) {
849 iterator __cur(begin());
850 for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
851 *__cur = *__first;
852 if (__first == __last)
853 erase(__cur, end());
854 else
855 insert(end(), __first, __last);
856 }
857
858 template <class _Tp, class _Alloc> template <class _ForwardIter>
859 void
860 vector<_Tp, _Alloc>::_M_assign_aux(_ForwardIter __first, _ForwardIter __last,
861 forward_iterator_tag) {
862 size_type __len = distance(__first, __last);
863
864 if (__len > capacity()) {
865 pointer __tmp(_M_allocate_and_copy(__len, __first, __last));
866 _Destroy(_M_start, _M_finish);
867 _M_deallocate(_M_start, _M_end_of_storage - _M_start);
868 _M_start = __tmp;
869 _M_end_of_storage = _M_finish = _M_start + __len;
870 }
871 else if (size() >= __len) {
872 iterator __new_finish(copy(__first, __last, _M_start));
873 _Destroy(__new_finish, end());
874 _M_finish = __new_finish.base();
875 }
876 else {
877 _ForwardIter __mid = __first;
878 advance(__mid, size());
879 copy(__first, __mid, _M_start);
880 _M_finish = uninitialized_copy(__mid, __last, _M_finish);
881 }
882 }
883
884 template <class _Tp, class _Alloc>
885 void
886 vector<_Tp, _Alloc>::_M_insert_aux(iterator __position, const _Tp& __x)
887 {
888 if (_M_finish != _M_end_of_storage) {
889 _Construct(_M_finish, *(_M_finish - 1));
890 ++_M_finish;
891 _Tp __x_copy = __x;
892 copy_backward(__position, iterator(_M_finish - 2), iterator(_M_finish- 1));
893 *__position = __x_copy;
894 }
895 else {
896 const size_type __old_size = size();
897 const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
898 iterator __new_start(_M_allocate(__len));
899 iterator __new_finish(__new_start);
900 try {
901 __new_finish = uninitialized_copy(iterator(_M_start), __position,
902 __new_start);
903 _Construct(__new_finish.base(), __x);
904 ++__new_finish;
905 __new_finish = uninitialized_copy(__position, iterator(_M_finish),
906 __new_finish);
907 }
908 catch(...)
909 {
910 _Destroy(__new_start,__new_finish);
911 _M_deallocate(__new_start.base(),__len);
912 __throw_exception_again;
913 }
914 _Destroy(begin(), end());
915 _M_deallocate(_M_start, _M_end_of_storage - _M_start);
916 _M_start = __new_start.base();
917 _M_finish = __new_finish.base();
918 _M_end_of_storage = __new_start.base() + __len;
919 }
920 }
921
922 template <class _Tp, class _Alloc>
923 void
924 vector<_Tp, _Alloc>::_M_insert_aux(iterator __position)
925 {
926 if (_M_finish != _M_end_of_storage) {
927 _Construct(_M_finish, *(_M_finish - 1));
928 ++_M_finish;
929 copy_backward(__position, iterator(_M_finish - 2),
930 iterator(_M_finish - 1));
931 *__position = _Tp();
932 }
933 else {
934 const size_type __old_size = size();
935 const size_type __len = __old_size != 0 ? 2 * __old_size : 1;
936 pointer __new_start = _M_allocate(__len);
937 pointer __new_finish = __new_start;
938 try {
939 __new_finish = uninitialized_copy(iterator(_M_start), __position,
940 __new_start);
941 _Construct(__new_finish);
942 ++__new_finish;
943 __new_finish = uninitialized_copy(__position, iterator(_M_finish),
944 __new_finish);
945 }
946 catch(...)
947 {
948 _Destroy(__new_start,__new_finish);
949 _M_deallocate(__new_start,__len);
950 __throw_exception_again;
951 }
952 _Destroy(begin(), end());
953 _M_deallocate(_M_start, _M_end_of_storage - _M_start);
954 _M_start = __new_start;
955 _M_finish = __new_finish;
956 _M_end_of_storage = __new_start + __len;
957 }
958 }
959
960 template <class _Tp, class _Alloc>
961 void vector<_Tp, _Alloc>::_M_fill_insert(iterator __position, size_type __n,
962 const _Tp& __x)
963 {
964 if (__n != 0) {
965 if (size_type(_M_end_of_storage - _M_finish) >= __n) {
966 _Tp __x_copy = __x;
967 const size_type __elems_after = end() - __position;
968 iterator __old_finish(_M_finish);
969 if (__elems_after > __n) {
970 uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);
971 _M_finish += __n;
972 copy_backward(__position, __old_finish - __n, __old_finish);
973 fill(__position, __position + __n, __x_copy);
974 }
975 else {
976 uninitialized_fill_n(_M_finish, __n - __elems_after, __x_copy);
977 _M_finish += __n - __elems_after;
978 uninitialized_copy(__position, __old_finish, _M_finish);
979 _M_finish += __elems_after;
980 fill(__position, __old_finish, __x_copy);
981 }
982 }
983 else {
984 const size_type __old_size = size();
985 const size_type __len = __old_size + max(__old_size, __n);
986 iterator __new_start(_M_allocate(__len));
987 iterator __new_finish(__new_start);
988 try {
989 __new_finish = uninitialized_copy(begin(), __position, __new_start);
990 __new_finish = uninitialized_fill_n(__new_finish, __n, __x);
991 __new_finish
992 = uninitialized_copy(__position, end(), __new_finish);
993 }
994 catch(...)
995 {
996 _Destroy(__new_start,__new_finish);
997 _M_deallocate(__new_start.base(),__len);
998 __throw_exception_again;
999 }
1000 _Destroy(_M_start, _M_finish);
1001 _M_deallocate(_M_start, _M_end_of_storage - _M_start);
1002 _M_start = __new_start.base();
1003 _M_finish = __new_finish.base();
1004 _M_end_of_storage = __new_start.base() + __len;
1005 }
1006 }
1007 }
1008
1009 template <class _Tp, class _Alloc> template <class _InputIterator>
1010 void
1011 vector<_Tp, _Alloc>::_M_range_insert(iterator __pos,
1012 _InputIterator __first,
1013 _InputIterator __last,
1014 input_iterator_tag)
1015 {
1016 for ( ; __first != __last; ++__first) {
1017 __pos = insert(__pos, *__first);
1018 ++__pos;
1019 }
1020 }
1021
1022 template <class _Tp, class _Alloc> template <class _ForwardIterator>
1023 void
1024 vector<_Tp, _Alloc>::_M_range_insert(iterator __position,
1025 _ForwardIterator __first,
1026 _ForwardIterator __last,
1027 forward_iterator_tag)
1028 {
1029 if (__first != __last) {
1030 size_type __n = distance(__first, __last);
1031 if (size_type(_M_end_of_storage - _M_finish) >= __n) {
1032 const size_type __elems_after = end() - __position;
1033 iterator __old_finish(_M_finish);
1034 if (__elems_after > __n) {
1035 uninitialized_copy(_M_finish - __n, _M_finish, _M_finish);
1036 _M_finish += __n;
1037 copy_backward(__position, __old_finish - __n, __old_finish);
1038 copy(__first, __last, __position);
1039 }
1040 else {
1041 _ForwardIterator __mid = __first;
1042 advance(__mid, __elems_after);
1043 uninitialized_copy(__mid, __last, _M_finish);
1044 _M_finish += __n - __elems_after;
1045 uninitialized_copy(__position, __old_finish, _M_finish);
1046 _M_finish += __elems_after;
1047 copy(__first, __mid, __position);
1048 }
1049 }
1050 else {
1051 const size_type __old_size = size();
1052 const size_type __len = __old_size + max(__old_size, __n);
1053 iterator __new_start(_M_allocate(__len));
1054 iterator __new_finish(__new_start);
1055 try {
1056 __new_finish = uninitialized_copy(iterator(_M_start),
1057 __position, __new_start);
1058 __new_finish = uninitialized_copy(__first, __last, __new_finish);
1059 __new_finish
1060 = uninitialized_copy(__position, iterator(_M_finish), __new_finish);
1061 }
1062 catch(...)
1063 {
1064 _Destroy(__new_start,__new_finish);
1065 _M_deallocate(__new_start.base(), __len);
1066 __throw_exception_again;
1067 }
1068 _Destroy(_M_start, _M_finish);
1069 _M_deallocate(_M_start, _M_end_of_storage - _M_start);
1070 _M_start = __new_start.base();
1071 _M_finish = __new_finish.base();
1072 _M_end_of_storage = __new_start.base() + __len;
1073 }
1074 }
1075 }
1076
1077 } // namespace std
1078
1079 #endif /* __GLIBCPP_INTERNAL_VECTOR_H */
1080
1081 // Local Variables:
1082 // mode:C++
1083 // End: