libstdc++
vector
Go to the documentation of this file.
00001 // Debugging vector implementation -*- C++ -*-
00002 
00003 // Copyright (C) 2003-2015 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           __glibcxx_check_valid_range(__first, __last);
00251           _Base::assign(__gnu_debug::__base(__first),
00252                         __gnu_debug::__base(__last));
00253           this->_M_invalidate_all();
00254           this->_M_update_guaranteed_capacity();
00255         }
00256 
00257       void
00258       assign(size_type __n, const _Tp& __u)
00259       {
00260         _Base::assign(__n, __u);
00261         this->_M_invalidate_all();
00262         this->_M_update_guaranteed_capacity();
00263       }
00264 
00265 #if __cplusplus >= 201103L
00266       void
00267       assign(initializer_list<value_type> __l)
00268       {
00269         _Base::assign(__l);
00270         this->_M_invalidate_all();
00271         this->_M_update_guaranteed_capacity();
00272       }
00273 #endif
00274 
00275       using _Base::get_allocator;
00276 
00277       // iterators:
00278       iterator
00279       begin() _GLIBCXX_NOEXCEPT
00280       { return iterator(_Base::begin(), this); }
00281 
00282       const_iterator
00283       begin() const _GLIBCXX_NOEXCEPT
00284       { return const_iterator(_Base::begin(), this); }
00285 
00286       iterator
00287       end() _GLIBCXX_NOEXCEPT
00288       { return iterator(_Base::end(), this); }
00289 
00290       const_iterator
00291       end() const _GLIBCXX_NOEXCEPT
00292       { return const_iterator(_Base::end(), this); }
00293 
00294       reverse_iterator
00295       rbegin() _GLIBCXX_NOEXCEPT
00296       { return reverse_iterator(end()); }
00297 
00298       const_reverse_iterator
00299       rbegin() const _GLIBCXX_NOEXCEPT
00300       { return const_reverse_iterator(end()); }
00301 
00302       reverse_iterator
00303       rend() _GLIBCXX_NOEXCEPT
00304       { return reverse_iterator(begin()); }
00305 
00306       const_reverse_iterator
00307       rend() const _GLIBCXX_NOEXCEPT
00308       { return const_reverse_iterator(begin()); }
00309 
00310 #if __cplusplus >= 201103L
00311       const_iterator
00312       cbegin() const noexcept
00313       { return const_iterator(_Base::begin(), this); }
00314 
00315       const_iterator
00316       cend() const noexcept
00317       { return const_iterator(_Base::end(), this); }
00318 
00319       const_reverse_iterator
00320       crbegin() const noexcept
00321       { return const_reverse_iterator(end()); }
00322 
00323       const_reverse_iterator
00324       crend() const noexcept
00325       { return const_reverse_iterator(begin()); }
00326 #endif
00327 
00328       // 23.2.4.2 capacity:
00329       using _Base::size;
00330       using _Base::max_size;
00331 
00332 #if __cplusplus >= 201103L
00333       void
00334       resize(size_type __sz)
00335       {
00336         bool __realloc = this->_M_requires_reallocation(__sz);
00337         if (__sz < this->size())
00338           this->_M_invalidate_after_nth(__sz);
00339         _Base::resize(__sz);
00340         if (__realloc)
00341           this->_M_invalidate_all();
00342         this->_M_update_guaranteed_capacity();
00343       }
00344 
00345       void
00346       resize(size_type __sz, const _Tp& __c)
00347       {
00348         bool __realloc = this->_M_requires_reallocation(__sz);
00349         if (__sz < this->size())
00350           this->_M_invalidate_after_nth(__sz);
00351         _Base::resize(__sz, __c);
00352         if (__realloc)
00353           this->_M_invalidate_all();
00354         this->_M_update_guaranteed_capacity();
00355       }
00356 #else
00357       void
00358       resize(size_type __sz, _Tp __c = _Tp())
00359       {
00360         bool __realloc = this->_M_requires_reallocation(__sz);
00361         if (__sz < this->size())
00362           this->_M_invalidate_after_nth(__sz);
00363         _Base::resize(__sz, __c);
00364         if (__realloc)
00365           this->_M_invalidate_all();
00366         this->_M_update_guaranteed_capacity();
00367       }
00368 #endif
00369 
00370 #if __cplusplus >= 201103L
00371       void
00372       shrink_to_fit()
00373       {
00374         if (_Base::_M_shrink_to_fit())
00375           {
00376             this->_M_guaranteed_capacity = _Base::capacity();
00377             this->_M_invalidate_all();
00378           }
00379       }
00380 #endif
00381 
00382       size_type
00383       capacity() const _GLIBCXX_NOEXCEPT
00384       {
00385 #ifdef _GLIBCXX_DEBUG_PEDANTIC
00386         return this->_M_guaranteed_capacity;
00387 #else
00388         return _Base::capacity();
00389 #endif
00390       }
00391 
00392       using _Base::empty;
00393 
00394       void
00395       reserve(size_type __n)
00396       {
00397         bool __realloc = this->_M_requires_reallocation(__n);
00398         _Base::reserve(__n);
00399         if (__n > this->_M_guaranteed_capacity)
00400           this->_M_guaranteed_capacity = __n;
00401         if (__realloc)
00402           this->_M_invalidate_all();
00403       }
00404 
00405       // element access:
00406       reference
00407       operator[](size_type __n) _GLIBCXX_NOEXCEPT
00408       {
00409         __glibcxx_check_subscript(__n);
00410         return _M_base()[__n];
00411       }
00412 
00413       const_reference
00414       operator[](size_type __n) const _GLIBCXX_NOEXCEPT
00415       {
00416         __glibcxx_check_subscript(__n);
00417         return _M_base()[__n];
00418       }
00419 
00420       using _Base::at;
00421 
00422       reference
00423       front() _GLIBCXX_NOEXCEPT
00424       {
00425         __glibcxx_check_nonempty();
00426         return _Base::front();
00427       }
00428 
00429       const_reference
00430       front() const _GLIBCXX_NOEXCEPT
00431       {
00432         __glibcxx_check_nonempty();
00433         return _Base::front();
00434       }
00435 
00436       reference
00437       back() _GLIBCXX_NOEXCEPT
00438       {
00439         __glibcxx_check_nonempty();
00440         return _Base::back();
00441       }
00442 
00443       const_reference
00444       back() const _GLIBCXX_NOEXCEPT
00445       {
00446         __glibcxx_check_nonempty();
00447         return _Base::back();
00448       }
00449 
00450       // _GLIBCXX_RESOLVE_LIB_DEFECTS
00451       // DR 464. Suggestion for new member functions in standard containers.
00452       using _Base::data;
00453 
00454       // 23.2.4.3 modifiers:
00455       void
00456       push_back(const _Tp& __x)
00457       {
00458         bool __realloc = this->_M_requires_reallocation(this->size() + 1);
00459         _Base::push_back(__x);
00460         if (__realloc)
00461           this->_M_invalidate_all();
00462         this->_M_update_guaranteed_capacity();
00463       }
00464 
00465 #if __cplusplus >= 201103L
00466       template<typename _Up = _Tp>
00467         typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value,
00468                                         void>::__type
00469         push_back(_Tp&& __x)
00470         { emplace_back(std::move(__x)); }
00471 
00472       template<typename... _Args>
00473         void
00474         emplace_back(_Args&&... __args)
00475         {
00476           bool __realloc = this->_M_requires_reallocation(this->size() + 1);
00477           _Base::emplace_back(std::forward<_Args>(__args)...);
00478           if (__realloc)
00479             this->_M_invalidate_all();
00480           this->_M_update_guaranteed_capacity();
00481         }
00482 #endif
00483 
00484       void
00485       pop_back() _GLIBCXX_NOEXCEPT
00486       {
00487         __glibcxx_check_nonempty();
00488         this->_M_invalidate_if(_Equal(--_Base::end()));
00489         _Base::pop_back();
00490       }
00491 
00492 #if __cplusplus >= 201103L
00493       template<typename... _Args>
00494         iterator
00495         emplace(const_iterator __position, _Args&&... __args)
00496         {
00497           __glibcxx_check_insert(__position);
00498           bool __realloc = this->_M_requires_reallocation(this->size() + 1);
00499           difference_type __offset = __position.base() - _Base::begin();
00500           _Base_iterator __res = _Base::emplace(__position.base(),
00501                                                 std::forward<_Args>(__args)...);
00502           if (__realloc)
00503             this->_M_invalidate_all();
00504           else
00505             this->_M_invalidate_after_nth(__offset);
00506           this->_M_update_guaranteed_capacity();
00507           return iterator(__res, this);
00508         }
00509 #endif
00510 
00511       iterator
00512 #if __cplusplus >= 201103L
00513       insert(const_iterator __position, const _Tp& __x)
00514 #else
00515       insert(iterator __position, const _Tp& __x)
00516 #endif
00517       {
00518         __glibcxx_check_insert(__position);
00519         bool __realloc = this->_M_requires_reallocation(this->size() + 1);
00520         difference_type __offset = __position.base() - _Base::begin();
00521         _Base_iterator __res = _Base::insert(__position.base(), __x);
00522         if (__realloc)
00523           this->_M_invalidate_all();
00524         else
00525           this->_M_invalidate_after_nth(__offset);
00526         this->_M_update_guaranteed_capacity();
00527         return iterator(__res, this);
00528       }
00529 
00530 #if __cplusplus >= 201103L
00531       template<typename _Up = _Tp>
00532         typename __gnu_cxx::__enable_if<!std::__are_same<_Up, bool>::__value,
00533                                         iterator>::__type
00534         insert(const_iterator __position, _Tp&& __x)
00535         { return emplace(__position, std::move(__x)); }
00536 
00537       iterator
00538       insert(const_iterator __position, initializer_list<value_type> __l)
00539       { return this->insert(__position, __l.begin(), __l.end()); }
00540 #endif
00541 
00542 #if __cplusplus >= 201103L
00543       iterator
00544       insert(const_iterator __position, size_type __n, const _Tp& __x)
00545       {
00546         __glibcxx_check_insert(__position);
00547         bool __realloc = this->_M_requires_reallocation(this->size() + __n);
00548         difference_type __offset = __position.base() - _Base::cbegin();
00549         _Base_iterator __res = _Base::insert(__position.base(), __n, __x);
00550         if (__realloc)
00551           this->_M_invalidate_all();
00552         else
00553           this->_M_invalidate_after_nth(__offset);
00554         this->_M_update_guaranteed_capacity();
00555         return iterator(__res, this);
00556       }
00557 #else
00558       void
00559       insert(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::begin();
00564         _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       }
00571 #endif
00572 
00573 #if __cplusplus >= 201103L
00574       template<class _InputIterator,
00575                typename = std::_RequireInputIter<_InputIterator>>
00576         iterator
00577         insert(const_iterator __position,
00578                _InputIterator __first, _InputIterator __last)
00579         {
00580           __glibcxx_check_insert_range(__position, __first, __last);
00581 
00582           /* Hard to guess if invalidation will occur, because __last
00583              - __first can't be calculated in all cases, so we just
00584              punt here by checking if it did occur. */
00585           _Base_iterator __old_begin = _M_base().begin();
00586           difference_type __offset = __position.base() - _Base::cbegin();
00587           _Base_iterator __res = _Base::insert(__position.base(),
00588                                                __gnu_debug::__base(__first),
00589                                                __gnu_debug::__base(__last));
00590 
00591           if (_M_base().begin() != __old_begin)
00592             this->_M_invalidate_all();
00593           else
00594             this->_M_invalidate_after_nth(__offset);
00595           this->_M_update_guaranteed_capacity();
00596           return iterator(__res, this);
00597         }
00598 #else
00599       template<class _InputIterator>
00600         void
00601         insert(iterator __position,
00602                _InputIterator __first, _InputIterator __last)
00603         {
00604           __glibcxx_check_insert_range(__position, __first, __last);
00605 
00606           /* Hard to guess if invalidation will occur, because __last
00607              - __first can't be calculated in all cases, so we just
00608              punt here by checking if it did occur. */
00609           _Base_iterator __old_begin = _M_base().begin();
00610           difference_type __offset = __position.base() - _Base::begin();
00611           _Base::insert(__position.base(), __gnu_debug::__base(__first),
00612                                            __gnu_debug::__base(__last));
00613 
00614           if (_M_base().begin() != __old_begin)
00615             this->_M_invalidate_all();
00616           else
00617             this->_M_invalidate_after_nth(__offset);
00618           this->_M_update_guaranteed_capacity();
00619         }
00620 #endif
00621 
00622       iterator
00623 #if __cplusplus >= 201103L
00624       erase(const_iterator __position)
00625 #else
00626       erase(iterator __position)
00627 #endif
00628       {
00629         __glibcxx_check_erase(__position);
00630         difference_type __offset = __position.base() - _Base::begin();
00631         _Base_iterator __res = _Base::erase(__position.base());
00632         this->_M_invalidate_after_nth(__offset);
00633         return iterator(__res, this);
00634       }
00635 
00636       iterator
00637 #if __cplusplus >= 201103L
00638       erase(const_iterator __first, const_iterator __last)
00639 #else
00640       erase(iterator __first, iterator __last)
00641 #endif
00642       {
00643         // _GLIBCXX_RESOLVE_LIB_DEFECTS
00644         // 151. can't currently clear() empty container
00645         __glibcxx_check_erase_range(__first, __last);
00646 
00647         if (__first.base() != __last.base())
00648           {
00649             difference_type __offset = __first.base() - _Base::begin();
00650             _Base_iterator __res = _Base::erase(__first.base(),
00651                                                 __last.base());
00652             this->_M_invalidate_after_nth(__offset);
00653             return iterator(__res, this);
00654           }
00655         else
00656 #if __cplusplus >= 201103L
00657           return begin() + (__first.base() - cbegin().base());
00658 #else
00659           return __first;
00660 #endif
00661       }
00662 
00663       void
00664       swap(vector& __x)
00665 #if __cplusplus >= 201103L
00666         noexcept( noexcept(declval<_Base>().swap(__x)) )
00667 #endif
00668       {
00669         _Safe::_M_swap(__x);
00670         _Base::swap(__x);
00671         std::swap(this->_M_guaranteed_capacity, __x._M_guaranteed_capacity);
00672       }
00673 
00674       void
00675       clear() _GLIBCXX_NOEXCEPT
00676       {
00677         _Base::clear();
00678         this->_M_invalidate_all();
00679       }
00680 
00681       _Base&
00682       _M_base() _GLIBCXX_NOEXCEPT { return *this; }
00683 
00684       const _Base&
00685       _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
00686 
00687     private:
00688       void
00689       _M_invalidate_after_nth(difference_type __n) _GLIBCXX_NOEXCEPT
00690       {
00691         typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
00692         this->_M_invalidate_if(_After_nth(__n, _Base::begin()));
00693       }
00694     };
00695 
00696   template<typename _Tp, typename _Alloc>
00697     inline bool
00698     operator==(const vector<_Tp, _Alloc>& __lhs,
00699                const vector<_Tp, _Alloc>& __rhs)
00700     { return __lhs._M_base() == __rhs._M_base(); }
00701 
00702   template<typename _Tp, typename _Alloc>
00703     inline bool
00704     operator!=(const vector<_Tp, _Alloc>& __lhs,
00705                const vector<_Tp, _Alloc>& __rhs)
00706     { return __lhs._M_base() != __rhs._M_base(); }
00707 
00708   template<typename _Tp, typename _Alloc>
00709     inline bool
00710     operator<(const vector<_Tp, _Alloc>& __lhs,
00711               const vector<_Tp, _Alloc>& __rhs)
00712     { return __lhs._M_base() < __rhs._M_base(); }
00713 
00714   template<typename _Tp, typename _Alloc>
00715     inline bool
00716     operator<=(const vector<_Tp, _Alloc>& __lhs,
00717                const vector<_Tp, _Alloc>& __rhs)
00718     { return __lhs._M_base() <= __rhs._M_base(); }
00719 
00720   template<typename _Tp, typename _Alloc>
00721     inline bool
00722     operator>=(const vector<_Tp, _Alloc>& __lhs,
00723                const vector<_Tp, _Alloc>& __rhs)
00724     { return __lhs._M_base() >= __rhs._M_base(); }
00725 
00726   template<typename _Tp, typename _Alloc>
00727     inline bool
00728     operator>(const vector<_Tp, _Alloc>& __lhs,
00729               const vector<_Tp, _Alloc>& __rhs)
00730     { return __lhs._M_base() > __rhs._M_base(); }
00731 
00732   template<typename _Tp, typename _Alloc>
00733     inline void
00734     swap(vector<_Tp, _Alloc>& __lhs, vector<_Tp, _Alloc>& __rhs)
00735     { __lhs.swap(__rhs); }
00736 
00737 } // namespace __debug
00738 
00739 #if __cplusplus >= 201103L
00740   // DR 1182.
00741   /// std::hash specialization for vector<bool>.
00742   template<typename _Alloc>
00743     struct hash<__debug::vector<bool, _Alloc>>
00744     : public __hash_base<size_t, __debug::vector<bool, _Alloc>>
00745     {
00746       size_t
00747       operator()(const __debug::vector<bool, _Alloc>& __b) const noexcept
00748       { return std::hash<_GLIBCXX_STD_C::vector<bool, _Alloc>>()
00749           (__b._M_base()); }
00750     };
00751 #endif
00752 
00753 } // namespace std
00754 
00755 namespace __gnu_debug
00756 {
00757   template<typename _Tp, typename _Alloc>
00758     struct _Is_contiguous_sequence<std::__debug::vector<_Tp, _Alloc> >
00759     : std::__true_type
00760     { };
00761 
00762   template<typename _Alloc>
00763     struct _Is_contiguous_sequence<std::__debug::vector<bool, _Alloc> >
00764     : std::__false_type
00765     { };
00766 }
00767 
00768 #endif