safe_iterator.tcc revision 1.1.1.1
1// Debugging iterator implementation (out of line) -*- C++ -*-
2
3// Copyright (C) 2003, 2004, 2005, 2006
4// Free Software Foundation, Inc.
5//
6// This file is part of the GNU ISO C++ Library.  This library is free
7// software; you can redistribute it and/or modify it under the
8// terms of the GNU General Public License as published by the
9// Free Software Foundation; either version 2, or (at your option)
10// any later version.
11
12// This library is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16
17// You should have received a copy of the GNU General Public License along
18// with this library; see the file COPYING.  If not, write to the Free
19// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20// USA.
21
22// As a special exception, you may use this file as part of a free software
23// library without restriction.  Specifically, if other files instantiate
24// templates or use macros or inline functions from this file, or you compile
25// this file and link it with other files to produce an executable, this
26// file does not by itself cause the resulting executable to be covered by
27// the GNU General Public License.  This exception does not however
28// invalidate any other reasons why the executable file might be covered by
29// the GNU General Public License.
30
31/** @file debug/safe_iterator.tcc
32 *  This file is a GNU debug extension to the Standard C++ Library.
33 */
34
35#ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_TCC
36#define _GLIBCXX_DEBUG_SAFE_ITERATOR_TCC 1
37
38namespace __gnu_debug
39{
40  template<typename _Iterator, typename _Sequence>
41    bool
42    _Safe_iterator<_Iterator, _Sequence>::
43    _M_can_advance(const difference_type& __n) const
44    {
45      typedef typename _Sequence::const_iterator const_iterator;
46
47      if (this->_M_singular())
48	return false;
49      if (__n == 0)
50	return true;
51      if (__n < 0)
52	{
53	  const_iterator __begin =
54	    static_cast<const _Sequence*>(_M_sequence)->begin();
55	  std::pair<difference_type, _Distance_precision> __dist =
56	    this->_M_get_distance(__begin, *this);
57	  bool __ok =  (__dist.second == __dp_exact && __dist.first >= -__n
58			|| __dist.second != __dp_exact && __dist.first > 0);
59	  return __ok;
60	}
61      else
62	{
63	  const_iterator __end =
64	    static_cast<const _Sequence*>(_M_sequence)->end();
65	  std::pair<difference_type, _Distance_precision> __dist =
66	    this->_M_get_distance(*this, __end);
67	  bool __ok = (__dist.second == __dp_exact && __dist.first >= __n
68		       || __dist.second != __dp_exact && __dist.first > 0);
69	  return __ok;
70	}
71    }
72
73  template<typename _Iterator, typename _Sequence>
74    template<typename _Other>
75      bool
76      _Safe_iterator<_Iterator, _Sequence>::
77      _M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const
78      {
79	if (!_M_can_compare(__rhs))
80	  return false;
81
82	/* Determine if we can order the iterators without the help of
83	   the container */
84	std::pair<difference_type, _Distance_precision> __dist =
85	  this->_M_get_distance(*this, __rhs);
86	switch (__dist.second) {
87	case __dp_equality:
88	  if (__dist.first == 0)
89	    return true;
90	  break;
91
92	case __dp_sign:
93	case __dp_exact:
94	  return __dist.first >= 0;
95	}
96
97	/* We can only test for equality, but check if one of the
98	   iterators is at an extreme. */
99	if (_M_is_begin() || __rhs._M_is_end())
100	  return true;
101	else if (_M_is_end() || __rhs._M_is_begin())
102	  return false;
103
104	// Assume that this is a valid range; we can't check anything else
105	return true;
106      }
107
108  template<typename _Iterator, typename _Sequence>
109    void
110    _Safe_iterator<_Iterator, _Sequence>::
111    _M_invalidate()
112    {
113      __gnu_cxx::__scoped_lock sentry(this->_M_get_mutex());
114      _M_invalidate_single();
115    }
116
117  template<typename _Iterator, typename _Sequence>
118    void
119    _Safe_iterator<_Iterator, _Sequence>::
120    _M_invalidate_single()
121    {
122      typedef typename _Sequence::iterator iterator;
123      typedef typename _Sequence::const_iterator const_iterator;
124
125      if (!this->_M_singular())
126	{
127	  for (_Safe_iterator_base* __iter = _M_sequence->_M_iterators;
128	       __iter; __iter = __iter->_M_next)
129	    {
130	      iterator* __victim = static_cast<iterator*>(__iter);
131	      if (this->base() == __victim->base())
132		__victim->_M_version = 0;
133	    }
134
135	  for (_Safe_iterator_base* __iter2 = _M_sequence->_M_const_iterators;
136	       __iter2; __iter2 = __iter2->_M_next)
137	    {
138	      const_iterator* __victim = static_cast<const_iterator*>(__iter2);
139	      if (__victim->base() == this->base())
140		__victim->_M_version = 0;
141	    }
142	  _M_version = 0;
143	}
144    }
145} // namespace __gnu_debug
146
147#endif
148
149