1 : // Vector implementation (out of line) -*- C++ -*-
2 :
3 : // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
4 : // 2011 Free Software Foundation, Inc.
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 3, 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 : // Under Section 7 of GPL version 3, you are granted additional
18 : // permissions described in the GCC Runtime Library Exception, version
19 : // 3.1, as published by the Free Software Foundation.
20 :
21 : // You should have received a copy of the GNU General Public License and
22 : // a copy of the GCC Runtime Library Exception along with this program;
23 : // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 : // <http://www.gnu.org/licenses/>.
25 :
26 : /*
27 : *
28 : * Copyright (c) 1994
29 : * Hewlett-Packard Company
30 : *
31 : * Permission to use, copy, modify, distribute and sell this software
32 : * and its documentation for any purpose is hereby granted without fee,
33 : * provided that the above copyright notice appear in all copies and
34 : * that both that copyright notice and this permission notice appear
35 : * in supporting documentation. Hewlett-Packard Company makes no
36 : * representations about the suitability of this software for any
37 : * purpose. It is provided "as is" without express or implied warranty.
38 : *
39 : *
40 : * Copyright (c) 1996
41 : * Silicon Graphics Computer Systems, Inc.
42 : *
43 : * Permission to use, copy, modify, distribute and sell this software
44 : * and its documentation for any purpose is hereby granted without fee,
45 : * provided that the above copyright notice appear in all copies and
46 : * that both that copyright notice and this permission notice appear
47 : * in supporting documentation. Silicon Graphics makes no
48 : * representations about the suitability of this software for any
49 : * purpose. It is provided "as is" without express or implied warranty.
50 : */
51 :
52 : /** @file bits/vector.tcc
53 : * This is an internal header file, included by other library headers.
54 : * Do not attempt to use it directly. @headername{vector}
55 : */
56 :
57 : #ifndef _VECTOR_TCC
58 : #define _VECTOR_TCC 1
59 :
60 : namespace std _GLIBCXX_VISIBILITY(default)
61 : {
62 : _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
63 :
64 : template<typename _Tp, typename _Alloc>
65 : void
66 : vector<_Tp, _Alloc>::
67 : reserve(size_type __n)
68 : {
69 : if (__n > this->max_size())
70 : __throw_length_error(__N("vector::reserve"));
71 : if (this->capacity() < __n)
72 : {
73 : const size_type __old_size = size();
74 : pointer __tmp = _M_allocate_and_copy(__n,
75 : _GLIBCXX_MAKE_MOVE_ITERATOR(this->_M_impl._M_start),
76 : _GLIBCXX_MAKE_MOVE_ITERATOR(this->_M_impl._M_finish));
77 : std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
78 : _M_get_Tp_allocator());
79 : _M_deallocate(this->_M_impl._M_start,
80 : this->_M_impl._M_end_of_storage
81 : - this->_M_impl._M_start);
82 : this->_M_impl._M_start = __tmp;
83 : this->_M_impl._M_finish = __tmp + __old_size;
84 : this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n;
85 : }
86 : }
87 :
88 : #ifdef __GXX_EXPERIMENTAL_CXX0X__
89 : template<typename _Tp, typename _Alloc>
90 : template<typename... _Args>
91 : void
92 : vector<_Tp, _Alloc>::
93 : emplace_back(_Args&&... __args)
94 : {
95 : if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
96 : {
97 : this->_M_impl.construct(this->_M_impl._M_finish,
98 : std::forward<_Args>(__args)...);
99 : ++this->_M_impl._M_finish;
100 : }
101 : else
102 : _M_insert_aux(end(), std::forward<_Args>(__args)...);
103 : }
104 : #endif
105 :
106 : template<typename _Tp, typename _Alloc>
107 : typename vector<_Tp, _Alloc>::iterator
108 : vector<_Tp, _Alloc>::
109 : insert(iterator __position, const value_type& __x)
110 : {
111 : const size_type __n = __position - begin();
112 : if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage
113 : && __position == end())
114 : {
115 : this->_M_impl.construct(this->_M_impl._M_finish, __x);
116 : ++this->_M_impl._M_finish;
117 : }
118 : else
119 : {
120 : #ifdef __GXX_EXPERIMENTAL_CXX0X__
121 : if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
122 : {
123 : _Tp __x_copy = __x;
124 : _M_insert_aux(__position, std::move(__x_copy));
125 : }
126 : else
127 : #endif
128 : _M_insert_aux(__position, __x);
129 : }
130 : return iterator(this->_M_impl._M_start + __n);
131 : }
132 :
133 : template<typename _Tp, typename _Alloc>
134 : typename vector<_Tp, _Alloc>::iterator
135 : vector<_Tp, _Alloc>::
136 : erase(iterator __position)
137 : {
138 : if (__position + 1 != end())
139 : _GLIBCXX_MOVE3(__position + 1, end(), __position);
140 : --this->_M_impl._M_finish;
141 : this->_M_impl.destroy(this->_M_impl._M_finish);
142 : return __position;
143 : }
144 :
145 : template<typename _Tp, typename _Alloc>
146 : typename vector<_Tp, _Alloc>::iterator
147 : vector<_Tp, _Alloc>::
148 : erase(iterator __first, iterator __last)
149 : {
150 : if (__first != __last)
151 : {
152 : if (__last != end())
153 : _GLIBCXX_MOVE3(__last, end(), __first);
154 : _M_erase_at_end(__first.base() + (end() - __last));
155 : }
156 : return __first;
157 : }
158 :
159 : template<typename _Tp, typename _Alloc>
160 : vector<_Tp, _Alloc>&
161 0 : vector<_Tp, _Alloc>::
162 : operator=(const vector<_Tp, _Alloc>& __x)
163 : {
164 0 : if (&__x != this)
165 : {
166 0 : const size_type __xlen = __x.size();
167 0 : if (__xlen > capacity())
168 : {
169 : pointer __tmp = _M_allocate_and_copy(__xlen, __x.begin(),
170 0 : __x.end());
171 0 : std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
172 : _M_get_Tp_allocator());
173 0 : _M_deallocate(this->_M_impl._M_start,
174 : this->_M_impl._M_end_of_storage
175 : - this->_M_impl._M_start);
176 0 : this->_M_impl._M_start = __tmp;
177 0 : this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __xlen;
178 : }
179 0 : else if (size() >= __xlen)
180 : {
181 0 : std::_Destroy(std::copy(__x.begin(), __x.end(), begin()),
182 : end(), _M_get_Tp_allocator());
183 : }
184 : else
185 : {
186 0 : std::copy(__x._M_impl._M_start, __x._M_impl._M_start + size(),
187 : this->_M_impl._M_start);
188 0 : std::__uninitialized_copy_a(__x._M_impl._M_start + size(),
189 : __x._M_impl._M_finish,
190 : this->_M_impl._M_finish,
191 : _M_get_Tp_allocator());
192 : }
193 0 : this->_M_impl._M_finish = this->_M_impl._M_start + __xlen;
194 : }
195 0 : return *this;
196 : }
197 :
198 : template<typename _Tp, typename _Alloc>
199 : void
200 : vector<_Tp, _Alloc>::
201 : _M_fill_assign(size_t __n, const value_type& __val)
202 : {
203 : if (__n > capacity())
204 : {
205 : vector __tmp(__n, __val, _M_get_Tp_allocator());
206 : __tmp.swap(*this);
207 : }
208 : else if (__n > size())
209 : {
210 : std::fill(begin(), end(), __val);
211 : std::__uninitialized_fill_n_a(this->_M_impl._M_finish,
212 : __n - size(), __val,
213 : _M_get_Tp_allocator());
214 : this->_M_impl._M_finish += __n - size();
215 : }
216 : else
217 : _M_erase_at_end(std::fill_n(this->_M_impl._M_start, __n, __val));
218 : }
219 :
220 : template<typename _Tp, typename _Alloc>
221 : template<typename _InputIterator>
222 : void
223 : vector<_Tp, _Alloc>::
224 : _M_assign_aux(_InputIterator __first, _InputIterator __last,
225 : std::input_iterator_tag)
226 : {
227 : pointer __cur(this->_M_impl._M_start);
228 : for (; __first != __last && __cur != this->_M_impl._M_finish;
229 : ++__cur, ++__first)
230 : *__cur = *__first;
231 : if (__first == __last)
232 : _M_erase_at_end(__cur);
233 : else
234 : insert(end(), __first, __last);
235 : }
236 :
237 : template<typename _Tp, typename _Alloc>
238 : template<typename _ForwardIterator>
239 : void
240 : vector<_Tp, _Alloc>::
241 : _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last,
242 : std::forward_iterator_tag)
243 : {
244 : const size_type __len = std::distance(__first, __last);
245 :
246 : if (__len > capacity())
247 : {
248 : pointer __tmp(_M_allocate_and_copy(__len, __first, __last));
249 : std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
250 : _M_get_Tp_allocator());
251 : _M_deallocate(this->_M_impl._M_start,
252 : this->_M_impl._M_end_of_storage
253 : - this->_M_impl._M_start);
254 : this->_M_impl._M_start = __tmp;
255 : this->_M_impl._M_finish = this->_M_impl._M_start + __len;
256 : this->_M_impl._M_end_of_storage = this->_M_impl._M_finish;
257 : }
258 : else if (size() >= __len)
259 : _M_erase_at_end(std::copy(__first, __last, this->_M_impl._M_start));
260 : else
261 : {
262 : _ForwardIterator __mid = __first;
263 : std::advance(__mid, size());
264 : std::copy(__first, __mid, this->_M_impl._M_start);
265 : this->_M_impl._M_finish =
266 : std::__uninitialized_copy_a(__mid, __last,
267 : this->_M_impl._M_finish,
268 : _M_get_Tp_allocator());
269 : }
270 : }
271 :
272 : #ifdef __GXX_EXPERIMENTAL_CXX0X__
273 : template<typename _Tp, typename _Alloc>
274 : template<typename... _Args>
275 : typename vector<_Tp, _Alloc>::iterator
276 : vector<_Tp, _Alloc>::
277 : emplace(iterator __position, _Args&&... __args)
278 : {
279 : const size_type __n = __position - begin();
280 : if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage
281 : && __position == end())
282 : {
283 : this->_M_impl.construct(this->_M_impl._M_finish,
284 : std::forward<_Args>(__args)...);
285 : ++this->_M_impl._M_finish;
286 : }
287 : else
288 : _M_insert_aux(__position, std::forward<_Args>(__args)...);
289 : return iterator(this->_M_impl._M_start + __n);
290 : }
291 :
292 : template<typename _Tp, typename _Alloc>
293 : template<typename... _Args>
294 : void
295 : vector<_Tp, _Alloc>::
296 : _M_insert_aux(iterator __position, _Args&&... __args)
297 : #else
298 : template<typename _Tp, typename _Alloc>
299 : void
300 642741 : vector<_Tp, _Alloc>::
301 : _M_insert_aux(iterator __position, const _Tp& __x)
302 : #endif
303 : {
304 642741 : if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
305 : {
306 0 : this->_M_impl.construct(this->_M_impl._M_finish,
307 : _GLIBCXX_MOVE(*(this->_M_impl._M_finish
308 : - 1)));
309 0 : ++this->_M_impl._M_finish;
310 : #ifndef __GXX_EXPERIMENTAL_CXX0X__
311 0 : _Tp __x_copy = __x;
312 : #endif
313 0 : _GLIBCXX_MOVE_BACKWARD3(__position.base(),
314 : this->_M_impl._M_finish - 2,
315 : this->_M_impl._M_finish - 1);
316 : #ifndef __GXX_EXPERIMENTAL_CXX0X__
317 0 : *__position = __x_copy;
318 : #else
319 : *__position = _Tp(std::forward<_Args>(__args)...);
320 : #endif
321 : }
322 : else
323 : {
324 : const size_type __len =
325 642741 : _M_check_len(size_type(1), "vector::_M_insert_aux");
326 642741 : const size_type __elems_before = __position - begin();
327 642741 : pointer __new_start(this->_M_allocate(__len));
328 642741 : pointer __new_finish(__new_start);
329 : __try
330 : {
331 : // The order of the three operations is dictated by the C++0x
332 : // case, where the moves could alter a new element belonging
333 : // to the existing vector. This is an issue only for callers
334 : // taking the element by const lvalue ref (see 23.1/13).
335 642741 : this->_M_impl.construct(__new_start + __elems_before,
336 : #ifdef __GXX_EXPERIMENTAL_CXX0X__
337 : std::forward<_Args>(__args)...);
338 : #else
339 : __x);
340 : #endif
341 642741 : __new_finish = 0;
342 :
343 642741 : __new_finish =
344 : std::__uninitialized_move_a(this->_M_impl._M_start,
345 : __position.base(), __new_start,
346 : _M_get_Tp_allocator());
347 642741 : ++__new_finish;
348 :
349 642741 : __new_finish =
350 : std::__uninitialized_move_a(__position.base(),
351 : this->_M_impl._M_finish,
352 : __new_finish,
353 : _M_get_Tp_allocator());
354 : }
355 0 : __catch(...)
356 : {
357 0 : if (!__new_finish)
358 0 : this->_M_impl.destroy(__new_start + __elems_before);
359 : else
360 0 : std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator());
361 0 : _M_deallocate(__new_start, __len);
362 0 : __throw_exception_again;
363 : }
364 642741 : std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
365 : _M_get_Tp_allocator());
366 642741 : _M_deallocate(this->_M_impl._M_start,
367 : this->_M_impl._M_end_of_storage
368 : - this->_M_impl._M_start);
369 642741 : this->_M_impl._M_start = __new_start;
370 642741 : this->_M_impl._M_finish = __new_finish;
371 642741 : this->_M_impl._M_end_of_storage = __new_start + __len;
372 : }
373 642741 : }
374 :
375 : template<typename _Tp, typename _Alloc>
376 : void
377 12290 : vector<_Tp, _Alloc>::
378 : _M_fill_insert(iterator __position, size_type __n, const value_type& __x)
379 : {
380 12290 : if (__n != 0)
381 : {
382 12290 : if (size_type(this->_M_impl._M_end_of_storage
383 : - this->_M_impl._M_finish) >= __n)
384 : {
385 8090 : value_type __x_copy = __x;
386 8090 : const size_type __elems_after = end() - __position;
387 8090 : pointer __old_finish(this->_M_impl._M_finish);
388 8090 : if (__elems_after > __n)
389 : {
390 0 : std::__uninitialized_move_a(this->_M_impl._M_finish - __n,
391 : this->_M_impl._M_finish,
392 : this->_M_impl._M_finish,
393 : _M_get_Tp_allocator());
394 0 : this->_M_impl._M_finish += __n;
395 0 : _GLIBCXX_MOVE_BACKWARD3(__position.base(),
396 : __old_finish - __n, __old_finish);
397 0 : std::fill(__position.base(), __position.base() + __n,
398 : __x_copy);
399 : }
400 : else
401 : {
402 8090 : std::__uninitialized_fill_n_a(this->_M_impl._M_finish,
403 : __n - __elems_after,
404 : __x_copy,
405 : _M_get_Tp_allocator());
406 8090 : this->_M_impl._M_finish += __n - __elems_after;
407 8090 : std::__uninitialized_move_a(__position.base(), __old_finish,
408 : this->_M_impl._M_finish,
409 : _M_get_Tp_allocator());
410 8090 : this->_M_impl._M_finish += __elems_after;
411 8090 : std::fill(__position.base(), __old_finish, __x_copy);
412 : }
413 : }
414 : else
415 : {
416 : const size_type __len =
417 4200 : _M_check_len(__n, "vector::_M_fill_insert");
418 4200 : const size_type __elems_before = __position - begin();
419 4200 : pointer __new_start(this->_M_allocate(__len));
420 4200 : pointer __new_finish(__new_start);
421 : __try
422 : {
423 : // See _M_insert_aux above.
424 4200 : std::__uninitialized_fill_n_a(__new_start + __elems_before,
425 : __n, __x,
426 : _M_get_Tp_allocator());
427 4200 : __new_finish = 0;
428 :
429 4200 : __new_finish =
430 : std::__uninitialized_move_a(this->_M_impl._M_start,
431 : __position.base(),
432 : __new_start,
433 : _M_get_Tp_allocator());
434 4200 : __new_finish += __n;
435 :
436 4200 : __new_finish =
437 : std::__uninitialized_move_a(__position.base(),
438 : this->_M_impl._M_finish,
439 : __new_finish,
440 : _M_get_Tp_allocator());
441 : }
442 0 : __catch(...)
443 : {
444 0 : if (!__new_finish)
445 0 : std::_Destroy(__new_start + __elems_before,
446 : __new_start + __elems_before + __n,
447 : _M_get_Tp_allocator());
448 : else
449 0 : std::_Destroy(__new_start, __new_finish,
450 : _M_get_Tp_allocator());
451 0 : _M_deallocate(__new_start, __len);
452 0 : __throw_exception_again;
453 : }
454 4200 : std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
455 : _M_get_Tp_allocator());
456 4200 : _M_deallocate(this->_M_impl._M_start,
457 : this->_M_impl._M_end_of_storage
458 : - this->_M_impl._M_start);
459 4200 : this->_M_impl._M_start = __new_start;
460 4200 : this->_M_impl._M_finish = __new_finish;
461 4200 : this->_M_impl._M_end_of_storage = __new_start + __len;
462 : }
463 : }
464 12290 : }
465 :
466 : #ifdef __GXX_EXPERIMENTAL_CXX0X__
467 : template<typename _Tp, typename _Alloc>
468 : void
469 : vector<_Tp, _Alloc>::
470 : _M_default_append(size_type __n)
471 : {
472 : if (__n != 0)
473 : {
474 : if (size_type(this->_M_impl._M_end_of_storage
475 : - this->_M_impl._M_finish) >= __n)
476 : {
477 : std::__uninitialized_default_n_a(this->_M_impl._M_finish,
478 : __n, _M_get_Tp_allocator());
479 : this->_M_impl._M_finish += __n;
480 : }
481 : else
482 : {
483 : const size_type __len =
484 : _M_check_len(__n, "vector::_M_default_append");
485 : const size_type __old_size = this->size();
486 : pointer __new_start(this->_M_allocate(__len));
487 : pointer __new_finish(__new_start);
488 : __try
489 : {
490 : __new_finish =
491 : std::__uninitialized_move_a(this->_M_impl._M_start,
492 : this->_M_impl._M_finish,
493 : __new_start,
494 : _M_get_Tp_allocator());
495 : std::__uninitialized_default_n_a(__new_finish, __n,
496 : _M_get_Tp_allocator());
497 : __new_finish += __n;
498 : }
499 : __catch(...)
500 : {
501 : std::_Destroy(__new_start, __new_finish,
502 : _M_get_Tp_allocator());
503 : _M_deallocate(__new_start, __len);
504 : __throw_exception_again;
505 : }
506 : std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
507 : _M_get_Tp_allocator());
508 : _M_deallocate(this->_M_impl._M_start,
509 : this->_M_impl._M_end_of_storage
510 : - this->_M_impl._M_start);
511 : this->_M_impl._M_start = __new_start;
512 : this->_M_impl._M_finish = __new_finish;
513 : this->_M_impl._M_end_of_storage = __new_start + __len;
514 : }
515 : }
516 : }
517 : #endif
518 :
519 : template<typename _Tp, typename _Alloc>
520 : template<typename _InputIterator>
521 : void
522 : vector<_Tp, _Alloc>::
523 : _M_range_insert(iterator __pos, _InputIterator __first,
524 : _InputIterator __last, std::input_iterator_tag)
525 : {
526 : for (; __first != __last; ++__first)
527 : {
528 : __pos = insert(__pos, *__first);
529 : ++__pos;
530 : }
531 : }
532 :
533 : template<typename _Tp, typename _Alloc>
534 : template<typename _ForwardIterator>
535 : void
536 0 : vector<_Tp, _Alloc>::
537 : _M_range_insert(iterator __position, _ForwardIterator __first,
538 : _ForwardIterator __last, std::forward_iterator_tag)
539 : {
540 0 : if (__first != __last)
541 : {
542 0 : const size_type __n = std::distance(__first, __last);
543 0 : if (size_type(this->_M_impl._M_end_of_storage
544 : - this->_M_impl._M_finish) >= __n)
545 : {
546 0 : const size_type __elems_after = end() - __position;
547 0 : pointer __old_finish(this->_M_impl._M_finish);
548 0 : if (__elems_after > __n)
549 : {
550 0 : std::__uninitialized_move_a(this->_M_impl._M_finish - __n,
551 : this->_M_impl._M_finish,
552 : this->_M_impl._M_finish,
553 : _M_get_Tp_allocator());
554 0 : this->_M_impl._M_finish += __n;
555 0 : _GLIBCXX_MOVE_BACKWARD3(__position.base(),
556 : __old_finish - __n, __old_finish);
557 0 : std::copy(__first, __last, __position);
558 : }
559 : else
560 : {
561 0 : _ForwardIterator __mid = __first;
562 0 : std::advance(__mid, __elems_after);
563 0 : std::__uninitialized_copy_a(__mid, __last,
564 : this->_M_impl._M_finish,
565 : _M_get_Tp_allocator());
566 0 : this->_M_impl._M_finish += __n - __elems_after;
567 0 : std::__uninitialized_move_a(__position.base(),
568 : __old_finish,
569 : this->_M_impl._M_finish,
570 : _M_get_Tp_allocator());
571 0 : this->_M_impl._M_finish += __elems_after;
572 0 : std::copy(__first, __mid, __position);
573 : }
574 : }
575 : else
576 : {
577 : const size_type __len =
578 0 : _M_check_len(__n, "vector::_M_range_insert");
579 0 : pointer __new_start(this->_M_allocate(__len));
580 0 : pointer __new_finish(__new_start);
581 : __try
582 : {
583 0 : __new_finish =
584 : std::__uninitialized_move_a(this->_M_impl._M_start,
585 : __position.base(),
586 : __new_start,
587 : _M_get_Tp_allocator());
588 0 : __new_finish =
589 : std::__uninitialized_copy_a(__first, __last,
590 : __new_finish,
591 : _M_get_Tp_allocator());
592 0 : __new_finish =
593 : std::__uninitialized_move_a(__position.base(),
594 : this->_M_impl._M_finish,
595 : __new_finish,
596 : _M_get_Tp_allocator());
597 : }
598 0 : __catch(...)
599 : {
600 0 : std::_Destroy(__new_start, __new_finish,
601 : _M_get_Tp_allocator());
602 0 : _M_deallocate(__new_start, __len);
603 0 : __throw_exception_again;
604 : }
605 0 : std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
606 : _M_get_Tp_allocator());
607 0 : _M_deallocate(this->_M_impl._M_start,
608 : this->_M_impl._M_end_of_storage
609 : - this->_M_impl._M_start);
610 0 : this->_M_impl._M_start = __new_start;
611 0 : this->_M_impl._M_finish = __new_finish;
612 0 : this->_M_impl._M_end_of_storage = __new_start + __len;
613 : }
614 : }
615 0 : }
616 :
617 :
618 : // vector<bool>
619 :
620 : template<typename _Alloc>
621 : void
622 : vector<bool, _Alloc>::
623 : reserve(size_type __n)
624 : {
625 : if (__n > this->max_size())
626 : __throw_length_error(__N("vector::reserve"));
627 : if (this->capacity() < __n)
628 : {
629 : _Bit_type* __q = this->_M_allocate(__n);
630 : this->_M_impl._M_finish = _M_copy_aligned(begin(), end(),
631 : iterator(__q, 0));
632 : this->_M_deallocate();
633 : this->_M_impl._M_start = iterator(__q, 0);
634 : this->_M_impl._M_end_of_storage = (__q + (__n + int(_S_word_bit) - 1)
635 : / int(_S_word_bit));
636 : }
637 : }
638 :
639 : template<typename _Alloc>
640 : void
641 : vector<bool, _Alloc>::
642 : _M_fill_insert(iterator __position, size_type __n, bool __x)
643 : {
644 : if (__n == 0)
645 : return;
646 : if (capacity() - size() >= __n)
647 : {
648 : std::copy_backward(__position, end(),
649 : this->_M_impl._M_finish + difference_type(__n));
650 : std::fill(__position, __position + difference_type(__n), __x);
651 : this->_M_impl._M_finish += difference_type(__n);
652 : }
653 : else
654 : {
655 : const size_type __len =
656 : _M_check_len(__n, "vector<bool>::_M_fill_insert");
657 : _Bit_type * __q = this->_M_allocate(__len);
658 : iterator __i = _M_copy_aligned(begin(), __position,
659 : iterator(__q, 0));
660 : std::fill(__i, __i + difference_type(__n), __x);
661 : this->_M_impl._M_finish = std::copy(__position, end(),
662 : __i + difference_type(__n));
663 : this->_M_deallocate();
664 : this->_M_impl._M_end_of_storage = (__q + ((__len
665 : + int(_S_word_bit) - 1)
666 : / int(_S_word_bit)));
667 : this->_M_impl._M_start = iterator(__q, 0);
668 : }
669 : }
670 :
671 : template<typename _Alloc>
672 : template<typename _ForwardIterator>
673 : void
674 : vector<bool, _Alloc>::
675 : _M_insert_range(iterator __position, _ForwardIterator __first,
676 : _ForwardIterator __last, std::forward_iterator_tag)
677 : {
678 : if (__first != __last)
679 : {
680 : size_type __n = std::distance(__first, __last);
681 : if (capacity() - size() >= __n)
682 : {
683 : std::copy_backward(__position, end(),
684 : this->_M_impl._M_finish
685 : + difference_type(__n));
686 : std::copy(__first, __last, __position);
687 : this->_M_impl._M_finish += difference_type(__n);
688 : }
689 : else
690 : {
691 : const size_type __len =
692 : _M_check_len(__n, "vector<bool>::_M_insert_range");
693 : _Bit_type * __q = this->_M_allocate(__len);
694 : iterator __i = _M_copy_aligned(begin(), __position,
695 : iterator(__q, 0));
696 : __i = std::copy(__first, __last, __i);
697 : this->_M_impl._M_finish = std::copy(__position, end(), __i);
698 : this->_M_deallocate();
699 : this->_M_impl._M_end_of_storage = (__q
700 : + ((__len
701 : + int(_S_word_bit) - 1)
702 : / int(_S_word_bit)));
703 : this->_M_impl._M_start = iterator(__q, 0);
704 : }
705 : }
706 : }
707 :
708 : template<typename _Alloc>
709 : void
710 : vector<bool, _Alloc>::
711 : _M_insert_aux(iterator __position, bool __x)
712 : {
713 : if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage)
714 : {
715 : std::copy_backward(__position, this->_M_impl._M_finish,
716 : this->_M_impl._M_finish + 1);
717 : *__position = __x;
718 : ++this->_M_impl._M_finish;
719 : }
720 : else
721 : {
722 : const size_type __len =
723 : _M_check_len(size_type(1), "vector<bool>::_M_insert_aux");
724 : _Bit_type * __q = this->_M_allocate(__len);
725 : iterator __i = _M_copy_aligned(begin(), __position,
726 : iterator(__q, 0));
727 : *__i++ = __x;
728 : this->_M_impl._M_finish = std::copy(__position, end(), __i);
729 : this->_M_deallocate();
730 : this->_M_impl._M_end_of_storage = (__q + ((__len
731 : + int(_S_word_bit) - 1)
732 : / int(_S_word_bit)));
733 : this->_M_impl._M_start = iterator(__q, 0);
734 : }
735 : }
736 :
737 : _GLIBCXX_END_NAMESPACE_CONTAINER
738 : } // namespace std
739 :
740 : #ifdef __GXX_EXPERIMENTAL_CXX0X__
741 :
742 : namespace std _GLIBCXX_VISIBILITY(default)
743 : {
744 : _GLIBCXX_BEGIN_NAMESPACE_VERSION
745 :
746 : template<typename _Alloc>
747 : size_t
748 : hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>::
749 : operator()(const _GLIBCXX_STD_C::vector<bool, _Alloc>& __b) const
750 : {
751 : size_t __hash = 0;
752 : using _GLIBCXX_STD_C::_S_word_bit;
753 : using _GLIBCXX_STD_C::_Bit_type;
754 :
755 : const size_t __words = __b.size() / _S_word_bit;
756 : if (__words)
757 : {
758 : const size_t __clength = __words * sizeof(_Bit_type);
759 : __hash = std::_Hash_impl::hash(__b._M_impl._M_start._M_p, __clength);
760 : }
761 :
762 : const size_t __extrabits = __b.size() % _S_word_bit;
763 : if (__extrabits)
764 : {
765 : _Bit_type __hiword = *__b._M_impl._M_finish._M_p;
766 : __hiword &= ~((~static_cast<_Bit_type>(0)) << __extrabits);
767 :
768 : const size_t __clength
769 : = (__extrabits + __CHAR_BIT__ - 1) / __CHAR_BIT__;
770 : if (__words)
771 : __hash = std::_Hash_impl::hash(&__hiword, __clength, __hash);
772 : else
773 : __hash = std::_Hash_impl::hash(&__hiword, __clength);
774 : }
775 :
776 : return __hash;
777 : }
778 :
779 : _GLIBCXX_END_NAMESPACE_VERSION
780 : } // namespace std
781 :
782 : #endif // __GXX_EXPERIMENTAL_CXX0X__
783 :
784 : #endif /* _VECTOR_TCC */
|