OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libstdc++-v3/] [include/] [debug/] [safe_iterator.h] - Blame information for rev 775

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.