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