111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Safe iterator implementation  -*- C++ -*-
211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Copyright (C) 2011-2014 Free Software Foundation, Inc.
411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//
511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This file is part of the GNU ISO C++ Library.  This library is free
611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// software; you can redistribute it and/or modify it under the
711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// terms of the GNU General Public License as published by the
811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Free Software Foundation; either version 3, or (at your option)
911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// any later version.
1011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
1111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This library is distributed in the hope that it will be useful,
1211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// but WITHOUT ANY WARRANTY; without even the implied warranty of
1311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// GNU General Public License for more details.
1511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
1611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Under Section 7 of GPL version 3, you are granted additional
1711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// permissions described in the GCC Runtime Library Exception, version
1811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 3.1, as published by the Free Software Foundation.
1911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
2011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// You should have received a copy of the GNU General Public License and
2111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// a copy of the GCC Runtime Library Exception along with this program;
2211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// <http://www.gnu.org/licenses/>.
2411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
2511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/** @file debug/safe_local_iterator.h
2611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *  This file is a GNU debug extension to the Standard C++ Library.
2711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
2811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
2911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef _GLIBCXX_DEBUG_SAFE_LOCAL_ITERATOR_H
3011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define _GLIBCXX_DEBUG_SAFE_LOCAL_ITERATOR_H 1
3111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
3211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <debug/debug.h>
3311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <debug/macros.h>
3411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <debug/functions.h>
3511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <debug/safe_unordered_base.h>
3611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <ext/type_traits.h>
3711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
3811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertnamespace __gnu_debug
3911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
4011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  /** \brief Safe iterator wrapper.
4111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   *
4211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   *  The class template %_Safe_local_iterator is a wrapper around an
4311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   *  iterator that tracks the iterator's movement among sequences and
4411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   *  checks that operations performed on the "safe" iterator are
4511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   *  legal. In additional to the basic iterator operations (which are
4611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   *  validated, and then passed to the underlying iterator),
4711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   *  %_Safe_local_iterator has member functions for iterator invalidation,
4811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   *  attaching/detaching the iterator from sequences, and querying
4911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   *  the iterator's state.
5011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   */
5111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  template<typename _Iterator, typename _Sequence>
5211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    class _Safe_local_iterator : public _Safe_local_iterator_base
5311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
5411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef _Safe_local_iterator _Self;
5511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef typename _Sequence::const_local_iterator _Const_local_iterator;
5611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef typename _Sequence::size_type size_type;
5711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
5811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      /// The underlying iterator
5911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _Iterator _M_current;
6011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
6111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      /// Determine if this is a constant iterator.
6211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      bool
6311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _M_constant() const
6411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      {
6511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return std::__are_same<_Const_local_iterator,
6611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			       _Safe_local_iterator>::__value;
6711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
6811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
6911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef std::iterator_traits<_Iterator> _Traits;
7011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
7111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    public:
7211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef _Iterator                           iterator_type;
7311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef typename _Traits::iterator_category iterator_category;
7411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef typename _Traits::value_type        value_type;
7511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef typename _Traits::difference_type   difference_type;
7611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef typename _Traits::reference         reference;
7711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef typename _Traits::pointer           pointer;
7811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
7911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      /// @post the iterator is singular and unattached
8011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _Safe_local_iterator() : _M_current() { }
8111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
8211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      /**
8311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       * @brief Safe iterator construction from an unsafe iterator and
8411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       * its sequence.
8511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       *
8611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       * @pre @p seq is not NULL
8711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       * @post this is not singular
8811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       */
8911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _Safe_local_iterator(const _Iterator& __i, const _Sequence* __seq)
9011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      : _Safe_local_iterator_base(__seq, _M_constant()), _M_current(__i)
9111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      {
9211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	_GLIBCXX_DEBUG_VERIFY(!this->_M_singular(),
9311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			      _M_message(__msg_init_singular)
9411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			      ._M_iterator(*this, "this"));
9511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
9611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
9711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      /**
9811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       * @brief Copy construction.
9911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       */
10011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _Safe_local_iterator(const _Safe_local_iterator& __x)
10111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      : _Safe_local_iterator_base(__x, _M_constant()),
10211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	_M_current(__x._M_current)
10311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      {
10411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	// _GLIBCXX_RESOLVE_LIB_DEFECTS
10511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	// DR 408. Is vector<reverse_iterator<char*> > forbidden?
10611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
10711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			      || __x.base() == _Iterator(),
10811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			      _M_message(__msg_init_copy_singular)
10911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			      ._M_iterator(*this, "this")
11011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			      ._M_iterator(__x, "other"));
11111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
11211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
11311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      /**
11411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       *  @brief Converting constructor from a mutable iterator to a
11511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       *  constant iterator.
11611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      */
11711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      template<typename _MutableIterator>
11811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	_Safe_local_iterator(
11911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  const _Safe_local_iterator<_MutableIterator,
12011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  typename __gnu_cxx::__enable_if<std::__are_same<
12111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	      _MutableIterator,
12211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	      typename _Sequence::local_iterator::iterator_type>::__value,
12311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert					  _Sequence>::__type>& __x)
12411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	: _Safe_local_iterator_base(__x, _M_constant()),
12511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  _M_current(__x.base())
12611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	{
12711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
12811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  // DR 408. Is vector<reverse_iterator<char*> > forbidden?
12911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
13011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				|| __x.base() == _Iterator(),
13111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				_M_message(__msg_init_const_singular)
13211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				._M_iterator(*this, "this")
13311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				._M_iterator(__x, "other"));
13411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
13511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
13611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      /**
13711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       * @brief Copy assignment.
13811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       */
13911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _Safe_local_iterator&
14011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      operator=(const _Safe_local_iterator& __x)
14111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      {
14211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	// _GLIBCXX_RESOLVE_LIB_DEFECTS
14311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	// DR 408. Is vector<reverse_iterator<char*> > forbidden?
14411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	_GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
14511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			      || __x.base() == _Iterator(),
14611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			      _M_message(__msg_copy_singular)
14711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			      ._M_iterator(*this, "this")
14811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			      ._M_iterator(__x, "other"));
14911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	_M_current = __x._M_current;
15011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	this->_M_attach(__x._M_sequence);
15111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return *this;
15211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
15311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
15411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      /**
15511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       *  @brief Iterator dereference.
15611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       *  @pre iterator is dereferenceable
15711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       */
15811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      reference
15911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      operator*() const
16011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      {
16111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	_GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
16211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			      _M_message(__msg_bad_deref)
16311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			      ._M_iterator(*this, "this"));
16411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return *_M_current;
16511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
16611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
16711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      /**
16811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       *  @brief Iterator dereference.
16911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       *  @pre iterator is dereferenceable
17011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       *  @todo Make this correct w.r.t. iterators that return proxies
17111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       */
17211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      pointer
17311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      operator->() const
17411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      {
17511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	_GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
17611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			      _M_message(__msg_bad_deref)
17711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			      ._M_iterator(*this, "this"));
17811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return std::__addressof(*_M_current);
17911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
18011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
18111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      // ------ Input iterator requirements ------
18211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      /**
18311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       *  @brief Iterator preincrement
18411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       *  @pre iterator is incrementable
18511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       */
18611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _Safe_local_iterator&
18711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      operator++()
18811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      {
18911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	_GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
19011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			      _M_message(__msg_bad_inc)
19111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			      ._M_iterator(*this, "this"));
19211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	++_M_current;
19311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return *this;
19411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
19511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
19611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      /**
19711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       *  @brief Iterator postincrement
19811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       *  @pre iterator is incrementable
19911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       */
20011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _Safe_local_iterator
20111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      operator++(int)
20211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      {
20311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	_GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
20411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			      _M_message(__msg_bad_inc)
20511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			      ._M_iterator(*this, "this"));
20611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	_Safe_local_iterator __tmp(*this);
20711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	++_M_current;
20811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return __tmp;
20911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
21011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
21111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      // ------ Utilities ------
21211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      /**
21311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       * @brief Return the underlying iterator
21411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       */
21511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _Iterator
21611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      base() const { return _M_current; }
21711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
21811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      /**
21911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       * @brief Return the bucket
22011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       */
22111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      size_type
22211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      bucket() const { return _M_current._M_get_bucket(); }
22311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
22411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      /**
22511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       * @brief Conversion to underlying non-debug iterator to allow
22611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       * better interaction with non-debug containers.
22711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert       */
22811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      operator _Iterator() const { return _M_current; }
22911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
23011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      /** Attach iterator to the given sequence. */
23111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      void
23211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _M_attach(_Safe_sequence_base* __seq)
23311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      { _Safe_iterator_base::_M_attach(__seq, _M_constant()); }
23411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
23511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      /** Likewise, but not thread-safe. */
23611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      void
23711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _M_attach_single(_Safe_sequence_base* __seq)
23811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      { _Safe_iterator_base::_M_attach_single(__seq, _M_constant()); }
23911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
24011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      /// Is the iterator dereferenceable?
24111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      bool
24211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _M_dereferenceable() const
24311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      { return !this->_M_singular() && !_M_is_end(); }
24411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
24511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      /// Is the iterator incrementable?
24611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      bool
24711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _M_incrementable() const
24811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      { return !this->_M_singular() && !_M_is_end(); }
24911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
25011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      // Is the iterator range [*this, __rhs) valid?
25111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      bool
25211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _M_valid_range(const _Safe_local_iterator& __rhs) const;
25311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
25411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      // The sequence this iterator references.
25511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typename
25611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __gnu_cxx::__conditional_type<std::__are_same<_Const_local_iterator,
25711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert						    _Safe_local_iterator>::__value,
25811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				    const _Sequence*,
25911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				    _Sequence*>::__type
26011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _M_get_sequence() const
26111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      { return static_cast<_Sequence*>(_M_sequence); }
26211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
26311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      /// Is this iterator equal to the sequence's begin(bucket) iterator?
26411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      bool _M_is_begin() const
26511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      { return base() == _M_get_sequence()->_M_base().begin(bucket()); }
26611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
26711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      /// Is this iterator equal to the sequence's end(bucket) iterator?
26811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      bool _M_is_end() const
26911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      { return base() == _M_get_sequence()->_M_base().end(bucket()); }
27011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
27111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      /// Is this iterator part of the same bucket as the other one?
27211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      template<typename _Other>
27311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	bool
27411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	_M_in_same_bucket(const _Safe_local_iterator<_Other,
27511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert						     _Sequence>& __other) const
27611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	{ return bucket() == __other.bucket(); }
27711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    };
27811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
27911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  template<typename _IteratorL, typename _IteratorR, typename _Sequence>
28011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    inline bool
28111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    operator==(const _Safe_local_iterator<_IteratorL, _Sequence>& __lhs,
28211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	       const _Safe_local_iterator<_IteratorR, _Sequence>& __rhs)
28311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
28411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
28511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    _M_message(__msg_iter_compare_bad)
28611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    ._M_iterator(__lhs, "lhs")
28711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    ._M_iterator(__rhs, "rhs"));
28811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
28911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    _M_message(__msg_compare_different)
29011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    ._M_iterator(__lhs, "lhs")
29111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    ._M_iterator(__rhs, "rhs"));
29211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _GLIBCXX_DEBUG_VERIFY(__lhs._M_in_same_bucket(__rhs),
29311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    _M_message(__msg_local_iter_compare_bad)
29411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    ._M_iterator(__lhs, "lhs")
29511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    ._M_iterator(__rhs, "rhs"));
29611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return __lhs.base() == __rhs.base();
29711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
29811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
29911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  template<typename _Iterator, typename _Sequence>
30011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    inline bool
30111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    operator==(const _Safe_local_iterator<_Iterator, _Sequence>& __lhs,
30211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	       const _Safe_local_iterator<_Iterator, _Sequence>& __rhs)
30311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
30411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
30511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    _M_message(__msg_iter_compare_bad)
30611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    ._M_iterator(__lhs, "lhs")
30711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    ._M_iterator(__rhs, "rhs"));
30811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
30911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    _M_message(__msg_compare_different)
31011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    ._M_iterator(__lhs, "lhs")
31111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    ._M_iterator(__rhs, "rhs"));
31211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _GLIBCXX_DEBUG_VERIFY(__lhs._M_in_same_bucket(__rhs),
31311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    _M_message(__msg_local_iter_compare_bad)
31411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    ._M_iterator(__lhs, "lhs")
31511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    ._M_iterator(__rhs, "rhs"));
31611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return __lhs.base() == __rhs.base();
31711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
31811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
31911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  template<typename _IteratorL, typename _IteratorR, typename _Sequence>
32011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    inline bool
32111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    operator!=(const _Safe_local_iterator<_IteratorL, _Sequence>& __lhs,
32211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	       const _Safe_local_iterator<_IteratorR, _Sequence>& __rhs)
32311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
32411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
32511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    _M_message(__msg_iter_compare_bad)
32611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    ._M_iterator(__lhs, "lhs")
32711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    ._M_iterator(__rhs, "rhs"));
32811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
32911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    _M_message(__msg_compare_different)
33011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    ._M_iterator(__lhs, "lhs")
33111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    ._M_iterator(__rhs, "rhs"));
33211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _GLIBCXX_DEBUG_VERIFY(__lhs._M_in_same_bucket(__rhs),
33311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    _M_message(__msg_local_iter_compare_bad)
33411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    ._M_iterator(__lhs, "lhs")
33511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    ._M_iterator(__rhs, "rhs"));
33611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return __lhs.base() != __rhs.base();
33711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
33811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
33911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  template<typename _Iterator, typename _Sequence>
34011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    inline bool
34111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    operator!=(const _Safe_local_iterator<_Iterator, _Sequence>& __lhs,
34211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	       const _Safe_local_iterator<_Iterator, _Sequence>& __rhs)
34311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
34411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _GLIBCXX_DEBUG_VERIFY(!__lhs._M_singular() && !__rhs._M_singular(),
34511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    _M_message(__msg_iter_compare_bad)
34611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    ._M_iterator(__lhs, "lhs")
34711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    ._M_iterator(__rhs, "rhs"));
34811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
34911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    _M_message(__msg_compare_different)
35011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    ._M_iterator(__lhs, "lhs")
35111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    ._M_iterator(__rhs, "rhs"));
35211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _GLIBCXX_DEBUG_VERIFY(__lhs._M_in_same_bucket(__rhs),
35311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    _M_message(__msg_local_iter_compare_bad)
35411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    ._M_iterator(__lhs, "lhs")
35511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    ._M_iterator(__rhs, "rhs"));
35611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return __lhs.base() != __rhs.base();
35711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
35811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} // namespace __gnu_debug
35911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
36011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <debug/safe_local_iterator.tcc>
36111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
36211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
363