1 // Safe iterator implementation  -*- C++ -*-
2 
3 // Copyright (C) 2003-2016 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
_S_Is_BeforeBeginHelper49 	_S_Is(const _Safe_iterator<_Iterator, _Sequence>&)
50 	{ return false; }
51 
52       template<typename _Iterator>
53 	static bool
_S_Is_Beginnest_BeforeBeginHelper54 	_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
_S_size_Sequence_traits65       _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
_M_constant()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 
_Safe_iterator(const _Iterator & __i,_Safe_sequence_base * __seq,_Attach_single)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
_Safe_iterator()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        */
_Safe_iterator(const _Iterator & __i,const _Safe_sequence_base * __seq)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        */
_Safe_iterator(const _Safe_iterator & __x)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        */
_Safe_iterator(_Safe_iterator && __x)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>
_Safe_iterator(const _Safe_iterator<_MutableIterator,typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator,typename _Sequence::iterator::iterator_type>::__value),_Sequence>::__type> & __x)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        *  @todo Make this correct w.r.t. iterators that return proxies
278        */
279       pointer
280       operator->() const _GLIBCXX_NOEXCEPT
281       {
282 	_GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
283 			      _M_message(__msg_bad_deref)
284 			      ._M_iterator(*this, "this"));
285 	return std::__addressof(*base());
286       }
287 
288       // ------ Input iterator requirements ------
289       /**
290        *  @brief Iterator preincrement
291        *  @pre iterator is incrementable
292        */
293       _Safe_iterator&
294       operator++() _GLIBCXX_NOEXCEPT
295       {
296 	_GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
297 			      _M_message(__msg_bad_inc)
298 			      ._M_iterator(*this, "this"));
299 	__gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
300 	++base();
301 	return *this;
302       }
303 
304       /**
305        *  @brief Iterator postincrement
306        *  @pre iterator is incrementable
307        */
308       _Safe_iterator
309       operator++(int) _GLIBCXX_NOEXCEPT
310       {
311 	_GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
312 			      _M_message(__msg_bad_inc)
313 			      ._M_iterator(*this, "this"));
314 	__gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
315 	return _Safe_iterator(base()++, this->_M_sequence, _Attach_single());
316       }
317 
318       // ------ Bidirectional iterator requirements ------
319       /**
320        *  @brief Iterator predecrement
321        *  @pre iterator is decrementable
322        */
323       _Safe_iterator&
324       operator--() _GLIBCXX_NOEXCEPT
325       {
326 	_GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
327 			      _M_message(__msg_bad_dec)
328 			      ._M_iterator(*this, "this"));
329 	__gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
330 	--base();
331 	return *this;
332       }
333 
334       /**
335        *  @brief Iterator postdecrement
336        *  @pre iterator is decrementable
337        */
338       _Safe_iterator
339       operator--(int) _GLIBCXX_NOEXCEPT
340       {
341 	_GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
342 			      _M_message(__msg_bad_dec)
343 			      ._M_iterator(*this, "this"));
344 	__gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
345 	return _Safe_iterator(base()--, this->_M_sequence, _Attach_single());
346       }
347 
348       // ------ Random access iterator requirements ------
349       reference
350       operator[](const difference_type& __n) const _GLIBCXX_NOEXCEPT
351       {
352 	_GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
353 			      && this->_M_can_advance(__n+1),
354 			      _M_message(__msg_iter_subscript_oob)
355 			      ._M_iterator(*this)._M_integer(__n));
356 	return base()[__n];
357       }
358 
359       _Safe_iterator&
360       operator+=(const difference_type& __n) _GLIBCXX_NOEXCEPT
361       {
362 	_GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
363 			      _M_message(__msg_advance_oob)
364 			      ._M_iterator(*this)._M_integer(__n));
365 	__gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
366 	base() += __n;
367 	return *this;
368       }
369 
370       _Safe_iterator
371       operator+(const difference_type& __n) const _GLIBCXX_NOEXCEPT
372       {
373 	_GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
374 			      _M_message(__msg_advance_oob)
375 			      ._M_iterator(*this)._M_integer(__n));
376 	return _Safe_iterator(base() + __n, this->_M_sequence);
377       }
378 
379       _Safe_iterator&
380       operator-=(const difference_type& __n) _GLIBCXX_NOEXCEPT
381       {
382 	_GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
383 			      _M_message(__msg_retreat_oob)
384 			      ._M_iterator(*this)._M_integer(__n));
385 	__gnu_cxx::__scoped_lock __l(this->_M_get_mutex());
386 	base() -= __n;
387 	return *this;
388       }
389 
390       _Safe_iterator
391       operator-(const difference_type& __n) const _GLIBCXX_NOEXCEPT
392       {
393 	_GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
394 			      _M_message(__msg_retreat_oob)
395 			      ._M_iterator(*this)._M_integer(__n));
396 	return _Safe_iterator(base() - __n, this->_M_sequence);
397       }
398 
399       // ------ Utilities ------
400       /**
401        * @brief Return the underlying iterator
402        */
403       _Iterator&
base()404       base() _GLIBCXX_NOEXCEPT { return *this; }
405 
406       const _Iterator&
base()407       base() const _GLIBCXX_NOEXCEPT { return *this; }
408 
409       /**
410        * @brief Conversion to underlying non-debug iterator to allow
411        * better interaction with non-debug containers.
412        */
_Iterator()413       operator _Iterator() const _GLIBCXX_NOEXCEPT { return *this; }
414 
415       /** Attach iterator to the given sequence. */
416       void
_M_attach(_Safe_sequence_base * __seq)417       _M_attach(_Safe_sequence_base* __seq)
418       { _Safe_base::_M_attach(__seq, _M_constant()); }
419 
420       /** Likewise, but not thread-safe. */
421       void
_M_attach_single(_Safe_sequence_base * __seq)422       _M_attach_single(_Safe_sequence_base* __seq)
423       { _Safe_base::_M_attach_single(__seq, _M_constant()); }
424 
425       /// Is the iterator dereferenceable?
426       bool
_M_dereferenceable()427       _M_dereferenceable() const
428       { return !this->_M_singular() && !_M_is_end() && !_M_is_before_begin(); }
429 
430       /// Is the iterator before a dereferenceable one?
431       bool
_M_before_dereferenceable()432       _M_before_dereferenceable() const
433       {
434 	if (this->_M_incrementable())
435 	{
436 	  _Iterator __base = base();
437 	  return ++__base != _M_get_sequence()->_M_base().end();
438 	}
439 	return false;
440       }
441 
442       /// Is the iterator incrementable?
443       bool
_M_incrementable()444       _M_incrementable() const
445       { return !this->_M_singular() && !_M_is_end(); }
446 
447       // Is the iterator decrementable?
448       bool
_M_decrementable()449       _M_decrementable() const { return !_M_singular() && !_M_is_begin(); }
450 
451       // Can we advance the iterator @p __n steps (@p __n may be negative)
452       bool
453       _M_can_advance(const difference_type& __n) const;
454 
455       // Is the iterator range [*this, __rhs) valid?
456       bool
457       _M_valid_range(const _Safe_iterator& __rhs,
458 		     std::pair<difference_type, _Distance_precision>& __dist,
459 		     bool __check_dereferenceable = true) const;
460 
461       // The sequence this iterator references.
462       typename
463       __gnu_cxx::__conditional_type<std::__are_same<_Const_iterator,
464 						    _Safe_iterator>::__value,
465 				    const _Sequence*,
466 				    _Sequence*>::__type
_M_get_sequence()467       _M_get_sequence() const
468       { return static_cast<_Sequence*>(_M_sequence); }
469 
470       /// Is this iterator equal to the sequence's begin() iterator?
471       bool
_M_is_begin()472       _M_is_begin() const
473       { return base() == _M_get_sequence()->_M_base().begin(); }
474 
475       /// Is this iterator equal to the sequence's end() iterator?
476       bool
_M_is_end()477       _M_is_end() const
478       { return base() == _M_get_sequence()->_M_base().end(); }
479 
480       /// Is this iterator equal to the sequence's before_begin() iterator if
481       /// any?
482       bool
_M_is_before_begin()483       _M_is_before_begin() const
484       { return _BeforeBeginHelper<_Sequence>::_S_Is(*this); }
485 
486       /// Is this iterator equal to the sequence's before_begin() iterator if
487       /// any or begin() otherwise?
488       bool
_M_is_beginnest()489       _M_is_beginnest() const
490       { return _BeforeBeginHelper<_Sequence>::_S_Is_Beginnest(*this); }
491     };
492 
493   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
494     inline bool
495     operator==(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
496 	       const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
497     _GLIBCXX_NOEXCEPT
498     {
499       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
500 			    _M_message(__msg_iter_compare_bad)
501 			    ._M_iterator(__lhs, "lhs")
502 			    ._M_iterator(__rhs, "rhs"));
503       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
504 			    _M_message(__msg_compare_different)
505 			    ._M_iterator(__lhs, "lhs")
506 			    ._M_iterator(__rhs, "rhs"));
507       return __lhs.base() == __rhs.base();
508     }
509 
510   template<typename _Iterator, typename _Sequence>
511     inline bool
512     operator==(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
513 	       const _Safe_iterator<_Iterator, _Sequence>& __rhs)
514     _GLIBCXX_NOEXCEPT
515     {
516       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
517 			    _M_message(__msg_iter_compare_bad)
518 			    ._M_iterator(__lhs, "lhs")
519 			    ._M_iterator(__rhs, "rhs"));
520       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
521 			    _M_message(__msg_compare_different)
522 			    ._M_iterator(__lhs, "lhs")
523 			    ._M_iterator(__rhs, "rhs"));
524       return __lhs.base() == __rhs.base();
525     }
526 
527   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
528     inline bool
529     operator!=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
530 	       const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
531     _GLIBCXX_NOEXCEPT
532     {
533       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
534 			    _M_message(__msg_iter_compare_bad)
535 			    ._M_iterator(__lhs, "lhs")
536 			    ._M_iterator(__rhs, "rhs"));
537       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
538 			    _M_message(__msg_compare_different)
539 			    ._M_iterator(__lhs, "lhs")
540 			    ._M_iterator(__rhs, "rhs"));
541       return __lhs.base() != __rhs.base();
542     }
543 
544   template<typename _Iterator, typename _Sequence>
545     inline bool
546     operator!=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
547 	       const _Safe_iterator<_Iterator, _Sequence>& __rhs)
548     _GLIBCXX_NOEXCEPT
549     {
550       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
551 			    _M_message(__msg_iter_compare_bad)
552 			    ._M_iterator(__lhs, "lhs")
553 			    ._M_iterator(__rhs, "rhs"));
554       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
555 			    _M_message(__msg_compare_different)
556 			    ._M_iterator(__lhs, "lhs")
557 			    ._M_iterator(__rhs, "rhs"));
558       return __lhs.base() != __rhs.base();
559     }
560 
561   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
562     inline bool
563     operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
564 	      const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
565     _GLIBCXX_NOEXCEPT
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 _Iterator, typename _Sequence>
579     inline bool
580     operator<(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
581 	      const _Safe_iterator<_Iterator, _Sequence>& __rhs)
582     _GLIBCXX_NOEXCEPT
583     {
584       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
585 			    _M_message(__msg_iter_order_bad)
586 			    ._M_iterator(__lhs, "lhs")
587 			    ._M_iterator(__rhs, "rhs"));
588       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
589 			    _M_message(__msg_order_different)
590 			    ._M_iterator(__lhs, "lhs")
591 			    ._M_iterator(__rhs, "rhs"));
592       return __lhs.base() < __rhs.base();
593     }
594 
595   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
596     inline bool
597     operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
598 	       const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
599     _GLIBCXX_NOEXCEPT
600     {
601       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
602 			    _M_message(__msg_iter_order_bad)
603 			    ._M_iterator(__lhs, "lhs")
604 			    ._M_iterator(__rhs, "rhs"));
605       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
606 			    _M_message(__msg_order_different)
607 			    ._M_iterator(__lhs, "lhs")
608 			    ._M_iterator(__rhs, "rhs"));
609       return __lhs.base() <= __rhs.base();
610     }
611 
612   template<typename _Iterator, typename _Sequence>
613     inline bool
614     operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
615 	       const _Safe_iterator<_Iterator, _Sequence>& __rhs)
616     _GLIBCXX_NOEXCEPT
617     {
618       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
619 			    _M_message(__msg_iter_order_bad)
620 			    ._M_iterator(__lhs, "lhs")
621 			    ._M_iterator(__rhs, "rhs"));
622       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
623 			    _M_message(__msg_order_different)
624 			    ._M_iterator(__lhs, "lhs")
625 			    ._M_iterator(__rhs, "rhs"));
626       return __lhs.base() <= __rhs.base();
627     }
628 
629   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
630     inline bool
631     operator>(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
632 	      const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
633     _GLIBCXX_NOEXCEPT
634     {
635       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
636 			    _M_message(__msg_iter_order_bad)
637 			    ._M_iterator(__lhs, "lhs")
638 			    ._M_iterator(__rhs, "rhs"));
639       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
640 			    _M_message(__msg_order_different)
641 			    ._M_iterator(__lhs, "lhs")
642 			    ._M_iterator(__rhs, "rhs"));
643       return __lhs.base() > __rhs.base();
644     }
645 
646   template<typename _Iterator, typename _Sequence>
647     inline bool
648     operator>(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
649 	      const _Safe_iterator<_Iterator, _Sequence>& __rhs)
650     _GLIBCXX_NOEXCEPT
651     {
652       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
653 			    _M_message(__msg_iter_order_bad)
654 			    ._M_iterator(__lhs, "lhs")
655 			    ._M_iterator(__rhs, "rhs"));
656       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
657 			    _M_message(__msg_order_different)
658 			    ._M_iterator(__lhs, "lhs")
659 			    ._M_iterator(__rhs, "rhs"));
660       return __lhs.base() > __rhs.base();
661     }
662 
663   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
664     inline bool
665     operator>=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
666 	       const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
667     _GLIBCXX_NOEXCEPT
668     {
669       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
670 			    _M_message(__msg_iter_order_bad)
671 			    ._M_iterator(__lhs, "lhs")
672 			    ._M_iterator(__rhs, "rhs"));
673       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
674 			    _M_message(__msg_order_different)
675 			    ._M_iterator(__lhs, "lhs")
676 			    ._M_iterator(__rhs, "rhs"));
677       return __lhs.base() >= __rhs.base();
678     }
679 
680   template<typename _Iterator, typename _Sequence>
681     inline bool
682     operator>=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
683 	       const _Safe_iterator<_Iterator, _Sequence>& __rhs)
684     _GLIBCXX_NOEXCEPT
685     {
686       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
687 			    _M_message(__msg_iter_order_bad)
688 			    ._M_iterator(__lhs, "lhs")
689 			    ._M_iterator(__rhs, "rhs"));
690       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
691 			    _M_message(__msg_order_different)
692 			    ._M_iterator(__lhs, "lhs")
693 			    ._M_iterator(__rhs, "rhs"));
694       return __lhs.base() >= __rhs.base();
695     }
696 
697   // _GLIBCXX_RESOLVE_LIB_DEFECTS
698   // According to the resolution of DR179 not only the various comparison
699   // operators but also operator- must accept mixed iterator/const_iterator
700   // parameters.
701   template<typename _IteratorL, typename _IteratorR, typename _Sequence>
702     inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type
703     operator-(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
704 	      const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
705     _GLIBCXX_NOEXCEPT
706     {
707       _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
708 			    _M_message(__msg_distance_bad)
709 			    ._M_iterator(__lhs, "lhs")
710 			    ._M_iterator(__rhs, "rhs"));
711       _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
712 			    _M_message(__msg_distance_different)
713 			    ._M_iterator(__lhs, "lhs")
714 			    ._M_iterator(__rhs, "rhs"));
715       return __lhs.base() - __rhs.base();
716     }
717 
718    template<typename _Iterator, typename _Sequence>
719      inline typename _Safe_iterator<_Iterator, _Sequence>::difference_type
720      operator-(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
721 	       const _Safe_iterator<_Iterator, _Sequence>& __rhs)
722     _GLIBCXX_NOEXCEPT
723      {
724        _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
725 			     _M_message(__msg_distance_bad)
726 			     ._M_iterator(__lhs, "lhs")
727 			     ._M_iterator(__rhs, "rhs"));
728        _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
729 			     _M_message(__msg_distance_different)
730 			     ._M_iterator(__lhs, "lhs")
731 			     ._M_iterator(__rhs, "rhs"));
732        return __lhs.base() - __rhs.base();
733      }
734 
735   template<typename _Iterator, typename _Sequence>
736     inline _Safe_iterator<_Iterator, _Sequence>
737     operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n,
738 	      const _Safe_iterator<_Iterator, _Sequence>& __i) _GLIBCXX_NOEXCEPT
739     { return __i + __n; }
740 
741   /** Safe iterators know if they are dereferenceable. */
742   template<typename _Iterator, typename _Sequence>
743     inline bool
__check_dereferenceable(const _Safe_iterator<_Iterator,_Sequence> & __x)744     __check_dereferenceable(const _Safe_iterator<_Iterator, _Sequence>& __x)
745     { return __x._M_dereferenceable(); }
746 
747   /** Safe iterators know how to check if they form a valid range. */
748   template<typename _Iterator, typename _Sequence>
749     inline bool
__valid_range(const _Safe_iterator<_Iterator,_Sequence> & __first,const _Safe_iterator<_Iterator,_Sequence> & __last,typename _Distance_traits<_Iterator>::__type & __dist)750     __valid_range(const _Safe_iterator<_Iterator, _Sequence>& __first,
751 		  const _Safe_iterator<_Iterator, _Sequence>& __last,
752 		  typename _Distance_traits<_Iterator>::__type& __dist)
753     { return __first._M_valid_range(__last, __dist); }
754 
755   /** Safe iterators can help to get better distance knowledge. */
756   template<typename _Iterator, typename _Sequence>
757     inline typename _Distance_traits<_Iterator>::__type
__get_distance(const _Safe_iterator<_Iterator,_Sequence> & __first,const _Safe_iterator<_Iterator,_Sequence> & __last,std::random_access_iterator_tag)758     __get_distance(const _Safe_iterator<_Iterator, _Sequence>& __first,
759 		   const _Safe_iterator<_Iterator, _Sequence>& __last,
760 		   std::random_access_iterator_tag)
761     { return std::make_pair(__last.base() - __first.base(), __dp_exact); }
762 
763   template<typename _Iterator, typename _Sequence>
764     inline typename _Distance_traits<_Iterator>::__type
__get_distance(const _Safe_iterator<_Iterator,_Sequence> & __first,const _Safe_iterator<_Iterator,_Sequence> & __last,std::input_iterator_tag)765     __get_distance(const _Safe_iterator<_Iterator, _Sequence>& __first,
766 		   const _Safe_iterator<_Iterator, _Sequence>& __last,
767 		   std::input_iterator_tag)
768     {
769       typedef typename _Distance_traits<_Iterator>::__type _Diff;
770       typedef _Sequence_traits<_Sequence> _SeqTraits;
771 
772       if (__first.base() == __last.base())
773 	return std::make_pair(0, __dp_exact);
774 
775       if (__first._M_is_before_begin())
776 	{
777 	  if (__last._M_is_begin())
778 	    return std::make_pair(1, __dp_exact);
779 
780 	  return std::make_pair(1, __dp_sign);
781 	}
782 
783       if (__first._M_is_begin())
784 	{
785 	  if (__last._M_is_before_begin())
786 	    return std::make_pair(-1, __dp_exact);
787 
788 	  if (__last._M_is_end())
789 	    return _SeqTraits::_S_size(*__first._M_get_sequence());
790 
791 	  return std::make_pair(1, __dp_sign);
792 	}
793 
794       if (__first._M_is_end())
795 	{
796 	  if (__last._M_is_before_begin())
797 	    return std::make_pair(-1, __dp_exact);
798 
799 	  if (__last._M_is_begin())
800 	    {
801 	      _Diff __diff = _SeqTraits::_S_size(*__first._M_get_sequence());
802 	      return std::make_pair(-__diff.first, __diff.second);
803 	    }
804 
805 	  return std::make_pair(-1, __dp_sign);
806 	}
807 
808       if (__last._M_is_before_begin() || __last._M_is_begin())
809 	return std::make_pair(-1, __dp_sign);
810 
811       if (__last._M_is_end())
812 	return std::make_pair(1, __dp_sign);
813 
814       return std::make_pair(1, __dp_equality);
815     }
816 
817   // Get distance from sequence begin to specified iterator.
818   template<typename _Iterator, typename _Sequence>
819     inline typename _Distance_traits<_Iterator>::__type
__get_distance_from_begin(const _Safe_iterator<_Iterator,_Sequence> & __it)820     __get_distance_from_begin(const _Safe_iterator<_Iterator, _Sequence>& __it)
821     {
822       typedef _Sequence_traits<_Sequence> _SeqTraits;
823 
824       // No need to consider before_begin as this function is only used in
825       // _M_can_advance which won't be used for forward_list iterators.
826       if (__it._M_is_begin())
827 	return std::make_pair(0, __dp_exact);
828 
829       if (__it._M_is_end())
830 	return _SeqTraits::_S_size(*__it._M_get_sequence());
831 
832       typename _Distance_traits<_Iterator>::__type __res
833 	= __get_distance(__it._M_get_sequence()->_M_base().begin(), __it.base());
834 
835       if (__res.second == __dp_equality)
836 	return std::make_pair(1, __dp_sign);
837 
838       return __res;
839     }
840 
841   // Get distance from specified iterator to sequence end.
842   template<typename _Iterator, typename _Sequence>
843     inline typename _Distance_traits<_Iterator>::__type
__get_distance_to_end(const _Safe_iterator<_Iterator,_Sequence> & __it)844     __get_distance_to_end(const _Safe_iterator<_Iterator, _Sequence>& __it)
845     {
846       typedef _Sequence_traits<_Sequence> _SeqTraits;
847 
848       // No need to consider before_begin as this function is only used in
849       // _M_can_advance which won't be used for forward_list iterators.
850       if (__it._M_is_begin())
851 	return _SeqTraits::_S_size(*__it._M_get_sequence());
852 
853       if (__it._M_is_end())
854 	return std::make_pair(0, __dp_exact);
855 
856       typename _Distance_traits<_Iterator>::__type __res
857 	= __get_distance(__it.base(), __it._M_get_sequence()->_M_base().end());
858 
859       if (__res.second == __dp_equality)
860 	return std::make_pair(1, __dp_sign);
861 
862       return __res;
863     }
864 
865 #if __cplusplus < 201103L
866   template<typename _Iterator, typename _Sequence>
867     struct __is_safe_random_iterator<_Safe_iterator<_Iterator, _Sequence> >
868     : std::__are_same<std::random_access_iterator_tag,
869                       typename std::iterator_traits<_Iterator>::
870 		      iterator_category>
871     { };
872 #else
873   template<typename _Iterator, typename _Sequence>
874     _Iterator
875     __base(const _Safe_iterator<_Iterator, _Sequence>& __it,
876 	   std::random_access_iterator_tag)
877     { return __it.base(); }
878 
879   template<typename _Iterator, typename _Sequence>
880     const _Safe_iterator<_Iterator, _Sequence>&
881     __base(const _Safe_iterator<_Iterator, _Sequence>& __it,
882 	   std::input_iterator_tag)
883     { return __it; }
884 
885   template<typename _Iterator, typename _Sequence>
886     auto
887     __base(const _Safe_iterator<_Iterator, _Sequence>& __it)
888     -> decltype(__base(__it, std::__iterator_category(__it)))
889     { return __base(__it, std::__iterator_category(__it)); }
890 #endif
891 
892 #if __cplusplus < 201103L
893   template<typename _Iterator, typename _Sequence>
894     struct _Unsafe_type<_Safe_iterator<_Iterator, _Sequence> >
895     { typedef _Iterator _Type; };
896 #endif
897 
898   template<typename _Iterator, typename _Sequence>
899     inline _Iterator
900     __unsafe(const _Safe_iterator<_Iterator, _Sequence>& __it)
901     { return __it.base(); }
902 
903 } // namespace __gnu_debug
904 
905 #include <debug/safe_iterator.tcc>
906 
907 #endif
908