00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 #ifndef _GLIBCXX_DEBUG_DEQUE
00032 #define _GLIBCXX_DEBUG_DEQUE 1
00033 
00034 #include <deque>
00035 #include <debug/safe_sequence.h>
00036 #include <debug/safe_iterator.h>
00037 
00038 namespace __gnu_debug_def
00039 {
00040   template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
00041     class deque
00042     : public _GLIBCXX_STD::deque<_Tp, _Allocator>,
00043       public __gnu_debug::_Safe_sequence<deque<_Tp, _Allocator> >
00044     {
00045       typedef  _GLIBCXX_STD::deque<_Tp, _Allocator> _Base;
00046       typedef __gnu_debug::_Safe_sequence<deque> _Safe_base;
00047 
00048     public:
00049       typedef typename _Base::reference             reference;
00050       typedef typename _Base::const_reference       const_reference;
00051 
00052       typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,deque>
00053                             iterator;
00054       typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,deque>
00055                              const_iterator;
00056 
00057       typedef typename _Base::size_type             size_type;
00058       typedef typename _Base::difference_type       difference_type;
00059 
00060       typedef _Tp                   value_type;
00061       typedef _Allocator                allocator_type;
00062       typedef typename _Base::pointer               pointer;
00063       typedef typename _Base::const_pointer         const_pointer;
00064       typedef std::reverse_iterator<iterator>       reverse_iterator;
00065       typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00066 
00067       
00068       explicit deque(const _Allocator& __a = _Allocator())
00069       : _Base(__a) { }
00070 
00071       explicit deque(size_type __n, const _Tp& __value = _Tp(),
00072              const _Allocator& __a = _Allocator())
00073       : _Base(__n, __value, __a) { }
00074 
00075       template<class _InputIterator>
00076         deque(_InputIterator __first, _InputIterator __last,
00077           const _Allocator& __a = _Allocator())
00078     : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, __a)
00079         { }
00080 
00081       deque(const deque<_Tp,_Allocator>& __x) : _Base(__x), _Safe_base() { }
00082 
00083       deque(const _Base& __x) : _Base(__x), _Safe_base() { }
00084 
00085       ~deque() { }
00086 
00087       deque<_Tp,_Allocator>&
00088       operator=(const deque<_Tp,_Allocator>& __x)
00089       {
00090     *static_cast<_Base*>(this) = __x;
00091     this->_M_invalidate_all();
00092     return *this;
00093       }
00094 
00095       template<class _InputIterator>
00096         void
00097         assign(_InputIterator __first, _InputIterator __last)
00098         {
00099       __glibcxx_check_valid_range(__first, __last);
00100       _Base::assign(__first, __last);
00101       this->_M_invalidate_all();
00102     }
00103 
00104       void
00105       assign(size_type __n, const _Tp& __t)
00106       {
00107     _Base::assign(__n, __t);
00108     this->_M_invalidate_all();
00109       }
00110 
00111       using _Base::get_allocator;
00112 
00113       
00114       iterator
00115       begin()
00116       { return iterator(_Base::begin(), this); }
00117 
00118       const_iterator
00119       begin() const
00120       { return const_iterator(_Base::begin(), this); }
00121 
00122       iterator
00123       end()
00124       { return iterator(_Base::end(), this); }
00125 
00126       const_iterator
00127       end() const
00128       { return const_iterator(_Base::end(), this); }
00129 
00130       reverse_iterator
00131       rbegin()
00132       { return reverse_iterator(end()); }
00133 
00134       const_reverse_iterator
00135       rbegin() const
00136       { return const_reverse_iterator(end()); }
00137 
00138       reverse_iterator
00139       rend()
00140       { return reverse_iterator(begin()); }
00141 
00142       const_reverse_iterator
00143       rend() const
00144       { return const_reverse_iterator(begin()); }
00145 
00146       
00147       using _Base::size;
00148       using _Base::max_size;
00149 
00150       void
00151       resize(size_type __sz, _Tp __c = _Tp())
00152       {
00153     typedef typename _Base::const_iterator _Base_const_iterator;
00154     typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
00155 
00156     bool __invalidate_all = __sz > this->size();
00157     if (__sz < this->size())
00158       this->_M_invalidate_if(_After_nth(__sz, _M_base().begin()));
00159 
00160     _Base::resize(__sz, __c);
00161 
00162     if (__invalidate_all)
00163       this->_M_invalidate_all();
00164       }
00165 
00166       using _Base::empty;
00167 
00168       
00169       reference
00170       operator[](size_type __n)
00171       {
00172     __glibcxx_check_subscript(__n);
00173     return _M_base()[__n];
00174       }
00175 
00176       const_reference
00177       operator[](size_type __n) const
00178       {
00179     __glibcxx_check_subscript(__n);
00180     return _M_base()[__n];
00181       }
00182 
00183       using _Base::at;
00184 
00185       reference
00186       front()
00187       {
00188     __glibcxx_check_nonempty();
00189     return _Base::front();
00190       }
00191 
00192       const_reference
00193       front() const
00194       {
00195     __glibcxx_check_nonempty();
00196     return _Base::front();
00197       }
00198 
00199       reference
00200       back()
00201       {
00202     __glibcxx_check_nonempty();
00203     return _Base::back();
00204       }
00205 
00206       const_reference
00207       back() const
00208       {
00209     __glibcxx_check_nonempty();
00210     return _Base::back();
00211       }
00212 
00213       
00214       void
00215       push_front(const _Tp& __x)
00216       {
00217     _Base::push_front(__x);
00218     this->_M_invalidate_all();
00219       }
00220 
00221       void
00222       push_back(const _Tp& __x)
00223       {
00224     _Base::push_back(__x);
00225     this->_M_invalidate_all();
00226       }
00227 
00228       iterator
00229       insert(iterator __position, const _Tp& __x)
00230       {
00231     __glibcxx_check_insert(__position);
00232     typename _Base::iterator __res = _Base::insert(__position.base(), __x);
00233     this->_M_invalidate_all();
00234     return iterator(__res, this);
00235       }
00236 
00237       void
00238       insert(iterator __position, size_type __n, const _Tp& __x)
00239       {
00240     __glibcxx_check_insert(__position);
00241     _Base::insert(__position.base(), __n, __x);
00242     this->_M_invalidate_all();
00243       }
00244 
00245       template<class _InputIterator>
00246         void
00247         insert(iterator __position,
00248            _InputIterator __first, _InputIterator __last)
00249         {
00250       __glibcxx_check_insert_range(__position, __first, __last);
00251       _Base::insert(__position.base(), __first, __last);
00252       this->_M_invalidate_all();
00253     }
00254 
00255       void
00256       pop_front()
00257       {
00258     __glibcxx_check_nonempty();
00259     iterator __victim = begin();
00260     __victim._M_invalidate();
00261     _Base::pop_front();
00262       }
00263 
00264       void
00265       pop_back()
00266       {
00267     __glibcxx_check_nonempty();
00268     iterator __victim = end();
00269     --__victim;
00270     __victim._M_invalidate();
00271     _Base::pop_back();
00272       }
00273 
00274       iterator
00275       erase(iterator __position)
00276       {
00277     __glibcxx_check_erase(__position);
00278     if (__position == begin() || __position == end()-1)
00279       {
00280         __position._M_invalidate();
00281         return iterator(_Base::erase(__position.base()), this);
00282       }
00283     else
00284       {
00285         typename _Base::iterator __res = _Base::erase(__position.base());
00286         this->_M_invalidate_all();
00287         return iterator(__res, this);
00288       }
00289       }
00290 
00291       iterator
00292       erase(iterator __first, iterator __last)
00293       {
00294     
00295     
00296     __glibcxx_check_erase_range(__first, __last);
00297         if (__first == begin() || __last == end())
00298       {
00299         this->_M_detach_singular();
00300         for (iterator __position = __first; __position != __last; )
00301           {
00302         iterator __victim = __position++;
00303         __victim._M_invalidate();
00304           }
00305         try
00306           {
00307         return iterator(_Base::erase(__first.base(), __last.base()),
00308                 this);
00309           }
00310         catch (...)
00311           {
00312         this->_M_revalidate_singular();
00313         __throw_exception_again;
00314           }
00315       }
00316     else
00317       {
00318         typename _Base::iterator __res = _Base::erase(__first.base(),
00319                               __last.base());
00320         this->_M_invalidate_all();
00321         return iterator(__res, this);
00322       }
00323       }
00324 
00325       void
00326       swap(deque<_Tp,_Allocator>& __x)
00327       {
00328     _Base::swap(__x);
00329     this->_M_swap(__x);
00330       }
00331 
00332       void
00333       clear()
00334       {
00335     _Base::clear();
00336     this->_M_invalidate_all();
00337       }
00338 
00339       _Base&
00340       _M_base()       { return *this; }
00341 
00342       const _Base&
00343       _M_base() const { return *this; }
00344     };
00345 
00346   template<typename _Tp, typename _Alloc>
00347     inline bool
00348     operator==(const deque<_Tp, _Alloc>& __lhs,
00349            const deque<_Tp, _Alloc>& __rhs)
00350     { return __lhs._M_base() == __rhs._M_base(); }
00351 
00352   template<typename _Tp, typename _Alloc>
00353     inline bool
00354     operator!=(const deque<_Tp, _Alloc>& __lhs,
00355            const deque<_Tp, _Alloc>& __rhs)
00356     { return __lhs._M_base() != __rhs._M_base(); }
00357 
00358   template<typename _Tp, typename _Alloc>
00359     inline bool
00360     operator<(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs)
00361     { return __lhs._M_base() < __rhs._M_base(); }
00362 
00363   template<typename _Tp, typename _Alloc>
00364     inline bool
00365     operator<=(const deque<_Tp, _Alloc>& __lhs,
00366            const deque<_Tp, _Alloc>& __rhs)
00367     { return __lhs._M_base() <= __rhs._M_base(); }
00368 
00369   template<typename _Tp, typename _Alloc>
00370     inline bool
00371     operator>=(const deque<_Tp, _Alloc>& __lhs,
00372            const deque<_Tp, _Alloc>& __rhs)
00373     { return __lhs._M_base() >= __rhs._M_base(); }
00374 
00375   template<typename _Tp, typename _Alloc>
00376     inline bool
00377     operator>(const deque<_Tp, _Alloc>& __lhs, const deque<_Tp, _Alloc>& __rhs)
00378     { return __lhs._M_base() > __rhs._M_base(); }
00379 
00380   template<typename _Tp, typename _Alloc>
00381     inline void
00382     swap(deque<_Tp, _Alloc>& __lhs, deque<_Tp, _Alloc>& __rhs)
00383     { __lhs.swap(__rhs); }
00384 } 
00385 
00386 #endif