|
libstdc++
|
00001 // Vector implementation (out of line) -*- C++ -*- 00002 00003 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 00004 // 2011 Free Software Foundation, Inc. 00005 // 00006 // This file is part of the GNU ISO C++ Library. This library is free 00007 // software; you can redistribute it and/or modify it under the 00008 // terms of the GNU General Public License as published by the 00009 // Free Software Foundation; either version 3, or (at your option) 00010 // any later version. 00011 00012 // This library is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 00017 // Under Section 7 of GPL version 3, you are granted additional 00018 // permissions described in the GCC Runtime Library Exception, version 00019 // 3.1, as published by the Free Software Foundation. 00020 00021 // You should have received a copy of the GNU General Public License and 00022 // a copy of the GCC Runtime Library Exception along with this program; 00023 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00024 // <http://www.gnu.org/licenses/>. 00025 00026 /* 00027 * 00028 * Copyright (c) 1994 00029 * Hewlett-Packard Company 00030 * 00031 * Permission to use, copy, modify, distribute and sell this software 00032 * and its documentation for any purpose is hereby granted without fee, 00033 * provided that the above copyright notice appear in all copies and 00034 * that both that copyright notice and this permission notice appear 00035 * in supporting documentation. Hewlett-Packard Company makes no 00036 * representations about the suitability of this software for any 00037 * purpose. It is provided "as is" without express or implied warranty. 00038 * 00039 * 00040 * Copyright (c) 1996 00041 * Silicon Graphics Computer Systems, Inc. 00042 * 00043 * Permission to use, copy, modify, distribute and sell this software 00044 * and its documentation for any purpose is hereby granted without fee, 00045 * provided that the above copyright notice appear in all copies and 00046 * that both that copyright notice and this permission notice appear 00047 * in supporting documentation. Silicon Graphics makes no 00048 * representations about the suitability of this software for any 00049 * purpose. It is provided "as is" without express or implied warranty. 00050 */ 00051 00052 /** @file bits/vector.tcc 00053 * This is an internal header file, included by other library headers. 00054 * Do not attempt to use it directly. @headername{vector} 00055 */ 00056 00057 #ifndef _VECTOR_TCC 00058 #define _VECTOR_TCC 1 00059 00060 namespace std _GLIBCXX_VISIBILITY(default) 00061 { 00062 _GLIBCXX_BEGIN_NAMESPACE_CONTAINER 00063 00064 template<typename _Tp, typename _Alloc> 00065 void 00066 vector<_Tp, _Alloc>:: 00067 reserve(size_type __n) 00068 { 00069 if (__n > this->max_size()) 00070 __throw_length_error(__N("vector::reserve")); 00071 if (this->capacity() < __n) 00072 { 00073 const size_type __old_size = size(); 00074 pointer __tmp = _M_allocate_and_copy(__n, 00075 _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(this->_M_impl._M_start), 00076 _GLIBCXX_MAKE_MOVE_IF_NOEXCEPT_ITERATOR(this->_M_impl._M_finish)); 00077 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, 00078 _M_get_Tp_allocator()); 00079 _M_deallocate(this->_M_impl._M_start, 00080 this->_M_impl._M_end_of_storage 00081 - this->_M_impl._M_start); 00082 this->_M_impl._M_start = __tmp; 00083 this->_M_impl._M_finish = __tmp + __old_size; 00084 this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __n; 00085 } 00086 } 00087 00088 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00089 template<typename _Tp, typename _Alloc> 00090 template<typename... _Args> 00091 void 00092 vector<_Tp, _Alloc>:: 00093 emplace_back(_Args&&... __args) 00094 { 00095 if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) 00096 { 00097 _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, 00098 std::forward<_Args>(__args)...); 00099 ++this->_M_impl._M_finish; 00100 } 00101 else 00102 _M_emplace_back_aux(std::forward<_Args>(__args)...); 00103 } 00104 #endif 00105 00106 template<typename _Tp, typename _Alloc> 00107 typename vector<_Tp, _Alloc>::iterator 00108 vector<_Tp, _Alloc>:: 00109 insert(iterator __position, const value_type& __x) 00110 { 00111 const size_type __n = __position - begin(); 00112 if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage 00113 && __position == end()) 00114 { 00115 _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, __x); 00116 ++this->_M_impl._M_finish; 00117 } 00118 else 00119 { 00120 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00121 if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) 00122 { 00123 _Tp __x_copy = __x; 00124 _M_insert_aux(__position, std::move(__x_copy)); 00125 } 00126 else 00127 #endif 00128 _M_insert_aux(__position, __x); 00129 } 00130 return iterator(this->_M_impl._M_start + __n); 00131 } 00132 00133 template<typename _Tp, typename _Alloc> 00134 typename vector<_Tp, _Alloc>::iterator 00135 vector<_Tp, _Alloc>:: 00136 erase(iterator __position) 00137 { 00138 if (__position + 1 != end()) 00139 _GLIBCXX_MOVE3(__position + 1, end(), __position); 00140 --this->_M_impl._M_finish; 00141 _Alloc_traits::destroy(this->_M_impl, this->_M_impl._M_finish); 00142 return __position; 00143 } 00144 00145 template<typename _Tp, typename _Alloc> 00146 typename vector<_Tp, _Alloc>::iterator 00147 vector<_Tp, _Alloc>:: 00148 erase(iterator __first, iterator __last) 00149 { 00150 if (__first != __last) 00151 { 00152 if (__last != end()) 00153 _GLIBCXX_MOVE3(__last, end(), __first); 00154 _M_erase_at_end(__first.base() + (end() - __last)); 00155 } 00156 return __first; 00157 } 00158 00159 template<typename _Tp, typename _Alloc> 00160 vector<_Tp, _Alloc>& 00161 vector<_Tp, _Alloc>:: 00162 operator=(const vector<_Tp, _Alloc>& __x) 00163 { 00164 if (&__x != this) 00165 { 00166 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00167 if (_Alloc_traits::_S_propagate_on_copy_assign()) 00168 { 00169 if (!_Alloc_traits::_S_always_equal() 00170 && _M_get_Tp_allocator() != __x._M_get_Tp_allocator()) 00171 { 00172 // replacement allocator cannot free existing storage 00173 this->clear(); 00174 _M_deallocate(this->_M_impl._M_start, 00175 this->_M_impl._M_end_of_storage 00176 - this->_M_impl._M_start); 00177 this->_M_impl._M_start = nullptr; 00178 this->_M_impl._M_finish = nullptr; 00179 this->_M_impl._M_end_of_storage = nullptr; 00180 } 00181 std::__alloc_on_copy(_M_get_Tp_allocator(), 00182 __x._M_get_Tp_allocator()); 00183 } 00184 #endif 00185 const size_type __xlen = __x.size(); 00186 if (__xlen > capacity()) 00187 { 00188 pointer __tmp = _M_allocate_and_copy(__xlen, __x.begin(), 00189 __x.end()); 00190 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, 00191 _M_get_Tp_allocator()); 00192 _M_deallocate(this->_M_impl._M_start, 00193 this->_M_impl._M_end_of_storage 00194 - this->_M_impl._M_start); 00195 this->_M_impl._M_start = __tmp; 00196 this->_M_impl._M_end_of_storage = this->_M_impl._M_start + __xlen; 00197 } 00198 else if (size() >= __xlen) 00199 { 00200 std::_Destroy(std::copy(__x.begin(), __x.end(), begin()), 00201 end(), _M_get_Tp_allocator()); 00202 } 00203 else 00204 { 00205 std::copy(__x._M_impl._M_start, __x._M_impl._M_start + size(), 00206 this->_M_impl._M_start); 00207 std::__uninitialized_copy_a(__x._M_impl._M_start + size(), 00208 __x._M_impl._M_finish, 00209 this->_M_impl._M_finish, 00210 _M_get_Tp_allocator()); 00211 } 00212 this->_M_impl._M_finish = this->_M_impl._M_start + __xlen; 00213 } 00214 return *this; 00215 } 00216 00217 template<typename _Tp, typename _Alloc> 00218 void 00219 vector<_Tp, _Alloc>:: 00220 _M_fill_assign(size_t __n, const value_type& __val) 00221 { 00222 if (__n > capacity()) 00223 { 00224 vector __tmp(__n, __val, _M_get_Tp_allocator()); 00225 __tmp.swap(*this); 00226 } 00227 else if (__n > size()) 00228 { 00229 std::fill(begin(), end(), __val); 00230 std::__uninitialized_fill_n_a(this->_M_impl._M_finish, 00231 __n - size(), __val, 00232 _M_get_Tp_allocator()); 00233 this->_M_impl._M_finish += __n - size(); 00234 } 00235 else 00236 _M_erase_at_end(std::fill_n(this->_M_impl._M_start, __n, __val)); 00237 } 00238 00239 template<typename _Tp, typename _Alloc> 00240 template<typename _InputIterator> 00241 void 00242 vector<_Tp, _Alloc>:: 00243 _M_assign_aux(_InputIterator __first, _InputIterator __last, 00244 std::input_iterator_tag) 00245 { 00246 pointer __cur(this->_M_impl._M_start); 00247 for (; __first != __last && __cur != this->_M_impl._M_finish; 00248 ++__cur, ++__first) 00249 *__cur = *__first; 00250 if (__first == __last) 00251 _M_erase_at_end(__cur); 00252 else 00253 insert(end(), __first, __last); 00254 } 00255 00256 template<typename _Tp, typename _Alloc> 00257 template<typename _ForwardIterator> 00258 void 00259 vector<_Tp, _Alloc>:: 00260 _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, 00261 std::forward_iterator_tag) 00262 { 00263 const size_type __len = std::distance(__first, __last); 00264 00265 if (__len > capacity()) 00266 { 00267 pointer __tmp(_M_allocate_and_copy(__len, __first, __last)); 00268 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, 00269 _M_get_Tp_allocator()); 00270 _M_deallocate(this->_M_impl._M_start, 00271 this->_M_impl._M_end_of_storage 00272 - this->_M_impl._M_start); 00273 this->_M_impl._M_start = __tmp; 00274 this->_M_impl._M_finish = this->_M_impl._M_start + __len; 00275 this->_M_impl._M_end_of_storage = this->_M_impl._M_finish; 00276 } 00277 else if (size() >= __len) 00278 _M_erase_at_end(std::copy(__first, __last, this->_M_impl._M_start)); 00279 else 00280 { 00281 _ForwardIterator __mid = __first; 00282 std::advance(__mid, size()); 00283 std::copy(__first, __mid, this->_M_impl._M_start); 00284 this->_M_impl._M_finish = 00285 std::__uninitialized_copy_a(__mid, __last, 00286 this->_M_impl._M_finish, 00287 _M_get_Tp_allocator()); 00288 } 00289 } 00290 00291 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00292 template<typename _Tp, typename _Alloc> 00293 template<typename... _Args> 00294 typename vector<_Tp, _Alloc>::iterator 00295 vector<_Tp, _Alloc>:: 00296 emplace(iterator __position, _Args&&... __args) 00297 { 00298 const size_type __n = __position - begin(); 00299 if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage 00300 && __position == end()) 00301 { 00302 _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, 00303 std::forward<_Args>(__args)...); 00304 ++this->_M_impl._M_finish; 00305 } 00306 else 00307 _M_insert_aux(__position, std::forward<_Args>(__args)...); 00308 return iterator(this->_M_impl._M_start + __n); 00309 } 00310 00311 template<typename _Tp, typename _Alloc> 00312 template<typename... _Args> 00313 void 00314 vector<_Tp, _Alloc>:: 00315 _M_insert_aux(iterator __position, _Args&&... __args) 00316 #else 00317 template<typename _Tp, typename _Alloc> 00318 void 00319 vector<_Tp, _Alloc>:: 00320 _M_insert_aux(iterator __position, const _Tp& __x) 00321 #endif 00322 { 00323 if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage) 00324 { 00325 _Alloc_traits::construct(this->_M_impl, this->_M_impl._M_finish, 00326 _GLIBCXX_MOVE(*(this->_M_impl._M_finish 00327 - 1))); 00328 ++this->_M_impl._M_finish; 00329 #ifndef __GXX_EXPERIMENTAL_CXX0X__ 00330 _Tp __x_copy = __x; 00331 #endif 00332 _GLIBCXX_MOVE_BACKWARD3(__position.base(), 00333 this->_M_impl._M_finish - 2, 00334 this->_M_impl._M_finish - 1); 00335 #ifndef __GXX_EXPERIMENTAL_CXX0X__ 00336 *__position = __x_copy; 00337 #else 00338 *__position = _Tp(std::forward<_Args>(__args)...); 00339 #endif 00340 } 00341 else 00342 { 00343 const size_type __len = 00344 _M_check_len(size_type(1), "vector::_M_insert_aux"); 00345 const size_type __elems_before = __position - begin(); 00346 pointer __new_start(this->_M_allocate(__len)); 00347 pointer __new_finish(__new_start); 00348 __try 00349 { 00350 // The order of the three operations is dictated by the C++0x 00351 // case, where the moves could alter a new element belonging 00352 // to the existing vector. This is an issue only for callers 00353 // taking the element by const lvalue ref (see 23.1/13). 00354 _Alloc_traits::construct(this->_M_impl, 00355 __new_start + __elems_before, 00356 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00357 std::forward<_Args>(__args)...); 00358 #else 00359 __x); 00360 #endif 00361 __new_finish = 0; 00362 00363 __new_finish 00364 = std::__uninitialized_move_if_noexcept_a 00365 (this->_M_impl._M_start, __position.base(), 00366 __new_start, _M_get_Tp_allocator()); 00367 00368 ++__new_finish; 00369 00370 __new_finish 00371 = std::__uninitialized_move_if_noexcept_a 00372 (__position.base(), this->_M_impl._M_finish, 00373 __new_finish, _M_get_Tp_allocator()); 00374 } 00375 __catch(...) 00376 { 00377 if (!__new_finish) 00378 _Alloc_traits::destroy(this->_M_impl, 00379 __new_start + __elems_before); 00380 else 00381 std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator()); 00382 _M_deallocate(__new_start, __len); 00383 __throw_exception_again; 00384 } 00385 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, 00386 _M_get_Tp_allocator()); 00387 _M_deallocate(this->_M_impl._M_start, 00388 this->_M_impl._M_end_of_storage 00389 - this->_M_impl._M_start); 00390 this->_M_impl._M_start = __new_start; 00391 this->_M_impl._M_finish = __new_finish; 00392 this->_M_impl._M_end_of_storage = __new_start + __len; 00393 } 00394 } 00395 00396 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00397 template<typename _Tp, typename _Alloc> 00398 template<typename... _Args> 00399 void 00400 vector<_Tp, _Alloc>:: 00401 _M_emplace_back_aux(_Args&&... __args) 00402 { 00403 const size_type __len = 00404 _M_check_len(size_type(1), "vector::_M_emplace_back_aux"); 00405 pointer __new_start(this->_M_allocate(__len)); 00406 pointer __new_finish(__new_start); 00407 __try 00408 { 00409 _Alloc_traits::construct(this->_M_impl, __new_start + size(), 00410 std::forward<_Args>(__args)...); 00411 __new_finish = 0; 00412 00413 __new_finish 00414 = std::__uninitialized_move_if_noexcept_a 00415 (this->_M_impl._M_start, this->_M_impl._M_finish, 00416 __new_start, _M_get_Tp_allocator()); 00417 00418 ++__new_finish; 00419 } 00420 __catch(...) 00421 { 00422 if (!__new_finish) 00423 _Alloc_traits::destroy(this->_M_impl, __new_start + size()); 00424 else 00425 std::_Destroy(__new_start, __new_finish, _M_get_Tp_allocator()); 00426 _M_deallocate(__new_start, __len); 00427 __throw_exception_again; 00428 } 00429 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, 00430 _M_get_Tp_allocator()); 00431 _M_deallocate(this->_M_impl._M_start, 00432 this->_M_impl._M_end_of_storage 00433 - this->_M_impl._M_start); 00434 this->_M_impl._M_start = __new_start; 00435 this->_M_impl._M_finish = __new_finish; 00436 this->_M_impl._M_end_of_storage = __new_start + __len; 00437 } 00438 #endif 00439 00440 template<typename _Tp, typename _Alloc> 00441 void 00442 vector<_Tp, _Alloc>:: 00443 _M_fill_insert(iterator __position, size_type __n, const value_type& __x) 00444 { 00445 if (__n != 0) 00446 { 00447 if (size_type(this->_M_impl._M_end_of_storage 00448 - this->_M_impl._M_finish) >= __n) 00449 { 00450 value_type __x_copy = __x; 00451 const size_type __elems_after = end() - __position; 00452 pointer __old_finish(this->_M_impl._M_finish); 00453 if (__elems_after > __n) 00454 { 00455 std::__uninitialized_move_a(this->_M_impl._M_finish - __n, 00456 this->_M_impl._M_finish, 00457 this->_M_impl._M_finish, 00458 _M_get_Tp_allocator()); 00459 this->_M_impl._M_finish += __n; 00460 _GLIBCXX_MOVE_BACKWARD3(__position.base(), 00461 __old_finish - __n, __old_finish); 00462 std::fill(__position.base(), __position.base() + __n, 00463 __x_copy); 00464 } 00465 else 00466 { 00467 std::__uninitialized_fill_n_a(this->_M_impl._M_finish, 00468 __n - __elems_after, 00469 __x_copy, 00470 _M_get_Tp_allocator()); 00471 this->_M_impl._M_finish += __n - __elems_after; 00472 std::__uninitialized_move_a(__position.base(), __old_finish, 00473 this->_M_impl._M_finish, 00474 _M_get_Tp_allocator()); 00475 this->_M_impl._M_finish += __elems_after; 00476 std::fill(__position.base(), __old_finish, __x_copy); 00477 } 00478 } 00479 else 00480 { 00481 const size_type __len = 00482 _M_check_len(__n, "vector::_M_fill_insert"); 00483 const size_type __elems_before = __position - begin(); 00484 pointer __new_start(this->_M_allocate(__len)); 00485 pointer __new_finish(__new_start); 00486 __try 00487 { 00488 // See _M_insert_aux above. 00489 std::__uninitialized_fill_n_a(__new_start + __elems_before, 00490 __n, __x, 00491 _M_get_Tp_allocator()); 00492 __new_finish = 0; 00493 00494 __new_finish 00495 = std::__uninitialized_move_if_noexcept_a 00496 (this->_M_impl._M_start, __position.base(), 00497 __new_start, _M_get_Tp_allocator()); 00498 00499 __new_finish += __n; 00500 00501 __new_finish 00502 = std::__uninitialized_move_if_noexcept_a 00503 (__position.base(), this->_M_impl._M_finish, 00504 __new_finish, _M_get_Tp_allocator()); 00505 } 00506 __catch(...) 00507 { 00508 if (!__new_finish) 00509 std::_Destroy(__new_start + __elems_before, 00510 __new_start + __elems_before + __n, 00511 _M_get_Tp_allocator()); 00512 else 00513 std::_Destroy(__new_start, __new_finish, 00514 _M_get_Tp_allocator()); 00515 _M_deallocate(__new_start, __len); 00516 __throw_exception_again; 00517 } 00518 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, 00519 _M_get_Tp_allocator()); 00520 _M_deallocate(this->_M_impl._M_start, 00521 this->_M_impl._M_end_of_storage 00522 - this->_M_impl._M_start); 00523 this->_M_impl._M_start = __new_start; 00524 this->_M_impl._M_finish = __new_finish; 00525 this->_M_impl._M_end_of_storage = __new_start + __len; 00526 } 00527 } 00528 } 00529 00530 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00531 template<typename _Tp, typename _Alloc> 00532 void 00533 vector<_Tp, _Alloc>:: 00534 _M_default_append(size_type __n) 00535 { 00536 if (__n != 0) 00537 { 00538 if (size_type(this->_M_impl._M_end_of_storage 00539 - this->_M_impl._M_finish) >= __n) 00540 { 00541 std::__uninitialized_default_n_a(this->_M_impl._M_finish, 00542 __n, _M_get_Tp_allocator()); 00543 this->_M_impl._M_finish += __n; 00544 } 00545 else 00546 { 00547 const size_type __len = 00548 _M_check_len(__n, "vector::_M_default_append"); 00549 const size_type __old_size = this->size(); 00550 pointer __new_start(this->_M_allocate(__len)); 00551 pointer __new_finish(__new_start); 00552 __try 00553 { 00554 __new_finish 00555 = std::__uninitialized_move_if_noexcept_a 00556 (this->_M_impl._M_start, this->_M_impl._M_finish, 00557 __new_start, _M_get_Tp_allocator()); 00558 std::__uninitialized_default_n_a(__new_finish, __n, 00559 _M_get_Tp_allocator()); 00560 __new_finish += __n; 00561 } 00562 __catch(...) 00563 { 00564 std::_Destroy(__new_start, __new_finish, 00565 _M_get_Tp_allocator()); 00566 _M_deallocate(__new_start, __len); 00567 __throw_exception_again; 00568 } 00569 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, 00570 _M_get_Tp_allocator()); 00571 _M_deallocate(this->_M_impl._M_start, 00572 this->_M_impl._M_end_of_storage 00573 - this->_M_impl._M_start); 00574 this->_M_impl._M_start = __new_start; 00575 this->_M_impl._M_finish = __new_finish; 00576 this->_M_impl._M_end_of_storage = __new_start + __len; 00577 } 00578 } 00579 } 00580 00581 template<typename _Tp, typename _Alloc> 00582 bool 00583 vector<_Tp, _Alloc>:: 00584 _M_shrink_to_fit() 00585 { 00586 if (capacity() == size()) 00587 return false; 00588 return std::__shrink_to_fit_aux<vector>::_S_do_it(*this); 00589 } 00590 #endif 00591 00592 template<typename _Tp, typename _Alloc> 00593 template<typename _InputIterator> 00594 void 00595 vector<_Tp, _Alloc>:: 00596 _M_range_insert(iterator __pos, _InputIterator __first, 00597 _InputIterator __last, std::input_iterator_tag) 00598 { 00599 for (; __first != __last; ++__first) 00600 { 00601 __pos = insert(__pos, *__first); 00602 ++__pos; 00603 } 00604 } 00605 00606 template<typename _Tp, typename _Alloc> 00607 template<typename _ForwardIterator> 00608 void 00609 vector<_Tp, _Alloc>:: 00610 _M_range_insert(iterator __position, _ForwardIterator __first, 00611 _ForwardIterator __last, std::forward_iterator_tag) 00612 { 00613 if (__first != __last) 00614 { 00615 const size_type __n = std::distance(__first, __last); 00616 if (size_type(this->_M_impl._M_end_of_storage 00617 - this->_M_impl._M_finish) >= __n) 00618 { 00619 const size_type __elems_after = end() - __position; 00620 pointer __old_finish(this->_M_impl._M_finish); 00621 if (__elems_after > __n) 00622 { 00623 std::__uninitialized_move_a(this->_M_impl._M_finish - __n, 00624 this->_M_impl._M_finish, 00625 this->_M_impl._M_finish, 00626 _M_get_Tp_allocator()); 00627 this->_M_impl._M_finish += __n; 00628 _GLIBCXX_MOVE_BACKWARD3(__position.base(), 00629 __old_finish - __n, __old_finish); 00630 std::copy(__first, __last, __position); 00631 } 00632 else 00633 { 00634 _ForwardIterator __mid = __first; 00635 std::advance(__mid, __elems_after); 00636 std::__uninitialized_copy_a(__mid, __last, 00637 this->_M_impl._M_finish, 00638 _M_get_Tp_allocator()); 00639 this->_M_impl._M_finish += __n - __elems_after; 00640 std::__uninitialized_move_a(__position.base(), 00641 __old_finish, 00642 this->_M_impl._M_finish, 00643 _M_get_Tp_allocator()); 00644 this->_M_impl._M_finish += __elems_after; 00645 std::copy(__first, __mid, __position); 00646 } 00647 } 00648 else 00649 { 00650 const size_type __len = 00651 _M_check_len(__n, "vector::_M_range_insert"); 00652 pointer __new_start(this->_M_allocate(__len)); 00653 pointer __new_finish(__new_start); 00654 __try 00655 { 00656 __new_finish 00657 = std::__uninitialized_move_if_noexcept_a 00658 (this->_M_impl._M_start, __position.base(), 00659 __new_start, _M_get_Tp_allocator()); 00660 __new_finish 00661 = std::__uninitialized_copy_a(__first, __last, 00662 __new_finish, 00663 _M_get_Tp_allocator()); 00664 __new_finish 00665 = std::__uninitialized_move_if_noexcept_a 00666 (__position.base(), this->_M_impl._M_finish, 00667 __new_finish, _M_get_Tp_allocator()); 00668 } 00669 __catch(...) 00670 { 00671 std::_Destroy(__new_start, __new_finish, 00672 _M_get_Tp_allocator()); 00673 _M_deallocate(__new_start, __len); 00674 __throw_exception_again; 00675 } 00676 std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish, 00677 _M_get_Tp_allocator()); 00678 _M_deallocate(this->_M_impl._M_start, 00679 this->_M_impl._M_end_of_storage 00680 - this->_M_impl._M_start); 00681 this->_M_impl._M_start = __new_start; 00682 this->_M_impl._M_finish = __new_finish; 00683 this->_M_impl._M_end_of_storage = __new_start + __len; 00684 } 00685 } 00686 } 00687 00688 00689 // vector<bool> 00690 template<typename _Alloc> 00691 void 00692 vector<bool, _Alloc>:: 00693 _M_reallocate(size_type __n) 00694 { 00695 _Bit_type* __q = this->_M_allocate(__n); 00696 this->_M_impl._M_finish = _M_copy_aligned(begin(), end(), 00697 iterator(__q, 0)); 00698 this->_M_deallocate(); 00699 this->_M_impl._M_start = iterator(__q, 0); 00700 this->_M_impl._M_end_of_storage = __q + _S_nword(__n); 00701 } 00702 00703 template<typename _Alloc> 00704 void 00705 vector<bool, _Alloc>:: 00706 _M_fill_insert(iterator __position, size_type __n, bool __x) 00707 { 00708 if (__n == 0) 00709 return; 00710 if (capacity() - size() >= __n) 00711 { 00712 std::copy_backward(__position, end(), 00713 this->_M_impl._M_finish + difference_type(__n)); 00714 std::fill(__position, __position + difference_type(__n), __x); 00715 this->_M_impl._M_finish += difference_type(__n); 00716 } 00717 else 00718 { 00719 const size_type __len = 00720 _M_check_len(__n, "vector<bool>::_M_fill_insert"); 00721 _Bit_type * __q = this->_M_allocate(__len); 00722 iterator __i = _M_copy_aligned(begin(), __position, 00723 iterator(__q, 0)); 00724 std::fill(__i, __i + difference_type(__n), __x); 00725 this->_M_impl._M_finish = std::copy(__position, end(), 00726 __i + difference_type(__n)); 00727 this->_M_deallocate(); 00728 this->_M_impl._M_end_of_storage = __q + _S_nword(__len); 00729 this->_M_impl._M_start = iterator(__q, 0); 00730 } 00731 } 00732 00733 template<typename _Alloc> 00734 template<typename _ForwardIterator> 00735 void 00736 vector<bool, _Alloc>:: 00737 _M_insert_range(iterator __position, _ForwardIterator __first, 00738 _ForwardIterator __last, std::forward_iterator_tag) 00739 { 00740 if (__first != __last) 00741 { 00742 size_type __n = std::distance(__first, __last); 00743 if (capacity() - size() >= __n) 00744 { 00745 std::copy_backward(__position, end(), 00746 this->_M_impl._M_finish 00747 + difference_type(__n)); 00748 std::copy(__first, __last, __position); 00749 this->_M_impl._M_finish += difference_type(__n); 00750 } 00751 else 00752 { 00753 const size_type __len = 00754 _M_check_len(__n, "vector<bool>::_M_insert_range"); 00755 _Bit_type * __q = this->_M_allocate(__len); 00756 iterator __i = _M_copy_aligned(begin(), __position, 00757 iterator(__q, 0)); 00758 __i = std::copy(__first, __last, __i); 00759 this->_M_impl._M_finish = std::copy(__position, end(), __i); 00760 this->_M_deallocate(); 00761 this->_M_impl._M_end_of_storage = __q + _S_nword(__len); 00762 this->_M_impl._M_start = iterator(__q, 0); 00763 } 00764 } 00765 } 00766 00767 template<typename _Alloc> 00768 void 00769 vector<bool, _Alloc>:: 00770 _M_insert_aux(iterator __position, bool __x) 00771 { 00772 if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_of_storage) 00773 { 00774 std::copy_backward(__position, this->_M_impl._M_finish, 00775 this->_M_impl._M_finish + 1); 00776 *__position = __x; 00777 ++this->_M_impl._M_finish; 00778 } 00779 else 00780 { 00781 const size_type __len = 00782 _M_check_len(size_type(1), "vector<bool>::_M_insert_aux"); 00783 _Bit_type * __q = this->_M_allocate(__len); 00784 iterator __i = _M_copy_aligned(begin(), __position, 00785 iterator(__q, 0)); 00786 *__i++ = __x; 00787 this->_M_impl._M_finish = std::copy(__position, end(), __i); 00788 this->_M_deallocate(); 00789 this->_M_impl._M_end_of_storage = __q + _S_nword(__len); 00790 this->_M_impl._M_start = iterator(__q, 0); 00791 } 00792 } 00793 00794 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00795 template<typename _Alloc> 00796 bool 00797 vector<bool, _Alloc>:: 00798 _M_shrink_to_fit() 00799 { 00800 if (capacity() - size() < int(_S_word_bit)) 00801 return false; 00802 __try 00803 { 00804 _M_reallocate(size()); 00805 return true; 00806 } 00807 __catch(...) 00808 { return false; } 00809 } 00810 #endif 00811 00812 _GLIBCXX_END_NAMESPACE_CONTAINER 00813 } // namespace std 00814 00815 #ifdef __GXX_EXPERIMENTAL_CXX0X__ 00816 00817 namespace std _GLIBCXX_VISIBILITY(default) 00818 { 00819 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00820 00821 template<typename _Alloc> 00822 size_t 00823 hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>:: 00824 operator()(const _GLIBCXX_STD_C::vector<bool, _Alloc>& __b) const noexcept 00825 { 00826 size_t __hash = 0; 00827 using _GLIBCXX_STD_C::_S_word_bit; 00828 using _GLIBCXX_STD_C::_Bit_type; 00829 00830 const size_t __words = __b.size() / _S_word_bit; 00831 if (__words) 00832 { 00833 const size_t __clength = __words * sizeof(_Bit_type); 00834 __hash = std::_Hash_impl::hash(__b._M_impl._M_start._M_p, __clength); 00835 } 00836 00837 const size_t __extrabits = __b.size() % _S_word_bit; 00838 if (__extrabits) 00839 { 00840 _Bit_type __hiword = *__b._M_impl._M_finish._M_p; 00841 __hiword &= ~((~static_cast<_Bit_type>(0)) << __extrabits); 00842 00843 const size_t __clength 00844 = (__extrabits + __CHAR_BIT__ - 1) / __CHAR_BIT__; 00845 if (__words) 00846 __hash = std::_Hash_impl::hash(&__hiword, __clength, __hash); 00847 else 00848 __hash = std::_Hash_impl::hash(&__hiword, __clength); 00849 } 00850 00851 return __hash; 00852 } 00853 00854 _GLIBCXX_END_NAMESPACE_VERSION 00855 } // namespace std 00856 00857 #endif // __GXX_EXPERIMENTAL_CXX0X__ 00858 00859 #endif /* _VECTOR_TCC */