STLdoc
STLdocumentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
safe_local_iterator.h
Go to the documentation of this file.
1 // Safe iterator implementation -*- C++ -*-
2 
3 // Copyright (C) 2011-2013 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 
29 #ifndef _GLIBCXX_DEBUG_SAFE_LOCAL_ITERATOR_H
30 #define _GLIBCXX_DEBUG_SAFE_LOCAL_ITERATOR_H 1
31 
32 #include <debug/debug.h>
33 #include <debug/macros.h>
34 #include <debug/functions.h>
36 #include <ext/type_traits.h>
37 
38 namespace __gnu_debug
39 {
51  template<typename _Iterator, typename _Sequence>
52  class _Safe_local_iterator : public _Safe_local_iterator_base
53  {
55  typedef typename _Sequence::size_type size_type;
56 
58  _Iterator _M_current;
59 
62 
64  bool
65  _M_constant() const
66  {
67  typedef typename _Sequence::const_local_iterator const_iterator;
68  return std::__are_same<const_iterator, _Safe_local_iterator>::__value;
69  }
70 
71  typedef std::iterator_traits<_Iterator> _Traits;
72 
73  public:
74  typedef _Iterator iterator_type;
75  typedef typename _Traits::iterator_category iterator_category;
76  typedef typename _Traits::value_type value_type;
77  typedef typename _Traits::difference_type difference_type;
78  typedef typename _Traits::reference reference;
79  typedef typename _Traits::pointer pointer;
80 
83 
91  _Safe_local_iterator(const _Iterator& __i, size_type __bucket,
92  const _Sequence* __seq)
94  _M_bucket(__bucket)
95  {
97  _M_message(__msg_init_singular)
98  ._M_iterator(*this, "this"));
99  }
100 
107  {
108  // _GLIBCXX_RESOLVE_LIB_DEFECTS
109  // DR 408. Is vector<reverse_iterator<char*> > forbidden?
110  _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
111  || __x._M_current == _Iterator(),
112  _M_message(__msg_init_copy_singular)
113  ._M_iterator(*this, "this")
114  ._M_iterator(__x, "other"));
115  }
116 
121  template<typename _MutableIterator>
123  const _Safe_local_iterator<_MutableIterator,
124  typename __gnu_cxx::__enable_if<std::__are_same<
125  _MutableIterator,
126  typename _Sequence::local_iterator::iterator_type>::__value,
127  _Sequence>::__type>& __x)
129  _M_current(__x.base()), _M_bucket(__x._M_bucket)
130  {
131  // _GLIBCXX_RESOLVE_LIB_DEFECTS
132  // DR 408. Is vector<reverse_iterator<char*> > forbidden?
133  _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
134  || __x.base() == _Iterator(),
135  _M_message(__msg_init_const_singular)
136  ._M_iterator(*this, "this")
137  ._M_iterator(__x, "other"));
138  }
139 
145  {
146  // _GLIBCXX_RESOLVE_LIB_DEFECTS
147  // DR 408. Is vector<reverse_iterator<char*> > forbidden?
148  _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
149  || __x._M_current == _Iterator(),
150  _M_message(__msg_copy_singular)
151  ._M_iterator(*this, "this")
152  ._M_iterator(__x, "other"));
153  _M_current = __x._M_current;
154  _M_bucket = __x._M_bucket;
155  this->_M_attach(__x._M_sequence);
156  return *this;
157  }
158 
163  reference
164  operator*() const
165  {
167  _M_message(__msg_bad_deref)
168  ._M_iterator(*this, "this"));
169  return *_M_current;
170  }
171 
178  pointer
179  operator->() const
180  {
182  _M_message(__msg_bad_deref)
183  ._M_iterator(*this, "this"));
184  return &*_M_current;
185  }
186 
187  // ------ Input iterator requirements ------
194  {
196  _M_message(__msg_bad_inc)
197  ._M_iterator(*this, "this"));
198  ++_M_current;
199  return *this;
200  }
201 
208  {
210  _M_message(__msg_bad_inc)
211  ._M_iterator(*this, "this"));
212  _Safe_local_iterator __tmp(*this);
213  ++_M_current;
214  return __tmp;
215  }
216 
217  // ------ Utilities ------
221  _Iterator
222  base() const { return _M_current; }
223 
227  size_type
228  bucket() const { return _M_bucket; }
229 
234  operator _Iterator() const { return _M_current; }
235 
237  void
240 
242  void
245 
247  bool
249  { return !this->_M_singular() && !_M_is_end(); }
250 
252  bool
254  { return !this->_M_singular() && !_M_is_end(); }
255 
256  // Is the iterator range [*this, __rhs) valid?
257  template<typename _Other>
258  bool
260  _Sequence>& __rhs) const;
261 
262  // The sequence this iterator references.
263  const _Sequence*
265  { return static_cast<const _Sequence*>(_M_sequence); }
266 
268  bool _M_is_begin() const
269  { return base() == _M_get_sequence()->_M_base().begin(_M_bucket); }
270 
272  bool _M_is_end() const
273  { return base() == _M_get_sequence()->_M_base().end(_M_bucket); }
274 
276  template <typename _Other>
278  _Sequence>& __other) const
279  { return _M_bucket == __other.bucket(); }
280  };
281 
282  template<typename _IteratorL, typename _IteratorR, typename _Sequence>
283  inline bool
286  {
287  _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
288  _M_message(__msg_iter_compare_bad)
289  ._M_iterator(__lhs, "lhs")
290  ._M_iterator(__rhs, "rhs"));
291  _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
292  _M_message(__msg_compare_different)
293  ._M_iterator(__lhs, "lhs")
294  ._M_iterator(__rhs, "rhs"));
295  _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
296  _M_message(__msg_compare_different)
297  ._M_iterator(__lhs, "lhs")
298  ._M_iterator(__rhs, "rhs"));
299  _GLIBCXX_DEBUG_VERIFY(__lhs._M_in_same_bucket(__rhs),
300  _M_message(__msg_local_iter_compare_bad)
301  ._M_iterator(__lhs, "lhs")
302  ._M_iterator(__rhs, "rhs"));
303  return __lhs.base() == __rhs.base();
304  }
305 
306  template<typename _Iterator, typename _Sequence>
307  inline bool
310  {
311  _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
312  _M_message(__msg_iter_compare_bad)
313  ._M_iterator(__lhs, "lhs")
314  ._M_iterator(__rhs, "rhs"));
315  _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
316  _M_message(__msg_compare_different)
317  ._M_iterator(__lhs, "lhs")
318  ._M_iterator(__rhs, "rhs"));
319  _GLIBCXX_DEBUG_VERIFY(__lhs._M_in_same_bucket(__rhs),
320  _M_message(__msg_local_iter_compare_bad)
321  ._M_iterator(__lhs, "lhs")
322  ._M_iterator(__rhs, "rhs"));
323  return __lhs.base() == __rhs.base();
324  }
325 
326  template<typename _IteratorL, typename _IteratorR, typename _Sequence>
327  inline bool
330  {
331  _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
332  _M_message(__msg_iter_compare_bad)
333  ._M_iterator(__lhs, "lhs")
334  ._M_iterator(__rhs, "rhs"));
335  _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
336  _M_message(__msg_compare_different)
337  ._M_iterator(__lhs, "lhs")
338  ._M_iterator(__rhs, "rhs"));
339  _GLIBCXX_DEBUG_VERIFY(__lhs._M_in_same_bucket(__rhs),
340  _M_message(__msg_local_iter_compare_bad)
341  ._M_iterator(__lhs, "lhs")
342  ._M_iterator(__rhs, "rhs"));
343  return __lhs.base() != __rhs.base();
344  }
345 
346  template<typename _Iterator, typename _Sequence>
347  inline bool
350  {
351  _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
352  _M_message(__msg_iter_compare_bad)
353  ._M_iterator(__lhs, "lhs")
354  ._M_iterator(__rhs, "rhs"));
355  _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
356  _M_message(__msg_compare_different)
357  ._M_iterator(__lhs, "lhs")
358  ._M_iterator(__rhs, "rhs"));
359  _GLIBCXX_DEBUG_VERIFY(__lhs._M_in_same_bucket(__rhs),
360  _M_message(__msg_local_iter_compare_bad)
361  ._M_iterator(__lhs, "lhs")
362  ._M_iterator(__rhs, "rhs"));
363  return __lhs.base() != __rhs.base();
364  }
365 } // namespace __gnu_debug
366 
368 
369 #endif
Definition: formatter.h:86
_Iterator base() const
Return the underlying iterator.
Definition: safe_local_iterator.h:222
Definition: formatter.h:91
_Safe_local_iterator(const _Safe_local_iterator &__x)
Copy construction.
Definition: safe_local_iterator.h:104
bool _M_dereferenceable() const
Is the iterator dereferenceable?
Definition: safe_local_iterator.h:248
bool _M_is_begin() const
Is this iterator equal to the sequence's begin() iterator?
Definition: safe_local_iterator.h:268
Definition: formatter.h:84
_Iterator _M_current
The underlying iterator.
Definition: safe_local_iterator.h:58
void _M_attach_single(_Safe_sequence_base *__seq)
Definition: safe_local_iterator.h:243
_Safe_sequence_base * _M_sequence
Definition: safe_base.h:55
_Safe_local_iterator _Self
Definition: safe_local_iterator.h:54
reference operator*() const
Iterator dereference.
Definition: safe_local_iterator.h:164
size_type bucket() const
Return the bucket.
Definition: safe_local_iterator.h:228
_Safe_local_iterator(const _Safe_local_iterator< _MutableIterator, typename __gnu_cxx::__enable_if< std::__are_same< _MutableIterator, typename _Sequence::local_iterator::iterator_type >::__value, _Sequence >::__type > &__x)
Converting constructor from a mutable iterator to a constant iterator.
Definition: safe_local_iterator.h:122
Definition: formatter.h:92
Definition: formatter.h:85
bool _M_in_same_bucket(const _Safe_local_iterator< _Other, _Sequence > &__other) const
Is this iterator part of the same bucket as the other one?
Definition: safe_local_iterator.h:277
_Iterator iterator_type
Definition: safe_local_iterator.h:74
void _M_attach(_Safe_sequence_base *__seq, bool __constant)
size_type _M_bucket
The bucket this local iterator belongs to.
Definition: safe_local_iterator.h:61
_Safe_local_iterator()
Definition: safe_local_iterator.h:82
_Traits::reference reference
Definition: safe_local_iterator.h:78
_Safe_local_iterator operator++(int)
Iterator postincrement.
Definition: safe_local_iterator.h:207
_Sequence::size_type size_type
Definition: safe_local_iterator.h:55
Definition: formatter.h:83
const _Sequence * _M_get_sequence() const
Definition: safe_local_iterator.h:264
_Safe_local_iterator(const _Iterator &__i, size_type __bucket, const _Sequence *__seq)
Safe iterator construction from an unsafe iterator and its sequence.
Definition: safe_local_iterator.h:91
void _M_attach_single(_Safe_sequence_base *__seq, bool __constant)
std::iterator_traits< _Iterator > _Traits
Definition: safe_local_iterator.h:71
bool _M_constant() const
Determine if this is a constant iterator.
Definition: safe_local_iterator.h:65
_Traits::iterator_category iterator_category
Definition: safe_local_iterator.h:75
_Traits::pointer pointer
Definition: safe_local_iterator.h:79
_Safe_local_iterator & operator++()
Iterator preincrement.
Definition: safe_local_iterator.h:193
pointer operator->() const
Iterator dereference.
Definition: safe_local_iterator.h:179
_Safe_local_iterator & operator=(const _Safe_local_iterator &__x)
Copy assignment.
Definition: safe_local_iterator.h:144
Basic functionality for a safe iterator.
Definition: safe_unordered_base.h:50
Definition: formatter.h:81
_GLIBCXX_PURE bool _M_singular() const
Base class that supports tracking of iterators that reference a sequence.
Definition: safe_base.h:177
bool operator==(const _Safe_iterator< _IteratorL, _Sequence > &__lhs, const _Safe_iterator< _IteratorR, _Sequence > &__rhs)
Definition: safe_iterator.h:484
#define _GLIBCXX_DEBUG_VERIFY(_Condition, _ErrorMessage)
Definition: macros.h:49
void _M_attach(_Safe_sequence_base *__seq)
Definition: safe_local_iterator.h:238
bool _M_incrementable() const
Is the iterator incrementable?
Definition: safe_local_iterator.h:253
bool _M_valid_range(const _Safe_local_iterator< _Other, _Sequence > &__rhs) const
Definition: safe_local_iterator.tcc:38
_Traits::value_type value_type
Definition: safe_local_iterator.h:76
Safe iterator wrapper.
Definition: formatter.h:49
Definition: formatter.h:82
bool _M_is_end() const
Is this iterator equal to the sequence's end() iterator?
Definition: safe_local_iterator.h:272
bool operator!=(const _Safe_iterator< _IteratorL, _Sequence > &__lhs, const _Safe_iterator< _IteratorR, _Sequence > &__rhs)
Definition: safe_iterator.h:516
_Traits::difference_type difference_type
Definition: safe_local_iterator.h:77