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