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