libstdc++
vector.tcc
Go to the documentation of this file.
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 */