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