136ac495dSmrg // Debugging support implementation -*- C++ -*- 236ac495dSmrg 3*8feb0f0bSmrg // Copyright (C) 2003-2020 Free Software Foundation, Inc. 436ac495dSmrg // 536ac495dSmrg // This file is part of the GNU ISO C++ Library. This library is free 636ac495dSmrg // software; you can redistribute it and/or modify it under the 736ac495dSmrg // terms of the GNU General Public License as published by the 836ac495dSmrg // Free Software Foundation; either version 3, or (at your option) 936ac495dSmrg // any later version. 1036ac495dSmrg 1136ac495dSmrg // This library is distributed in the hope that it will be useful, 1236ac495dSmrg // but WITHOUT ANY WARRANTY; without even the implied warranty of 1336ac495dSmrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1436ac495dSmrg // GNU General Public License for more details. 1536ac495dSmrg 1636ac495dSmrg // Under Section 7 of GPL version 3, you are granted additional 1736ac495dSmrg // permissions described in the GCC Runtime Library Exception, version 1836ac495dSmrg // 3.1, as published by the Free Software Foundation. 1936ac495dSmrg 2036ac495dSmrg // You should have received a copy of the GNU General Public License and 2136ac495dSmrg // a copy of the GCC Runtime Library Exception along with this program; 2236ac495dSmrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 2336ac495dSmrg // <http://www.gnu.org/licenses/>. 2436ac495dSmrg 2536ac495dSmrg /** @file debug/helper_functions.h 2636ac495dSmrg * This file is a GNU debug extension to the Standard C++ Library. 2736ac495dSmrg */ 2836ac495dSmrg 2936ac495dSmrg #ifndef _GLIBCXX_DEBUG_HELPER_FUNCTIONS_H 3036ac495dSmrg #define _GLIBCXX_DEBUG_HELPER_FUNCTIONS_H 1 3136ac495dSmrg 32*8feb0f0bSmrg #include <bits/move.h> // for __addressof 3336ac495dSmrg #include <bits/stl_iterator_base_types.h> // for iterator_traits, 3436ac495dSmrg // categories and _Iter_base 3536ac495dSmrg #include <bits/cpp_type_traits.h> // for __is_integer 3636ac495dSmrg 3736ac495dSmrg #include <bits/stl_pair.h> // for pair 3836ac495dSmrg 3936ac495dSmrg namespace __gnu_debug 4036ac495dSmrg { 41c0a68be4Smrg template<typename _Iterator, typename _Sequence, typename _Category> 42c0a68be4Smrg class _Safe_iterator; 43c0a68be4Smrg 44c0a68be4Smrg #if __cplusplus >= 201103L 45c0a68be4Smrg template<typename _Iterator, typename _Sequence> 46c0a68be4Smrg class _Safe_local_iterator; 47c0a68be4Smrg #endif 48c0a68be4Smrg 4936ac495dSmrg /** The precision to which we can calculate the distance between 5036ac495dSmrg * two iterators. 5136ac495dSmrg */ 5236ac495dSmrg enum _Distance_precision 5336ac495dSmrg { 5436ac495dSmrg __dp_none, // Not even an iterator type 5536ac495dSmrg __dp_equality, //< Can compare iterator equality, only 5636ac495dSmrg __dp_sign, //< Can determine equality and ordering 57*8feb0f0bSmrg __dp_sign_max_size, //< __dp_sign and gives max range size 5836ac495dSmrg __dp_exact //< Can determine distance precisely 5936ac495dSmrg }; 6036ac495dSmrg 6136ac495dSmrg template<typename _Iterator, 6236ac495dSmrg typename = typename std::__is_integer<_Iterator>::__type> 6336ac495dSmrg struct _Distance_traits 6436ac495dSmrg { 6536ac495dSmrg private: 6636ac495dSmrg typedef 6736ac495dSmrg typename std::iterator_traits<_Iterator>::difference_type _ItDiffType; 6836ac495dSmrg 6936ac495dSmrg template<typename _DiffType, 7036ac495dSmrg typename = typename std::__is_void<_DiffType>::__type> 7136ac495dSmrg struct _DiffTraits 7236ac495dSmrg { typedef _DiffType __type; }; 7336ac495dSmrg 7436ac495dSmrg template<typename _DiffType> 7536ac495dSmrg struct _DiffTraits<_DiffType, std::__true_type> 7636ac495dSmrg { typedef std::ptrdiff_t __type; }; 7736ac495dSmrg 7836ac495dSmrg typedef typename _DiffTraits<_ItDiffType>::__type _DiffType; 7936ac495dSmrg 8036ac495dSmrg public: 8136ac495dSmrg typedef std::pair<_DiffType, _Distance_precision> __type; 8236ac495dSmrg }; 8336ac495dSmrg 8436ac495dSmrg template<typename _Integral> 8536ac495dSmrg struct _Distance_traits<_Integral, std::__true_type> 8636ac495dSmrg { typedef std::pair<std::ptrdiff_t, _Distance_precision> __type; }; 8736ac495dSmrg 8836ac495dSmrg /** Determine the distance between two iterators with some known 8936ac495dSmrg * precision. 9036ac495dSmrg */ 9136ac495dSmrg template<typename _Iterator> 92*8feb0f0bSmrg _GLIBCXX_CONSTEXPR 9336ac495dSmrg inline typename _Distance_traits<_Iterator>::__type 94c0a68be4Smrg __get_distance(_Iterator __lhs, _Iterator __rhs, 9536ac495dSmrg std::random_access_iterator_tag) 9636ac495dSmrg { return std::make_pair(__rhs - __lhs, __dp_exact); } 9736ac495dSmrg 9836ac495dSmrg template<typename _Iterator> 99*8feb0f0bSmrg _GLIBCXX14_CONSTEXPR 10036ac495dSmrg inline typename _Distance_traits<_Iterator>::__type 101c0a68be4Smrg __get_distance(_Iterator __lhs, _Iterator __rhs, 10236ac495dSmrg std::input_iterator_tag) 10336ac495dSmrg { 10436ac495dSmrg if (__lhs == __rhs) 10536ac495dSmrg return std::make_pair(0, __dp_exact); 10636ac495dSmrg 10736ac495dSmrg return std::make_pair(1, __dp_equality); 10836ac495dSmrg } 10936ac495dSmrg 11036ac495dSmrg template<typename _Iterator> 111*8feb0f0bSmrg _GLIBCXX_CONSTEXPR 11236ac495dSmrg inline typename _Distance_traits<_Iterator>::__type 113c0a68be4Smrg __get_distance(_Iterator __lhs, _Iterator __rhs) 11436ac495dSmrg { return __get_distance(__lhs, __rhs, std::__iterator_category(__lhs)); } 11536ac495dSmrg 116*8feb0f0bSmrg // An arbitrary iterator pointer is not singular. 117*8feb0f0bSmrg inline bool 118*8feb0f0bSmrg __check_singular_aux(const void*) { return false; } 119*8feb0f0bSmrg 120*8feb0f0bSmrg // We may have an iterator that derives from _Safe_iterator_base but isn't 121*8feb0f0bSmrg // a _Safe_iterator. 122*8feb0f0bSmrg template<typename _Iterator> 123*8feb0f0bSmrg inline bool 124*8feb0f0bSmrg __check_singular(_Iterator const& __x) 125*8feb0f0bSmrg { return __check_singular_aux(std::__addressof(__x)); } 126*8feb0f0bSmrg 127*8feb0f0bSmrg /** Non-NULL pointers are nonsingular. */ 128*8feb0f0bSmrg template<typename _Tp> 129*8feb0f0bSmrg inline bool 130*8feb0f0bSmrg __check_singular(_Tp* const& __ptr) 131*8feb0f0bSmrg { return __ptr == 0; } 132*8feb0f0bSmrg 13336ac495dSmrg /** We say that integral types for a valid range, and defer to other 13436ac495dSmrg * routines to realize what to do with integral types instead of 13536ac495dSmrg * iterators. 13636ac495dSmrg */ 13736ac495dSmrg template<typename _Integral> 138*8feb0f0bSmrg _GLIBCXX_CONSTEXPR 139*8feb0f0bSmrg inline bool 140*8feb0f0bSmrg __valid_range_aux(_Integral, _Integral, std::__true_type) 141*8feb0f0bSmrg { return true; } 142*8feb0f0bSmrg 143*8feb0f0bSmrg template<typename _Integral> 144*8feb0f0bSmrg _GLIBCXX20_CONSTEXPR 14536ac495dSmrg inline bool 146c0a68be4Smrg __valid_range_aux(_Integral, _Integral, 14736ac495dSmrg typename _Distance_traits<_Integral>::__type& __dist, 14836ac495dSmrg std::__true_type) 14936ac495dSmrg { 15036ac495dSmrg __dist = std::make_pair(0, __dp_none); 15136ac495dSmrg return true; 15236ac495dSmrg } 15336ac495dSmrg 154*8feb0f0bSmrg template<typename _InputIterator> 155*8feb0f0bSmrg _GLIBCXX_CONSTEXPR 156*8feb0f0bSmrg inline bool 157*8feb0f0bSmrg __valid_range_aux(_InputIterator __first, _InputIterator __last, 158*8feb0f0bSmrg std::input_iterator_tag) 159*8feb0f0bSmrg { 160*8feb0f0bSmrg return __first == __last 161*8feb0f0bSmrg || (!__check_singular(__first) && !__check_singular(__last)); 162*8feb0f0bSmrg } 163*8feb0f0bSmrg 164*8feb0f0bSmrg template<typename _InputIterator> 165*8feb0f0bSmrg _GLIBCXX_CONSTEXPR 166*8feb0f0bSmrg inline bool 167*8feb0f0bSmrg __valid_range_aux(_InputIterator __first, _InputIterator __last, 168*8feb0f0bSmrg std::random_access_iterator_tag) 169*8feb0f0bSmrg { 170*8feb0f0bSmrg return 171*8feb0f0bSmrg __valid_range_aux(__first, __last, std::input_iterator_tag()) 172*8feb0f0bSmrg && __first <= __last; 173*8feb0f0bSmrg } 174*8feb0f0bSmrg 175c0a68be4Smrg /** We have iterators, so figure out what kind of iterators they are 17636ac495dSmrg * to see if we can check the range ahead of time. 17736ac495dSmrg */ 17836ac495dSmrg template<typename _InputIterator> 179*8feb0f0bSmrg _GLIBCXX_CONSTEXPR 180*8feb0f0bSmrg inline bool 181*8feb0f0bSmrg __valid_range_aux(_InputIterator __first, _InputIterator __last, 182*8feb0f0bSmrg std::__false_type) 183*8feb0f0bSmrg { 184*8feb0f0bSmrg return __valid_range_aux(__first, __last, 185*8feb0f0bSmrg std::__iterator_category(__first)); 186*8feb0f0bSmrg } 187*8feb0f0bSmrg 188*8feb0f0bSmrg template<typename _InputIterator> 189*8feb0f0bSmrg _GLIBCXX20_CONSTEXPR 19036ac495dSmrg inline bool 191c0a68be4Smrg __valid_range_aux(_InputIterator __first, _InputIterator __last, 19236ac495dSmrg typename _Distance_traits<_InputIterator>::__type& __dist, 19336ac495dSmrg std::__false_type) 19436ac495dSmrg { 195*8feb0f0bSmrg if (!__valid_range_aux(__first, __last, std::input_iterator_tag())) 196*8feb0f0bSmrg return false; 197*8feb0f0bSmrg 19836ac495dSmrg __dist = __get_distance(__first, __last); 19936ac495dSmrg switch (__dist.second) 20036ac495dSmrg { 20136ac495dSmrg case __dp_none: 20236ac495dSmrg break; 20336ac495dSmrg case __dp_equality: 20436ac495dSmrg if (__dist.first == 0) 20536ac495dSmrg return true; 20636ac495dSmrg break; 20736ac495dSmrg case __dp_sign: 208*8feb0f0bSmrg case __dp_sign_max_size: 20936ac495dSmrg case __dp_exact: 21036ac495dSmrg return __dist.first >= 0; 21136ac495dSmrg } 21236ac495dSmrg 21336ac495dSmrg // Can't tell so assume it is fine. 21436ac495dSmrg return true; 21536ac495dSmrg } 21636ac495dSmrg 21736ac495dSmrg /** Don't know what these iterators are, or if they are even 21836ac495dSmrg * iterators (we may get an integral type for InputIterator), so 21936ac495dSmrg * see if they are integral and pass them on to the next phase 22036ac495dSmrg * otherwise. 22136ac495dSmrg */ 22236ac495dSmrg template<typename _InputIterator> 223*8feb0f0bSmrg _GLIBCXX20_CONSTEXPR 22436ac495dSmrg inline bool 225c0a68be4Smrg __valid_range(_InputIterator __first, _InputIterator __last, 22636ac495dSmrg typename _Distance_traits<_InputIterator>::__type& __dist) 22736ac495dSmrg { 228*8feb0f0bSmrg #ifdef __cpp_lib_is_constant_evaluated 229*8feb0f0bSmrg if (std::is_constant_evaluated()) 230*8feb0f0bSmrg // Detected by the compiler directly. 231*8feb0f0bSmrg return true; 232*8feb0f0bSmrg #endif 23336ac495dSmrg typedef typename std::__is_integer<_InputIterator>::__type _Integral; 23436ac495dSmrg return __valid_range_aux(__first, __last, __dist, _Integral()); 23536ac495dSmrg } 23636ac495dSmrg 237c0a68be4Smrg template<typename _Iterator, typename _Sequence, typename _Category> 238c0a68be4Smrg bool 239c0a68be4Smrg __valid_range(const _Safe_iterator<_Iterator, _Sequence, _Category>&, 240c0a68be4Smrg const _Safe_iterator<_Iterator, _Sequence, _Category>&, 241c0a68be4Smrg typename _Distance_traits<_Iterator>::__type&); 242c0a68be4Smrg 243c0a68be4Smrg #if __cplusplus >= 201103L 244c0a68be4Smrg template<typename _Iterator,typename _Sequence> 245c0a68be4Smrg bool 246c0a68be4Smrg __valid_range(const _Safe_local_iterator<_Iterator, _Sequence>&, 247c0a68be4Smrg const _Safe_local_iterator<_Iterator, _Sequence>&, 248c0a68be4Smrg typename _Distance_traits<_Iterator>::__type&); 249c0a68be4Smrg #endif 250c0a68be4Smrg 25136ac495dSmrg template<typename _InputIterator> 252*8feb0f0bSmrg _GLIBCXX14_CONSTEXPR 25336ac495dSmrg inline bool 254c0a68be4Smrg __valid_range(_InputIterator __first, _InputIterator __last) 25536ac495dSmrg { 256*8feb0f0bSmrg #ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED 257*8feb0f0bSmrg if (__builtin_is_constant_evaluated()) 258*8feb0f0bSmrg // Detected by the compiler directly. 259*8feb0f0bSmrg return true; 260*8feb0f0bSmrg #endif 261*8feb0f0bSmrg typedef typename std::__is_integer<_InputIterator>::__type _Integral; 262*8feb0f0bSmrg return __valid_range_aux(__first, __last, _Integral()); 26336ac495dSmrg } 26436ac495dSmrg 265c0a68be4Smrg template<typename _Iterator, typename _Sequence, typename _Category> 266c0a68be4Smrg bool 267c0a68be4Smrg __valid_range(const _Safe_iterator<_Iterator, _Sequence, _Category>&, 268c0a68be4Smrg const _Safe_iterator<_Iterator, _Sequence, _Category>&); 26936ac495dSmrg 270c0a68be4Smrg #if __cplusplus >= 201103L 271c0a68be4Smrg template<typename _Iterator, typename _Sequence> 272c0a68be4Smrg bool 273c0a68be4Smrg __valid_range(const _Safe_local_iterator<_Iterator, _Sequence>&, 274c0a68be4Smrg const _Safe_local_iterator<_Iterator, _Sequence>&); 275c0a68be4Smrg #endif 276c0a68be4Smrg 277c0a68be4Smrg // Fallback method, always ok. 278c0a68be4Smrg template<typename _InputIterator, typename _Size> 279*8feb0f0bSmrg _GLIBCXX_CONSTEXPR 280c0a68be4Smrg inline bool 281c0a68be4Smrg __can_advance(_InputIterator, _Size) 282c0a68be4Smrg { return true; } 283c0a68be4Smrg 284c0a68be4Smrg template<typename _Iterator, typename _Sequence, typename _Category, 285c0a68be4Smrg typename _Size> 286c0a68be4Smrg bool 287c0a68be4Smrg __can_advance(const _Safe_iterator<_Iterator, _Sequence, _Category>&, 288c0a68be4Smrg _Size); 28936ac495dSmrg 290*8feb0f0bSmrg template<typename _InputIterator, typename _Diff> 291*8feb0f0bSmrg _GLIBCXX_CONSTEXPR 292*8feb0f0bSmrg inline bool 293*8feb0f0bSmrg __can_advance(_InputIterator, const std::pair<_Diff, _Distance_precision>&, int) 294*8feb0f0bSmrg { return true; } 295*8feb0f0bSmrg 296*8feb0f0bSmrg template<typename _Iterator, typename _Sequence, typename _Category, 297*8feb0f0bSmrg typename _Diff> 298*8feb0f0bSmrg bool 299*8feb0f0bSmrg __can_advance(const _Safe_iterator<_Iterator, _Sequence, _Category>&, 300*8feb0f0bSmrg const std::pair<_Diff, _Distance_precision>&, int); 301*8feb0f0bSmrg 30236ac495dSmrg /** Helper function to extract base iterator of random access safe iterator 303c0a68be4Smrg * in order to reduce performance impact of debug mode. Limited to random 304c0a68be4Smrg * access iterator because it is the only category for which it is possible 305c0a68be4Smrg * to check for correct iterators order in the __valid_range function 306c0a68be4Smrg * thanks to the < operator. 30736ac495dSmrg */ 30836ac495dSmrg template<typename _Iterator> 309*8feb0f0bSmrg _GLIBCXX_CONSTEXPR 31036ac495dSmrg inline _Iterator 31136ac495dSmrg __base(_Iterator __it) 31236ac495dSmrg { return __it; } 31336ac495dSmrg 31436ac495dSmrg #if __cplusplus < 201103L 31536ac495dSmrg template<typename _Iterator> 31636ac495dSmrg struct _Unsafe_type 31736ac495dSmrg { typedef _Iterator _Type; }; 31836ac495dSmrg #endif 31936ac495dSmrg 32036ac495dSmrg /* Remove debug mode safe iterator layer, if any. */ 32136ac495dSmrg template<typename _Iterator> 32236ac495dSmrg inline _Iterator 32336ac495dSmrg __unsafe(_Iterator __it) 32436ac495dSmrg { return __it; } 32536ac495dSmrg } 32636ac495dSmrg 32736ac495dSmrg #endif 328