]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/debug/safe_iterator.h
* many: Replace uses of __GXX_EXPERIMENTAL_CXX0X__ with __cplusplus.
[thirdparty/gcc.git] / libstdc++-v3 / include / debug / safe_iterator.h
CommitLineData
285b36d6
BK
1// Safe iterator implementation -*- C++ -*-
2
8ad8655c 3// Copyright (C) 2003, 2004, 2005, 2006, 2009, 2010, 2011, 2012
285b36d6
BK
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
748086b7 9// Free Software Foundation; either version 3, or (at your option)
285b36d6
BK
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
748086b7
JJ
17// Under Section 7 of GPL version 3, you are granted additional
18// permissions described in the GCC Runtime Library Exception, version
19// 3.1, as published by the Free Software Foundation.
285b36d6 20
748086b7
JJ
21// You should have received a copy of the GNU General Public License and
22// a copy of the GCC Runtime Library Exception along with this program;
23// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24// <http://www.gnu.org/licenses/>.
285b36d6 25
78a53887
BK
26/** @file debug/safe_iterator.h
27 * This file is a GNU debug extension to the Standard C++ Library.
28 */
29
285b36d6
BK
30#ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H
31#define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1
32
285b36d6 33#include <debug/debug.h>
d2763ab5
BK
34#include <debug/macros.h>
35#include <debug/functions.h>
285b36d6 36#include <debug/safe_base.h>
d2763ab5 37#include <bits/stl_pair.h>
105c6331 38#include <ext/type_traits.h>
285b36d6
BK
39
40namespace __gnu_debug
41{
b8b4301e
PC
42 /** Helper struct to deal with sequence offering a before_begin
43 * iterator.
44 **/
45 template <typename _Sequence>
46 struct _BeforeBeginHelper
47 {
48 typedef typename _Sequence::const_iterator _It;
afe96d41 49 typedef typename _It::iterator_type _BaseIt;
b8b4301e
PC
50
51 static bool
079c74f3 52 _S_Is(_BaseIt, const _Sequence*)
b8b4301e 53 { return false; }
079c74f3
PC
54
55 static bool
56 _S_Is_Beginnest(_BaseIt __it, const _Sequence* __seq)
57 { return __it == __seq->_M_base().begin(); }
b8b4301e
PC
58 };
59
285b36d6
BK
60 /** Iterators that derive from _Safe_iterator_base but that aren't
61 * _Safe_iterators can be determined singular or non-singular via
526da49c 62 * _Safe_iterator_base.
285b36d6 63 */
d2763ab5
BK
64 inline bool
65 __check_singular_aux(const _Safe_iterator_base* __x)
285b36d6 66 { return __x->_M_singular(); }
526da49c 67
77e0bf4e
FD
68 /** The precision to which we can calculate the distance between
69 * two iterators.
70 */
71 enum _Distance_precision
72 {
73 __dp_equality, //< Can compare iterator equality, only
74 __dp_sign, //< Can determine equality and ordering
75 __dp_exact //< Can determine distance precisely
76 };
77
78 /** Determine the distance between two iterators with some known
79 * precision.
80 */
81 template<typename _Iterator1, typename _Iterator2>
82 inline std::pair<typename std::iterator_traits<_Iterator1>::difference_type,
83 _Distance_precision>
84 __get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
85 std::random_access_iterator_tag)
86 { return std::make_pair(__rhs - __lhs, __dp_exact); }
87
88 template<typename _Iterator1, typename _Iterator2>
89 inline std::pair<typename std::iterator_traits<_Iterator1>::difference_type,
90 _Distance_precision>
91 __get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs,
92 std::forward_iterator_tag)
93 { return std::make_pair(__lhs == __rhs? 0 : 1, __dp_equality); }
94
95 template<typename _Iterator1, typename _Iterator2>
96 inline std::pair<typename std::iterator_traits<_Iterator1>::difference_type,
97 _Distance_precision>
98 __get_distance(const _Iterator1& __lhs, const _Iterator2& __rhs)
99 {
100 typedef typename std::iterator_traits<_Iterator1>::iterator_category
101 _Category;
102 return __get_distance(__lhs, __rhs, _Category());
103 }
104
285b36d6 105 /** \brief Safe iterator wrapper.
526da49c 106 *
285b36d6
BK
107 * The class template %_Safe_iterator is a wrapper around an
108 * iterator that tracks the iterator's movement among sequences and
109 * checks that operations performed on the "safe" iterator are
110 * legal. In additional to the basic iterator operations (which are
111 * validated, and then passed to the underlying iterator),
112 * %_Safe_iterator has member functions for iterator invalidation,
113 * attaching/detaching the iterator from sequences, and querying
114 * the iterator's state.
115 */
116 template<typename _Iterator, typename _Sequence>
117 class _Safe_iterator : public _Safe_iterator_base
118 {
119 typedef _Safe_iterator _Self;
120
285b36d6
BK
121 /// The underlying iterator
122 _Iterator _M_current;
123
124 /// Determine if this is a constant iterator.
526da49c 125 bool
285b36d6
BK
126 _M_constant() const
127 {
128 typedef typename _Sequence::const_iterator const_iterator;
67c495be 129 return std::__are_same<const_iterator, _Safe_iterator>::__value;
285b36d6
BK
130 }
131
45f388bb 132 typedef std::iterator_traits<_Iterator> _Traits;
285b36d6
BK
133
134 public:
1f5ca1a1 135 typedef _Iterator iterator_type;
285b36d6
BK
136 typedef typename _Traits::iterator_category iterator_category;
137 typedef typename _Traits::value_type value_type;
138 typedef typename _Traits::difference_type difference_type;
139 typedef typename _Traits::reference reference;
140 typedef typename _Traits::pointer pointer;
141
142 /// @post the iterator is singular and unattached
143 _Safe_iterator() : _M_current() { }
144
145 /**
146 * @brief Safe iterator construction from an unsafe iterator and
147 * its sequence.
148 *
149 * @pre @p seq is not NULL
150 * @post this is not singular
151 */
152 _Safe_iterator(const _Iterator& __i, const _Sequence* __seq)
153 : _Safe_iterator_base(__seq, _M_constant()), _M_current(__i)
526da49c 154 {
285b36d6
BK
155 _GLIBCXX_DEBUG_VERIFY(! this->_M_singular(),
156 _M_message(__msg_init_singular)
157 ._M_iterator(*this, "this"));
158 }
159
160 /**
161 * @brief Copy construction.
285b36d6
BK
162 */
163 _Safe_iterator(const _Safe_iterator& __x)
164 : _Safe_iterator_base(__x, _M_constant()), _M_current(__x._M_current)
526da49c 165 {
05168714
PC
166 // _GLIBCXX_RESOLVE_LIB_DEFECTS
167 // DR 408. Is vector<reverse_iterator<char*> > forbidden?
168 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
169 || __x._M_current == _Iterator(),
285b36d6
BK
170 _M_message(__msg_init_copy_singular)
171 ._M_iterator(*this, "this")
172 ._M_iterator(__x, "other"));
173 }
174
734f5023 175#if __cplusplus >= 201103L
faef17d8
JW
176 /**
177 * @brief Move construction.
178 * @post __x is singular and unattached
179 */
180 _Safe_iterator(_Safe_iterator&& __x) : _M_current()
181 {
8ad8655c
JW
182 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
183 || __x._M_current == _Iterator(),
184 _M_message(__msg_init_copy_singular)
185 ._M_iterator(*this, "this")
186 ._M_iterator(__x, "other"));
faef17d8
JW
187 std::swap(_M_current, __x._M_current);
188 this->_M_attach(__x._M_sequence);
189 __x._M_detach();
190 }
191#endif
192
526da49c 193 /**
285b36d6
BK
194 * @brief Converting constructor from a mutable iterator to a
195 * constant iterator.
285b36d6
BK
196 */
197 template<typename _MutableIterator>
261e5b9e
BK
198 _Safe_iterator(
199 const _Safe_iterator<_MutableIterator,
105c6331 200 typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator,
1f5ca1a1 201 typename _Sequence::iterator::iterator_type>::__value),
105c6331 202 _Sequence>::__type>& __x)
285b36d6 203 : _Safe_iterator_base(__x, _M_constant()), _M_current(__x.base())
526da49c 204 {
05168714
PC
205 // _GLIBCXX_RESOLVE_LIB_DEFECTS
206 // DR 408. Is vector<reverse_iterator<char*> > forbidden?
207 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
208 || __x.base() == _Iterator(),
285b36d6
BK
209 _M_message(__msg_init_const_singular)
210 ._M_iterator(*this, "this")
211 ._M_iterator(__x, "other"));
212 }
213
214 /**
215 * @brief Copy assignment.
285b36d6 216 */
526da49c 217 _Safe_iterator&
285b36d6
BK
218 operator=(const _Safe_iterator& __x)
219 {
05168714
PC
220 // _GLIBCXX_RESOLVE_LIB_DEFECTS
221 // DR 408. Is vector<reverse_iterator<char*> > forbidden?
222 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
223 || __x._M_current == _Iterator(),
285b36d6
BK
224 _M_message(__msg_copy_singular)
225 ._M_iterator(*this, "this")
226 ._M_iterator(__x, "other"));
227 _M_current = __x._M_current;
afe96d41 228 this->_M_attach(__x._M_sequence);
285b36d6
BK
229 return *this;
230 }
231
734f5023 232#if __cplusplus >= 201103L
faef17d8
JW
233 /**
234 * @brief Move assignment.
235 * @post __x is singular and unattached
236 */
237 _Safe_iterator&
238 operator=(_Safe_iterator&& __x)
239 {
739fd6a6
PC
240 _GLIBCXX_DEBUG_VERIFY(this != &__x,
241 _M_message(__msg_self_move_assign)
242 ._M_iterator(*this, "this"));
8ad8655c
JW
243 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
244 || __x._M_current == _Iterator(),
245 _M_message(__msg_copy_singular)
246 ._M_iterator(*this, "this")
247 ._M_iterator(__x, "other"));
faef17d8
JW
248 _M_current = __x._M_current;
249 _M_attach(__x._M_sequence);
250 __x._M_detach();
251 __x._M_current = _Iterator();
252 return *this;
253 }
254#endif
255
285b36d6
BK
256 /**
257 * @brief Iterator dereference.
258 * @pre iterator is dereferenceable
259 */
526da49c
BI
260 reference
261 operator*() const
285b36d6 262 {
285b36d6
BK
263 _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
264 _M_message(__msg_bad_deref)
265 ._M_iterator(*this, "this"));
266 return *_M_current;
267 }
268
269 /**
270 * @brief Iterator dereference.
271 * @pre iterator is dereferenceable
272 * @todo Make this correct w.r.t. iterators that return proxies
273 * @todo Use addressof() instead of & operator
274 */
526da49c 275 pointer
285b36d6
BK
276 operator->() const
277 {
278 _GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
279 _M_message(__msg_bad_deref)
280 ._M_iterator(*this, "this"));
281 return &*_M_current;
282 }
283
284 // ------ Input iterator requirements ------
285 /**
286 * @brief Iterator preincrement
287 * @pre iterator is incrementable
288 */
526da49c 289 _Safe_iterator&
285b36d6
BK
290 operator++()
291 {
292 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
293 _M_message(__msg_bad_inc)
294 ._M_iterator(*this, "this"));
295 ++_M_current;
296 return *this;
297 }
298
299 /**
300 * @brief Iterator postincrement
301 * @pre iterator is incrementable
302 */
526da49c 303 _Safe_iterator
285b36d6
BK
304 operator++(int)
305 {
306 _GLIBCXX_DEBUG_VERIFY(this->_M_incrementable(),
307 _M_message(__msg_bad_inc)
308 ._M_iterator(*this, "this"));
309 _Safe_iterator __tmp(*this);
310 ++_M_current;
311 return __tmp;
312 }
313
314 // ------ Bidirectional iterator requirements ------
315 /**
316 * @brief Iterator predecrement
317 * @pre iterator is decrementable
318 */
526da49c 319 _Safe_iterator&
285b36d6
BK
320 operator--()
321 {
322 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
323 _M_message(__msg_bad_dec)
324 ._M_iterator(*this, "this"));
325 --_M_current;
326 return *this;
327 }
328
329 /**
330 * @brief Iterator postdecrement
331 * @pre iterator is decrementable
332 */
526da49c 333 _Safe_iterator
285b36d6
BK
334 operator--(int)
335 {
336 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
337 _M_message(__msg_bad_dec)
338 ._M_iterator(*this, "this"));
339 _Safe_iterator __tmp(*this);
340 --_M_current;
341 return __tmp;
342 }
343
344 // ------ Random access iterator requirements ------
526da49c 345 reference
285b36d6
BK
346 operator[](const difference_type& __n) const
347 {
526da49c 348 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
285b36d6
BK
349 && this->_M_can_advance(__n+1),
350 _M_message(__msg_iter_subscript_oob)
351 ._M_iterator(*this)._M_integer(__n));
352
353 return _M_current[__n];
354 }
355
526da49c 356 _Safe_iterator&
285b36d6
BK
357 operator+=(const difference_type& __n)
358 {
359 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
360 _M_message(__msg_advance_oob)
361 ._M_iterator(*this)._M_integer(__n));
362 _M_current += __n;
363 return *this;
364 }
365
526da49c 366 _Safe_iterator
285b36d6
BK
367 operator+(const difference_type& __n) const
368 {
369 _Safe_iterator __tmp(*this);
370 __tmp += __n;
371 return __tmp;
372 }
373
526da49c 374 _Safe_iterator&
285b36d6
BK
375 operator-=(const difference_type& __n)
376 {
377 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
378 _M_message(__msg_retreat_oob)
379 ._M_iterator(*this)._M_integer(__n));
380 _M_current += -__n;
381 return *this;
382 }
383
526da49c 384 _Safe_iterator
285b36d6
BK
385 operator-(const difference_type& __n) const
386 {
387 _Safe_iterator __tmp(*this);
388 __tmp -= __n;
389 return __tmp;
390 }
391
392 // ------ Utilities ------
393 /**
394 * @brief Return the underlying iterator
526da49c
BI
395 */
396 _Iterator
285b36d6
BK
397 base() const { return _M_current; }
398
399 /**
400 * @brief Conversion to underlying non-debug iterator to allow
401 * better interaction with non-debug containers.
402 */
403 operator _Iterator() const { return _M_current; }
404
405 /** Attach iterator to the given sequence. */
526da49c 406 void
afe96d41 407 _M_attach(_Safe_sequence_base* __seq)
526da49c 408 {
afe96d41 409 _Safe_iterator_base::_M_attach(__seq, _M_constant());
285b36d6
BK
410 }
411
eebbe2c7
PC
412 /** Likewise, but not thread-safe. */
413 void
afe96d41 414 _M_attach_single(_Safe_sequence_base* __seq)
eebbe2c7 415 {
afe96d41 416 _Safe_iterator_base::_M_attach_single(__seq, _M_constant());
eebbe2c7
PC
417 }
418
285b36d6 419 /// Is the iterator dereferenceable?
526da49c 420 bool
285b36d6 421 _M_dereferenceable() const
b8b4301e
PC
422 { return !this->_M_singular() && !_M_is_end() && !_M_is_before_begin(); }
423
424 /// Is the iterator before a dereferenceable one?
425 bool
426 _M_before_dereferenceable() const
427 {
74345dec
FD
428 if (this->_M_incrementable())
429 {
430 _Iterator __base = base();
431 return ++__base != _M_get_sequence()->_M_base().end();
432 }
433 return false;
b8b4301e 434 }
285b36d6
BK
435
436 /// Is the iterator incrementable?
526da49c 437 bool
b8b4301e
PC
438 _M_incrementable() const
439 { return !this->_M_singular() && !_M_is_end(); }
285b36d6
BK
440
441 // Is the iterator decrementable?
526da49c 442 bool
285b36d6
BK
443 _M_decrementable() const { return !_M_singular() && !_M_is_begin(); }
444
445 // Can we advance the iterator @p __n steps (@p __n may be negative)
526da49c 446 bool
285b36d6
BK
447 _M_can_advance(const difference_type& __n) const;
448
449 // Is the iterator range [*this, __rhs) valid?
450 template<typename _Other>
526da49c 451 bool
285b36d6
BK
452 _M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const;
453
454 // The sequence this iterator references.
526da49c 455 const _Sequence*
285b36d6
BK
456 _M_get_sequence() const
457 { return static_cast<const _Sequence*>(_M_sequence); }
458
285b36d6
BK
459 /// Is this iterator equal to the sequence's begin() iterator?
460 bool _M_is_begin() const
afe96d41 461 { return base() == _M_get_sequence()->_M_base().begin(); }
285b36d6
BK
462
463 /// Is this iterator equal to the sequence's end() iterator?
464 bool _M_is_end() const
afe96d41 465 { return base() == _M_get_sequence()->_M_base().end(); }
b8b4301e
PC
466
467 /// Is this iterator equal to the sequence's before_begin() iterator if
468 /// any?
469 bool _M_is_before_begin() const
faef17d8 470 {
079c74f3
PC
471 return _BeforeBeginHelper<_Sequence>::_S_Is(base(), _M_get_sequence());
472 }
473
474 /// Is this iterator equal to the sequence's before_begin() iterator if
475 /// any or begin() otherwise?
476 bool _M_is_beginnest() const
477 {
478 return _BeforeBeginHelper<_Sequence>::_S_Is_Beginnest(base(),
479 _M_get_sequence());
faef17d8 480 }
285b36d6
BK
481 };
482
483 template<typename _IteratorL, typename _IteratorR, typename _Sequence>
484 inline bool
485 operator==(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
526da49c
BI
486 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
487 {
285b36d6
BK
488 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
489 _M_message(__msg_iter_compare_bad)
490 ._M_iterator(__lhs, "lhs")
491 ._M_iterator(__rhs, "rhs"));
492 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
493 _M_message(__msg_compare_different)
494 ._M_iterator(__lhs, "lhs")
495 ._M_iterator(__rhs, "rhs"));
526da49c 496 return __lhs.base() == __rhs.base();
285b36d6
BK
497 }
498
499 template<typename _Iterator, typename _Sequence>
500 inline bool
501 operator==(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
502 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
526da49c 503 {
285b36d6
BK
504 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
505 _M_message(__msg_iter_compare_bad)
506 ._M_iterator(__lhs, "lhs")
507 ._M_iterator(__rhs, "rhs"));
508 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
509 _M_message(__msg_compare_different)
510 ._M_iterator(__lhs, "lhs")
511 ._M_iterator(__rhs, "rhs"));
526da49c 512 return __lhs.base() == __rhs.base();
285b36d6
BK
513 }
514
515 template<typename _IteratorL, typename _IteratorR, typename _Sequence>
516 inline bool
517 operator!=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
526da49c
BI
518 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
519 {
285b36d6
BK
520 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
521 _M_message(__msg_iter_compare_bad)
522 ._M_iterator(__lhs, "lhs")
523 ._M_iterator(__rhs, "rhs"));
524 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
525 _M_message(__msg_compare_different)
526 ._M_iterator(__lhs, "lhs")
527 ._M_iterator(__rhs, "rhs"));
526da49c 528 return __lhs.base() != __rhs.base();
285b36d6
BK
529 }
530
531 template<typename _Iterator, typename _Sequence>
532 inline bool
533 operator!=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
534 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
526da49c 535 {
285b36d6
BK
536 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
537 _M_message(__msg_iter_compare_bad)
538 ._M_iterator(__lhs, "lhs")
539 ._M_iterator(__rhs, "rhs"));
540 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
541 _M_message(__msg_compare_different)
542 ._M_iterator(__lhs, "lhs")
543 ._M_iterator(__rhs, "rhs"));
526da49c 544 return __lhs.base() != __rhs.base();
285b36d6
BK
545 }
546
547 template<typename _IteratorL, typename _IteratorR, typename _Sequence>
548 inline bool
549 operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
550 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
526da49c 551 {
285b36d6
BK
552 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
553 _M_message(__msg_iter_order_bad)
554 ._M_iterator(__lhs, "lhs")
555 ._M_iterator(__rhs, "rhs"));
556 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
557 _M_message(__msg_order_different)
558 ._M_iterator(__lhs, "lhs")
559 ._M_iterator(__rhs, "rhs"));
526da49c 560 return __lhs.base() < __rhs.base();
285b36d6
BK
561 }
562
563 template<typename _Iterator, typename _Sequence>
564 inline bool
565 operator<(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
566 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
526da49c 567 {
285b36d6
BK
568 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
569 _M_message(__msg_iter_order_bad)
570 ._M_iterator(__lhs, "lhs")
571 ._M_iterator(__rhs, "rhs"));
572 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
573 _M_message(__msg_order_different)
574 ._M_iterator(__lhs, "lhs")
575 ._M_iterator(__rhs, "rhs"));
526da49c 576 return __lhs.base() < __rhs.base();
285b36d6
BK
577 }
578
579 template<typename _IteratorL, typename _IteratorR, typename _Sequence>
580 inline bool
581 operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
526da49c
BI
582 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
583 {
285b36d6
BK
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"));
526da49c 592 return __lhs.base() <= __rhs.base();
285b36d6
BK
593 }
594
595 template<typename _Iterator, typename _Sequence>
596 inline bool
597 operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
598 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
526da49c 599 {
285b36d6
BK
600 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
601 _M_message(__msg_iter_order_bad)
602 ._M_iterator(__lhs, "lhs")
603 ._M_iterator(__rhs, "rhs"));
604 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
605 _M_message(__msg_order_different)
606 ._M_iterator(__lhs, "lhs")
607 ._M_iterator(__rhs, "rhs"));
526da49c 608 return __lhs.base() <= __rhs.base();
285b36d6
BK
609 }
610
611 template<typename _IteratorL, typename _IteratorR, typename _Sequence>
612 inline bool
613 operator>(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
614 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
526da49c 615 {
285b36d6
BK
616 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
617 _M_message(__msg_iter_order_bad)
618 ._M_iterator(__lhs, "lhs")
619 ._M_iterator(__rhs, "rhs"));
620 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
621 _M_message(__msg_order_different)
622 ._M_iterator(__lhs, "lhs")
623 ._M_iterator(__rhs, "rhs"));
526da49c 624 return __lhs.base() > __rhs.base();
285b36d6
BK
625 }
626
627 template<typename _Iterator, typename _Sequence>
628 inline bool
629 operator>(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
630 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
526da49c 631 {
285b36d6
BK
632 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
633 _M_message(__msg_iter_order_bad)
634 ._M_iterator(__lhs, "lhs")
635 ._M_iterator(__rhs, "rhs"));
636 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
637 _M_message(__msg_order_different)
638 ._M_iterator(__lhs, "lhs")
639 ._M_iterator(__rhs, "rhs"));
526da49c 640 return __lhs.base() > __rhs.base();
285b36d6
BK
641 }
642
643 template<typename _IteratorL, typename _IteratorR, typename _Sequence>
644 inline bool
645 operator>=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
526da49c
BI
646 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
647 {
285b36d6
BK
648 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
649 _M_message(__msg_iter_order_bad)
650 ._M_iterator(__lhs, "lhs")
651 ._M_iterator(__rhs, "rhs"));
652 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
653 _M_message(__msg_order_different)
654 ._M_iterator(__lhs, "lhs")
655 ._M_iterator(__rhs, "rhs"));
526da49c 656 return __lhs.base() >= __rhs.base();
285b36d6
BK
657 }
658
659 template<typename _Iterator, typename _Sequence>
660 inline bool
661 operator>=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
662 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
526da49c 663 {
285b36d6
BK
664 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
665 _M_message(__msg_iter_order_bad)
666 ._M_iterator(__lhs, "lhs")
667 ._M_iterator(__rhs, "rhs"));
668 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
669 _M_message(__msg_order_different)
670 ._M_iterator(__lhs, "lhs")
671 ._M_iterator(__rhs, "rhs"));
526da49c 672 return __lhs.base() >= __rhs.base();
285b36d6
BK
673 }
674
675 // _GLIBCXX_RESOLVE_LIB_DEFECTS
676 // According to the resolution of DR179 not only the various comparison
677 // operators but also operator- must accept mixed iterator/const_iterator
678 // parameters.
679 template<typename _IteratorL, typename _IteratorR, typename _Sequence>
680 inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type
681 operator-(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
682 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
526da49c 683 {
285b36d6
BK
684 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
685 _M_message(__msg_distance_bad)
686 ._M_iterator(__lhs, "lhs")
687 ._M_iterator(__rhs, "rhs"));
688 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
689 _M_message(__msg_distance_different)
690 ._M_iterator(__lhs, "lhs")
691 ._M_iterator(__rhs, "rhs"));
526da49c 692 return __lhs.base() - __rhs.base();
285b36d6
BK
693 }
694
3af22b23
PC
695 template<typename _Iterator, typename _Sequence>
696 inline typename _Safe_iterator<_Iterator, _Sequence>::difference_type
697 operator-(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
698 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
699 {
700 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
701 _M_message(__msg_distance_bad)
702 ._M_iterator(__lhs, "lhs")
703 ._M_iterator(__rhs, "rhs"));
704 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
705 _M_message(__msg_distance_different)
706 ._M_iterator(__lhs, "lhs")
707 ._M_iterator(__rhs, "rhs"));
708 return __lhs.base() - __rhs.base();
709 }
710
285b36d6
BK
711 template<typename _Iterator, typename _Sequence>
712 inline _Safe_iterator<_Iterator, _Sequence>
713 operator+(typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n,
714 const _Safe_iterator<_Iterator, _Sequence>& __i)
715 { return __i + __n; }
716} // namespace __gnu_debug
717
ee3ee948 718#include <debug/safe_iterator.tcc>
285b36d6
BK
719
720#endif