1 // Vector implementation (out of line) -*- C++ -*-
3 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
4 // Free Software Foundation, Inc.
6 // This file is part of the GNU ISO C++ Library. This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 2, or (at your option)
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING. If not, write to the Free
19 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22 // As a special exception, you may use this file as part of a free software
23 // library without restriction. Specifically, if other files instantiate
24 // templates or use macros or inline functions from this file, or you compile
25 // this file and link it with other files to produce an executable, this
26 // file does not by itself cause the resulting executable to be covered by
27 // the GNU General Public License. This exception does not however
28 // invalidate any other reasons why the executable file might be covered by
29 // the GNU General Public License.
34 * Hewlett-Packard Company
36 * Permission to use, copy, modify, distribute and sell this software
37 * and its documentation for any purpose is hereby granted without fee,
38 * provided that the above copyright notice appear in all copies and
39 * that both that copyright notice and this permission notice appear
40 * in supporting documentation. Hewlett-Packard Company makes no
41 * representations about the suitability of this software for any
42 * purpose. It is provided "as is" without express or implied warranty.
46 * Silicon Graphics Computer Systems, Inc.
48 * Permission to use, copy, modify, distribute and sell this software
49 * and its documentation for any purpose is hereby granted without fee,
50 * provided that the above copyright notice appear in all copies and
51 * that both that copyright notice and this permission notice appear
52 * in supporting documentation. Silicon Graphics makes no
53 * representations about the suitability of this software for any
54 * purpose. It is provided "as is" without express or implied warranty.
58 * This is an internal header file, included by other library headers.
59 * You should not attempt to use it directly.
65 _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD_D)
67 template<typename _Tp, typename _Alloc>
70 reserve(size_type __n)
72 if (__n > this->max_size())
73 __throw_length_error(__N("vector::reserve"));
74 if (this->capacity() < __n)
76 const size_type __old_size = size();
77 pointer __tmp = _M_allocate_and_copy(__n,
78 _GLIBCXX_MAKE_MOVE_ITERATOR(this->_M_impl._M_start),
79 _GLIBCXX_MAKE_MOVE_ITERATOR(this->_M_impl._M_finish));
80 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
81 _M_get_Tp_allocator());
82 _M_deallocate(this->_M_impl._M_start,
83 this->_M_impl._M_end_of_storage
84 - this->_M_impl._M_start);
85 this->_M_impl._M_start = __tmp;
86 this->_M_impl._M_finish = __tmp + __old_size;
87 this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
91 template<typename _Tp, typename _Alloc>
92 typename vector<_Tp, _Alloc>::iterator
94 insert(iterator __position, const value_type& __x)
96 const size_type __n = __position - begin();
97 if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage
98 && __position == end())
100 this->_M_impl.construct(this->_M_impl._M_finish, __x);
101 ++this->_M_impl._M_finish;
105 #ifdef __GXX_EXPERIMENTAL_CXX0X__
106 if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
109 _M_insert_aux(__position, std::move(__x_copy));
113 _M_insert_aux(__position, __x);
115 return iterator(this->_M_impl._M_start + __n);
118 template<typename _Tp, typename _Alloc>
119 typename vector<_Tp, _Alloc>::iterator
120 vector<_Tp, _Alloc>::
121 erase(iterator __position)
123 if (__position + 1 != end())
124 _GLIBCXX_MOVE3(__position + 1, end(), __position);
125 --this->_M_impl._M_finish;
126 this->_M_impl.destroy(this->_M_impl._M_finish);
130 template<typename _Tp, typename _Alloc>
131 typename vector<_Tp, _Alloc>::iterator
132 vector<_Tp, _Alloc>::
133 erase(iterator __first, iterator __last)
136 _GLIBCXX_MOVE3(__last, end(), __first);
137 _M_erase_at_end(__first.base() + (end() - __last));
141 template<typename _Tp, typename _Alloc>
143 vector<_Tp, _Alloc>::
144 operator=(const vector<_Tp, _Alloc>& __x)
148 const size_type __xlen = __x.size();
149 if (__xlen > capacity())
151 pointer __tmp = _M_allocate_and_copy(__xlen, __x.begin(),
153 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
154 _M_get_Tp_allocator());
155 _M_deallocate(this->_M_impl._M_start,
156 this->_M_impl._M_end_of_storage
157 - this->_M_impl._M_start);
158 this->_M_impl._M_start = __tmp;
159 this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __xlen;
161 else if (size() >= __xlen)
163 std::_Destroy(std::copy(__x.begin(), __x.end(), begin()),
164 end(), _M_get_Tp_allocator());
168 std::copy(__x._M_impl._M_start, __x._M_impl._M_start + size(),
169 this->_M_impl._M_start);
170 std::__uninitialized_copy_a(__x._M_impl._M_start + size(),
171 __x._M_impl._M_finish,
172 this->_M_impl._M_finish,
173 _M_get_Tp_allocator());
175 this->_M_impl._M_finish = this->_M_impl._M_start + __xlen;
180 template<typename _Tp, typename _Alloc>
182 vector<_Tp, _Alloc>::
183 _M_fill_assign(size_t __n, const value_type& __val)
185 if (__n > capacity())
187 vector __tmp(__n, __val, _M_get_Tp_allocator());
190 else if (__n > size())
192 std::fill(begin(), end(), __val);
193 std::__uninitialized_fill_n_a(this->_M_impl._M_finish,
195 _M_get_Tp_allocator());
196 this->_M_impl._M_finish += __n - size();
199 _M_erase_at_end(std::fill_n(this->_M_impl._M_start, __n, __val));
202 template<typename _Tp, typename _Alloc>
203 template<typename _InputIterator>
205 vector<_Tp, _Alloc>::
206 _M_assign_aux(_InputIterator __first, _InputIterator __last,
207 std::input_iterator_tag)
209 pointer __cur(this->_M_impl._M_start);
210 for (; __first != __last && __cur != this->_M_impl._M_finish;
213 if (__first == __last)
214 _M_erase_at_end(__cur);
216 insert(end(), __first, __last);
219 template<typename _Tp, typename _Alloc>
220 template<typename _ForwardIterator>
222 vector<_Tp, _Alloc>::
223 _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
224 std::forward_iterator_tag)
226 const size_type __len = std::distance(__first, __last);
228 if (__len > capacity())
230 pointer __tmp(_M_allocate_and_copy(__len, __first, __last));
231 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
232 _M_get_Tp_allocator());
233 _M_deallocate(this->_M_impl._M_start,
234 this->_M_impl._M_end_of_storage
235 - this->_M_impl._M_start);
236 this->_M_impl._M_start = __tmp;
237 this->_M_impl._M_finish = this->_M_impl._M_start + __len;
238 this->_M_impl._M_end_of_storage = this->_M_impl._M_finish;
240 else if (size() >= __len)
241 _M_erase_at_end(std::copy(__first, __last, this->_M_impl._M_start));
244 _ForwardIterator __mid = __first;
245 std::advance(__mid, size());
246 std::copy(__first, __mid, this->_M_impl._M_start);
247 this->_M_impl._M_finish =
248 std::__uninitialized_copy_a(__mid, __last,
249 this->_M_impl._M_finish,
250 _M_get_Tp_allocator());
254 #ifdef __GXX_EXPERIMENTAL_CXX0X__
255 template<typename _Tp, typename _Alloc>
256 template<typename... _Args>
257 typename vector<_Tp, _Alloc>::iterator
258 vector<_Tp, _Alloc>::
259 emplace(iterator __position, _Args&&... __args)
261 const size_type __n = __position - begin();
262 if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage
263 && __position == end())
265 this->_M_impl.construct(this->_M_impl._M_finish,
266 std::forward<_Args>(__args)...);
267 ++this->_M_impl._M_finish;
270 _M_insert_aux(__position, std::forward<_Args>(__args)...);
271 return iterator(this->_M_impl._M_start + __n);
274 template<typename _Tp, typename _Alloc>
275 template<typename... _Args>
277 vector<_Tp, _Alloc>::
278 _M_insert_aux(iterator __position, _Args&&... __args)
280 template<typename _Tp, typename _Alloc>
282 vector<_Tp, _Alloc>::
283 _M_insert_aux(iterator __position, const _Tp& __x)
286 if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
288 this->_M_impl.construct(this->_M_impl._M_finish,
289 _GLIBCXX_MOVE(*(this->_M_impl._M_finish
291 ++this->_M_impl._M_finish;
292 #ifndef __GXX_EXPERIMENTAL_CXX0X__
295 _GLIBCXX_MOVE_BACKWARD3(__position.base(),
296 this->_M_impl._M_finish - 2,
297 this->_M_impl._M_finish - 1);
298 #ifndef __GXX_EXPERIMENTAL_CXX0X__
299 *__position = __x_copy;
301 *__position = _Tp(std::forward<_Args>(__args)...);
306 const size_type __len =
307 _M_check_len(size_type(1), "vector::_M_insert_aux");
308 pointer __new_start(this->_M_allocate(__len));
309 pointer __new_finish(__new_start);
312 #ifdef __GXX_EXPERIMENTAL_CXX0X__
313 this->_M_impl.construct(__new_start + (__position - begin()),
314 std::forward<_Args>(__args)...);
317 std::__uninitialized_move_a(this->_M_impl._M_start,
318 __position.base(), __new_start,
319 _M_get_Tp_allocator());
320 #ifndef __GXX_EXPERIMENTAL_CXX0X__
321 this->_M_impl.construct(__new_finish, __x);
325 std::__uninitialized_move_a(__position.base(),
326 this->_M_impl._M_finish,
328 _M_get_Tp_allocator());
332 std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator());
333 _M_deallocate(__new_start, __len);
334 __throw_exception_again;
336 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
337 _M_get_Tp_allocator());
338 _M_deallocate(this->_M_impl._M_start,
339 this->_M_impl._M_end_of_storage
340 - this->_M_impl._M_start);
341 this->_M_impl._M_start = __new_start;
342 this->_M_impl._M_finish = __new_finish;
343 this->_M_impl._M_end_of_storage = __new_start + __len;
347 template<typename _Tp, typename _Alloc>
349 vector<_Tp, _Alloc>::
350 _M_fill_insert(iterator __position, size_type __n, const value_type& __x)
354 #ifdef __GXX_EXPERIMENTAL_CXX0X__
355 value_type __x_copy = __x;
357 if (size_type(this->_M_impl._M_end_of_storage
358 - this->_M_impl._M_finish) >= __n)
360 #ifndef __GXX_EXPERIMENTAL_CXX0X__
361 value_type __x_copy = __x;
363 const size_type __elems_after = end() - __position;
364 pointer __old_finish(this->_M_impl._M_finish);
365 if (__elems_after > __n)
367 std::__uninitialized_move_a(this->_M_impl._M_finish - __n,
368 this->_M_impl._M_finish,
369 this->_M_impl._M_finish,
370 _M_get_Tp_allocator());
371 this->_M_impl._M_finish += __n;
372 _GLIBCXX_MOVE_BACKWARD3(__position.base(),
373 __old_finish - __n, __old_finish);
374 std::fill(__position.base(), __position.base() + __n,
379 std::__uninitialized_fill_n_a(this->_M_impl._M_finish,
382 _M_get_Tp_allocator());
383 this->_M_impl._M_finish += __n - __elems_after;
384 std::__uninitialized_move_a(__position.base(), __old_finish,
385 this->_M_impl._M_finish,
386 _M_get_Tp_allocator());
387 this->_M_impl._M_finish += __elems_after;
388 std::fill(__position.base(), __old_finish, __x_copy);
393 const size_type __len =
394 _M_check_len(__n, "vector::_M_fill_insert");
395 pointer __new_start(this->_M_allocate(__len));
396 pointer __new_finish(__new_start);
400 std::__uninitialized_move_a(this->_M_impl._M_start,
403 _M_get_Tp_allocator());
404 #ifdef __GXX_EXPERIMENTAL_CXX0X__
405 std::__uninitialized_fill_n_a(__new_finish, __n, __x_copy,
407 std::__uninitialized_fill_n_a(__new_finish, __n, __x,
409 _M_get_Tp_allocator());
412 std::__uninitialized_move_a(__position.base(),
413 this->_M_impl._M_finish,
415 _M_get_Tp_allocator());
419 std::_Destroy(__new_start, __new_finish,
420 _M_get_Tp_allocator());
421 _M_deallocate(__new_start, __len);
422 __throw_exception_again;
424 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
425 _M_get_Tp_allocator());
426 _M_deallocate(this->_M_impl._M_start,
427 this->_M_impl._M_end_of_storage
428 - this->_M_impl._M_start);
429 this->_M_impl._M_start = __new_start;
430 this->_M_impl._M_finish = __new_finish;
431 this->_M_impl._M_end_of_storage = __new_start + __len;
436 template<typename _Tp, typename _Alloc>
437 template<typename _InputIterator>
439 vector<_Tp, _Alloc>::
440 _M_range_insert(iterator __pos, _InputIterator __first,
441 _InputIterator __last, std::input_iterator_tag)
443 for (; __first != __last; ++__first)
445 __pos = insert(__pos, *__first);
450 template<typename _Tp, typename _Alloc>
451 template<typename _ForwardIterator>
453 vector<_Tp, _Alloc>::
454 _M_range_insert(iterator __position, _ForwardIterator __first,
455 _ForwardIterator __last, std::forward_iterator_tag)
457 if (__first != __last)
459 const size_type __n = std::distance(__first, __last);
460 if (size_type(this->_M_impl._M_end_of_storage
461 - this->_M_impl._M_finish) >= __n)
463 const size_type __elems_after = end() - __position;
464 pointer __old_finish(this->_M_impl._M_finish);
465 if (__elems_after > __n)
467 std::__uninitialized_move_a(this->_M_impl._M_finish - __n,
468 this->_M_impl._M_finish,
469 this->_M_impl._M_finish,
470 _M_get_Tp_allocator());
471 this->_M_impl._M_finish += __n;
472 _GLIBCXX_MOVE_BACKWARD3(__position.base(),
473 __old_finish - __n, __old_finish);
474 std::copy(__first, __last, __position);
478 _ForwardIterator __mid = __first;
479 std::advance(__mid, __elems_after);
480 std::__uninitialized_copy_a(__mid, __last,
481 this->_M_impl._M_finish,
482 _M_get_Tp_allocator());
483 this->_M_impl._M_finish += __n - __elems_after;
484 std::__uninitialized_move_a(__position.base(),
486 this->_M_impl._M_finish,
487 _M_get_Tp_allocator());
488 this->_M_impl._M_finish += __elems_after;
489 std::copy(__first, __mid, __position);
494 const size_type __len =
495 _M_check_len(__n, "vector::_M_range_insert");
496 pointer __new_start(this->_M_allocate(__len));
497 pointer __new_finish(__new_start);
501 std::__uninitialized_move_a(this->_M_impl._M_start,
504 _M_get_Tp_allocator());
506 std::__uninitialized_copy_a(__first, __last,
508 _M_get_Tp_allocator());
510 std::__uninitialized_move_a(__position.base(),
511 this->_M_impl._M_finish,
513 _M_get_Tp_allocator());
517 std::_Destroy(__new_start, __new_finish,
518 _M_get_Tp_allocator());
519 _M_deallocate(__new_start, __len);
520 __throw_exception_again;
522 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
523 _M_get_Tp_allocator());
524 _M_deallocate(this->_M_impl._M_start,
525 this->_M_impl._M_end_of_storage
526 - this->_M_impl._M_start);
527 this->_M_impl._M_start = __new_start;
528 this->_M_impl._M_finish = __new_finish;
529 this->_M_impl._M_end_of_storage = __new_start + __len;
537 template<typename _Alloc>
539 vector<bool, _Alloc>::
540 reserve(size_type __n)
542 if (__n > this->max_size())
543 __throw_length_error(__N("vector::reserve"));
544 if (this->capacity() < __n)
546 _Bit_type* __q = this->_M_allocate(__n);
547 this->_M_impl._M_finish = _M_copy_aligned(begin(), end(),
549 this->_M_deallocate();
550 this->_M_impl._M_start = iterator(__q, 0);
551 this->_M_impl._M_end_of_storage = (__q + (__n + int(_S_word_bit) - 1)
556 template<typename _Alloc>
558 vector<bool, _Alloc>::
559 _M_fill_insert(iterator __position, size_type __n, bool __x)
563 if (capacity() - size() >= __n)
565 std::copy_backward(__position, end(),
566 this->_M_impl._M_finish + difference_type(__n));
567 std::fill(__position, __position + difference_type(__n), __x);
568 this->_M_impl._M_finish += difference_type(__n);
572 const size_type __len =
573 _M_check_len(__n, "vector<bool>::_M_fill_insert");
574 _Bit_type * __q = this->_M_allocate(__len);
575 iterator __i = _M_copy_aligned(begin(), __position,
577 std::fill(__i, __i + difference_type(__n), __x);
578 this->_M_impl._M_finish = std::copy(__position, end(),
579 __i + difference_type(__n));
580 this->_M_deallocate();
581 this->_M_impl._M_end_of_storage = (__q + ((__len
582 + int(_S_word_bit) - 1)
583 / int(_S_word_bit)));
584 this->_M_impl._M_start = iterator(__q, 0);
588 template<typename _Alloc>
589 template<typename _ForwardIterator>
591 vector<bool, _Alloc>::
592 _M_insert_range(iterator __position, _ForwardIterator __first,
593 _ForwardIterator __last, std::forward_iterator_tag)
595 if (__first != __last)
597 size_type __n = std::distance(__first, __last);
598 if (capacity() - size() >= __n)
600 std::copy_backward(__position, end(),
601 this->_M_impl._M_finish
602 + difference_type(__n));
603 std::copy(__first, __last, __position);
604 this->_M_impl._M_finish += difference_type(__n);
608 const size_type __len =
609 _M_check_len(__n, "vector<bool>::_M_insert_range");
610 _Bit_type * __q = this->_M_allocate(__len);
611 iterator __i = _M_copy_aligned(begin(), __position,
613 __i = std::copy(__first, __last, __i);
614 this->_M_impl._M_finish = std::copy(__position, end(), __i);
615 this->_M_deallocate();
616 this->_M_impl._M_end_of_storage = (__q
618 + int(_S_word_bit) - 1)
619 / int(_S_word_bit)));
620 this->_M_impl._M_start = iterator(__q, 0);
625 template<typename _Alloc>
627 vector<bool, _Alloc>::
628 _M_insert_aux(iterator __position, bool __x)
630 if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage)
632 std::copy_backward(__position, this->_M_impl._M_finish,
633 this->_M_impl._M_finish + 1);
635 ++this->_M_impl._M_finish;
639 const size_type __len =
640 _M_check_len(size_type(1), "vector<bool>::_M_insert_aux");
641 _Bit_type * __q = this->_M_allocate(__len);
642 iterator __i = _M_copy_aligned(begin(), __position,
645 this->_M_impl._M_finish = std::copy(__position, end(), __i);
646 this->_M_deallocate();
647 this->_M_impl._M_end_of_storage = (__q + ((__len
648 + int(_S_word_bit) - 1)
649 / int(_S_word_bit)));
650 this->_M_impl._M_start = iterator(__q, 0);
654 _GLIBCXX_END_NESTED_NAMESPACE
656 #endif /* _VECTOR_TCC */