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