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