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