safe_iterator.tcc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_TCC
00031 #define _GLIBCXX_DEBUG_SAFE_ITERATOR_TCC 1
00032
00033 namespace __gnu_debug
00034 {
00035 template<typename _Iterator, typename _Sequence>
00036 bool
00037 _Safe_iterator<_Iterator, _Sequence>::
00038 _M_can_advance(const difference_type& __n) const
00039 {
00040 typedef typename _Sequence::const_iterator const_iterator;
00041
00042 if (this->_M_singular())
00043 return false;
00044 if (__n == 0)
00045 return true;
00046 if (__n < 0)
00047 {
00048 const_iterator __begin =
00049 static_cast<const _Sequence*>(_M_sequence)->begin();
00050 std::pair<difference_type, _Distance_precision> __dist =
00051 this->_M_get_distance(__begin, *this);
00052 bool __ok = ((__dist.second == __dp_exact && __dist.first >= -__n)
00053 || (__dist.second != __dp_exact && __dist.first > 0));
00054 return __ok;
00055 }
00056 else
00057 {
00058 const_iterator __end =
00059 static_cast<const _Sequence*>(_M_sequence)->end();
00060 std::pair<difference_type, _Distance_precision> __dist =
00061 this->_M_get_distance(*this, __end);
00062 bool __ok = ((__dist.second == __dp_exact && __dist.first >= __n)
00063 || (__dist.second != __dp_exact && __dist.first > 0));
00064 return __ok;
00065 }
00066 }
00067
00068 template<typename _Iterator, typename _Sequence>
00069 template<typename _Other>
00070 bool
00071 _Safe_iterator<_Iterator, _Sequence>::
00072 _M_valid_range(const _Safe_iterator<_Other, _Sequence>& __rhs) const
00073 {
00074 if (!_M_can_compare(__rhs))
00075 return false;
00076
00077
00078
00079 std::pair<difference_type, _Distance_precision> __dist =
00080 this->_M_get_distance(*this, __rhs);
00081 switch (__dist.second) {
00082 case __dp_equality:
00083 if (__dist.first == 0)
00084 return true;
00085 break;
00086
00087 case __dp_sign:
00088 case __dp_exact:
00089 return __dist.first >= 0;
00090 }
00091
00092
00093
00094 if (_M_is_begin() || __rhs._M_is_end())
00095 return true;
00096 else if (_M_is_end() || __rhs._M_is_begin())
00097 return false;
00098
00099
00100 return true;
00101 }
00102
00103 template<typename _Iterator, typename _Sequence>
00104 void
00105 _Safe_iterator<_Iterator, _Sequence>::
00106 _M_invalidate()
00107 {
00108 __gnu_cxx::__scoped_lock sentry(this->_M_get_mutex());
00109 _M_invalidate_single();
00110 }
00111
00112 template<typename _Iterator, typename _Sequence>
00113 void
00114 _Safe_iterator<_Iterator, _Sequence>::
00115 _M_invalidate_single()
00116 {
00117 typedef typename _Sequence::iterator iterator;
00118 typedef typename _Sequence::const_iterator const_iterator;
00119
00120 if (!this->_M_singular())
00121 {
00122 for (_Safe_iterator_base* __iter = _M_sequence->_M_iterators;
00123 __iter; __iter = __iter->_M_next)
00124 {
00125 iterator* __victim = static_cast<iterator*>(__iter);
00126 if (this->base() == __victim->base())
00127 __victim->_M_version = 0;
00128 }
00129
00130 for (_Safe_iterator_base* __iter2 = _M_sequence->_M_const_iterators;
00131 __iter2; __iter2 = __iter2->_M_next)
00132 {
00133 const_iterator* __victim = static_cast<const_iterator*>(__iter2);
00134 if (__victim->base() == this->base())
00135 __victim->_M_version = 0;
00136 }
00137 _M_version = 0;
00138 }
00139 }
00140 }
00141
00142 #endif
00143