]>
Commit | Line | Data |
---|---|---|
83144cfc PE |
1 | // Vector implementation (out of line) -*- C++ -*- |
2 | ||
232c4925 PC |
3 | // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 |
4 | // Free Software Foundation, Inc. | |
83144cfc PE |
5 | // |
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) | |
10 | // any later version. | |
11 | ||
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. | |
16 | ||
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 | |
83f51799 | 19 | // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, |
83144cfc PE |
20 | // USA. |
21 | ||
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. | |
30 | ||
31 | /* | |
32 | * | |
33 | * Copyright (c) 1994 | |
34 | * Hewlett-Packard Company | |
35 | * | |
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. | |
43 | * | |
44 | * | |
45 | * Copyright (c) 1996 | |
46 | * Silicon Graphics Computer Systems, Inc. | |
47 | * | |
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. | |
55 | */ | |
56 | ||
57 | /** @file vector.tcc | |
58 | * This is an internal header file, included by other library headers. | |
59 | * You should not attempt to use it directly. | |
60 | */ | |
61 | ||
3d7c150e BK |
62 | #ifndef _VECTOR_TCC |
63 | #define _VECTOR_TCC 1 | |
83144cfc | 64 | |
3cbc7af0 BK |
65 | _GLIBCXX_BEGIN_NESTED_NAMESPACE(std, _GLIBCXX_STD) |
66 | ||
af5fb6ab | 67 | template<typename _Tp, typename _Alloc> |
3971a4d2 | 68 | void |
874e7baa | 69 | vector<_Tp, _Alloc>:: |
3971a4d2 | 70 | reserve(size_type __n) |
83144cfc | 71 | { |
48d1c3c5 | 72 | if (__n > this->max_size()) |
ba9119ec | 73 | __throw_length_error(__N("vector::reserve")); |
48d1c3c5 BK |
74 | if (this->capacity() < __n) |
75 | { | |
76 | const size_type __old_size = size(); | |
bc9053ab | 77 | pointer __tmp = _M_allocate_and_copy(__n, this->_M_impl._M_start, |
03f9ea44 | 78 | this->_M_impl._M_finish); |
1985f1cd | 79 | std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, |
4fd20a8f | 80 | _M_get_Tp_allocator()); |
03f9ea44 | 81 | _M_deallocate(this->_M_impl._M_start, |
874e7baa PC |
82 | this->_M_impl._M_end_of_storage |
83 | - this->_M_impl._M_start); | |
03f9ea44 DM |
84 | this->_M_impl._M_start = __tmp; |
85 | this->_M_impl._M_finish = __tmp + __old_size; | |
86 | this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; | |
48d1c3c5 | 87 | } |
3971a4d2 | 88 | } |
ed6814f7 | 89 | |
af5fb6ab | 90 | template<typename _Tp, typename _Alloc> |
874e7baa PC |
91 | typename vector<_Tp, _Alloc>::iterator |
92 | vector<_Tp, _Alloc>:: | |
3971a4d2 PE |
93 | insert(iterator __position, const value_type& __x) |
94 | { | |
43da93a7 | 95 | const size_type __n = __position - begin(); |
874e7baa PC |
96 | if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage |
97 | && __position == end()) | |
98 | { | |
1985f1cd | 99 | this->_M_impl.construct(this->_M_impl._M_finish, __x); |
874e7baa PC |
100 | ++this->_M_impl._M_finish; |
101 | } | |
83144cfc | 102 | else |
3971a4d2 | 103 | _M_insert_aux(__position, __x); |
bc9053ab | 104 | return iterator(this->_M_impl._M_start + __n); |
83144cfc | 105 | } |
ed6814f7 | 106 | |
af5fb6ab | 107 | template<typename _Tp, typename _Alloc> |
874e7baa PC |
108 | typename vector<_Tp, _Alloc>::iterator |
109 | vector<_Tp, _Alloc>:: | |
3971a4d2 | 110 | erase(iterator __position) |
83144cfc | 111 | { |
3971a4d2 | 112 | if (__position + 1 != end()) |
2f805868 | 113 | std::copy(__position + 1, end(), __position); |
03f9ea44 | 114 | --this->_M_impl._M_finish; |
1985f1cd | 115 | this->_M_impl.destroy(this->_M_impl._M_finish); |
3971a4d2 | 116 | return __position; |
83144cfc | 117 | } |
ed6814f7 | 118 | |
af5fb6ab | 119 | template<typename _Tp, typename _Alloc> |
874e7baa PC |
120 | typename vector<_Tp, _Alloc>::iterator |
121 | vector<_Tp, _Alloc>:: | |
3971a4d2 | 122 | erase(iterator __first, iterator __last) |
83144cfc | 123 | { |
bc9053ab PC |
124 | if (__last != end()) |
125 | std::copy(__last, end(), __first); | |
126 | _M_erase_at_end(__first.base() + (end() - __last)); | |
3971a4d2 | 127 | return __first; |
83144cfc | 128 | } |
ed6814f7 | 129 | |
af5fb6ab | 130 | template<typename _Tp, typename _Alloc> |
874e7baa PC |
131 | vector<_Tp, _Alloc>& |
132 | vector<_Tp, _Alloc>:: | |
133 | operator=(const vector<_Tp, _Alloc>& __x) | |
83144cfc | 134 | { |
3971a4d2 | 135 | if (&__x != this) |
874e7baa PC |
136 | { |
137 | const size_type __xlen = __x.size(); | |
138 | if (__xlen > capacity()) | |
139 | { | |
140 | pointer __tmp = _M_allocate_and_copy(__xlen, __x.begin(), | |
141 | __x.end()); | |
1985f1cd | 142 | std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, |
4fd20a8f | 143 | _M_get_Tp_allocator()); |
874e7baa PC |
144 | _M_deallocate(this->_M_impl._M_start, |
145 | this->_M_impl._M_end_of_storage | |
146 | - this->_M_impl._M_start); | |
147 | this->_M_impl._M_start = __tmp; | |
148 | this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __xlen; | |
149 | } | |
150 | else if (size() >= __xlen) | |
151 | { | |
bc9053ab PC |
152 | std::_Destroy(std::copy(__x.begin(), __x.end(), begin()), |
153 | end(), _M_get_Tp_allocator()); | |
874e7baa PC |
154 | } |
155 | else | |
156 | { | |
bc9053ab | 157 | std::copy(__x._M_impl._M_start, __x._M_impl._M_start + size(), |
874e7baa | 158 | this->_M_impl._M_start); |
bc9053ab PC |
159 | std::__uninitialized_copy_a(__x._M_impl._M_start + size(), |
160 | __x._M_impl._M_finish, | |
161 | this->_M_impl._M_finish, | |
4fd20a8f | 162 | _M_get_Tp_allocator()); |
874e7baa PC |
163 | } |
164 | this->_M_impl._M_finish = this->_M_impl._M_start + __xlen; | |
165 | } | |
3971a4d2 | 166 | return *this; |
83144cfc | 167 | } |
ed6814f7 | 168 | |
af5fb6ab | 169 | template<typename _Tp, typename _Alloc> |
3971a4d2 | 170 | void |
874e7baa | 171 | vector<_Tp, _Alloc>:: |
3971a4d2 | 172 | _M_fill_assign(size_t __n, const value_type& __val) |
83144cfc | 173 | { |
3971a4d2 | 174 | if (__n > capacity()) |
874e7baa | 175 | { |
4fd20a8f | 176 | vector __tmp(__n, __val, _M_get_Tp_allocator()); |
874e7baa PC |
177 | __tmp.swap(*this); |
178 | } | |
3971a4d2 | 179 | else if (__n > size()) |
874e7baa PC |
180 | { |
181 | std::fill(begin(), end(), __val); | |
1985f1cd MA |
182 | std::__uninitialized_fill_n_a(this->_M_impl._M_finish, |
183 | __n - size(), __val, | |
4fd20a8f | 184 | _M_get_Tp_allocator()); |
368b7a30 | 185 | this->_M_impl._M_finish += __n - size(); |
874e7baa | 186 | } |
3971a4d2 | 187 | else |
bc9053ab | 188 | _M_erase_at_end(std::fill_n(this->_M_impl._M_start, __n, __val)); |
83144cfc | 189 | } |
ed6814f7 | 190 | |
874e7baa PC |
191 | template<typename _Tp, typename _Alloc> |
192 | template<typename _InputIterator> | |
193 | void | |
194 | vector<_Tp, _Alloc>:: | |
195 | _M_assign_aux(_InputIterator __first, _InputIterator __last, | |
6323b34e | 196 | std::input_iterator_tag) |
3971a4d2 | 197 | { |
bc9053ab PC |
198 | pointer __cur(this->_M_impl._M_start); |
199 | for (; __first != __last && __cur != this->_M_impl._M_finish; | |
200 | ++__cur, ++__first) | |
874e7baa PC |
201 | *__cur = *__first; |
202 | if (__first == __last) | |
bc9053ab | 203 | _M_erase_at_end(__cur); |
874e7baa PC |
204 | else |
205 | insert(end(), __first, __last); | |
3971a4d2 | 206 | } |
874e7baa PC |
207 | |
208 | template<typename _Tp, typename _Alloc> | |
209 | template<typename _ForwardIterator> | |
210 | void | |
43da93a7 | 211 | vector<_Tp, _Alloc>:: |
874e7baa | 212 | _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, |
6323b34e | 213 | std::forward_iterator_tag) |
3971a4d2 | 214 | { |
43da93a7 | 215 | const size_type __len = std::distance(__first, __last); |
874e7baa PC |
216 | |
217 | if (__len > capacity()) | |
218 | { | |
219 | pointer __tmp(_M_allocate_and_copy(__len, __first, __last)); | |
1985f1cd | 220 | std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, |
4fd20a8f | 221 | _M_get_Tp_allocator()); |
874e7baa PC |
222 | _M_deallocate(this->_M_impl._M_start, |
223 | this->_M_impl._M_end_of_storage | |
224 | - this->_M_impl._M_start); | |
225 | this->_M_impl._M_start = __tmp; | |
226 | this->_M_impl._M_finish = this->_M_impl._M_start + __len; | |
227 | this->_M_impl._M_end_of_storage = this->_M_impl._M_finish; | |
228 | } | |
229 | else if (size() >= __len) | |
bc9053ab | 230 | _M_erase_at_end(std::copy(__first, __last, this->_M_impl._M_start)); |
874e7baa PC |
231 | else |
232 | { | |
233 | _ForwardIterator __mid = __first; | |
234 | std::advance(__mid, size()); | |
235 | std::copy(__first, __mid, this->_M_impl._M_start); | |
1985f1cd MA |
236 | this->_M_impl._M_finish = |
237 | std::__uninitialized_copy_a(__mid, __last, | |
238 | this->_M_impl._M_finish, | |
4fd20a8f | 239 | _M_get_Tp_allocator()); |
874e7baa | 240 | } |
3971a4d2 | 241 | } |
ed6814f7 | 242 | |
af5fb6ab | 243 | template<typename _Tp, typename _Alloc> |
3971a4d2 | 244 | void |
43da93a7 | 245 | vector<_Tp, _Alloc>:: |
3971a4d2 PE |
246 | _M_insert_aux(iterator __position, const _Tp& __x) |
247 | { | |
03f9ea44 | 248 | if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) |
874e7baa | 249 | { |
1985f1cd MA |
250 | this->_M_impl.construct(this->_M_impl._M_finish, |
251 | *(this->_M_impl._M_finish - 1)); | |
874e7baa PC |
252 | ++this->_M_impl._M_finish; |
253 | _Tp __x_copy = __x; | |
bc9053ab PC |
254 | std::copy_backward(__position.base(), |
255 | this->_M_impl._M_finish - 2, | |
256 | this->_M_impl._M_finish - 1); | |
874e7baa PC |
257 | *__position = __x_copy; |
258 | } | |
83144cfc | 259 | else |
874e7baa PC |
260 | { |
261 | const size_type __old_size = size(); | |
996e5395 PC |
262 | if (__old_size == this->max_size()) |
263 | __throw_length_error(__N("vector::_M_insert_aux")); | |
264 | ||
265 | // When sizeof(value_type) == 1 and __old_size > size_type(-1)/2 | |
266 | // __len overflows: if we don't notice and _M_allocate doesn't | |
267 | // throw we crash badly later. | |
268 | size_type __len = __old_size != 0 ? 2 * __old_size : 1; | |
269 | if (__len < __old_size) | |
270 | __len = this->max_size(); | |
271 | ||
bc9053ab PC |
272 | pointer __new_start(this->_M_allocate(__len)); |
273 | pointer __new_finish(__new_start); | |
874e7baa PC |
274 | try |
275 | { | |
1985f1cd | 276 | __new_finish = |
bc9053ab PC |
277 | std::__uninitialized_copy_a(this->_M_impl._M_start, |
278 | __position.base(), __new_start, | |
4fd20a8f | 279 | _M_get_Tp_allocator()); |
bc9053ab | 280 | this->_M_impl.construct(__new_finish, __x); |
874e7baa | 281 | ++__new_finish; |
1985f1cd | 282 | __new_finish = |
bc9053ab PC |
283 | std::__uninitialized_copy_a(__position.base(), |
284 | this->_M_impl._M_finish, | |
1985f1cd | 285 | __new_finish, |
4fd20a8f | 286 | _M_get_Tp_allocator()); |
996e5395 | 287 | } |
874e7baa PC |
288 | catch(...) |
289 | { | |
4fd20a8f | 290 | std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator()); |
bc9053ab | 291 | _M_deallocate(__new_start, __len); |
874e7baa PC |
292 | __throw_exception_again; |
293 | } | |
bc9053ab PC |
294 | std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, |
295 | _M_get_Tp_allocator()); | |
874e7baa PC |
296 | _M_deallocate(this->_M_impl._M_start, |
297 | this->_M_impl._M_end_of_storage | |
298 | - this->_M_impl._M_start); | |
bc9053ab PC |
299 | this->_M_impl._M_start = __new_start; |
300 | this->_M_impl._M_finish = __new_finish; | |
301 | this->_M_impl._M_end_of_storage = __new_start + __len; | |
874e7baa | 302 | } |
83144cfc | 303 | } |
64ebadac | 304 | |
af5fb6ab | 305 | template<typename _Tp, typename _Alloc> |
3971a4d2 | 306 | void |
43da93a7 | 307 | vector<_Tp, _Alloc>:: |
3971a4d2 PE |
308 | _M_fill_insert(iterator __position, size_type __n, const value_type& __x) |
309 | { | |
310 | if (__n != 0) | |
874e7baa PC |
311 | { |
312 | if (size_type(this->_M_impl._M_end_of_storage | |
313 | - this->_M_impl._M_finish) >= __n) | |
314 | { | |
315 | value_type __x_copy = __x; | |
316 | const size_type __elems_after = end() - __position; | |
bc9053ab | 317 | pointer __old_finish(this->_M_impl._M_finish); |
874e7baa PC |
318 | if (__elems_after > __n) |
319 | { | |
1985f1cd MA |
320 | std::__uninitialized_copy_a(this->_M_impl._M_finish - __n, |
321 | this->_M_impl._M_finish, | |
322 | this->_M_impl._M_finish, | |
4fd20a8f | 323 | _M_get_Tp_allocator()); |
874e7baa | 324 | this->_M_impl._M_finish += __n; |
bc9053ab | 325 | std::copy_backward(__position.base(), __old_finish - __n, |
874e7baa | 326 | __old_finish); |
bc9053ab PC |
327 | std::fill(__position.base(), __position.base() + __n, |
328 | __x_copy); | |
874e7baa PC |
329 | } |
330 | else | |
331 | { | |
1985f1cd MA |
332 | std::__uninitialized_fill_n_a(this->_M_impl._M_finish, |
333 | __n - __elems_after, | |
334 | __x_copy, | |
4fd20a8f | 335 | _M_get_Tp_allocator()); |
874e7baa | 336 | this->_M_impl._M_finish += __n - __elems_after; |
bc9053ab | 337 | std::__uninitialized_copy_a(__position.base(), __old_finish, |
1985f1cd | 338 | this->_M_impl._M_finish, |
4fd20a8f | 339 | _M_get_Tp_allocator()); |
874e7baa | 340 | this->_M_impl._M_finish += __elems_after; |
bc9053ab | 341 | std::fill(__position.base(), __old_finish, __x_copy); |
874e7baa PC |
342 | } |
343 | } | |
344 | else | |
345 | { | |
346 | const size_type __old_size = size(); | |
996e5395 PC |
347 | if (this->max_size() - __old_size < __n) |
348 | __throw_length_error(__N("vector::_M_fill_insert")); | |
349 | ||
350 | // See _M_insert_aux above. | |
351 | size_type __len = __old_size + std::max(__old_size, __n); | |
352 | if (__len < __old_size) | |
353 | __len = this->max_size(); | |
354 | ||
bc9053ab PC |
355 | pointer __new_start(this->_M_allocate(__len)); |
356 | pointer __new_finish(__new_start); | |
874e7baa PC |
357 | try |
358 | { | |
1985f1cd | 359 | __new_finish = |
bc9053ab PC |
360 | std::__uninitialized_copy_a(this->_M_impl._M_start, |
361 | __position.base(), | |
1985f1cd | 362 | __new_start, |
4fd20a8f | 363 | _M_get_Tp_allocator()); |
1985f1cd | 364 | std::__uninitialized_fill_n_a(__new_finish, __n, __x, |
4fd20a8f | 365 | _M_get_Tp_allocator()); |
368b7a30 | 366 | __new_finish += __n; |
1985f1cd | 367 | __new_finish = |
bc9053ab PC |
368 | std::__uninitialized_copy_a(__position.base(), |
369 | this->_M_impl._M_finish, | |
370 | __new_finish, | |
4fd20a8f | 371 | _M_get_Tp_allocator()); |
874e7baa PC |
372 | } |
373 | catch(...) | |
374 | { | |
1985f1cd | 375 | std::_Destroy(__new_start, __new_finish, |
4fd20a8f | 376 | _M_get_Tp_allocator()); |
bc9053ab | 377 | _M_deallocate(__new_start, __len); |
874e7baa PC |
378 | __throw_exception_again; |
379 | } | |
1985f1cd | 380 | std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, |
4fd20a8f | 381 | _M_get_Tp_allocator()); |
874e7baa PC |
382 | _M_deallocate(this->_M_impl._M_start, |
383 | this->_M_impl._M_end_of_storage | |
384 | - this->_M_impl._M_start); | |
bc9053ab PC |
385 | this->_M_impl._M_start = __new_start; |
386 | this->_M_impl._M_finish = __new_finish; | |
387 | this->_M_impl._M_end_of_storage = __new_start + __len; | |
874e7baa PC |
388 | } |
389 | } | |
3971a4d2 | 390 | } |
ed6814f7 | 391 | |
232c4925 PC |
392 | template<typename _Tp, typename _Alloc> |
393 | template<typename _InputIterator> | |
394 | void | |
395 | vector<_Tp, _Alloc>:: | |
396 | _M_range_insert(iterator __pos, _InputIterator __first, | |
397 | _InputIterator __last, std::input_iterator_tag) | |
398 | { | |
399 | for (; __first != __last; ++__first) | |
400 | { | |
401 | __pos = insert(__pos, *__first); | |
402 | ++__pos; | |
403 | } | |
404 | } | |
ed6814f7 | 405 | |
874e7baa PC |
406 | template<typename _Tp, typename _Alloc> |
407 | template<typename _ForwardIterator> | |
408 | void | |
43da93a7 | 409 | vector<_Tp, _Alloc>:: |
996e5395 | 410 | _M_range_insert(iterator __position, _ForwardIterator __first, |
6323b34e | 411 | _ForwardIterator __last, std::forward_iterator_tag) |
3971a4d2 | 412 | { |
874e7baa PC |
413 | if (__first != __last) |
414 | { | |
43da93a7 | 415 | const size_type __n = std::distance(__first, __last); |
874e7baa PC |
416 | if (size_type(this->_M_impl._M_end_of_storage |
417 | - this->_M_impl._M_finish) >= __n) | |
418 | { | |
419 | const size_type __elems_after = end() - __position; | |
bc9053ab | 420 | pointer __old_finish(this->_M_impl._M_finish); |
874e7baa PC |
421 | if (__elems_after > __n) |
422 | { | |
1985f1cd MA |
423 | std::__uninitialized_copy_a(this->_M_impl._M_finish - __n, |
424 | this->_M_impl._M_finish, | |
425 | this->_M_impl._M_finish, | |
4fd20a8f | 426 | _M_get_Tp_allocator()); |
874e7baa | 427 | this->_M_impl._M_finish += __n; |
bc9053ab | 428 | std::copy_backward(__position.base(), __old_finish - __n, |
874e7baa PC |
429 | __old_finish); |
430 | std::copy(__first, __last, __position); | |
431 | } | |
432 | else | |
433 | { | |
434 | _ForwardIterator __mid = __first; | |
435 | std::advance(__mid, __elems_after); | |
1985f1cd MA |
436 | std::__uninitialized_copy_a(__mid, __last, |
437 | this->_M_impl._M_finish, | |
4fd20a8f | 438 | _M_get_Tp_allocator()); |
874e7baa | 439 | this->_M_impl._M_finish += __n - __elems_after; |
bc9053ab PC |
440 | std::__uninitialized_copy_a(__position.base(), |
441 | __old_finish, | |
1985f1cd | 442 | this->_M_impl._M_finish, |
4fd20a8f | 443 | _M_get_Tp_allocator()); |
874e7baa PC |
444 | this->_M_impl._M_finish += __elems_after; |
445 | std::copy(__first, __mid, __position); | |
446 | } | |
447 | } | |
448 | else | |
449 | { | |
450 | const size_type __old_size = size(); | |
996e5395 PC |
451 | if (this->max_size() - __old_size < __n) |
452 | __throw_length_error(__N("vector::_M_range_insert")); | |
453 | ||
454 | // See _M_insert_aux above. | |
455 | size_type __len = __old_size + std::max(__old_size, __n); | |
456 | if (__len < __old_size) | |
457 | __len = this->max_size(); | |
458 | ||
bc9053ab PC |
459 | pointer __new_start(this->_M_allocate(__len)); |
460 | pointer __new_finish(__new_start); | |
874e7baa PC |
461 | try |
462 | { | |
1985f1cd | 463 | __new_finish = |
bc9053ab PC |
464 | std::__uninitialized_copy_a(this->_M_impl._M_start, |
465 | __position.base(), | |
1985f1cd | 466 | __new_start, |
4fd20a8f | 467 | _M_get_Tp_allocator()); |
1985f1cd MA |
468 | __new_finish = |
469 | std::__uninitialized_copy_a(__first, __last, __new_finish, | |
4fd20a8f | 470 | _M_get_Tp_allocator()); |
1985f1cd | 471 | __new_finish = |
bc9053ab PC |
472 | std::__uninitialized_copy_a(__position.base(), |
473 | this->_M_impl._M_finish, | |
1985f1cd | 474 | __new_finish, |
4fd20a8f | 475 | _M_get_Tp_allocator()); |
874e7baa PC |
476 | } |
477 | catch(...) | |
478 | { | |
bc9053ab | 479 | std::_Destroy(__new_start, __new_finish, |
4fd20a8f | 480 | _M_get_Tp_allocator()); |
bc9053ab | 481 | _M_deallocate(__new_start, __len); |
874e7baa PC |
482 | __throw_exception_again; |
483 | } | |
1985f1cd | 484 | std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, |
4fd20a8f | 485 | _M_get_Tp_allocator()); |
874e7baa PC |
486 | _M_deallocate(this->_M_impl._M_start, |
487 | this->_M_impl._M_end_of_storage | |
488 | - this->_M_impl._M_start); | |
bc9053ab PC |
489 | this->_M_impl._M_start = __new_start; |
490 | this->_M_impl._M_finish = __new_finish; | |
491 | this->_M_impl._M_end_of_storage = __new_start + __len; | |
874e7baa PC |
492 | } |
493 | } | |
83144cfc | 494 | } |
3cbc7af0 | 495 | |
232c4925 PC |
496 | |
497 | // vector<bool> | |
498 | ||
499 | template<typename _Alloc> | |
500 | void | |
501 | vector<bool, _Alloc>:: | |
502 | _M_fill_insert(iterator __position, size_type __n, bool __x) | |
503 | { | |
504 | if (__n == 0) | |
505 | return; | |
506 | if (capacity() - size() >= __n) | |
507 | { | |
508 | std::copy_backward(__position, end(), | |
509 | this->_M_impl._M_finish + difference_type(__n)); | |
510 | std::fill(__position, __position + difference_type(__n), __x); | |
511 | this->_M_impl._M_finish += difference_type(__n); | |
512 | } | |
513 | else | |
514 | { | |
515 | const size_type __len = size() + std::max(size(), __n); | |
516 | _Bit_type * __q = this->_M_allocate(__len); | |
517 | iterator __i = _M_copy_aligned(begin(), __position, | |
518 | iterator(__q, 0)); | |
519 | std::fill(__i, __i + difference_type(__n), __x); | |
520 | this->_M_impl._M_finish = std::copy(__position, end(), | |
521 | __i + difference_type(__n)); | |
522 | this->_M_deallocate(); | |
523 | this->_M_impl._M_end_of_storage = (__q + ((__len | |
524 | + int(_S_word_bit) - 1) | |
525 | / int(_S_word_bit))); | |
526 | this->_M_impl._M_start = iterator(__q, 0); | |
527 | } | |
528 | } | |
529 | ||
530 | template<typename _Alloc> | |
531 | template<typename _ForwardIterator> | |
532 | void | |
533 | vector<bool, _Alloc>:: | |
534 | _M_insert_range(iterator __position, _ForwardIterator __first, | |
535 | _ForwardIterator __last, std::forward_iterator_tag) | |
536 | { | |
537 | if (__first != __last) | |
538 | { | |
539 | size_type __n = std::distance(__first, __last); | |
540 | if (capacity() - size() >= __n) | |
541 | { | |
542 | std::copy_backward(__position, end(), | |
543 | this->_M_impl._M_finish | |
544 | + difference_type(__n)); | |
545 | std::copy(__first, __last, __position); | |
546 | this->_M_impl._M_finish += difference_type(__n); | |
547 | } | |
548 | else | |
549 | { | |
550 | const size_type __len = size() + std::max(size(), __n); | |
551 | _Bit_type * __q = this->_M_allocate(__len); | |
552 | iterator __i = _M_copy_aligned(begin(), __position, | |
553 | iterator(__q, 0)); | |
554 | __i = std::copy(__first, __last, __i); | |
555 | this->_M_impl._M_finish = std::copy(__position, end(), __i); | |
556 | this->_M_deallocate(); | |
557 | this->_M_impl._M_end_of_storage = (__q | |
558 | + ((__len | |
559 | + int(_S_word_bit) - 1) | |
560 | / int(_S_word_bit))); | |
561 | this->_M_impl._M_start = iterator(__q, 0); | |
562 | } | |
563 | } | |
564 | } | |
565 | ||
566 | template<typename _Alloc> | |
567 | void | |
568 | vector<bool, _Alloc>:: | |
569 | _M_insert_aux(iterator __position, bool __x) | |
570 | { | |
571 | if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage) | |
572 | { | |
573 | std::copy_backward(__position, this->_M_impl._M_finish, | |
574 | this->_M_impl._M_finish + 1); | |
575 | *__position = __x; | |
576 | ++this->_M_impl._M_finish; | |
577 | } | |
578 | else | |
579 | { | |
580 | const size_type __len = size() ? 2 * size() | |
581 | : static_cast<size_type>(_S_word_bit); | |
582 | _Bit_type * __q = this->_M_allocate(__len); | |
583 | iterator __i = _M_copy_aligned(begin(), __position, | |
584 | iterator(__q, 0)); | |
585 | *__i++ = __x; | |
586 | this->_M_impl._M_finish = std::copy(__position, end(), __i); | |
587 | this->_M_deallocate(); | |
588 | this->_M_impl._M_end_of_storage = (__q + ((__len | |
589 | + int(_S_word_bit) - 1) | |
590 | / int(_S_word_bit))); | |
591 | this->_M_impl._M_start = iterator(__q, 0); | |
592 | } | |
593 | } | |
594 | ||
3cbc7af0 | 595 | _GLIBCXX_END_NESTED_NAMESPACE |
83144cfc | 596 | |
3d7c150e | 597 | #endif /* _VECTOR_TCC */ |