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