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