1 // Debugging iterator implementation (out of line) -*- C++ -*- 2 3 // Copyright (C) 2003-2018 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 /** @file debug/safe_iterator.tcc 26 * This file is a GNU debug extension to the Standard C++ Library. 27 */ 28 29 #ifndef _GLIBCXX_DEBUG_SAFE_ITERATOR_TCC 30 #define _GLIBCXX_DEBUG_SAFE_ITERATOR_TCC 1 31 32 namespace __gnu_debug 33 { 34 template<typename _Iterator, typename _Sequence> 35 bool 36 _Safe_iterator<_Iterator, _Sequence>:: _M_can_advance(const difference_type & __n) const37 _M_can_advance(const difference_type& __n) const 38 { 39 if (this->_M_singular()) 40 return false; 41 42 if (__n == 0) 43 return true; 44 45 if (__n < 0) 46 { 47 std::pair<difference_type, _Distance_precision> __dist = 48 __get_distance_from_begin(*this); 49 bool __ok = ((__dist.second == __dp_exact && __dist.first >= -__n) 50 || (__dist.second != __dp_exact && __dist.first > 0)); 51 return __ok; 52 } 53 else 54 { 55 std::pair<difference_type, _Distance_precision> __dist = 56 __get_distance_to_end(*this); 57 bool __ok = ((__dist.second == __dp_exact && __dist.first >= __n) 58 || (__dist.second != __dp_exact && __dist.first > 0)); 59 return __ok; 60 } 61 } 62 63 template<typename _Iterator, typename _Sequence> 64 bool 65 _Safe_iterator<_Iterator, _Sequence>:: _M_valid_range(const _Safe_iterator & __rhs,std::pair<difference_type,_Distance_precision> & __dist,bool __check_dereferenceable) const66 _M_valid_range(const _Safe_iterator& __rhs, 67 std::pair<difference_type, _Distance_precision>& __dist, 68 bool __check_dereferenceable) const 69 { 70 if (!_M_can_compare(__rhs)) 71 return false; 72 73 /* Determine iterators order */ 74 __dist = __get_distance(*this, __rhs); 75 switch (__dist.second) 76 { 77 case __dp_equality: 78 if (__dist.first == 0) 79 return true; 80 break; 81 82 case __dp_sign: 83 case __dp_exact: 84 // If range is not empty first iterator must be dereferenceable. 85 if (__dist.first > 0) 86 return !__check_dereferenceable || _M_dereferenceable(); 87 return __dist.first == 0; 88 } 89 90 // Assume that this is a valid range; we can't check anything else. 91 return true; 92 } 93 } // namespace __gnu_debug 94 95 #endif 96