libstdc++
vector
Go to the documentation of this file.
00001 // Debugging vector implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2003-2016 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file debug/vector
00026  *  This file is a GNU debug extension to the Standard C++ Library.
00027  */
00028 
00029 #ifndef _GLIBCXX_DEBUG_VECTOR
00030 #define _GLIBCXX_DEBUG_VECTOR 1
00031 
00032 #include <vector>
00033 #include <utility>
00034 #include <debug/safe_sequence.h>
00035 #include <debug/safe_container.h>
00036 #include <debug/safe_iterator.h>
00037 
00038 namespace __gnu_debug
00039 {
00040   /** @brief Base class for Debug Mode vector.
00041    *
00042    * Adds information about the guaranteed capacity, which is useful for
00043    * detecting code which relies on non-portable implementation details of
00044    * the libstdc++ reallocation policy.
00045    */
00046   template<typename _SafeSequence,
00047            typename _BaseSequence>
00048     class _Safe_vector
00049     {
00050       typedef typename _BaseSequence::size_type size_type;
00051 
00052       const _SafeSequence&
00053       _M_seq() const { return *static_cast<const _SafeSequence*>(this); }
00054 
00055     protected:
00056       _Safe_vector() _GLIBCXX_NOEXCEPT
00057         : _M_guaranteed_capacity(0)
00058       { _M_update_guaranteed_capacity(); }
00059 
00060       _Safe_vector(const _Safe_vector&) _GLIBCXX_NOEXCEPT
00061         : _M_guaranteed_capacity(0)
00062       { _M_update_guaranteed_capacity(); }
00063 
00064       _Safe_vector(size_type __n) _GLIBCXX_NOEXCEPT
00065         : _M_guaranteed_capacity(__n)
00066       { }
00067 
00068 #if __cplusplus >= 201103L
00069       _Safe_vector(_Safe_vector&& __x) noexcept
00070         : _Safe_vector()
00071       { __x._M_guaranteed_capacity = 0; }
00072 
00073       _Safe_vector&
00074       operator=(const _Safe_vector&) noexcept
00075       {
00076         _M_update_guaranteed_capacity();
00077         return *this;
00078       }
00079 
00080       _Safe_vector&
00081       operator=(_Safe_vector&& __x) noexcept
00082       {
00083         _M_update_guaranteed_capacity();
00084         __x._M_guaranteed_capacity = 0;
00085         return *this;
00086       }
00087 #endif
00088 
00089       size_type _M_guaranteed_capacity;
00090 
00091       bool
00092       _M_requires_reallocation(size_type __elements) const _GLIBCXX_NOEXCEPT
00093       { return __elements > _M_seq().capacity(); }
00094 
00095       void
00096       _M_update_guaranteed_capacity() _GLIBCXX_NOEXCEPT
00097       {
00098         if (_M_seq().size() > _M_guaranteed_capacity)
00099           _M_guaranteed_capacity = _M_seq().size();
00100       }
00101     };
00102 }
00103 
00104 namespace std _GLIBCXX_VISIBILITY(default)
00105 {
00106 namespace __debug
00107 {
00108   /// Class std::vector with safety/checking/debug instrumentation.
00109   template<typename _Tp,
00110            typename _Allocator = std::allocator<_Tp> >
00111     class vector
00112     : public __gnu_debug::_Safe_container<
00113         vector<_Tp, _Allocator>, _Allocator, __gnu_debug::_Safe_sequence>,
00114       public _GLIBCXX_STD_C::vector<_Tp, _Allocator>,
00115       public __gnu_debug::_Safe_vector<
00116         vector<_Tp, _Allocator>,
00117         _GLIBCXX_STD_C::vector<_Tp, _Allocator> >
00118     {
00119       typedef _GLIBCXX_STD_C::vector<_Tp, _Allocator>           _Base;
00120       typedef __gnu_debug::_Safe_container<
00121         vector, _Allocator, __gnu_debug::_Safe_sequence>        _Safe;
00122       typedef __gnu_debug::_Safe_vector<vector, _Base>          _Safe_vector;
00123 
00124       typedef typename _Base::iterator          _Base_iterator;
00125       typedef typename _Base::const_iterator    _Base_const_iterator;
00126       typedef __gnu_debug::_Equal_to<_Base_const_iterator> _Equal;
00127 
00128     public:
00129       typedef typename _Base::reference                 reference;
00130       typedef typename _Base::const_reference           const_reference;
00131 
00132       typedef __gnu_debug::_Safe_iterator<
00133         _Base_iterator, vector>                         iterator;
00134       typedef __gnu_debug::_Safe_iterator<
00135         _Base_const_iterator, vector>                   const_iterator;
00136 
00137       typedef typename _Base::size_type                 size_type;
00138       typedef typename _Base::difference_type           difference_type;
00139 
00140       typedef _Tp                                       value_type;
00141       typedef _Allocator                                allocator_type;
00142       typedef typename _Base::pointer                   pointer;
00143       typedef typename _Base::const_pointer             const_pointer;
00144       typedef std::reverse_iterator<iterator>           reverse_iterator;
00145       typedef std::reverse_iterator<const_iterator>     const_reverse_iterator;
00146 
00147       // 23.2.4.1 construct/copy/destroy:
00148 
00149 #if __cplusplus < 201103L
00150       vector() _GLIBCXX_NOEXCEPT
00151       : _Base() { }
00152 #else
00153       vector() = default;
00154 #endif
00155 
00156       explicit
00157       vector(const _Allocator& __a) _GLIBCXX_NOEXCEPT
00158       : _Base(__a) { }
00159 
00160 #if __cplusplus >= 201103L
00161       explicit
00162       vector(size_type __n, const _Allocator& __a = _Allocator())
00163       : _Base(__n, __a), _Safe_vector(__n) { }
00164 
00165       vector(size_type __n, const _Tp& __value,
00166              const _Allocator& __a = _Allocator())
00167       : _Base(__n, __value, __a) { }
00168 #else
00169       explicit
00170       vector(size_type __n, const _Tp& __value = _Tp(),
00171              const _Allocator& __a = _Allocator())
00172       : _Base(__n, __value, __a) { }
00173 #endif
00174 
00175 #if __cplusplus >= 201103L
00176       template<class _InputIterator,
00177                typename = std::_RequireInputIter<_InputIterator>>
00178 #else
00179       template<class _InputIterator>
00180 #endif
00181         vector(_InputIterator __first, _InputIterator __last,
00182                const _Allocator& __a = _Allocator())
00183         : _Base(__gnu_debug::__base(__gnu_debug::__check_valid_range(__first,
00184                                                                      __last)),
00185                 __gnu_debug::__base(__last), __a) { }
00186 
00187 #if __cplusplus < 201103L
00188       vector(const vector& __x)
00189       : _Base(__x) { }
00190 
00191       ~vector() _GLIBCXX_NOEXCEPT { }
00192 #else
00193       vector(const vector&) = default;
00194       vector(vector&&) = default;
00195 
00196       vector(const vector& __x, const allocator_type& __a)
00197       : _Base(__x, __a) { }
00198 
00199       vector(vector&& __x, const allocator_type& __a)
00200       : _Safe(std::move(__x._M_safe()), __a),
00201         _Base(std::move(__x._M_base()), __a),
00202         _Safe_vector(std::move(__x)) { }
00203 
00204       vector(initializer_list<value_type> __l,
00205              const allocator_type& __a = allocator_type())
00206       : _Base(__l, __a) { }
00207 
00208       ~vector() = default;
00209 #endif
00210 
00211       /// Construction from a normal-mode vector
00212       vector(const _Base& __x)
00213       : _Base(__x) { }
00214 
00215 #if __cplusplus < 201103L
00216       vector&
00217       operator=(const vector& __x)
00218       {
00219         this->_M_safe() = __x;
00220         _M_base() = __x;
00221         this->_M_update_guaranteed_capacity();
00222         return *this;
00223       }
00224 #else
00225       vector&
00226       operator=(const vector&) = default;
00227 
00228       vector&
00229       operator=(vector&&) = default;
00230 
00231       vector&
00232       operator=(initializer_list<value_type> __l)
00233       {
00234         _M_base() = __l;
00235         this->_M_invalidate_all();
00236         this->_M_update_guaranteed_capacity();
00237         return *this;
00238       }
00239 #endif
00240 
00241 #if __cplusplus >= 201103L
00242       template<typename _InputIterator,
00243                typename = std::_RequireInputIter<_InputIterator>>
00244 #else
00245       template<typename _InputIterator>
00246 #endif
00247         void
00248         assign(_InputIterator __first, _InputIterator __last)
00249         {
00250           typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
00251           __glibcxx_check_valid_range2(__first, __last, __dist);
00252 
00253           if (__dist.second >= __gnu_debug::__dp_sign)
00254             _Base::assign(__gnu_debug::__unsafe(__first),
00255                           __gnu_debug::__unsafe(__last));
00256           else
00257             _Base::assign(__first, __last);
00258 
00259           this->_M_invalidate_all();
00260           this->_M_update_guaranteed_capacity();
00261         }
00262 
00263       void
00264       assign(size_type __n, const _Tp& __u)
00265       {
00266         _Base::assign(__n, __u);
00267         this->_M_invalidate_all();
00268         this->_M_update_guaranteed_capacity();
00269       }
00270 
00271 #if __cplusplus >= 201103L
00272       void
00273       assign(initializer_list<value_type> __l)
00274       {
00275         _Base::assign(__l);
00276         this->_M_invalidate_all();
00277         this->_M_update_guaranteed_capacity();
00278       }
00279 #endif
00280 
00281       using _Base::get_allocator;
00282 
00283       // iterators:
00284       iterator
00285       begin() _GLIBCXX_NOEXCEPT
00286       { return iterator(_Base::begin(), this); }
00287 
00288       const_iterator
00289       begin() const _GLIBCXX_NOEXCEPT
00290       { return const_iterator(_Base::begin(), this); }
00291 
00292       iterator
00293       end() _GLIBCXX_NOEXCEPT
00294       { return iterator(_Base::end(), this); }
00295 
00296       const_iterator
00297       end() const _GLIBCXX_NOEXCEPT
00298       { return const_iterator(_Base::end(), this); }
00299 
00300       reverse_iterator
00301       rbegin() _GLIBCXX_NOEXCEPT
00302       { return reverse_iterator(end()); }
00303 
00304       const_reverse_iterator
00305       rbegin() const _GLIBCXX_NOEXCEPT
00306       { return const_reverse_iterator(end()); }
00307 
00308       reverse_iterator
00309       rend() _GLIBCXX_NOEXCEPT
00310       { return reverse_iterator(begin()); }
00311 
00312       const_reverse_iterator
00313       rend() const _GLIBCXX_NOEXCEPT
00314       { return const_reverse_iterator(begin()); }
00315 
00316 #if __cplusplus >= 201103L
00317       const_iterator
00318       cbegin() const noexcept
00319       { return const_iterator(_Base::begin(), this); }
00320 
00321       const_iterator
00322       cend() const noexcept
00323       { return const_iterator(_Base::end(), this); }
00324 
00325       const_reverse_iterator
00326       crbegin() const noexcept
00327       { return const_reverse_iterator(end()); }
00328 
00329       const_reverse_iterator
00330       crend() const noexcept
00331       { return const_reverse_iterator(begin()); }
00332 #endif
00333 
00334       // 23.2.4.2 capacity:
00335       using _Base::size;
00336       using _Base::max_size;
00337 
00338 #if __cplusplus >= 201103L
00339       void
00340       resize(size_type __sz)
00341       {
00342         bool __realloc = this->_M_requires_reallocation(__sz);
00343         if (__sz < this->size())
00344           this->_M_invalidate_after_nth(__sz);
00345         _Base::resize(__sz);
00346         if (__realloc)
00347           this->_M_invalidate_all();
00348         this->_M_update_guaranteed_capacity();
00349       }
00350 
00351       void
00352       resize(size_type __sz, const _Tp& __c)
00353       {
00354         bool __realloc = this->_M_requires_reallocation(__sz);
00355         if (__sz < this->size())
00356           this->_M_invalidate_after_nth(__sz);
00357         _Base::resize(__sz, __c);
00358         if (__realloc)
00359           this->_M_invalidate_all();
00360         this->_M_update_guaranteed_capacity();
00361       }
00362 #else
00363       void
00364       resize(size_type __sz, _Tp __c = _Tp())
00365       {
00366         bool __realloc = this->_M_requires_reallocation(__sz);
00367         if (__sz < this->size())
00368           this->_M_invalidate_after_nth(__sz);
00369         _Base::resize(__sz, __c);
00370         if (__realloc)
00371           this->_M_invalidate_all();
00372         this->_M_update_guaranteed_capacity();
00373       }
00374 #endif
00375 
00376 #if __cplusplus >= 201103L
00377       void
00378       shrink_to_fit()
00379       {
00380         if (_Base::_M_shrink_to_fit())
00381           {
00382             this->_M_guaranteed_capacity = _Base::capacity();
00383             this->_M_invalidate_all();
00384           }
00385       }
00386 #endif
00387 
00388       size_type
00389       capacity() const _GLIBCXX_NOEXCEPT
00390       {
00391 #ifdef _GLIBCXX_DEBUG_PEDANTIC
00392         return this->_M_guaranteed_capacity;
00393 #else
00394         return _Base::capacity();
00395 #endif
00396       }
00397 
00398       using _Base::empty;
00399 
00400       void
00401       reserve(size_type __n)
00402       {
00403         bool __realloc = this->_M_requires_reallocation(__n);
00404         _Base::reserve(__n);
00405         if (__n > this->_M_guaranteed_capacity)
00406           this->_M_guaranteed_capacity = __n;
00407         if (__realloc)
00408           this->_M_invalidate_all();
00409       }
00410 
00411       // element access:
00412       reference
00413       operator[](size_type __n) _GLIBCXX_NOEXCEPT
00414       {
00415         __glibcxx_check_subscript(__n);
00416         return _M_base()[__n];
00417       }
00418 
00419       const_reference
00420       operator[](size_type __n) const _GLIBCXX_NOEXCEPT
00421       {
00422         __glibcxx_check_subscript(__n);
00423         return _M_base()[__n];
00424       }
00425 
00426       using _Base::at;
00427 
00428       reference
00429       front() _GLIBCXX_NOEXCEPT
00430       {
00431         __glibcxx_check_nonempty();
00432         return _Base::front();
00433       }
00434 
00435       const_reference
00436       front() const _GLIBCXX_NOEXCEPT
00437       {
00438         __glibcxx_check_nonempty();
00439         return _Base::front();
00440       }
00441 
00442       reference
00443       back() _GLIBCXX_NOEXCEPT
00444       {
00445         __glibcxx_check_nonempty();
00446         return _Base::back();
00447       }
00448 
00449       const_reference
00450       back() const _GLIBCXX_NOEXCEPT
00451       {
00452         __glibcxx_check_nonempty();
00453         return _Base::back();
00454       }
00455 
00456       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00457       // DR 464. Suggestion for new member functions in standard containers.
00458       using _Base::data;
00459 
00460       // 23.2.4.3 modifiers:
00461       void
00462       push_back(const _Tp& __x)
00463       {
00464         bool __realloc = this->_M_requires_reallocation(this->size() + 1);
00465         _Base::push_back(__x);
00466         if (__realloc)
00467           this->_M_invalidate_all();
00468         this->_M_update_guaranteed_capacity();
00469       }
00470 
00471 #if __cplusplus >= 201103L
00472       template<typename _Up = _Tp>
00473         typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value,
00474                                         void>::__type
00475         push_back(_Tp&& __x)
00476         { emplace_back(std::move(__x)); }
00477 
00478       template<typename... _Args>
00479         void
00480         emplace_back(_Args&&... __args)
00481         {
00482           bool __realloc = this->_M_requires_reallocation(this->size() + 1);
00483           _Base::emplace_back(std::forward<_Args>(__args)...);
00484           if (__realloc)
00485             this->_M_invalidate_all();
00486           this->_M_update_guaranteed_capacity();
00487         }
00488 #endif
00489 
00490       void
00491       pop_back() _GLIBCXX_NOEXCEPT
00492       {
00493         __glibcxx_check_nonempty();
00494         this->_M_invalidate_if(_Equal(--_Base::end()));
00495         _Base::pop_back();
00496       }
00497 
00498 #if __cplusplus >= 201103L
00499       template<typename... _Args>
00500         iterator
00501         emplace(const_iterator __position, _Args&&... __args)
00502         {
00503           __glibcxx_check_insert(__position);
00504           bool __realloc = this->_M_requires_reallocation(this->size() + 1);
00505           difference_type __offset = __position.base() - _Base::begin();
00506           _Base_iterator __res = _Base::emplace(__position.base(),
00507                                                 std::forward<_Args>(__args)...);
00508           if (__realloc)
00509             this->_M_invalidate_all();
00510           else
00511             this->_M_invalidate_after_nth(__offset);
00512           this->_M_update_guaranteed_capacity();
00513           return iterator(__res, this);
00514         }
00515 #endif
00516 
00517       iterator
00518 #if __cplusplus >= 201103L
00519       insert(const_iterator __position, const _Tp& __x)
00520 #else
00521       insert(iterator __position, const _Tp& __x)
00522 #endif
00523       {
00524         __glibcxx_check_insert(__position);
00525         bool __realloc = this->_M_requires_reallocation(this->size() + 1);
00526         difference_type __offset = __position.base() - _Base::begin();
00527         _Base_iterator __res = _Base::insert(__position.base(), __x);
00528         if (__realloc)
00529           this->_M_invalidate_all();
00530         else
00531           this->_M_invalidate_after_nth(__offset);
00532         this->_M_update_guaranteed_capacity();
00533         return iterator(__res, this);
00534       }
00535 
00536 #if __cplusplus >= 201103L
00537       template<typename _Up = _Tp>
00538         typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value,
00539                                         iterator>::__type
00540         insert(const_iterator __position, _Tp&& __x)
00541         { return emplace(__position, std::move(__x)); }
00542 
00543       iterator
00544       insert(const_iterator __position, initializer_list<value_type> __l)
00545       { return this->insert(__position, __l.begin(), __l.end()); }
00546 #endif
00547 
00548 #if __cplusplus >= 201103L
00549       iterator
00550       insert(const_iterator __position, size_type __n, const _Tp& __x)
00551       {
00552         __glibcxx_check_insert(__position);
00553         bool __realloc = this->_M_requires_reallocation(this->size() + __n);
00554         difference_type __offset = __position.base() - _Base::cbegin();
00555         _Base_iterator __res = _Base::insert(__position.base(), __n, __x);
00556         if (__realloc)
00557           this->_M_invalidate_all();
00558         else
00559           this->_M_invalidate_after_nth(__offset);
00560         this->_M_update_guaranteed_capacity();
00561         return iterator(__res, this);
00562       }
00563 #else
00564       void
00565       insert(iterator __position, size_type __n, const _Tp& __x)
00566       {
00567         __glibcxx_check_insert(__position);
00568         bool __realloc = this->_M_requires_reallocation(this->size() + __n);
00569         difference_type __offset = __position.base() - _Base::begin();
00570         _Base::insert(__position.base(), __n, __x);
00571         if (__realloc)
00572           this->_M_invalidate_all();
00573         else
00574           this->_M_invalidate_after_nth(__offset);
00575         this->_M_update_guaranteed_capacity();
00576       }
00577 #endif
00578 
00579 #if __cplusplus >= 201103L
00580       template<class _InputIterator,
00581                typename = std::_RequireInputIter<_InputIterator>>
00582         iterator
00583         insert(const_iterator __position,
00584                _InputIterator __first, _InputIterator __last)
00585         {
00586           typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
00587           __glibcxx_check_insert_range(__position, __first, __last, __dist);
00588 
00589           /* Hard to guess if invalidation will occur, because __last
00590              - __first can't be calculated in all cases, so we just
00591              punt here by checking if it did occur. */
00592           _Base_iterator __old_begin = _M_base().begin();
00593           difference_type __offset = __position.base() - _Base::cbegin();
00594           _Base_iterator __res;
00595           if (__dist.second >= __gnu_debug::__dp_sign)
00596             __res = _Base::insert(__position.base(),
00597                                   __gnu_debug::__unsafe(__first),
00598                                   __gnu_debug::__unsafe(__last));
00599           else
00600             __res = _Base::insert(__position.base(), __first, __last);
00601 
00602           if (_M_base().begin() != __old_begin)
00603             this->_M_invalidate_all();
00604           else
00605             this->_M_invalidate_after_nth(__offset);
00606           this->_M_update_guaranteed_capacity();
00607           return iterator(__res, this);
00608         }
00609 #else
00610       template<class _InputIterator>
00611         void
00612         insert(iterator __position,
00613                _InputIterator __first, _InputIterator __last)
00614         {
00615           typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
00616           __glibcxx_check_insert_range(__position, __first, __last, __dist);
00617 
00618           /* Hard to guess if invalidation will occur, because __last
00619              - __first can't be calculated in all cases, so we just
00620              punt here by checking if it did occur. */
00621           _Base_iterator __old_begin = _M_base().begin();
00622           difference_type __offset = __position.base() - _Base::begin();
00623           if (__dist.second >= __gnu_debug::__dp_sign)
00624             _Base::insert(__position.base(), __gnu_debug::__unsafe(__first),
00625                                              __gnu_debug::__unsafe(__last));
00626           else
00627             _Base::insert(__position.base(), __first, __last);
00628 
00629           if (_M_base().begin() != __old_begin)
00630             this->_M_invalidate_all();
00631           else
00632             this->_M_invalidate_after_nth(__offset);
00633           this->_M_update_guaranteed_capacity();
00634         }
00635 #endif
00636 
00637       iterator
00638 #if __cplusplus >= 201103L
00639       erase(const_iterator __position)
00640 #else
00641       erase(iterator __position)
00642 #endif
00643       {
00644         __glibcxx_check_erase(__position);
00645         difference_type __offset = __position.base() - _Base::begin();
00646         _Base_iterator __res = _Base::erase(__position.base());
00647         this->_M_invalidate_after_nth(__offset);
00648         return iterator(__res, this);
00649       }
00650 
00651       iterator
00652 #if __cplusplus >= 201103L
00653       erase(const_iterator __first, const_iterator __last)
00654 #else
00655       erase(iterator __first, iterator __last)
00656 #endif
00657       {
00658         // _GLIBCXX_RESOLVE_LIB_DEFECTS
00659         // 151. can't currently clear() empty container
00660         __glibcxx_check_erase_range(__first, __last);
00661 
00662         if (__first.base() != __last.base())
00663           {
00664             difference_type __offset = __first.base() - _Base::begin();
00665             _Base_iterator __res = _Base::erase(__first.base(),
00666                                                 __last.base());
00667             this->_M_invalidate_after_nth(__offset);
00668             return iterator(__res, this);
00669           }
00670         else
00671 #if __cplusplus >= 201103L
00672           return begin() + (__first.base() - cbegin().base());
00673 #else
00674           return __first;
00675 #endif
00676       }
00677 
00678       void
00679       swap(vector& __x)
00680       _GLIBCXX_NOEXCEPT_IF( noexcept(declval<_Base&>().swap(__x)) )
00681       {
00682         _Safe::_M_swap(__x);
00683         _Base::swap(__x);
00684         std::swap(this->_M_guaranteed_capacity, __x._M_guaranteed_capacity);
00685       }
00686 
00687       void
00688       clear() _GLIBCXX_NOEXCEPT
00689       {
00690         _Base::clear();
00691         this->_M_invalidate_all();
00692       }
00693 
00694       _Base&
00695       _M_base() _GLIBCXX_NOEXCEPT { return *this; }
00696 
00697       const _Base&
00698       _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
00699 
00700     private:
00701       void
00702       _M_invalidate_after_nth(difference_type __n) _GLIBCXX_NOEXCEPT
00703       {
00704         typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
00705         this->_M_invalidate_if(_After_nth(__n, _Base::begin()));
00706       }
00707     };
00708 
00709   template<typename _Tp, typename _Alloc>
00710     inline bool
00711     operator==(const vector<_Tp, _Alloc>& __lhs,
00712                const vector<_Tp, _Alloc>& __rhs)
00713     { return __lhs._M_base() == __rhs._M_base(); }
00714 
00715   template<typename _Tp, typename _Alloc>
00716     inline bool
00717     operator!=(const vector<_Tp, _Alloc>& __lhs,
00718                const vector<_Tp, _Alloc>& __rhs)
00719     { return __lhs._M_base() != __rhs._M_base(); }
00720 
00721   template<typename _Tp, typename _Alloc>
00722     inline bool
00723     operator<(const vector<_Tp, _Alloc>& __lhs,
00724               const vector<_Tp, _Alloc>& __rhs)
00725     { return __lhs._M_base() < __rhs._M_base(); }
00726 
00727   template<typename _Tp, typename _Alloc>
00728     inline bool
00729     operator<=(const vector<_Tp, _Alloc>& __lhs,
00730                const vector<_Tp, _Alloc>& __rhs)
00731     { return __lhs._M_base() <= __rhs._M_base(); }
00732 
00733   template<typename _Tp, typename _Alloc>
00734     inline bool
00735     operator>=(const vector<_Tp, _Alloc>& __lhs,
00736                const vector<_Tp, _Alloc>& __rhs)
00737     { return __lhs._M_base() >= __rhs._M_base(); }
00738 
00739   template<typename _Tp, typename _Alloc>
00740     inline bool
00741     operator>(const vector<_Tp, _Alloc>& __lhs,
00742               const vector<_Tp, _Alloc>& __rhs)
00743     { return __lhs._M_base() > __rhs._M_base(); }
00744 
00745   template<typename _Tp, typename _Alloc>
00746     inline void
00747     swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
00748     _GLIBCXX_NOEXCEPT_IF(noexcept(__lhs.swap(__rhs)))
00749     { __lhs.swap(__rhs); }
00750 
00751 } // namespace __debug
00752 
00753 #if __cplusplus >= 201103L
00754   // DR 1182.
00755   /// std::hash specialization for vector<bool>.
00756   template<typename _Alloc>
00757     struct hash<__debug::vector<bool, _Alloc>>
00758     : public __hash_base<size_t, __debug::vector<bool, _Alloc>>
00759     {
00760       size_t
00761       operator()(const __debug::vector<bool, _Alloc>& __b) const noexcept
00762       { return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>()(__b); }
00763     };
00764 #endif
00765 
00766 } // namespace std
00767 
00768 namespace __gnu_debug
00769 {
00770   template<typename _Tp, typename _Alloc>
00771     struct _Is_contiguous_sequence<std::__debug::vector<_Tp, _Alloc> >
00772     : std::__true_type
00773     { };
00774 
00775   template<typename _Alloc>
00776     struct _Is_contiguous_sequence<std::__debug::vector<bool, _Alloc> >
00777     : std::__false_type
00778     { };
00779 }
00780 
00781 #endif