1 // Safe iterator implementation  -*- C++ -*-
2 
3 // Copyright (C) 2003-2018 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/assertions.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>
45     struct _BeforeBeginHelper
46     {
47       template<typename _Iterator>
48 	static bool
49 	_S_Is(const _Safe_iterator<_Iterator, _Sequence>&)
50 	{ return false; }
51 
52       template<typename _Iterator>
53 	static bool
54 	_S_Is_Beginnest(const _Safe_iterator<_Iterator, _Sequence>& __it)
55 	{ return __it.base() == __it._M_get_sequence()->_M_base().begin(); }
56     };
57 
58   /** Sequence traits giving the size of a container if possible. */
59   template<typename _Sequence>
60     struct _Sequence_traits
61     {
62       typedef _Distance_traits<typename _Sequence::iterator> _DistTraits;
63 
64       static typename _DistTraits::__type
65       _S_size(const _Sequence& __seq)
66       { return std::make_pair(__seq.size(), __dp_exact); }
67     };
68 
69   /** \brief Safe iterator wrapper.
70    *
71    *  The class template %_Safe_iterator is a wrapper around an
72    *  iterator that tracks the iterator's movement among sequences and
73    *  checks that operations performed on the "safe" iterator are
74    *  legal. In additional to the basic iterator operations (which are
75    *  validated, and then passed to the underlying iterator),
76    *  %_Safe_iterator has member functions for iterator invalidation,
77    *  attaching/detaching the iterator from sequences, and querying
78    *  the iterator's state.
79    *
80    *  Note that _Iterator must be the first base class so that it gets
81    *  initialized before the iterator is being attached to the container's list
82    *  of iterators and it is being detached before _Iterator get
83    *  destroyed. Otherwise it would result in a data race.
84    */
85   template<typename _Iterator, typename _Sequence>
86     class _Safe_iterator
87     : private _Iterator,
88       public _Safe_iterator_base
89     {
90       typedef _Iterator _Iter_base;
91       typedef _Safe_iterator_base _Safe_base;
92       typedef typename _Sequence::const_iterator _Const_iterator;
93 
94       /// Determine if this is a constant iterator.
95       bool
96       _M_constant() const
97       { return std::__are_same<_Const_iterator, _Safe_iterator>::__value; }
98 
99       typedef std::iterator_traits<_Iterator> _Traits;
100 
101       struct _Attach_single
102       { };
103 
104       _Safe_iterator(const _Iterator& __i, _Safe_sequence_base* __seq,
105 		     _Attach_single)
106       _GLIBCXX_NOEXCEPT
107       : _Iter_base(__i)
108       { _M_attach_single(__seq); }
109 
110     public:
111       typedef _Iterator					iterator_type;
112       typedef typename _Traits::iterator_category	iterator_category;
113       typedef typename _Traits::value_type		value_type;
114       typedef typename _Traits::difference_type		difference_type;
115       typedef typename _Traits::reference		reference;
116       typedef typename _Traits::pointer			pointer;
117 
118       /// @post the iterator is singular and unattached
119       _Safe_iterator() _GLIBCXX_NOEXCEPT : _Iter_base() { }
120 
121       /**
122        * @brief Safe iterator construction from an unsafe iterator and
123        * its sequence.
124        *
125        * @pre @p seq is not NULL
126        * @post this is not singular
127        */
128       _Safe_iterator(const _Iterator& __i, const _Safe_sequence_base* __seq)
129       _GLIBCXX_NOEXCEPT
130       : _Iter_base(__i), _Safe_base(__seq, _M_constant())
131       {
132 	_GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
133 			      _M_message(__msg_init_singular)
134 			      ._M_iterator(*this, "this"));
135       }
136 
137       /**
138        * @brief Copy construction.
139        */
140       _Safe_iterator(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT
141       : _Iter_base(__x.base())
142       {
143 	// _GLIBCXX_RESOLVE_LIB_DEFECTS
144 	// DR 408. Is vector<reverse_iterator<char*> > forbidden?
145 	_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
146 			      || __x.base() == _Iterator(),
147 			      _M_message(__msg_init_copy_singular)
148 			      ._M_iterator(*this, "this")
149 			      ._M_iterator(__x, "other"));
150 	_M_attach(__x._M_sequence);
151       }
152 
153 #if __cplusplus >= 201103L
154       /**
155        * @brief Move construction.
156        * @post __x is singular and unattached
157        */
158       _Safe_iterator(_Safe_iterator&& __x) noexcept
159       : _Iter_base()
160       {
161 	_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
162 			      || __x.base() == _Iterator(),
163 			      _M_message(__msg_init_copy_singular)
164 			      ._M_iterator(*this, "this")
165 			      ._M_iterator(__x, "other"));
166 	_Safe_sequence_base* __seq = __x._M_sequence;
167 	__x._M_detach();
168 	std::swap(base(), __x.base());
169 	_M_attach(__seq);
170       }
171 #endif
172 
173       /**
174        *  @brief Converting constructor from a mutable iterator to a
175        *  constant iterator.
176       */
177       template<typename _MutableIterator>
178 	_Safe_iterator(
179 	  const _Safe_iterator<_MutableIterator,
180 	  typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator,
181 		      typename _Sequence::iterator::iterator_type>::__value),
182 		   _Sequence>::__type>& __x) _GLIBCXX_NOEXCEPT
183 	: _Iter_base(__x.base())
184 	{
185 	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
186 	  // DR 408. Is vector<reverse_iterator<char*> > forbidden?
187 	  _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
188 				|| __x.base() == _Iterator(),
189 				_M_message(__msg_init_const_singular)
190 				._M_iterator(*this, "this")
191 				._M_iterator(__x, "other"));
192 	  _M_attach(__x._M_sequence);
193 	}
194 
195       /**
196        * @brief Copy assignment.
197        */
198       _Safe_iterator&
199       operator=(const _Safe_iterator& __x) _GLIBCXX_NOEXCEPT
200       {
201 	// _GLIBCXX_RESOLVE_LIB_DEFECTS
202 	// DR 408. Is vector<reverse_iterator<char*> > forbidden?
203 	_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
204 			      || __x.base() == _Iterator(),
205 			      _M_message(__msg_copy_singular)
206 			      ._M_iterator(*this, "this")
207 			      ._M_iterator(__x, "other"));
208 
209 	if (this->_M_sequence && this->_M_sequence == __x._M_sequence)
210 	  {
211 	    __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
212 	    base() = __x.base();
213 	    _M_version = __x._M_sequence->_M_version;
214 	  }
215 	else
216 	  {
217 	    _M_detach();
218 	    base() = __x.base();
219 	    _M_attach(__x._M_sequence);
220 	  }
221 
222 	return *this;
223       }
224 
225 #if __cplusplus >= 201103L
226       /**
227        * @brief Move assignment.
228        * @post __x is singular and unattached
229        */
230       _Safe_iterator&
231       operator=(_Safe_iterator&& __x) noexcept
232       {
233 	_GLIBCXX_DEBUG_VERIFY(this != &__x,
234 			      _M_message(__msg_self_move_assign)
235 			      ._M_iterator(*this, "this"));
236 	_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
237 			      || __x.base() == _Iterator(),
238 			      _M_message(__msg_copy_singular)
239 			      ._M_iterator(*this, "this")
240 			      ._M_iterator(__x, "other"));
241 
242 	if (this->_M_sequence && this->_M_sequence == __x._M_sequence)
243 	  {
244 	    __gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
245 	    base() = __x.base();
246 	    _M_version = __x._M_sequence->_M_version;
247 	  }
248 	else
249 	  {
250 	    _M_detach();
251 	    base() = __x.base();
252 	    _M_attach(__x._M_sequence);
253 	  }
254 
255 	__x._M_detach();
256 	__x.base() = _Iterator();
257 	return *this;
258       }
259 #endif
260 
261       /**
262        *  @brief Iterator dereference.
263        *  @pre iterator is dereferenceable
264        */
265       reference
266       operator*() const _GLIBCXX_NOEXCEPT
267       {
268 	_GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
269 			      _M_message(__msg_bad_deref)
270 			      ._M_iterator(*this, "this"));
271 	return *base();
272       }
273 
274       /**
275        *  @brief Iterator dereference.
276        *  @pre iterator is dereferenceable
277        */
278       pointer
279       operator->() const _GLIBCXX_NOEXCEPT
280       {
281 	_GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
282 			      _M_message(__msg_bad_deref)
283 			      ._M_iterator(*this, "this"));
284 	return base().operator->();
285       }
286 
287       // ------ Input iterator requirements ------
288       /**
289        *  @brief Iterator preincrement
290        *  @pre iterator is incrementable
291        */
292       _Safe_iterator&
293       operator++() _GLIBCXX_NOEXCEPT
294       {
295 	_GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
296 			      _M_message(__msg_bad_inc)
297 			      ._M_iterator(*this, "this"));
298 	__gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
299 	++base();
300 	return *this;
301       }
302 
303       /**
304        *  @brief Iterator postincrement
305        *  @pre iterator is incrementable
306        */
307       _Safe_iterator
308       operator++(int) _GLIBCXX_NOEXCEPT
309       {
310 	_GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
311 			      _M_message(__msg_bad_inc)
312 			      ._M_iterator(*this, "this"));
313 	__gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
314 	return _Safe_iterator(base()++, this->_M_sequence, _Attach_single());
315       }
316 
317       // ------ Bidirectional iterator requirements ------
318       /**
319        *  @brief Iterator predecrement
320        *  @pre iterator is decrementable
321        */
322       _Safe_iterator&
323       operator--() _GLIBCXX_NOEXCEPT
324       {
325 	_GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
326 			      _M_message(__msg_bad_dec)
327 			      ._M_iterator(*this, "this"));
328 	__gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
329 	--base();
330 	return *this;
331       }
332 
333       /**
334        *  @brief Iterator postdecrement
335        *  @pre iterator is decrementable
336        */
337       _Safe_iterator
338       operator--(int) _GLIBCXX_NOEXCEPT
339       {
340 	_GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
341 			      _M_message(__msg_bad_dec)
342 			      ._M_iterator(*this, "this"));
343 	__gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
344 	return _Safe_iterator(base()--, this->_M_sequence, _Attach_single());
345       }
346 
347       // ------ Random access iterator requirements ------
348       reference
349       operator[](const difference_type& __n) const _GLIBCXX_NOEXCEPT
350       {
351 	_GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
352 			      && this->_M_can_advance(__n+1),
353 			      _M_message(__msg_iter_subscript_oob)
354 			      ._M_iterator(*this)._M_integer(__n));
355 	return base()[__n];
356       }
357 
358       _Safe_iterator&
359       operator+=(const difference_type& __n) _GLIBCXX_NOEXCEPT
360       {
361 	_GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
362 			      _M_message(__msg_advance_oob)
363 			      ._M_iterator(*this)._M_integer(__n));
364 	__gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
365 	base() += __n;
366 	return *this;
367       }
368 
369       _Safe_iterator
370       operator+(const difference_type& __n) const _GLIBCXX_NOEXCEPT
371       {
372 	_GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
373 			      _M_message(__msg_advance_oob)
374 			      ._M_iterator(*this)._M_integer(__n));
375 	return _Safe_iterator(base() + __n, this->_M_sequence);
376       }
377 
378       _Safe_iterator&
379       operator-=(const difference_type& __n) _GLIBCXX_NOEXCEPT
380       {
381 	_GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
382 			      _M_message(__msg_retreat_oob)
383 			      ._M_iterator(*this)._M_integer(__n));
384 	__gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
385 	base() -= __n;
386 	return *this;
387       }
388 
389       _Safe_iterator
390       operator-(const difference_type& __n) const _GLIBCXX_NOEXCEPT
391       {
392 	_GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
393 			      _M_message(__msg_retreat_oob)
394 			      ._M_iterator(*this)._M_integer(__n));
395 	return _Safe_iterator(base() - __n, this->_M_sequence);
396       }
397 
398       // ------ Utilities ------
399       /**
400        * @brief Return the underlying iterator
401        */
402       _Iterator&
403       base() _GLIBCXX_NOEXCEPT { return *this; }
404 
405       const _Iterator&
406       base() const _GLIBCXX_NOEXCEPT { return *this; }
407 
408       /**
409        * @brief Conversion to underlying non-debug iterator to allow
410        * better interaction with non-debug containers.
411        */
412       operator _Iterator() const _GLIBCXX_NOEXCEPT { return *this; }
413 
414       /** Attach iterator to the given sequence. */
415       void
416       _M_attach(_Safe_sequence_base* __seq)
417       { _Safe_base::_M_attach(__seq, _M_constant()); }
418 
419       /** Likewise, but not thread-safe. */
420       void
421       _M_attach_single(_Safe_sequence_base* __seq)
422       { _Safe_base::_M_attach_single(__seq, _M_constant()); }
423 
424       /// Is the iterator dereferenceable?
425       bool
426       _M_dereferenceable() const
427       { return !this->_M_singular() && !_M_is_end() && !_M_is_before_begin(); }
428 
429       /// Is the iterator before a dereferenceable one?
430       bool
431       _M_before_dereferenceable() const
432       {
433 	if (this->_M_incrementable())
434 	{
435 	  _Iterator __base = base();
436 	  return ++__base != _M_get_sequence()->_M_base().end();
437 	}
438 	return false;
439       }
440 
441       /// Is the iterator incrementable?
442       bool
443       _M_incrementable() const
444       { return !this->_M_singular() && !_M_is_end(); }
445 
446       // Is the iterator decrementable?
447       bool
448       _M_decrementable() const { return !_M_singular() && !_M_is_begin(); }
449 
450       // Can we advance the iterator @p __n steps (@p __n may be negative)
451       bool
452       _M_can_advance(const difference_type& __n) const;
453 
454       // Is the iterator range [*this, __rhs) valid?
455       bool
456       _M_valid_range(const _Safe_iterator& __rhs,
457 		     std::pair<difference_type, _Distance_precision>& __dist,
458 		     bool __check_dereferenceable = true) const;
459 
460       // The sequence this iterator references.
461       typename
462       __gnu_cxx::__conditional_type<std::__are_same<_Const_iterator,
463 						    _Safe_iterator>::__value,
464 				    const _Sequence*,
465 				    _Sequence*>::__type
466       _M_get_sequence() const
467       { return static_cast<_Sequence*>(_M_sequence); }
468 
469       /// Is this iterator equal to the sequence's begin() iterator?
470       bool
471       _M_is_begin() const
472       { return base() == _M_get_sequence()->_M_base().begin(); }
473 
474       /// Is this iterator equal to the sequence's end() iterator?
475       bool
476       _M_is_end() const
477       { return base() == _M_get_sequence()->_M_base().end(); }
478 
479       /// Is this iterator equal to the sequence's before_begin() iterator if
480       /// any?
481       bool
482       _M_is_before_begin() const
483       { return _BeforeBeginHelper<_Sequence>::_S_Is(*this); }
484 
485       /// Is this iterator equal to the sequence's before_begin() iterator if
486       /// any or begin() otherwise?
487       bool
488       _M_is_beginnest() const
489       { return _BeforeBeginHelper<_Sequence>::_S_Is_Beginnest(*this); }
490     };
491 
492   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
493     inline bool
494     operator==(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
495 	       const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
496     _GLIBCXX_NOEXCEPT
497     {
498       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
499 			    _M_message(__msg_iter_compare_bad)
500 			    ._M_iterator(__lhs, "lhs")
501 			    ._M_iterator(__rhs, "rhs"));
502       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
503 			    _M_message(__msg_compare_different)
504 			    ._M_iterator(__lhs, "lhs")
505 			    ._M_iterator(__rhs, "rhs"));
506       return __lhs.base() == __rhs.base();
507     }
508 
509   template<typename _Iterator, typename _Sequence>
510     inline bool
511     operator==(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
512 	       const _Safe_iterator<_Iterator, _Sequence>& __rhs)
513     _GLIBCXX_NOEXCEPT
514     {
515       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
516 			    _M_message(__msg_iter_compare_bad)
517 			    ._M_iterator(__lhs, "lhs")
518 			    ._M_iterator(__rhs, "rhs"));
519       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
520 			    _M_message(__msg_compare_different)
521 			    ._M_iterator(__lhs, "lhs")
522 			    ._M_iterator(__rhs, "rhs"));
523       return __lhs.base() == __rhs.base();
524     }
525 
526   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
527     inline bool
528     operator!=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
529 	       const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
530     _GLIBCXX_NOEXCEPT
531     {
532       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
533 			    _M_message(__msg_iter_compare_bad)
534 			    ._M_iterator(__lhs, "lhs")
535 			    ._M_iterator(__rhs, "rhs"));
536       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
537 			    _M_message(__msg_compare_different)
538 			    ._M_iterator(__lhs, "lhs")
539 			    ._M_iterator(__rhs, "rhs"));
540       return __lhs.base() != __rhs.base();
541     }
542 
543   template<typename _Iterator, typename _Sequence>
544     inline bool
545     operator!=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
546 	       const _Safe_iterator<_Iterator, _Sequence>& __rhs)
547     _GLIBCXX_NOEXCEPT
548     {
549       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
550 			    _M_message(__msg_iter_compare_bad)
551 			    ._M_iterator(__lhs, "lhs")
552 			    ._M_iterator(__rhs, "rhs"));
553       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
554 			    _M_message(__msg_compare_different)
555 			    ._M_iterator(__lhs, "lhs")
556 			    ._M_iterator(__rhs, "rhs"));
557       return __lhs.base() != __rhs.base();
558     }
559 
560   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
561     inline bool
562     operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
563 	      const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
564     _GLIBCXX_NOEXCEPT
565     {
566       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
567 			    _M_message(__msg_iter_order_bad)
568 			    ._M_iterator(__lhs, "lhs")
569 			    ._M_iterator(__rhs, "rhs"));
570       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
571 			    _M_message(__msg_order_different)
572 			    ._M_iterator(__lhs, "lhs")
573 			    ._M_iterator(__rhs, "rhs"));
574       return __lhs.base() < __rhs.base();
575     }
576 
577   template<typename _Iterator, typename _Sequence>
578     inline bool
579     operator<(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
580 	      const _Safe_iterator<_Iterator, _Sequence>& __rhs)
581     _GLIBCXX_NOEXCEPT
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 _IteratorL, typename _IteratorR, typename _Sequence>
595     inline bool
596     operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
597 	       const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
598     _GLIBCXX_NOEXCEPT
599     {
600       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
601 			    _M_message(__msg_iter_order_bad)
602 			    ._M_iterator(__lhs, "lhs")
603 			    ._M_iterator(__rhs, "rhs"));
604       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
605 			    _M_message(__msg_order_different)
606 			    ._M_iterator(__lhs, "lhs")
607 			    ._M_iterator(__rhs, "rhs"));
608       return __lhs.base() <= __rhs.base();
609     }
610 
611   template<typename _Iterator, typename _Sequence>
612     inline bool
613     operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
614 	       const _Safe_iterator<_Iterator, _Sequence>& __rhs)
615     _GLIBCXX_NOEXCEPT
616     {
617       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
618 			    _M_message(__msg_iter_order_bad)
619 			    ._M_iterator(__lhs, "lhs")
620 			    ._M_iterator(__rhs, "rhs"));
621       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
622 			    _M_message(__msg_order_different)
623 			    ._M_iterator(__lhs, "lhs")
624 			    ._M_iterator(__rhs, "rhs"));
625       return __lhs.base() <= __rhs.base();
626     }
627 
628   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
629     inline bool
630     operator>(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
631 	      const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
632     _GLIBCXX_NOEXCEPT
633     {
634       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
635 			    _M_message(__msg_iter_order_bad)
636 			    ._M_iterator(__lhs, "lhs")
637 			    ._M_iterator(__rhs, "rhs"));
638       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
639 			    _M_message(__msg_order_different)
640 			    ._M_iterator(__lhs, "lhs")
641 			    ._M_iterator(__rhs, "rhs"));
642       return __lhs.base() > __rhs.base();
643     }
644 
645   template<typename _Iterator, typename _Sequence>
646     inline bool
647     operator>(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
648 	      const _Safe_iterator<_Iterator, _Sequence>& __rhs)
649     _GLIBCXX_NOEXCEPT
650     {
651       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
652 			    _M_message(__msg_iter_order_bad)
653 			    ._M_iterator(__lhs, "lhs")
654 			    ._M_iterator(__rhs, "rhs"));
655       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
656 			    _M_message(__msg_order_different)
657 			    ._M_iterator(__lhs, "lhs")
658 			    ._M_iterator(__rhs, "rhs"));
659       return __lhs.base() > __rhs.base();
660     }
661 
662   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
663     inline bool
664     operator>=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
665 	       const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
666     _GLIBCXX_NOEXCEPT
667     {
668       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
669 			    _M_message(__msg_iter_order_bad)
670 			    ._M_iterator(__lhs, "lhs")
671 			    ._M_iterator(__rhs, "rhs"));
672       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
673 			    _M_message(__msg_order_different)
674 			    ._M_iterator(__lhs, "lhs")
675 			    ._M_iterator(__rhs, "rhs"));
676       return __lhs.base() >= __rhs.base();
677     }
678 
679   template<typename _Iterator, typename _Sequence>
680     inline bool
681     operator>=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
682 	       const _Safe_iterator<_Iterator, _Sequence>& __rhs)
683     _GLIBCXX_NOEXCEPT
684     {
685       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
686 			    _M_message(__msg_iter_order_bad)
687 			    ._M_iterator(__lhs, "lhs")
688 			    ._M_iterator(__rhs, "rhs"));
689       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
690 			    _M_message(__msg_order_different)
691 			    ._M_iterator(__lhs, "lhs")
692 			    ._M_iterator(__rhs, "rhs"));
693       return __lhs.base() >= __rhs.base();
694     }
695 
696   // _GLIBCXX_RESOLVE_LIB_DEFECTS
697   // According to the resolution of DR179 not only the various comparison
698   // operators but also operator- must accept mixed iterator/const_iterator
699   // parameters.
700   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
701     inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type
702     operator-(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
703 	      const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
704     _GLIBCXX_NOEXCEPT
705     {
706       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
707 			    _M_message(__msg_distance_bad)
708 			    ._M_iterator(__lhs, "lhs")
709 			    ._M_iterator(__rhs, "rhs"));
710       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
711 			    _M_message(__msg_distance_different)
712 			    ._M_iterator(__lhs, "lhs")
713 			    ._M_iterator(__rhs, "rhs"));
714       return __lhs.base() - __rhs.base();
715     }
716 
717    template<typename _Iterator, typename _Sequence>
718      inline typename _Safe_iterator<_Iterator, _Sequence>::difference_type
719      operator-(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
720 	       const _Safe_iterator<_Iterator, _Sequence>& __rhs)
721     _GLIBCXX_NOEXCEPT
722      {
723        _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
724 			     _M_message(__msg_distance_bad)
725 			     ._M_iterator(__lhs, "lhs")
726 			     ._M_iterator(__rhs, "rhs"));
727        _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
728 			     _M_message(__msg_distance_different)
729 			     ._M_iterator(__lhs, "lhs")
730 			     ._M_iterator(__rhs, "rhs"));
731        return __lhs.base() - __rhs.base();
732      }
733 
734   template<typename _Iterator, typename _Sequence>
735     inline _Safe_iterator<_Iterator, _Sequence>
736     operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n,
737 	      const _Safe_iterator<_Iterator, _Sequence>& __i) _GLIBCXX_NOEXCEPT
738     { return __i + __n; }
739 
740   /** Safe iterators know if they are dereferenceable. */
741   template<typename _Iterator, typename _Sequence>
742     inline bool
743     __check_dereferenceable(const _Safe_iterator<_Iterator, _Sequence>& __x)
744     { return __x._M_dereferenceable(); }
745 
746   /** Safe iterators know how to check if they form a valid range. */
747   template<typename _Iterator, typename _Sequence>
748     inline bool
749     __valid_range(const _Safe_iterator<_Iterator, _Sequence>& __first,
750 		  const _Safe_iterator<_Iterator, _Sequence>& __last,
751 		  typename _Distance_traits<_Iterator>::__type& __dist)
752     { return __first._M_valid_range(__last, __dist); }
753 
754   /** Safe iterators can help to get better distance knowledge. */
755   template<typename _Iterator, typename _Sequence>
756     inline typename _Distance_traits<_Iterator>::__type
757     __get_distance(const _Safe_iterator<_Iterator, _Sequence>& __first,
758 		   const _Safe_iterator<_Iterator, _Sequence>& __last,
759 		   std::random_access_iterator_tag)
760     { return std::make_pair(__last.base() - __first.base(), __dp_exact); }
761 
762   template<typename _Iterator, typename _Sequence>
763     inline typename _Distance_traits<_Iterator>::__type
764     __get_distance(const _Safe_iterator<_Iterator, _Sequence>& __first,
765 		   const _Safe_iterator<_Iterator, _Sequence>& __last,
766 		   std::input_iterator_tag)
767     {
768       typedef typename _Distance_traits<_Iterator>::__type _Diff;
769       typedef _Sequence_traits<_Sequence> _SeqTraits;
770 
771       if (__first.base() == __last.base())
772 	return std::make_pair(0, __dp_exact);
773 
774       if (__first._M_is_before_begin())
775 	{
776 	  if (__last._M_is_begin())
777 	    return std::make_pair(1, __dp_exact);
778 
779 	  return std::make_pair(1, __dp_sign);
780 	}
781 
782       if (__first._M_is_begin())
783 	{
784 	  if (__last._M_is_before_begin())
785 	    return std::make_pair(-1, __dp_exact);
786 
787 	  if (__last._M_is_end())
788 	    return _SeqTraits::_S_size(*__first._M_get_sequence());
789 
790 	  return std::make_pair(1, __dp_sign);
791 	}
792 
793       if (__first._M_is_end())
794 	{
795 	  if (__last._M_is_before_begin())
796 	    return std::make_pair(-1, __dp_exact);
797 
798 	  if (__last._M_is_begin())
799 	    {
800 	      _Diff __diff = _SeqTraits::_S_size(*__first._M_get_sequence());
801 	      return std::make_pair(-__diff.first, __diff.second);
802 	    }
803 
804 	  return std::make_pair(-1, __dp_sign);
805 	}
806 
807       if (__last._M_is_before_begin() || __last._M_is_begin())
808 	return std::make_pair(-1, __dp_sign);
809 
810       if (__last._M_is_end())
811 	return std::make_pair(1, __dp_sign);
812 
813       return std::make_pair(1, __dp_equality);
814     }
815 
816   // Get distance from sequence begin to specified iterator.
817   template<typename _Iterator, typename _Sequence>
818     inline typename _Distance_traits<_Iterator>::__type
819     __get_distance_from_begin(const _Safe_iterator<_Iterator, _Sequence>& __it)
820     {
821       typedef _Sequence_traits<_Sequence> _SeqTraits;
822 
823       // No need to consider before_begin as this function is only used in
824       // _M_can_advance which won't be used for forward_list iterators.
825       if (__it._M_is_begin())
826 	return std::make_pair(0, __dp_exact);
827 
828       if (__it._M_is_end())
829 	return _SeqTraits::_S_size(*__it._M_get_sequence());
830 
831       typename _Distance_traits<_Iterator>::__type __res
832 	= __get_distance(__it._M_get_sequence()->_M_base().begin(), __it.base());
833 
834       if (__res.second == __dp_equality)
835 	return std::make_pair(1, __dp_sign);
836 
837       return __res;
838     }
839 
840   // Get distance from specified iterator to sequence end.
841   template<typename _Iterator, typename _Sequence>
842     inline typename _Distance_traits<_Iterator>::__type
843     __get_distance_to_end(const _Safe_iterator<_Iterator, _Sequence>& __it)
844     {
845       typedef _Sequence_traits<_Sequence> _SeqTraits;
846 
847       // No need to consider before_begin as this function is only used in
848       // _M_can_advance which won't be used for forward_list iterators.
849       if (__it._M_is_begin())
850 	return _SeqTraits::_S_size(*__it._M_get_sequence());
851 
852       if (__it._M_is_end())
853 	return std::make_pair(0, __dp_exact);
854 
855       typename _Distance_traits<_Iterator>::__type __res
856 	= __get_distance(__it.base(), __it._M_get_sequence()->_M_base().end());
857 
858       if (__res.second == __dp_equality)
859 	return std::make_pair(1, __dp_sign);
860 
861       return __res;
862     }
863 
864 #if __cplusplus < 201103L
865   template<typename _Iterator, typename _Sequence>
866     struct __is_safe_random_iterator<_Safe_iterator<_Iterator, _Sequence> >
867     : std::__are_same<std::random_access_iterator_tag,
868                       typename std::iterator_traits<_Iterator>::
869 		      iterator_category>
870     { };
871 #else
872   template<typename _Iterator, typename _Sequence>
873     _Iterator
874     __base(const _Safe_iterator<_Iterator, _Sequence>& __it,
875 	   std::random_access_iterator_tag)
876     { return __it.base(); }
877 
878   template<typename _Iterator, typename _Sequence>
879     const _Safe_iterator<_Iterator, _Sequence>&
880     __base(const _Safe_iterator<_Iterator, _Sequence>& __it,
881 	   std::input_iterator_tag)
882     { return __it; }
883 
884   template<typename _Iterator, typename _Sequence>
885     auto
886     __base(const _Safe_iterator<_Iterator, _Sequence>& __it)
887     -> decltype(__base(__it, std::__iterator_category(__it)))
888     { return __base(__it, std::__iterator_category(__it)); }
889 #endif
890 
891 #if __cplusplus < 201103L
892   template<typename _Iterator, typename _Sequence>
893     struct _Unsafe_type<_Safe_iterator<_Iterator, _Sequence> >
894     { typedef _Iterator _Type; };
895 #endif
896 
897   template<typename _Iterator, typename _Sequence>
898     inline _Iterator
899     __unsafe(const _Safe_iterator<_Iterator, _Sequence>& __it)
900     { return __it.base(); }
901 
902 } // namespace __gnu_debug
903 
904 #include <debug/safe_iterator.tcc>
905 
906 #endif
907