libstdc++
safe_iterator.h
Go to the documentation of this file.
1 // Safe iterator implementation -*- C++ -*-
2 
3 // Copyright (C) 2003, 2004, 2005, 2006, 2009
4 // Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library. This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 3, or (at your option)
10 // any later version.
11 
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 
17 // Under Section 7 of GPL version 3, you are granted additional
18 // permissions described in the GCC Runtime Library Exception, version
19 // 3.1, as published by the Free Software Foundation.
20 
21 // You should have received a copy of the GNU General Public License and
22 // a copy of the GCC Runtime Library Exception along with this program;
23 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 // <http://www.gnu.org/licenses/>.
25 
26 /** @file debug/safe_iterator.h
27  * This file is a GNU debug extension to the Standard C++ Library.
28  */
29 
30 #ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H
31 #define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1
32 
33 #include <debug/debug.h>
34 #include <debug/macros.h>
35 #include <debug/functions.h>
36 #include <debug/formatter.h>
37 #include <debug/safe_base.h>
38 #include <bits/stl_pair.h>
39 #include <ext/type_traits.h>
40 
41 namespace __gnu_debug
42 {
43  /** Iterators that derive from _Safe_iterator_base but that aren't
44  * _Safe_iterators can be determined singular or non-singular via
45  * _Safe_iterator_base.
46  */
47  inline bool
48  __check_singular_aux(const _Safe_iterator_base* __x)
49  { return __x->_M_singular(); }
50 
51  /** \brief Safe iterator wrapper.
52  *
53  * The class template %_Safe_iterator is a wrapper around an
54  * iterator that tracks the iterator's movement among sequences and
55  * checks that operations performed on the "safe" iterator are
56  * legal. In additional to the basic iterator operations (which are
57  * validated, and then passed to the underlying iterator),
58  * %_Safe_iterator has member functions for iterator invalidation,
59  * attaching/detaching the iterator from sequences, and querying
60  * the iterator's state.
61  */
62  template<typename _Iterator, typename _Sequence>
63  class _Safe_iterator : public _Safe_iterator_base
64  {
65  typedef _Safe_iterator _Self;
66 
67  /** The precision to which we can calculate the distance between
68  * two iterators.
69  */
70  enum _Distance_precision
71  {
72  __dp_equality, //< Can compare iterator equality, only
73  __dp_sign, //< Can determine equality and ordering
74  __dp_exact //< Can determine distance precisely
75  };
76 
77  /// The underlying iterator
78  _Iterator _M_current;
79 
80  /// Determine if this is a constant iterator.
81  bool
82  _M_constant() const
83  {
84  typedef typename _Sequence::const_iterator const_iterator;
85  return __is_same<const_iterator, _Safe_iterator>::value;
86  }
87 
88  typedef std::iterator_traits<_Iterator> _Traits;
89 
90  public:
91  typedef _Iterator _Base_iterator;
92  typedef typename _Traits::iterator_category iterator_category;
93  typedef typename _Traits::value_type value_type;
94  typedef typename _Traits::difference_type difference_type;
95  typedef typename _Traits::reference reference;
96  typedef typename _Traits::pointer pointer;
97 
98  /// @post the iterator is singular and unattached
99  _Safe_iterator() : _M_current() { }
100 
101  /**
102  * @brief Safe iterator construction from an unsafe iterator and
103  * its sequence.
104  *
105  * @pre @p seq is not NULL
106  * @post this is not singular
107  */
108  _Safe_iterator(const _Iterator& __i, const _Sequence* __seq)
109  : _Safe_iterator_base(__seq, _M_constant()), _M_current(__i)
110  {
112  _M_message(__msg_init_singular)
113  ._M_iterator(*this, "this"));
114  }
115 
116  /**
117  * @brief Copy construction.
118  * @pre @p x is not singular
119  */
121  : _Safe_iterator_base(__x, _M_constant()), _M_current(__x._M_current)
122  {
123  _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(),
124  _M_message(__msg_init_copy_singular)
125  ._M_iterator(*this, "this")
126  ._M_iterator(__x, "other"));
127  }
128 
129  /**
130  * @brief Converting constructor from a mutable iterator to a
131  * constant iterator.
132  *
133  * @pre @p x is not singular
134  */
135  template<typename _MutableIterator>
137  const _Safe_iterator<_MutableIterator,
138  typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator,
139  typename _Sequence::iterator::_Base_iterator>::__value),
140  _Sequence>::__type>& __x)
141  : _Safe_iterator_base(__x, _M_constant()), _M_current(__x.base())
142  {
143  _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(),
144  _M_message(__msg_init_const_singular)
145  ._M_iterator(*this, "this")
146  ._M_iterator(__x, "other"));
147  }
148 
149  /**
150  * @brief Copy assignment.
151  * @pre @p x is not singular
152  */
155  {
156  _GLIBCXX_DEBUG_VERIFY(!__x._M_singular(),
157  _M_message(__msg_copy_singular)
158  ._M_iterator(*this, "this")
159  ._M_iterator(__x, "other"));
160  _M_current = __x._M_current;
161  this->_M_attach(static_cast<_Sequence*>(__x._M_sequence));
162  return *this;
163  }
164 
165  /**
166  * @brief Iterator dereference.
167  * @pre iterator is dereferenceable
168  */
169  reference
170  operator*() const
171  {
172 
174  _M_message(__msg_bad_deref)
175  ._M_iterator(*this, "this"));
176  return *_M_current;
177  }
178 
179  /**
180  * @brief Iterator dereference.
181  * @pre iterator is dereferenceable
182  * @todo Make this correct w.r.t. iterators that return proxies
183  * @todo Use addressof() instead of & operator
184  */
185  pointer
186  operator->() const
187  {
189  _M_message(__msg_bad_deref)
190  ._M_iterator(*this, "this"));
191  return &*_M_current;
192  }
193 
194  // ------ Input iterator requirements ------
195  /**
196  * @brief Iterator preincrement
197  * @pre iterator is incrementable
198  */
201  {
203  _M_message(__msg_bad_inc)
204  ._M_iterator(*this, "this"));
205  ++_M_current;
206  return *this;
207  }
208 
209  /**
210  * @brief Iterator postincrement
211  * @pre iterator is incrementable
212  */
215  {
217  _M_message(__msg_bad_inc)
218  ._M_iterator(*this, "this"));
219  _Safe_iterator __tmp(*this);
220  ++_M_current;
221  return __tmp;
222  }
223 
224  // ------ Bidirectional iterator requirements ------
225  /**
226  * @brief Iterator predecrement
227  * @pre iterator is decrementable
228  */
231  {
232  _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
233  _M_message(__msg_bad_dec)
234  ._M_iterator(*this, "this"));
235  --_M_current;
236  return *this;
237  }
238 
239  /**
240  * @brief Iterator postdecrement
241  * @pre iterator is decrementable
242  */
245  {
246  _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
247  _M_message(__msg_bad_dec)
248  ._M_iterator(*this, "this"));
249  _Safe_iterator __tmp(*this);
250  --_M_current;
251  return __tmp;
252  }
253 
254  // ------ Random access iterator requirements ------
255  reference
256  operator[](const difference_type& __n) const
257  {
258  _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
259  && this->_M_can_advance(__n+1),
260  _M_message(__msg_iter_subscript_oob)
261  ._M_iterator(*this)._M_integer(__n));
262 
263  return _M_current[__n];
264  }
265 
267  operator+=(const difference_type& __n)
268  {
269  _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
270  _M_message(__msg_advance_oob)
271  ._M_iterator(*this)._M_integer(__n));
272  _M_current += __n;
273  return *this;
274  }
275 
277  operator+(const difference_type& __n) const
278  {
279  _Safe_iterator __tmp(*this);
280  __tmp += __n;
281  return __tmp;
282  }
283 
285  operator-=(const difference_type& __n)
286  {
287  _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
288  _M_message(__msg_retreat_oob)
289  ._M_iterator(*this)._M_integer(__n));
290  _M_current += -__n;
291  return *this;
292  }
293 
295  operator-(const difference_type& __n) const
296  {
297  _Safe_iterator __tmp(*this);
298  __tmp -= __n;
299  return __tmp;
300  }
301 
302  // ------ Utilities ------
303  /**
304  * @brief Return the underlying iterator
305  */
306  _Iterator
307  base() const { return _M_current; }
308 
309  /**
310  * @brief Conversion to underlying non-debug iterator to allow
311  * better interaction with non-debug containers.
312  */
313  operator _Iterator() const { return _M_current; }
314 
315  /** Attach iterator to the given sequence. */
316  void
317  _M_attach(const _Sequence* __seq)
318  {
319  _Safe_iterator_base::_M_attach(const_cast<_Sequence*>(__seq),
320  _M_constant());
321  }
322 
323  /** Likewise, but not thread-safe. */
324  void
325  _M_attach_single(const _Sequence* __seq)
326  {
327  _Safe_iterator_base::_M_attach_single(const_cast<_Sequence*>(__seq),
328  _M_constant());
329  }
330 
331  /** Invalidate the iterator, making it singular. */
332  void
333  _M_invalidate();
334 
335  /** Likewise, but not thread-safe. */
336  void
338 
339  /// Is the iterator dereferenceable?
340  bool
342  { return !this->_M_singular() && !_M_is_end(); }
343 
344  /// Is the iterator incrementable?
345  bool
346  _M_incrementable() const { return this->_M_dereferenceable(); }
347 
348  // Is the iterator decrementable?
349  bool
350  _M_decrementable() const { return !_M_singular() && !_M_is_begin(); }
351 
352  // Can we advance the iterator @p __n steps (@p __n may be negative)
353  bool
354  _M_can_advance(const difference_type& __n) const;
355 
356  // Is the iterator range [*this, __rhs) valid?
357  template<typename _Other>
358  bool
359  _M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const;
360 
361  // The sequence this iterator references.
362  const _Sequence*
363  _M_get_sequence() const
364  { return static_cast<const _Sequence*>(_M_sequence); }
365 
366  /** Determine the distance between two iterators with some known
367  * precision.
368  */
369  template<typename _Iterator1, typename _Iterator2>
371  _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs)
372  {
373  typedef typename std::iterator_traits<_Iterator1>::iterator_category
374  _Category;
375  return _M_get_distance(__lhs, __rhs, _Category());
376  }
377 
378  template<typename _Iterator1, typename _Iterator2>
380  _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
382  {
383  return std::make_pair(__rhs.base() - __lhs.base(), __dp_exact);
384  }
385 
386  template<typename _Iterator1, typename _Iterator2>
388  _M_get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
390  {
391  return std::make_pair(__lhs.base() == __rhs.base()? 0 : 1,
392  __dp_equality);
393  }
394 
395  /// Is this iterator equal to the sequence's begin() iterator?
396  bool _M_is_begin() const
397  { return *this == static_cast<const _Sequence*>(_M_sequence)->begin(); }
398 
399  /// Is this iterator equal to the sequence's end() iterator?
400  bool _M_is_end() const
401  { return *this == static_cast<const _Sequence*>(_M_sequence)->end(); }
402  };
403 
404  template<typename _IteratorL, typename _IteratorR, typename _Sequence>
405  inline bool
406  operator==(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
407  const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
408  {
409  _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
410  _M_message(__msg_iter_compare_bad)
411  ._M_iterator(__lhs, "lhs")
412  ._M_iterator(__rhs, "rhs"));
413  _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
414  _M_message(__msg_compare_different)
415  ._M_iterator(__lhs, "lhs")
416  ._M_iterator(__rhs, "rhs"));
417  return __lhs.base() == __rhs.base();
418  }
419 
420  template<typename _Iterator, typename _Sequence>
421  inline bool
422  operator==(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
423  const _Safe_iterator<_Iterator, _Sequence>& __rhs)
424  {
425  _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
426  _M_message(__msg_iter_compare_bad)
427  ._M_iterator(__lhs, "lhs")
428  ._M_iterator(__rhs, "rhs"));
429  _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
430  _M_message(__msg_compare_different)
431  ._M_iterator(__lhs, "lhs")
432  ._M_iterator(__rhs, "rhs"));
433  return __lhs.base() == __rhs.base();
434  }
435 
436  template<typename _IteratorL, typename _IteratorR, typename _Sequence>
437  inline bool
438  operator!=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
439  const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
440  {
441  _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
442  _M_message(__msg_iter_compare_bad)
443  ._M_iterator(__lhs, "lhs")
444  ._M_iterator(__rhs, "rhs"));
445  _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
446  _M_message(__msg_compare_different)
447  ._M_iterator(__lhs, "lhs")
448  ._M_iterator(__rhs, "rhs"));
449  return __lhs.base() != __rhs.base();
450  }
451 
452  template<typename _Iterator, typename _Sequence>
453  inline bool
454  operator!=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
455  const _Safe_iterator<_Iterator, _Sequence>& __rhs)
456  {
457  _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
458  _M_message(__msg_iter_compare_bad)
459  ._M_iterator(__lhs, "lhs")
460  ._M_iterator(__rhs, "rhs"));
461  _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
462  _M_message(__msg_compare_different)
463  ._M_iterator(__lhs, "lhs")
464  ._M_iterator(__rhs, "rhs"));
465  return __lhs.base() != __rhs.base();
466  }
467 
468  template<typename _IteratorL, typename _IteratorR, typename _Sequence>
469  inline bool
470  operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
471  const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
472  {
473  _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
474  _M_message(__msg_iter_order_bad)
475  ._M_iterator(__lhs, "lhs")
476  ._M_iterator(__rhs, "rhs"));
477  _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
478  _M_message(__msg_order_different)
479  ._M_iterator(__lhs, "lhs")
480  ._M_iterator(__rhs, "rhs"));
481  return __lhs.base() < __rhs.base();
482  }
483 
484  template<typename _Iterator, typename _Sequence>
485  inline bool
486  operator<(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
487  const _Safe_iterator<_Iterator, _Sequence>& __rhs)
488  {
489  _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
490  _M_message(__msg_iter_order_bad)
491  ._M_iterator(__lhs, "lhs")
492  ._M_iterator(__rhs, "rhs"));
493  _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
494  _M_message(__msg_order_different)
495  ._M_iterator(__lhs, "lhs")
496  ._M_iterator(__rhs, "rhs"));
497  return __lhs.base() < __rhs.base();
498  }
499 
500  template<typename _IteratorL, typename _IteratorR, typename _Sequence>
501  inline bool
502  operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
503  const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
504  {
505  _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
506  _M_message(__msg_iter_order_bad)
507  ._M_iterator(__lhs, "lhs")
508  ._M_iterator(__rhs, "rhs"));
509  _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
510  _M_message(__msg_order_different)
511  ._M_iterator(__lhs, "lhs")
512  ._M_iterator(__rhs, "rhs"));
513  return __lhs.base() <= __rhs.base();
514  }
515 
516  template<typename _Iterator, typename _Sequence>
517  inline bool
518  operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
519  const _Safe_iterator<_Iterator, _Sequence>& __rhs)
520  {
521  _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
522  _M_message(__msg_iter_order_bad)
523  ._M_iterator(__lhs, "lhs")
524  ._M_iterator(__rhs, "rhs"));
525  _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
526  _M_message(__msg_order_different)
527  ._M_iterator(__lhs, "lhs")
528  ._M_iterator(__rhs, "rhs"));
529  return __lhs.base() <= __rhs.base();
530  }
531 
532  template<typename _IteratorL, typename _IteratorR, typename _Sequence>
533  inline bool
534  operator>(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
535  const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
536  {
537  _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
538  _M_message(__msg_iter_order_bad)
539  ._M_iterator(__lhs, "lhs")
540  ._M_iterator(__rhs, "rhs"));
541  _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
542  _M_message(__msg_order_different)
543  ._M_iterator(__lhs, "lhs")
544  ._M_iterator(__rhs, "rhs"));
545  return __lhs.base() > __rhs.base();
546  }
547 
548  template<typename _Iterator, typename _Sequence>
549  inline bool
550  operator>(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
551  const _Safe_iterator<_Iterator, _Sequence>& __rhs)
552  {
553  _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
554  _M_message(__msg_iter_order_bad)
555  ._M_iterator(__lhs, "lhs")
556  ._M_iterator(__rhs, "rhs"));
557  _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
558  _M_message(__msg_order_different)
559  ._M_iterator(__lhs, "lhs")
560  ._M_iterator(__rhs, "rhs"));
561  return __lhs.base() > __rhs.base();
562  }
563 
564  template<typename _IteratorL, typename _IteratorR, typename _Sequence>
565  inline bool
566  operator>=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
567  const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
568  {
569  _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
570  _M_message(__msg_iter_order_bad)
571  ._M_iterator(__lhs, "lhs")
572  ._M_iterator(__rhs, "rhs"));
573  _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
574  _M_message(__msg_order_different)
575  ._M_iterator(__lhs, "lhs")
576  ._M_iterator(__rhs, "rhs"));
577  return __lhs.base() >= __rhs.base();
578  }
579 
580  template<typename _Iterator, typename _Sequence>
581  inline bool
582  operator>=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
583  const _Safe_iterator<_Iterator, _Sequence>& __rhs)
584  {
585  _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
586  _M_message(__msg_iter_order_bad)
587  ._M_iterator(__lhs, "lhs")
588  ._M_iterator(__rhs, "rhs"));
589  _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
590  _M_message(__msg_order_different)
591  ._M_iterator(__lhs, "lhs")
592  ._M_iterator(__rhs, "rhs"));
593  return __lhs.base() >= __rhs.base();
594  }
595 
596  // _GLIBCXX_RESOLVE_LIB_DEFECTS
597  // According to the resolution of DR179 not only the various comparison
598  // operators but also operator- must accept mixed iterator/const_iterator
599  // parameters.
600  template<typename _IteratorL, typename _IteratorR, typename _Sequence>
601  inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type
602  operator-(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
603  const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
604  {
605  _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
606  _M_message(__msg_distance_bad)
607  ._M_iterator(__lhs, "lhs")
608  ._M_iterator(__rhs, "rhs"));
609  _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
610  _M_message(__msg_distance_different)
611  ._M_iterator(__lhs, "lhs")
612  ._M_iterator(__rhs, "rhs"));
613  return __lhs.base() - __rhs.base();
614  }
615 
616  template<typename _Iterator, typename _Sequence>
617  inline typename _Safe_iterator<_Iterator, _Sequence>::difference_type
618  operator-(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
619  const _Safe_iterator<_Iterator, _Sequence>& __rhs)
620  {
621  _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
622  _M_message(__msg_distance_bad)
623  ._M_iterator(__lhs, "lhs")
624  ._M_iterator(__rhs, "rhs"));
625  _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
626  _M_message(__msg_distance_different)
627  ._M_iterator(__lhs, "lhs")
628  ._M_iterator(__rhs, "rhs"));
629  return __lhs.base() - __rhs.base();
630  }
631 
632  template<typename _Iterator, typename _Sequence>
633  inline _Safe_iterator<_Iterator, _Sequence>
634  operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n,
635  const _Safe_iterator<_Iterator, _Sequence>& __i)
636  { return __i + __n; }
637 } // namespace __gnu_debug
638 
639 #ifndef _GLIBCXX_EXPORT_TEMPLATE
640 # include <debug/safe_iterator.tcc>
641 #endif
642 
643 #endif
bool _M_is_end() const
Is this iterator equal to the sequence's end() iterator?
_Safe_iterator(const _Safe_iterator &__x)
Copy construction.
_Safe_iterator(const _Safe_iterator< _MutableIterator, typename __gnu_cxx::__enable_if<(std::__are_same< _MutableIterator, typename _Sequence::iterator::_Base_iterator >::__value), _Sequence >::__type > &__x)
Converting constructor from a mutable iterator to a constant iterator.
pair holds two objects of arbitrary type.
Definition: stl_pair.h:67
bool _M_dereferenceable() const
Is the iterator dereferenceable?
void _M_attach(_Safe_sequence_base *__seq, bool __constant)
void _M_attach_single(_Safe_sequence_base *__seq, bool __constant)
_Safe_iterator operator++(int)
Iterator postincrement.
#define _GLIBCXX_DEBUG_VERIFY(_Condition, _ErrorMessage)
Definition: macros.h:42
void _M_attach(const _Sequence *__seq)
reference operator*() const
Iterator dereference.
_Safe_iterator(const _Iterator &__i, const _Sequence *__seq)
Safe iterator construction from an unsafe iterator and its sequence.
_Safe_iterator & operator++()
Iterator preincrement.
bool _M_incrementable() const
Is the iterator incrementable?
_Safe_sequence_base * _M_sequence
Definition: safe_base.h:56
static std::pair< difference_type, _Distance_precision > _M_get_distance(const _Iterator1 &__lhs, const _Iterator2 &__rhs)
_Safe_iterator operator--(int)
Iterator postdecrement.
bool _M_is_begin() const
Is this iterator equal to the sequence's begin() iterator?
_Safe_iterator & operator=(const _Safe_iterator &__x)
Copy assignment.
Basic functionality for a "safe" iterator.
Definition: safe_base.h:51
Random-access iterators support a superset of bidirectional iterator operations.
pointer operator->() const
Iterator dereference.
Forward iterators support a superset of input iterator operations.
_Iterator base() const
Return the underlying iterator.
Safe iterator wrapper.
Definition: formatter.h:57
void _M_attach_single(const _Sequence *__seq)
_Safe_iterator & operator--()
Iterator predecrement.