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 #ifndef _GLIBCXX_DEBUG_DEQUE
00031 #define _GLIBCXX_DEBUG_DEQUE 1
00032
00033 #include <deque>
00034 #include <debug/safe_sequence.h>
00035 #include <debug/safe_iterator.h>
00036
00037 namespace std
00038 {
00039 namespace __debug
00040 {
00041
00042 template<typename _Tp, typename _Allocator = std::allocator<_Tp> >
00043 class deque
00044 : public _GLIBCXX_STD_D::deque<_Tp, _Allocator>,
00045 public __gnu_debug::_Safe_sequence<deque<_Tp, _Allocator> >
00046 {
00047 typedef _GLIBCXX_STD_D::deque<_Tp, _Allocator> _Base;
00048 typedef __gnu_debug::_Safe_sequence<deque> _Safe_base;
00049
00050 public:
00051 typedef typename _Base::reference reference;
00052 typedef typename _Base::const_reference const_reference;
00053
00054 typedef __gnu_debug::_Safe_iterator<typename _Base::iterator,deque>
00055 iterator;
00056 typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator,deque>
00057 const_iterator;
00058
00059 typedef typename _Base::size_type size_type;
00060 typedef typename _Base::difference_type difference_type;
00061
00062 typedef _Tp value_type;
00063 typedef _Allocator allocator_type;
00064 typedef typename _Base::pointer pointer;
00065 typedef typename _Base::const_pointer const_pointer;
00066 typedef std::reverse_iterator<iterator> reverse_iterator;
00067 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
00068
00069
00070 explicit deque(const _Allocator& __a = _Allocator())
00071 : _Base(__a) { }
00072
00073 explicit deque(size_type __n, const _Tp& __value = _Tp(),
00074 const _Allocator& __a = _Allocator())
00075 : _Base(__n, __value, __a) { }
00076
00077 template<class _InputIterator>
00078 deque(_InputIterator __first, _InputIterator __last,
00079 const _Allocator& __a = _Allocator())
00080 : _Base(__gnu_debug::__check_valid_range(__first, __last), __last, __a)
00081 { }
00082
00083 deque(const deque& __x)
00084 : _Base(__x), _Safe_base() { }
00085
00086 deque(const _Base& __x)
00087 : _Base(__x), _Safe_base() { }
00088
00089 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00090 deque(deque&& __x)
00091 : _Base(std::forward<deque>(__x)), _Safe_base()
00092 { this->_M_swap(__x); }
00093
00094 deque(initializer_list<value_type> __l,
00095 const allocator_type& __a = allocator_type())
00096 : _Base(__l, __a), _Safe_base() { }
00097 #endif
00098
00099 ~deque() { }
00100
00101 deque&
00102 operator=(const deque& __x)
00103 {
00104 *static_cast<_Base*>(this) = __x;
00105 this->_M_invalidate_all();
00106 return *this;
00107 }
00108
00109 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00110 deque&
00111 operator=(deque&& __x)
00112 {
00113
00114
00115 clear();
00116 swap(__x);
00117 return *this;
00118 }
00119
00120 deque&
00121 operator=(initializer_list<value_type> __l)
00122 {
00123 *static_cast<_Base*>(this) = __l;
00124 this->_M_invalidate_all();
00125 return *this;
00126 }
00127 #endif
00128
00129 template<class _InputIterator>
00130 void
00131 assign(_InputIterator __first, _InputIterator __last)
00132 {
00133 __glibcxx_check_valid_range(__first, __last);
00134 _Base::assign(__first, __last);
00135 this->_M_invalidate_all();
00136 }
00137
00138 void
00139 assign(size_type __n, const _Tp& __t)
00140 {
00141 _Base::assign(__n, __t);
00142 this->_M_invalidate_all();
00143 }
00144
00145 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00146 void
00147 assign(initializer_list<value_type> __l)
00148 {
00149 _Base::assign(__l);
00150 this->_M_invalidate_all();
00151 }
00152 #endif
00153
00154 using _Base::get_allocator;
00155
00156
00157 iterator
00158 begin()
00159 { return iterator(_Base::begin(), this); }
00160
00161 const_iterator
00162 begin() const
00163 { return const_iterator(_Base::begin(), this); }
00164
00165 iterator
00166 end()
00167 { return iterator(_Base::end(), this); }
00168
00169 const_iterator
00170 end() const
00171 { return const_iterator(_Base::end(), this); }
00172
00173 reverse_iterator
00174 rbegin()
00175 { return reverse_iterator(end()); }
00176
00177 const_reverse_iterator
00178 rbegin() const
00179 { return const_reverse_iterator(end()); }
00180
00181 reverse_iterator
00182 rend()
00183 { return reverse_iterator(begin()); }
00184
00185 const_reverse_iterator
00186 rend() const
00187 { return const_reverse_iterator(begin()); }
00188
00189 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00190 const_iterator
00191 cbegin() const
00192 { return const_iterator(_Base::begin(), this); }
00193
00194 const_iterator
00195 cend() const
00196 { return const_iterator(_Base::end(), this); }
00197
00198 const_reverse_iterator
00199 crbegin() const
00200 { return const_reverse_iterator(end()); }
00201
00202 const_reverse_iterator
00203 crend() const
00204 { return const_reverse_iterator(begin()); }
00205 #endif
00206
00207
00208 using _Base::size;
00209 using _Base::max_size;
00210
00211 void
00212 resize(size_type __sz, _Tp __c = _Tp())
00213 {
00214 typedef typename _Base::const_iterator _Base_const_iterator;
00215 typedef __gnu_debug::_After_nth_from<_Base_const_iterator> _After_nth;
00216
00217 bool __invalidate_all = __sz > this->size();
00218 if (__sz < this->size())
00219 this->_M_invalidate_if(_After_nth(__sz, _M_base().begin()));
00220
00221 _Base::resize(__sz, __c);
00222
00223 if (__invalidate_all)
00224 this->_M_invalidate_all();
00225 }
00226
00227 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00228 using _Base::shrink_to_fit;
00229 #endif
00230
00231 using _Base::empty;
00232
00233
00234 reference
00235 operator[](size_type __n)
00236 {
00237 __glibcxx_check_subscript(__n);
00238 return _M_base()[__n];
00239 }
00240
00241 const_reference
00242 operator[](size_type __n) const
00243 {
00244 __glibcxx_check_subscript(__n);
00245 return _M_base()[__n];
00246 }
00247
00248 using _Base::at;
00249
00250 reference
00251 front()
00252 {
00253 __glibcxx_check_nonempty();
00254 return _Base::front();
00255 }
00256
00257 const_reference
00258 front() const
00259 {
00260 __glibcxx_check_nonempty();
00261 return _Base::front();
00262 }
00263
00264 reference
00265 back()
00266 {
00267 __glibcxx_check_nonempty();
00268 return _Base::back();
00269 }
00270
00271 const_reference
00272 back() const
00273 {
00274 __glibcxx_check_nonempty();
00275 return _Base::back();
00276 }
00277
00278
00279 void
00280 push_front(const _Tp& __x)
00281 {
00282 _Base::push_front(__x);
00283 this->_M_invalidate_all();
00284 }
00285
00286 void
00287 push_back(const _Tp& __x)
00288 {
00289 _Base::push_back(__x);
00290 this->_M_invalidate_all();
00291 }
00292
00293 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00294 void
00295 push_front(_Tp&& __x)
00296 { emplace_front(std::move(__x)); }
00297
00298 void
00299 push_back(_Tp&& __x)
00300 { emplace_back(std::move(__x)); }
00301
00302 template<typename... _Args>
00303 void
00304 emplace_front(_Args&&... __args)
00305 {
00306 _Base::emplace_front(std::forward<_Args>(__args)...);
00307 this->_M_invalidate_all();
00308 }
00309
00310 template<typename... _Args>
00311 void
00312 emplace_back(_Args&&... __args)
00313 {
00314 _Base::emplace_back(std::forward<_Args>(__args)...);
00315 this->_M_invalidate_all();
00316 }
00317
00318 template<typename... _Args>
00319 iterator
00320 emplace(iterator __position, _Args&&... __args)
00321 {
00322 __glibcxx_check_insert(__position);
00323 typename _Base::iterator __res = _Base::emplace(__position.base(),
00324 std::forward<_Args>(__args)...);
00325 this->_M_invalidate_all();
00326 return iterator(__res, this);
00327 }
00328 #endif
00329
00330 iterator
00331 insert(iterator __position, const _Tp& __x)
00332 {
00333 __glibcxx_check_insert(__position);
00334 typename _Base::iterator __res = _Base::insert(__position.base(), __x);
00335 this->_M_invalidate_all();
00336 return iterator(__res, this);
00337 }
00338
00339 #ifdef __GXX_EXPERIMENTAL_CXX0X__
00340 iterator
00341 insert(iterator __position, _Tp&& __x)
00342 { return emplace(__position, std::move(__x)); }
00343
00344 void
00345 insert(iterator __p, initializer_list<value_type> __l)
00346 {
00347 _Base::insert(__p, __l);
00348 this->_M_invalidate_all();
00349 }
00350 #endif
00351
00352 void
00353 insert(iterator __position, size_type __n, const _Tp& __x)
00354 {
00355 __glibcxx_check_insert(__position);
00356 _Base::insert(__position.base(), __n, __x);
00357 this->_M_invalidate_all();
00358 }
00359
00360 template<class _InputIterator>
00361 void
00362 insert(iterator __position,
00363 _InputIterator __first, _InputIterator __last)
00364 {
00365 __glibcxx_check_insert_range(__position, __first, __last);
00366 _Base::insert(__position.base(), __first, __last);
00367 this->_M_invalidate_all();
00368 }
00369
00370 void
00371 pop_front()
00372 {
00373 __glibcxx_check_nonempty();
00374 iterator __victim = begin();
00375 __victim._M_invalidate();
00376 _Base::pop_front();
00377 }
00378
00379 void
00380 pop_back()
00381 {
00382 __glibcxx_check_nonempty();
00383 iterator __victim = end();
00384 --__victim;
00385 __victim._M_invalidate();
00386 _Base::pop_back();
00387 }
00388
00389 iterator
00390 erase(iterator __position)
00391 {
00392 __glibcxx_check_erase(__position);
00393 if (__position == begin() || __position == end()-1)
00394 {
00395 __position._M_invalidate();
00396 return iterator(_Base::erase(__position.base()), this);
00397 }
00398 else
00399 {
00400 typename _Base::iterator __res = _Base::erase(__position.base());
00401 this->_M_invalidate_all();
00402 return iterator(__res, this);
00403 }
00404 }
00405
00406 iterator
00407 erase(iterator __first, iterator __last)
00408 {
00409
00410
00411 __glibcxx_check_erase_range(__first, __last);
00412 if (__first == begin() || __last == end())
00413 {
00414 this->_M_detach_singular();
00415 for (iterator __position = __first; __position != __last; )
00416 {
00417 iterator __victim = __position++;
00418 __victim._M_invalidate();
00419 }
00420 __try
00421 {
00422 return iterator(_Base::erase(__first.base(), __last.base()),
00423 this);
00424 }
00425 __catch(...)
00426 {
00427 this->_M_revalidate_singular();
00428 __throw_exception_again;
00429 }
00430 }
00431 else
00432 {
00433 typename _Base::iterator __res = _Base::erase(__first.base(),
00434 __last.base());
00435 this->_M_invalidate_all();
00436 return iterator(__res, this);
00437 }
00438 }
00439
00440 void
00441 swap(deque& __x)
00442 {
00443 _Base::swap(__x);
00444 this->_M_swap(__x);
00445 }
00446
00447 void
00448 clear()
00449 {
00450 _Base::clear();
00451 this->_M_invalidate_all();
00452 }
00453
00454 _Base&
00455 _M_base() { return *this; }
00456
00457 const _Base&
00458 _M_base() const { return *this; }
00459 };
00460
00461 template<typename _Tp, typename _Alloc>
00462 inline bool
00463 operator==(const deque<_Tp, _Alloc>& __lhs,
00464 const deque<_Tp, _Alloc>& __rhs)
00465 { return __lhs._M_base() == __rhs._M_base(); }
00466
00467 template<typename _Tp, typename _Alloc>
00468 inline bool
00469 operator!=(const deque<_Tp, _Alloc>& __lhs,
00470 const deque<_Tp, _Alloc>& __rhs)
00471 { return __lhs._M_base() != __rhs._M_base(); }
00472
00473 template<typename _Tp, typename _Alloc>
00474 inline bool
00475 operator<(const deque<_Tp, _Alloc>& __lhs,
00476 const deque<_Tp, _Alloc>& __rhs)
00477 { return __lhs._M_base() < __rhs._M_base(); }
00478
00479 template<typename _Tp, typename _Alloc>
00480 inline bool
00481 operator<=(const deque<_Tp, _Alloc>& __lhs,
00482 const deque<_Tp, _Alloc>& __rhs)
00483 { return __lhs._M_base() <= __rhs._M_base(); }
00484
00485 template<typename _Tp, typename _Alloc>
00486 inline bool
00487 operator>=(const deque<_Tp, _Alloc>& __lhs,
00488 const deque<_Tp, _Alloc>& __rhs)
00489 { return __lhs._M_base() >= __rhs._M_base(); }
00490
00491 template<typename _Tp, typename _Alloc>
00492 inline bool
00493 operator>(const deque<_Tp, _Alloc>& __lhs,
00494 const deque<_Tp, _Alloc>& __rhs)
00495 { return __lhs._M_base() > __rhs._M_base(); }
00496
00497 template<typename _Tp, typename _Alloc>
00498 inline void
00499 swap(deque<_Tp, _Alloc>& __lhs, deque<_Tp, _Alloc>& __rhs)
00500 { __lhs.swap(__rhs); }
00501
00502 }
00503 }
00504
00505 #endif