29 #ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_H
30 #define _GLIBCXX_DEBUG_SAFE_ITERATOR_H 1
44 template<
typename _Sequence>
47 template<
typename _Iterator>
52 template<
typename _Iterator>
55 {
return __it.
base() == __it._M_get_sequence()->_M_base().begin(); }
59 template<
typename _Sequence>
62 typedef _Distance_traits<typename _Sequence::iterator> _DistTraits;
65 _S_size(
const _Sequence& __seq)
85 template<
typename _Iterator,
typename _Sequence>
90 typedef _Iterator _Iter_base;
92 typedef typename _Sequence::const_iterator _Const_iterator;
97 {
return std::__are_same<_Const_iterator, _Safe_iterator>::__value; }
99 typedef std::iterator_traits<_Iterator> _Traits;
101 struct _Attach_single
111 typedef _Iterator iterator_type;
112 typedef typename _Traits::iterator_category iterator_category;
113 typedef typename _Traits::value_type value_type;
114 typedef typename _Traits::difference_type difference_type;
115 typedef typename _Traits::reference reference;
116 typedef typename _Traits::pointer pointer;
130 : _Iter_base(__i), _Safe_base(__seq, _M_constant())
133 _M_message(__msg_init_singular)
134 ._M_iterator(*
this,
"this"));
141 : _Iter_base(__x.base())
145 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
146 || __x.base() == _Iterator(),
147 _M_message(__msg_init_copy_singular)
148 ._M_iterator(*
this,
"this")
149 ._M_iterator(__x,
"other"));
153 #if __cplusplus >= 201103L
161 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
162 || __x.base() == _Iterator(),
163 _M_message(__msg_init_copy_singular)
164 ._M_iterator(*
this,
"this")
165 ._M_iterator(__x,
"other"));
168 std::swap(
base(), __x.base());
177 template<
typename _MutableIterator>
180 typename __gnu_cxx::__enable_if<(std::__are_same<_MutableIterator,
181 typename _Sequence::iterator::iterator_type>::__value),
182 _Sequence>::__type>& __x) _GLIBCXX_NOEXCEPT
183 : _Iter_base(__x.
base())
187 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
188 || __x.base() == _Iterator(),
189 _M_message(__msg_init_const_singular)
190 ._M_iterator(*
this,
"this")
191 ._M_iterator(__x,
"other"));
203 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
204 || __x.base() == _Iterator(),
205 _M_message(__msg_copy_singular)
206 ._M_iterator(*
this,
"this")
207 ._M_iterator(__x,
"other"));
225 #if __cplusplus >= 201103L
233 _GLIBCXX_DEBUG_VERIFY(
this != &__x,
234 _M_message(__msg_self_move_assign)
235 ._M_iterator(*
this,
"this"));
236 _GLIBCXX_DEBUG_VERIFY(!__x._M_singular()
237 || __x.base() == _Iterator(),
238 _M_message(__msg_copy_singular)
239 ._M_iterator(*
this,
"this")
240 ._M_iterator(__x,
"other"));
256 __x.base() = _Iterator();
269 _M_message(__msg_bad_deref)
270 ._M_iterator(*
this,
"this"));
283 _M_message(__msg_bad_deref)
284 ._M_iterator(*
this,
"this"));
297 _M_message(__msg_bad_inc)
298 ._M_iterator(*
this,
"this"));
312 _M_message(__msg_bad_inc)
313 ._M_iterator(*
this,
"this"));
326 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
327 _M_message(__msg_bad_dec)
328 ._M_iterator(*
this,
"this"));
341 _GLIBCXX_DEBUG_VERIFY(this->_M_decrementable(),
342 _M_message(__msg_bad_dec)
343 ._M_iterator(*
this,
"this"));
350 operator[](
const difference_type& __n)
const _GLIBCXX_NOEXCEPT
352 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n)
353 && this->_M_can_advance(__n+1),
354 _M_message(__msg_iter_subscript_oob)
355 ._M_iterator(*this)._M_integer(__n));
360 operator+=(
const difference_type& __n) _GLIBCXX_NOEXCEPT
362 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
363 _M_message(__msg_advance_oob)
364 ._M_iterator(*this)._M_integer(__n));
371 operator+(
const difference_type& __n)
const _GLIBCXX_NOEXCEPT
373 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(__n),
374 _M_message(__msg_advance_oob)
375 ._M_iterator(*this)._M_integer(__n));
380 operator-=(
const difference_type& __n) _GLIBCXX_NOEXCEPT
382 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
383 _M_message(__msg_retreat_oob)
384 ._M_iterator(*this)._M_integer(__n));
391 operator-(
const difference_type& __n)
const _GLIBCXX_NOEXCEPT
393 _GLIBCXX_DEBUG_VERIFY(this->_M_can_advance(-__n),
394 _M_message(__msg_retreat_oob)
395 ._M_iterator(*this)._M_integer(__n));
404 base() _GLIBCXX_NOEXCEPT {
return *
this; }
407 base() const _GLIBCXX_NOEXCEPT {
return *
this; }
413 operator _Iterator() const _GLIBCXX_NOEXCEPT {
return *
this; }
436 _Iterator __base =
base();
437 return ++__base != _M_get_sequence()->_M_base().end();
453 _M_can_advance(
const difference_type& __n)
const;
463 __gnu_cxx::__conditional_type<std::__are_same<_Const_iterator,
467 _M_get_sequence()
const
473 {
return base() == _M_get_sequence()->_M_base().begin(); }
478 {
return base() == _M_get_sequence()->_M_base().end(); }
493 template<
typename _IteratorL,
typename _IteratorR,
typename _Sequence>
495 operator==(
const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
496 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
499 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
500 _M_message(__msg_iter_compare_bad)
501 ._M_iterator(__lhs,
"lhs")
502 ._M_iterator(__rhs,
"rhs"));
503 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
504 _M_message(__msg_compare_different)
505 ._M_iterator(__lhs,
"lhs")
506 ._M_iterator(__rhs,
"rhs"));
507 return __lhs.base() == __rhs.base();
510 template<
typename _Iterator,
typename _Sequence>
512 operator==(
const _Safe_iterator<_Iterator, _Sequence>& __lhs,
513 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
516 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
517 _M_message(__msg_iter_compare_bad)
518 ._M_iterator(__lhs,
"lhs")
519 ._M_iterator(__rhs,
"rhs"));
520 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
521 _M_message(__msg_compare_different)
522 ._M_iterator(__lhs,
"lhs")
523 ._M_iterator(__rhs,
"rhs"));
524 return __lhs.base() == __rhs.base();
527 template<
typename _IteratorL,
typename _IteratorR,
typename _Sequence>
529 operator!=(
const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
530 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
533 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
534 _M_message(__msg_iter_compare_bad)
535 ._M_iterator(__lhs,
"lhs")
536 ._M_iterator(__rhs,
"rhs"));
537 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
538 _M_message(__msg_compare_different)
539 ._M_iterator(__lhs,
"lhs")
540 ._M_iterator(__rhs,
"rhs"));
541 return __lhs.base() != __rhs.base();
544 template<
typename _Iterator,
typename _Sequence>
546 operator!=(
const _Safe_iterator<_Iterator, _Sequence>& __lhs,
547 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
550 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
551 _M_message(__msg_iter_compare_bad)
552 ._M_iterator(__lhs,
"lhs")
553 ._M_iterator(__rhs,
"rhs"));
554 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
555 _M_message(__msg_compare_different)
556 ._M_iterator(__lhs,
"lhs")
557 ._M_iterator(__rhs,
"rhs"));
558 return __lhs.base() != __rhs.base();
561 template<
typename _IteratorL,
typename _IteratorR,
typename _Sequence>
563 operator<(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
564 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
567 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
568 _M_message(__msg_iter_order_bad)
569 ._M_iterator(__lhs,
"lhs")
570 ._M_iterator(__rhs,
"rhs"));
571 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
572 _M_message(__msg_order_different)
573 ._M_iterator(__lhs,
"lhs")
574 ._M_iterator(__rhs,
"rhs"));
575 return __lhs.base() < __rhs.base();
578 template<
typename _Iterator,
typename _Sequence>
580 operator<(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
581 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
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"));
592 return __lhs.base() < __rhs.base();
595 template<
typename _IteratorL,
typename _IteratorR,
typename _Sequence>
597 operator<=(const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
598 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
601 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
602 _M_message(__msg_iter_order_bad)
603 ._M_iterator(__lhs,
"lhs")
604 ._M_iterator(__rhs,
"rhs"));
605 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
606 _M_message(__msg_order_different)
607 ._M_iterator(__lhs,
"lhs")
608 ._M_iterator(__rhs,
"rhs"));
609 return __lhs.base() <= __rhs.base();
612 template<
typename _Iterator,
typename _Sequence>
614 operator<=(const _Safe_iterator<_Iterator, _Sequence>& __lhs,
615 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
618 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
619 _M_message(__msg_iter_order_bad)
620 ._M_iterator(__lhs,
"lhs")
621 ._M_iterator(__rhs,
"rhs"));
622 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
623 _M_message(__msg_order_different)
624 ._M_iterator(__lhs,
"lhs")
625 ._M_iterator(__rhs,
"rhs"));
626 return __lhs.base() <= __rhs.base();
629 template<
typename _IteratorL,
typename _IteratorR,
typename _Sequence>
631 operator>(
const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
632 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
635 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
636 _M_message(__msg_iter_order_bad)
637 ._M_iterator(__lhs,
"lhs")
638 ._M_iterator(__rhs,
"rhs"));
639 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
640 _M_message(__msg_order_different)
641 ._M_iterator(__lhs,
"lhs")
642 ._M_iterator(__rhs,
"rhs"));
643 return __lhs.base() > __rhs.base();
646 template<
typename _Iterator,
typename _Sequence>
648 operator>(
const _Safe_iterator<_Iterator, _Sequence>& __lhs,
649 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
652 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
653 _M_message(__msg_iter_order_bad)
654 ._M_iterator(__lhs,
"lhs")
655 ._M_iterator(__rhs,
"rhs"));
656 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
657 _M_message(__msg_order_different)
658 ._M_iterator(__lhs,
"lhs")
659 ._M_iterator(__rhs,
"rhs"));
660 return __lhs.base() > __rhs.base();
663 template<
typename _IteratorL,
typename _IteratorR,
typename _Sequence>
665 operator>=(
const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
666 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
669 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
670 _M_message(__msg_iter_order_bad)
671 ._M_iterator(__lhs,
"lhs")
672 ._M_iterator(__rhs,
"rhs"));
673 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
674 _M_message(__msg_order_different)
675 ._M_iterator(__lhs,
"lhs")
676 ._M_iterator(__rhs,
"rhs"));
677 return __lhs.base() >= __rhs.base();
680 template<
typename _Iterator,
typename _Sequence>
682 operator>=(
const _Safe_iterator<_Iterator, _Sequence>& __lhs,
683 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
686 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
687 _M_message(__msg_iter_order_bad)
688 ._M_iterator(__lhs,
"lhs")
689 ._M_iterator(__rhs,
"rhs"));
690 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
691 _M_message(__msg_order_different)
692 ._M_iterator(__lhs,
"lhs")
693 ._M_iterator(__rhs,
"rhs"));
694 return __lhs.base() >= __rhs.base();
701 template<
typename _IteratorL,
typename _IteratorR,
typename _Sequence>
702 inline typename _Safe_iterator<_IteratorL, _Sequence>::difference_type
703 operator-(
const _Safe_iterator<_IteratorL, _Sequence>& __lhs,
704 const _Safe_iterator<_IteratorR, _Sequence>& __rhs)
707 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
708 _M_message(__msg_distance_bad)
709 ._M_iterator(__lhs,
"lhs")
710 ._M_iterator(__rhs,
"rhs"));
711 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
712 _M_message(__msg_distance_different)
713 ._M_iterator(__lhs,
"lhs")
714 ._M_iterator(__rhs,
"rhs"));
715 return __lhs.base() - __rhs.base();
718 template<
typename _Iterator,
typename _Sequence>
719 inline typename _Safe_iterator<_Iterator, _Sequence>::difference_type
720 operator-(
const _Safe_iterator<_Iterator, _Sequence>& __lhs,
721 const _Safe_iterator<_Iterator, _Sequence>& __rhs)
724 _GLIBCXX_DEBUG_VERIFY(! __lhs._M_singular() && ! __rhs._M_singular(),
725 _M_message(__msg_distance_bad)
726 ._M_iterator(__lhs,
"lhs")
727 ._M_iterator(__rhs,
"rhs"));
728 _GLIBCXX_DEBUG_VERIFY(__lhs._M_can_compare(__rhs),
729 _M_message(__msg_distance_different)
730 ._M_iterator(__lhs,
"lhs")
731 ._M_iterator(__rhs,
"rhs"));
732 return __lhs.base() - __rhs.base();
735 template<
typename _Iterator,
typename _Sequence>
736 inline _Safe_iterator<_Iterator, _Sequence>
737 operator+(
typename _Safe_iterator<_Iterator,_Sequence>::difference_type __n,
738 const _Safe_iterator<_Iterator, _Sequence>& __i) _GLIBCXX_NOEXCEPT
739 {
return __i + __n; }
742 template<
typename _Iterator,
typename _Sequence>
748 template<
typename _Iterator,
typename _Sequence>
753 {
return __first._M_valid_range(__last, __dist); }
756 template<
typename _Iterator,
typename _Sequence>
757 inline typename _Distance_traits<_Iterator>::__type
763 template<
typename _Iterator,
typename _Sequence>
764 inline typename _Distance_traits<_Iterator>::__type
765 __get_distance(
const _Safe_iterator<_Iterator, _Sequence>& __first,
766 const _Safe_iterator<_Iterator, _Sequence>& __last,
769 typedef typename _Distance_traits<_Iterator>::__type _Diff;
770 typedef _Sequence_traits<_Sequence> _SeqTraits;
772 if (__first.base() == __last.base())
775 if (__first._M_is_before_begin())
777 if (__last._M_is_begin())
783 if (__first._M_is_begin())
785 if (__last._M_is_before_begin())
788 if (__last._M_is_end())
789 return _SeqTraits::_S_size(*__first._M_get_sequence());
794 if (__first._M_is_end())
796 if (__last._M_is_before_begin())
799 if (__last._M_is_begin())
801 _Diff __diff = _SeqTraits::_S_size(*__first._M_get_sequence());
808 if (__last._M_is_before_begin() || __last._M_is_begin())
811 if (__last._M_is_end())
818 template<
typename _Iterator,
typename _Sequence>
819 inline typename _Distance_traits<_Iterator>::__type
820 __get_distance_from_begin(
const _Safe_iterator<_Iterator, _Sequence>& __it)
822 typedef _Sequence_traits<_Sequence> _SeqTraits;
826 if (__it._M_is_begin())
829 if (__it._M_is_end())
830 return _SeqTraits::_S_size(*__it._M_get_sequence());
832 typename _Distance_traits<_Iterator>::__type __res
833 =
__get_distance(__it._M_get_sequence()->_M_base().begin(), __it.base());
835 if (__res.second == __dp_equality)
842 template<
typename _Iterator,
typename _Sequence>
843 inline typename _Distance_traits<_Iterator>::__type
844 __get_distance_to_end(
const _Safe_iterator<_Iterator, _Sequence>& __it)
846 typedef _Sequence_traits<_Sequence> _SeqTraits;
850 if (__it._M_is_begin())
851 return _SeqTraits::_S_size(*__it._M_get_sequence());
853 if (__it._M_is_end())
856 typename _Distance_traits<_Iterator>::__type __res
857 =
__get_distance(__it.base(), __it._M_get_sequence()->_M_base().end());
859 if (__res.second == __dp_equality)
865 #if __cplusplus < 201103L
866 template<
typename _Iterator,
typename _Sequence>
867 struct __is_safe_random_iterator<_Safe_iterator<_Iterator, _Sequence> >
868 : std::__are_same<std::random_access_iterator_tag,
869 typename std::iterator_traits<_Iterator>::
873 template<
typename _Iterator,
typename _Sequence>
875 __base(
const _Safe_iterator<_Iterator, _Sequence>& __it,
877 {
return __it.base(); }
879 template<
typename _Iterator,
typename _Sequence>
880 const _Safe_iterator<_Iterator, _Sequence>&
881 __base(
const _Safe_iterator<_Iterator, _Sequence>& __it,
885 template<
typename _Iterator,
typename _Sequence>
887 __base(
const _Safe_iterator<_Iterator, _Sequence>& __it)
892 #if __cplusplus < 201103L
893 template<
typename _Iterator,
typename _Sequence>
894 struct _Unsafe_type<_Safe_iterator<_Iterator, _Sequence> >
895 {
typedef _Iterator _Type; };
898 template<
typename _Iterator,
typename _Sequence>
900 __unsafe(
const _Safe_iterator<_Iterator, _Sequence>& __it)
901 {
return __it.base(); }
iterator_traits< _Iter >::iterator_category __iterator_category(const _Iter &)
_Safe_iterator & operator--() noexcept
Iterator predecrement.
reference operator*() const noexcept
Iterator dereference.
bool _M_is_beginnest() const
Is this iterator equal to the sequence's before_begin() iterator if any or begin() otherwise...
_Distance_traits< _Iterator >::__type __get_distance(const _Iterator &__lhs, const _Iterator &__rhs, std::random_access_iterator_tag)
_Safe_iterator(const _Safe_iterator &__x) noexcept
Copy construction.
_Safe_iterator operator--(int) noexcept
Iterator postdecrement.
void _M_attach(_Safe_sequence_base *__seq)
Struct holding two objects of arbitrary type.
bool _M_dereferenceable() const
Is the iterator dereferenceable?
_Safe_iterator() noexcept
Random-access iterators support a superset of bidirectional iterator operations.
_Iterator & base() noexcept
Return the underlying iterator.
void _M_detach(_Safe_iterator_base *__it)
void _M_attach(_Safe_sequence_base *__seq, bool __constant)
void _M_attach_single(_Safe_sequence_base *__seq, bool __constant)
_Tp * __addressof(_Tp &__r) noexcept
Same as C++11 std::addressof.
bool _M_is_begin() const
Is this iterator equal to the sequence's begin() iterator?
pointer operator->() const noexcept
Iterator dereference.
bool _M_incrementable() const
Is the iterator incrementable?
_Safe_iterator & operator=(_Safe_iterator &&__x) noexcept
Move assignment.
_Safe_iterator(const _Iterator &__i, const _Safe_sequence_base *__seq) noexcept
Safe iterator construction from an unsafe iterator and its sequence.
__gnu_cxx::__mutex & _M_get_mutex()
bool _M_is_before_begin() const
Is this iterator equal to the sequence's before_begin() iterator if any?
bool __valid_range(const _InputIterator &__first, const _InputIterator &__last, typename _Distance_traits< _InputIterator >::__type &__dist)
bool __check_dereferenceable(const _Iterator &)
constexpr pair< typename __decay_and_strip< _T1 >::__type, typename __decay_and_strip< _T2 >::__type > make_pair(_T1 &&__x, _T2 &&__y)
A convenience wrapper for creating a pair from two objects.
_Safe_iterator(const _Safe_iterator< _MutableIterator, typename __gnu_cxx::__enable_if<(std::__are_same< _MutableIterator, typename _Sequence::iterator::iterator_type >::__value), _Sequence >::__type > &__x) noexcept
Converting constructor from a mutable iterator to a constant iterator.
GNU debug classes for public use.
Basic functionality for a safe iterator.
_Safe_sequence_base * _M_sequence
_Safe_iterator(_Safe_iterator &&__x) noexcept
Move construction.
Base class that supports tracking of iterators that reference a sequence.
void _M_attach_single(_Safe_sequence_base *__seq)
bool _M_is_end() const
Is this iterator equal to the sequence's end() iterator?
_Safe_iterator & operator=(const _Safe_iterator &__x) noexcept
Copy assignment.
bool _M_before_dereferenceable() const
Is the iterator before a dereferenceable one?
_Safe_iterator & operator++() noexcept
Iterator preincrement.
_Safe_iterator operator++(int) noexcept
Iterator postincrement.