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_SAFE_ITERATOR_H
00032 #define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1
00033
00034 #include <debug/debug.h>
00035 #include <debug/macros.h>
00036 #include <debug/functions.h>
00037 #include <debug/formatter.h>
00038 #include <debug/safe_base.h>
00039 #include <bits/stl_pair.h>
00040 #include <bits/cpp_type_traits.h>
00041
00042 namespace __gnu_debug
00043 {
00044 using std::iterator_traits;
00045 using std::pair;
00046
00051 inline bool
00052 __check_singular_aux(const _Safe_iterator_base* __x)
00053 { return __x->_M_singular(); }
00054
00066 template<typename _Iterator, typename _Sequence>
00067 class _Safe_iterator : public _Safe_iterator_base
00068 {
00069 typedef _Safe_iterator _Self;
00070
00074 enum _Distance_precision
00075 {
00076 __dp_equality,
00077 __dp_sign,
00078 __dp_exact
00079 };
00080
00082 _Iterator _M_current;
00083
00085 bool
00086 _M_constant() const
00087 {
00088 typedef typename _Sequence::const_iterator const_iterator;
00089 return __is_same<const_iterator, _Safe_iterator>::value;
00090 }
00091
00092 typedef iterator_traits<_Iterator> _Traits;
00093
00094 public:
00095 typedef _Iterator _Base_iterator;
00096 typedef typename _Traits::iterator_category iterator_category;
00097 typedef typename _Traits::value_type value_type;
00098 typedef typename _Traits::difference_type difference_type;
00099 typedef typename _Traits::reference reference;
00100 typedef typename _Traits::pointer pointer;
00101
00103 _Safe_iterator() : _M_current() { }
00104
00112 _Safe_iterator(const _Iterator& __i, const _Sequence* __seq)
00113 : _Safe_iterator_base(__seq, _M_constant()), _M_current(__i)
00114 {
00115 _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
00116 _M_message(__msg_init_singular)
00117 ._M_iterator(*this, "this"));
00118 }
00119
00124 _Safe_iterator(const _Safe_iterator& __x)
00125 : _Safe_iterator_base(__x, _M_constant()), _M_current(__x._M_current)
00126 {
00127 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(),
00128 _M_message(__msg_init_copy_singular)
00129 ._M_iterator(*this, "this")
00130 ._M_iterator(__x, "other"));
00131 }
00132
00139 template<typename _MutableIterator>
00140 _Safe_iterator(
00141 const _Safe_iterator<_MutableIterator,
00142 typename std::__enable_if<
00143 _Sequence,
00144 (std::__are_same<_MutableIterator,
00145 typename _Sequence::iterator::_Base_iterator>::__value)
00146 >::__type>& __x)
00147 : _Safe_iterator_base(__x, _M_constant()), _M_current(__x.base())
00148 {
00149 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(),
00150 _M_message(__msg_init_const_singular)
00151 ._M_iterator(*this, "this")
00152 ._M_iterator(__x, "other"));
00153 }
00154
00159 _Safe_iterator&
00160 operator=(const _Safe_iterator& __x)
00161 {
00162 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(),
00163 _M_message(__msg_copy_singular)
00164 ._M_iterator(*this, "this")
00165 ._M_iterator(__x, "other"));
00166 _M_current = __x._M_current;
00167 this->_M_attach(static_cast<_Sequence*>(__x._M_sequence));
00168 return *this;
00169 }
00170
00175 reference
00176 operator*() const
00177 {
00178
00179 _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
00180 _M_message(__msg_bad_deref)
00181 ._M_iterator(*this, "this"));
00182 return *_M_current;
00183 }
00184
00191 pointer
00192 operator->() const
00193 {
00194 _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
00195 _M_message(__msg_bad_deref)
00196 ._M_iterator(*this, "this"));
00197 return &*_M_current;
00198 }
00199
00200
00205 _Safe_iterator&
00206 operator++()
00207 {
00208 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
00209 _M_message(__msg_bad_inc)
00210 ._M_iterator(*this, "this"));
00211 ++_M_current;
00212 return *this;
00213 }
00214
00219 _Safe_iterator
00220 operator++(int)
00221 {
00222 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
00223 _M_message(__msg_bad_inc)
00224 ._M_iterator(*this, "this"));
00225 _Safe_iterator __tmp(*this);
00226 ++_M_current;
00227 return __tmp;
00228 }
00229
00230
00235 _Safe_iterator&
00236 operator--()
00237 {
00238 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
00239 _M_message(__msg_bad_dec)
00240 ._M_iterator(*this, "this"));
00241 --_M_current;
00242 return *this;
00243 }
00244
00249 _Safe_iterator
00250 operator--(int)
00251 {
00252 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
00253 _M_message(__msg_bad_dec)
00254 ._M_iterator(*this, "this"));
00255 _Safe_iterator __tmp(*this);
00256 --_M_current;
00257 return __tmp;
00258 }
00259
00260
00261 reference
00262 operator[](const difference_type& __n) const
00263 {
00264 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
00265 && this->_M_can_advance(__n+1),
00266 _M_message(__msg_iter_subscript_oob)
00267 ._M_iterator(*this)._M_integer(__n));
00268
00269 return _M_current[__n];
00270 }
00271
00272 _Safe_iterator&
00273 operator+=(const difference_type& __n)
00274 {
00275 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
00276 _M_message(__msg_advance_oob)
00277 ._M_iterator(*this)._M_integer(__n));
00278 _M_current += __n;
00279 return *this;
00280 }
00281
00282 _Safe_iterator
00283 operator+(const difference_type& __n) const
00284 {
00285 _Safe_iterator __tmp(*this);
00286 __tmp += __n;
00287 return __tmp;
00288 }
00289
00290 _Safe_iterator&
00291 operator-=(const difference_type& __n)
00292 {
00293 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
00294 _M_message(__msg_retreat_oob)
00295 ._M_iterator(*this)._M_integer(__n));
00296 _M_current += -__n;
00297 return *this;
00298 }
00299
00300 _Safe_iterator
00301 operator-(const difference_type& __n) const
00302 {
00303 _Safe_iterator __tmp(*this);
00304 __tmp -= __n;
00305 return __tmp;
00306 }
00307
00308
00312 _Iterator
00313 base() const { return _M_current; }
00314
00319 operator _Iterator() const { return _M_current; }
00320
00322 void
00323 _M_attach(const _Sequence* __seq)
00324 {
00325 _Safe_iterator_base::_M_attach(const_cast<_Sequence*>(__seq),
00326 _M_constant());
00327 }
00328
00330 void
00331 _M_invalidate();
00332
00334 bool
00335 _M_dereferenceable() const
00336 { return !this->_M_singular() && !_M_is_end(); }
00337
00339 bool
00340 _M_incrementable() const { return this->_M_dereferenceable(); }
00341
00342
00343 bool
00344 _M_decrementable() const { return !_M_singular() && !_M_is_begin(); }
00345
00346
00347 bool
00348 _M_can_advance(const difference_type& __n) const;
00349
00350
00351 template<typename _Other>
00352 bool
00353 _M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const;
00354
00355
00356 const _Sequence*
00357 _M_get_sequence() const
00358 { return static_cast<const _Sequence*>(_M_sequence); }
00359
00363 template<typename _Iterator1, typename _Iterator2>
00364 static pair<difference_type, _Distance_precision>
00365 _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs)
00366 {
00367 typedef typename iterator_traits<_Iterator1>::iterator_category
00368 _Category;
00369 return _M_get_distance(__lhs, __rhs, _Category());
00370 }
00371
00372 template<typename _Iterator1, typename _Iterator2>
00373 static pair<difference_type, _Distance_precision>
00374 _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
00375 std::random_access_iterator_tag)
00376 {
00377 return std::make_pair(__rhs.base() - __lhs.base(), __dp_exact);
00378 }
00379
00380 template<typename _Iterator1, typename _Iterator2>
00381 static pair<difference_type, _Distance_precision>
00382 _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
00383 std::forward_iterator_tag)
00384 {
00385 return std::make_pair(__lhs.base() == __rhs.base()? 0 : 1,
00386 __dp_equality);
00387 }
00388
00390 bool _M_is_begin() const
00391 { return *this == static_cast<const _Sequence*>(_M_sequence)->begin(); }
00392
00394 bool _M_is_end() const
00395 { return *this == static_cast<const _Sequence*>(_M_sequence)->end(); }
00396 };
00397
00398 template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00399 inline bool
00400 operator==(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
00401 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
00402 {
00403 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00404 _M_message(__msg_iter_compare_bad)
00405 ._M_iterator(__lhs, "lhs")
00406 ._M_iterator(__rhs, "rhs"));
00407 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00408 _M_message(__msg_compare_different)
00409 ._M_iterator(__lhs, "lhs")
00410 ._M_iterator(__rhs, "rhs"));
00411 return __lhs.base() == __rhs.base();
00412 }
00413
00414 template<typename _Iterator, typename _Sequence>
00415 inline bool
00416 operator==(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
00417 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
00418 {
00419 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00420 _M_message(__msg_iter_compare_bad)
00421 ._M_iterator(__lhs, "lhs")
00422 ._M_iterator(__rhs, "rhs"));
00423 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00424 _M_message(__msg_compare_different)
00425 ._M_iterator(__lhs, "lhs")
00426 ._M_iterator(__rhs, "rhs"));
00427 return __lhs.base() == __rhs.base();
00428 }
00429
00430 template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00431 inline bool
00432 operator!=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
00433 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
00434 {
00435 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00436 _M_message(__msg_iter_compare_bad)
00437 ._M_iterator(__lhs, "lhs")
00438 ._M_iterator(__rhs, "rhs"));
00439 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00440 _M_message(__msg_compare_different)
00441 ._M_iterator(__lhs, "lhs")
00442 ._M_iterator(__rhs, "rhs"));
00443 return __lhs.base() != __rhs.base();
00444 }
00445
00446 template<typename _Iterator, typename _Sequence>
00447 inline bool
00448 operator!=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
00449 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
00450 {
00451 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00452 _M_message(__msg_iter_compare_bad)
00453 ._M_iterator(__lhs, "lhs")
00454 ._M_iterator(__rhs, "rhs"));
00455 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00456 _M_message(__msg_compare_different)
00457 ._M_iterator(__lhs, "lhs")
00458 ._M_iterator(__rhs, "rhs"));
00459 return __lhs.base() != __rhs.base();
00460 }
00461
00462 template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00463 inline bool
00464 operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
00465 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
00466 {
00467 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00468 _M_message(__msg_iter_order_bad)
00469 ._M_iterator(__lhs, "lhs")
00470 ._M_iterator(__rhs, "rhs"));
00471 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00472 _M_message(__msg_order_different)
00473 ._M_iterator(__lhs, "lhs")
00474 ._M_iterator(__rhs, "rhs"));
00475 return __lhs.base() < __rhs.base();
00476 }
00477
00478 template<typename _Iterator, typename _Sequence>
00479 inline bool
00480 operator<(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
00481 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
00482 {
00483 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00484 _M_message(__msg_iter_order_bad)
00485 ._M_iterator(__lhs, "lhs")
00486 ._M_iterator(__rhs, "rhs"));
00487 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00488 _M_message(__msg_order_different)
00489 ._M_iterator(__lhs, "lhs")
00490 ._M_iterator(__rhs, "rhs"));
00491 return __lhs.base() < __rhs.base();
00492 }
00493
00494 template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00495 inline bool
00496 operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
00497 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
00498 {
00499 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00500 _M_message(__msg_iter_order_bad)
00501 ._M_iterator(__lhs, "lhs")
00502 ._M_iterator(__rhs, "rhs"));
00503 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00504 _M_message(__msg_order_different)
00505 ._M_iterator(__lhs, "lhs")
00506 ._M_iterator(__rhs, "rhs"));
00507 return __lhs.base() <= __rhs.base();
00508 }
00509
00510 template<typename _Iterator, typename _Sequence>
00511 inline bool
00512 operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
00513 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
00514 {
00515 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00516 _M_message(__msg_iter_order_bad)
00517 ._M_iterator(__lhs, "lhs")
00518 ._M_iterator(__rhs, "rhs"));
00519 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00520 _M_message(__msg_order_different)
00521 ._M_iterator(__lhs, "lhs")
00522 ._M_iterator(__rhs, "rhs"));
00523 return __lhs.base() <= __rhs.base();
00524 }
00525
00526 template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00527 inline bool
00528 operator>(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
00529 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
00530 {
00531 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00532 _M_message(__msg_iter_order_bad)
00533 ._M_iterator(__lhs, "lhs")
00534 ._M_iterator(__rhs, "rhs"));
00535 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00536 _M_message(__msg_order_different)
00537 ._M_iterator(__lhs, "lhs")
00538 ._M_iterator(__rhs, "rhs"));
00539 return __lhs.base() > __rhs.base();
00540 }
00541
00542 template<typename _Iterator, typename _Sequence>
00543 inline bool
00544 operator>(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
00545 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
00546 {
00547 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00548 _M_message(__msg_iter_order_bad)
00549 ._M_iterator(__lhs, "lhs")
00550 ._M_iterator(__rhs, "rhs"));
00551 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00552 _M_message(__msg_order_different)
00553 ._M_iterator(__lhs, "lhs")
00554 ._M_iterator(__rhs, "rhs"));
00555 return __lhs.base() > __rhs.base();
00556 }
00557
00558 template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00559 inline bool
00560 operator>=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
00561 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
00562 {
00563 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00564 _M_message(__msg_iter_order_bad)
00565 ._M_iterator(__lhs, "lhs")
00566 ._M_iterator(__rhs, "rhs"));
00567 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00568 _M_message(__msg_order_different)
00569 ._M_iterator(__lhs, "lhs")
00570 ._M_iterator(__rhs, "rhs"));
00571 return __lhs.base() >= __rhs.base();
00572 }
00573
00574 template<typename _Iterator, typename _Sequence>
00575 inline bool
00576 operator>=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
00577 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
00578 {
00579 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00580 _M_message(__msg_iter_order_bad)
00581 ._M_iterator(__lhs, "lhs")
00582 ._M_iterator(__rhs, "rhs"));
00583 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00584 _M_message(__msg_order_different)
00585 ._M_iterator(__lhs, "lhs")
00586 ._M_iterator(__rhs, "rhs"));
00587 return __lhs.base() >= __rhs.base();
00588 }
00589
00590
00591
00592
00593
00594 template<typename _IteratorL, typename _IteratorR, typename _Sequence>
00595 inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type
00596 operator-(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
00597 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
00598 {
00599 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
00600 _M_message(__msg_distance_bad)
00601 ._M_iterator(__lhs, "lhs")
00602 ._M_iterator(__rhs, "rhs"));
00603 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
00604 _M_message(__msg_distance_different)
00605 ._M_iterator(__lhs, "lhs")
00606 ._M_iterator(__rhs, "rhs"));
00607 return __lhs.base() - __rhs.base();
00608 }
00609
00610 template<typename _Iterator, typename _Sequence>
00611 inline _Safe_iterator<_Iterator, _Sequence>
00612 operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n,
00613 const _Safe_iterator<_Iterator, _Sequence>& __i)
00614 { return __i + __n; }
00615 }
00616
00617 #ifndef _GLIBCXX_EXPORT_TEMPLATE
00618 # include <debug/safe_iterator.tcc>
00619 #endif
00620
00621 #endif