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