| 1 | // Debugging support implementation -*- C++ -*- | 
 
 
 
 
 | 2 |  | 
 
 
 
 
 | 3 | // Copyright (C) 2003-2021 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/functions.h | 
 
 
 
 
 | 26 | *  This file is a GNU debug extension to the Standard C++ Library. | 
 
 
 
 
 | 27 | */ | 
 
 
 
 
 | 28 |  | 
 
 
 
 
 | 29 | #ifndef _GLIBCXX_DEBUG_FUNCTIONS_H | 
 
 
 
 
 | 30 | #define _GLIBCXX_DEBUG_FUNCTIONS_H 1 | 
 
 
 
 
 | 31 |  | 
 
 
 
 
 | 32 | #include <bits/stl_function.h>  // for less | 
 
 
 
 
 | 33 |  | 
 
 
 
 
 | 34 | #if __cplusplus >= 201103L | 
 
 
 
 
 | 35 | # include <bits/stl_iterator.h> // for __miter_base | 
 
 
 
 
 | 36 | # include <type_traits>         // for is_lvalue_reference and conditional. | 
 
 
 
 
 | 37 | #endif | 
 
 
 
 
 | 38 |  | 
 
 
 
 
 | 39 | #include <debug/helper_functions.h> | 
 
 
 
 
 | 40 | #include <debug/formatter.h> | 
 
 
 
 
 | 41 |  | 
 
 
 
 
 | 42 | namespace __gnu_debug | 
 
 
 
 
 | 43 | { | 
 
 
 
 
 | 44 | template<typename _Sequence> | 
 
 
 
 
 | 45 | struct _Insert_range_from_self_is_safe | 
 
 
 
 
 | 46 | { enum { __value = 0 }; }; | 
 
 
 
 
 | 47 |  | 
 
 
 
 
 | 48 | template<typename _Sequence> | 
 
 
 
 
 | 49 | struct _Is_contiguous_sequence : std::__false_type { }; | 
 
 
 
 
 | 50 |  | 
 
 
 
 
 | 51 | /* Checks that [first, last) is a valid range, and then returns | 
 
 
 
 
 | 52 | * __first. This routine is useful when we can't use a separate | 
 
 
 
 
 | 53 | * assertion statement because, e.g., we are in a constructor. | 
 
 
 
 
 | 54 | */ | 
 
 
 
 
 | 55 | template<typename _InputIterator> | 
 
 
 
 
 | 56 | inline _InputIterator | 
 
 
 
 
 | 57 | __check_valid_range(const _InputIterator& __first, | 
 
 
 
 
 | 58 | const _InputIterator& __last, | 
 
 
 
 
 | 59 | const char* __file, | 
 
 
 
 
 | 60 | unsigned int __line, | 
 
 
 
 
 | 61 | const char* __function) | 
 
 
 
 
 | 62 | { | 
 
 
 
 
 | 63 | __glibcxx_check_valid_range_at(__first, __last, | 
 
 
 
 
 | 64 | __file, __line, __function); | 
 
 
 
 
 | 65 | return __first; | 
 
 
 
 
 | 66 | } | 
 
 
 
 
 | 67 |  | 
 
 
 
 
 | 68 | /* Handle the case where __other is a pointer to _Sequence::value_type. */ | 
 
 
 
 
 | 69 | template<typename _Iterator, typename _Sequence, typename _Category> | 
 
 
 
 
 | 70 | inline bool | 
 
 
 
 
 | 71 | __foreign_iterator_aux4( | 
 
 
 
 
 | 72 | const _Safe_iterator<_Iterator, _Sequence, _Category>& __it, | 
 
 
 
 
 | 73 | const typename _Sequence::value_type* __other) | 
 
 
 
 
 | 74 | { | 
 
 
 
 
 | 75 | typedef const typename _Sequence::value_type* _PointerType; | 
 
 
 
 
 | 76 | typedef std::less<_PointerType> _Less; | 
 
 
 
 
 | 77 | #if __cplusplus >= 201103L | 
 
 
 
 
 | 78 | constexpr _Less __l{}; | 
 
 
 
 
 | 79 | #else | 
 
 
 
 
 | 80 | const _Less __l = _Less(); | 
 
 
 
 
 | 81 | #endif | 
 
 
 
 
 | 82 | const _Sequence* __seq = __it._M_get_sequence(); | 
 
 
 
 
 | 83 | const _PointerType __begin = std::__addressof(*__seq->_M_base().begin()); | 
 
 
 
 
 | 84 | const _PointerType __end = std::__addressof(*(__seq->_M_base().end()-1)); | 
 
 
 
 
 | 85 |  | 
 
 
 
 
 | 86 | // Check whether __other points within the contiguous storage. | 
 
 
 
 
 | 87 | return __l(__other, __begin) || __l(__end, __other); | 
 
 
 
 
 | 88 | } | 
 
 
 
 
 | 89 |  | 
 
 
 
 
 | 90 | /* Fallback overload for when we can't tell, assume it is valid. */ | 
 
 
 
 
 | 91 | template<typename _Iterator, typename _Sequence, typename _Category> | 
 
 
 
 
 | 92 | inline bool | 
 
 
 
 
 | 93 | __foreign_iterator_aux4( | 
 
 
 
 
 | 94 | const _Safe_iterator<_Iterator, _Sequence, _Category>&, ...) | 
 
 
 
 
 | 95 | { return true; } | 
 
 
 
 
 | 96 |  | 
 
 
 
 
 | 97 | /* Handle sequences with contiguous storage */ | 
 
 
 
 
 | 98 | template<typename _Iterator, typename _Sequence, typename _Category, | 
 
 
 
 
 | 99 | typename _InputIterator> | 
 
 
 
 
 | 100 | inline bool | 
 
 
 
 
 | 101 | __foreign_iterator_aux3( | 
 
 
 
 
 | 102 | const _Safe_iterator<_Iterator, _Sequence, _Category>& __it, | 
 
 
 
 
 | 103 | const _InputIterator& __other, const _InputIterator& __other_end, | 
 
 
 
 
 | 104 | std::__true_type) | 
 
 
 
 
 | 105 | { | 
 
 
 
 
 | 106 | if (__other == __other_end) | 
 
 
 
 
 | 107 | return true;  // inserting nothing is safe even if not foreign iters | 
 
 
 
 
 | 108 | if (__it._M_get_sequence()->empty()) | 
 
 
 
 
 | 109 | return true;  // can't be self-inserting if self is empty | 
 
 
 
 
 | 110 | return __foreign_iterator_aux4(__it, std::__addressof(*__other)); | 
 
 
 
 
 | 111 | } | 
 
 
 
 
 | 112 |  | 
 
 
 
 
 | 113 | /* Handle non-contiguous containers, assume it is valid. */ | 
 
 
 
 
 | 114 | template<typename _Iterator, typename _Sequence, typename _Category, | 
 
 
 
 
 | 115 | typename _InputIterator> | 
 
 
 
 
 | 116 | inline bool | 
 
 
 
 
 | 117 | __foreign_iterator_aux3( | 
 
 
 
 
 | 118 | const _Safe_iterator<_Iterator, _Sequence, _Category>&, | 
 
 
 
 
 | 119 | const _InputIterator&, const _InputIterator&, | 
 
 
 
 
 | 120 | std::__false_type) | 
 
 
 
 
 | 121 | { return true; } | 
 
 
 
 
 | 122 |  | 
 
 
 
 
 | 123 | /** Handle debug iterators from the same type of container. */ | 
 
 
 
 
 | 124 | template<typename _Iterator, typename _Sequence, typename _Category, | 
 
 
 
 
 | 125 | typename _OtherIterator> | 
 
 
 
 
 | 126 | inline bool | 
 
 
 
 
 | 127 | __foreign_iterator_aux2( | 
 
 
 
 
 | 128 | const _Safe_iterator<_Iterator, _Sequence, _Category>& __it, | 
 
 
 
 
 | 129 | const _Safe_iterator<_OtherIterator, _Sequence, _Category>& __other, | 
 
 
 
 
 | 130 | const _Safe_iterator<_OtherIterator, _Sequence, _Category>&) | 
 
 
 
 
 | 131 | { return __it._M_get_sequence() != __other._M_get_sequence(); } | 
 
 
 
 
 | 132 |  | 
 
 
 
 
 | 133 | /** Handle debug iterators from different types of container. */ | 
 
 
 
 
 | 134 | template<typename _Iterator, typename _Sequence, typename _Category, | 
 
 
 
 
 | 135 | typename _OtherIterator, typename _OtherSequence, | 
 
 
 
 
 | 136 | typename _OtherCategory> | 
 
 
 
 
 | 137 | inline bool | 
 
 
 
 
 | 138 | __foreign_iterator_aux2( | 
 
 
 
 
 | 139 | const _Safe_iterator<_Iterator, _Sequence, _Category>&, | 
 
 
 
 
 | 140 | const _Safe_iterator<_OtherIterator, _OtherSequence, | 
 
 
 
 
 | 141 | _OtherCategory>&, | 
 
 
 
 
 | 142 | const _Safe_iterator<_OtherIterator, _OtherSequence, | 
 
 
 
 
 | 143 | _OtherCategory>&) | 
 
 
 
 
 | 144 | { return true; } | 
 
 
 
 
 | 145 |  | 
 
 
 
 
 | 146 | /* Handle non-debug iterators. */ | 
 
 
 
 
 | 147 | template<typename _Iterator, typename _Sequence, typename _Category, | 
 
 
 
 
 | 148 | typename _InputIterator> | 
 
 
 
 
 | 149 | inline bool | 
 
 
 
 
 | 150 | __foreign_iterator_aux2( | 
 
 
 
 
 | 151 | const _Safe_iterator<_Iterator, _Sequence, _Category>& __it, | 
 
 
 
 
 | 152 | const _InputIterator& __other, | 
 
 
 
 
 | 153 | const _InputIterator& __other_end) | 
 
 
 
 
 | 154 | { | 
 
 
 
 
 | 155 | #if __cplusplus < 201103L | 
 
 
 
 
 | 156 | typedef _Is_contiguous_sequence<_Sequence> __tag; | 
 
 
 
 
 | 157 | #else | 
 
 
 
 
 | 158 | using __lvalref = std::is_lvalue_reference< | 
 
 
 
 
 | 159 | typename std::iterator_traits<_InputIterator>::reference>; | 
 
 
 
 
 | 160 | using __contiguous = _Is_contiguous_sequence<_Sequence>; | 
 
 
 
 
 | 161 | using __tag = typename std::conditional<__lvalref::value, __contiguous, | 
 
 
 
 
 | 162 | std::__false_type>::type; | 
 
 
 
 
 | 163 | #endif | 
 
 
 
 
 | 164 | return __foreign_iterator_aux3(__it, __other, __other_end, __tag()); | 
 
 
 
 
 | 165 | } | 
 
 
 
 
 | 166 |  | 
 
 
 
 
 | 167 | /* Handle the case where we aren't really inserting a range after all */ | 
 
 
 
 
 | 168 | template<typename _Iterator, typename _Sequence, typename _Category, | 
 
 
 
 
 | 169 | typename _Integral> | 
 
 
 
 
 | 170 | inline bool | 
 
 
 
 
 | 171 | __foreign_iterator_aux( | 
 
 
 
 
 | 172 | const _Safe_iterator<_Iterator, _Sequence, _Category>&, | 
 
 
 
 
 | 173 | _Integral, _Integral, std::__true_type) | 
 
 
 
 
 | 174 | { return true; } | 
 
 
 
 
 | 175 |  | 
 
 
 
 
 | 176 | /* Handle all iterators. */ | 
 
 
 
 
 | 177 | template<typename _Iterator, typename _Sequence, typename _Category, | 
 
 
 
 
 | 178 | typename _InputIterator> | 
 
 
 
 
 | 179 | inline bool | 
 
 
 
 
 | 180 | __foreign_iterator_aux( | 
 
 
 
 
 | 181 | const _Safe_iterator<_Iterator, _Sequence, _Category>& __it, | 
 
 
 
 
 | 182 | _InputIterator __other, _InputIterator __other_end, | 
 
 
 
 
 | 183 | std::__false_type) | 
 
 
 
 
 | 184 | { | 
 
 
 
 
 | 185 | return _Insert_range_from_self_is_safe<_Sequence>::__value | 
 
 
 
 
 | 186 | || __foreign_iterator_aux2(__it, std::__miter_base(__other), | 
 
 
 
 
 | 187 | std::__miter_base(__other_end)); | 
 
 
 
 
 | 188 | } | 
 
 
 
 
 | 189 |  | 
 
 
 
 
 | 190 | template<typename _Iterator, typename _Sequence, typename _Category, | 
 
 
 
 
 | 191 | typename _InputIterator> | 
 
 
 
 
 | 192 | inline bool | 
 
 
 
 
 | 193 | __foreign_iterator( | 
 
 
 
 
 | 194 | const _Safe_iterator<_Iterator, _Sequence, _Category>& __it, | 
 
 
 
 
 | 195 | _InputIterator __other, _InputIterator __other_end) | 
 
 
 
 
 | 196 | { | 
 
 
 
 
 | 197 | typedef typename std::__is_integer<_InputIterator>::__type _Integral; | 
 
 
 
 
 | 198 | return __foreign_iterator_aux(__it, __other, __other_end, _Integral()); | 
 
 
 
 
 | 199 | } | 
 
 
 
 
 | 200 |  | 
 
 
 
 
 | 201 | // Can't check if an input iterator sequence is sorted, because we | 
 
 
 
 
 | 202 | // can't step through the sequence. | 
 
 
 
 
 | 203 | template<typename _InputIterator> | 
 
 
 
 
 | 204 | _GLIBCXX20_CONSTEXPR | 
 
 
 
 
 | 205 | inline bool | 
 
 
 
 
 | 206 | __check_sorted_aux(const _InputIterator&, const _InputIterator&, | 
 
 
 
 
 | 207 | std::input_iterator_tag) | 
 
 
 
 
 | 208 | { return true; } | 
 
 
 
 
 | 209 |  | 
 
 
 
 
 | 210 | // Can verify if a forward iterator sequence is in fact sorted using | 
 
 
 
 
 | 211 | // std::__is_sorted | 
 
 
 
 
 | 212 | template<typename _ForwardIterator> | 
 
 
 
 
 | 213 | _GLIBCXX20_CONSTEXPR | 
 
 
 
 
 | 214 | inline bool | 
 
 
 
 
 | 215 | __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last, | 
 
 
 
 
 | 216 | std::forward_iterator_tag) | 
 
 
 
 
 | 217 | { | 
 
 
 
 
 | 218 | if (__first == __last) | 
 
 
 
 
 | 219 | return true; | 
 
 
 
 
 | 220 |  | 
 
 
 
 
 | 221 | _ForwardIterator __next = __first; | 
 
 
 
 
 | 222 | for (++__next; __next != __last; __first = __next, (void)++__next) | 
 
 
 
 
 | 223 | if (*__next < *__first) | 
 
 
 
 
 | 224 | return false; | 
 
 
 
 
 | 225 |  | 
 
 
 
 
 | 226 | return true; | 
 
 
 
 
 | 227 | } | 
 
 
 
 
 | 228 |  | 
 
 
 
 
 | 229 | // Can't check if an input iterator sequence is sorted, because we can't step | 
 
 
 
 
 | 230 | // through the sequence. | 
 
 
 
 
 | 231 | template<typename _InputIterator, typename _Predicate> | 
 
 
 
 
 | 232 | _GLIBCXX20_CONSTEXPR | 
 
 
 
 
 | 233 | inline bool | 
 
 
 
 
 | 234 | __check_sorted_aux(const _InputIterator&, const _InputIterator&, | 
 
 
 
 
 | 235 | _Predicate, std::input_iterator_tag) | 
 
 
 
 
 | 236 | { return true; } | 
 
 
 
 
 | 237 |  | 
 
 
 
 
 | 238 | // Can verify if a forward iterator sequence is in fact sorted using | 
 
 
 
 
 | 239 | // std::__is_sorted | 
 
 
 
 
 | 240 | template<typename _ForwardIterator, typename _Predicate> | 
 
 
 
 
 | 241 | _GLIBCXX20_CONSTEXPR | 
 
 
 
 
 | 242 | inline bool | 
 
 
 
 
 | 243 | __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last, | 
 
 
 
 
 | 244 | _Predicate __pred, std::forward_iterator_tag) | 
 
 
 
 
 | 245 | { | 
 
 
 
 
 | 246 | if (__first == __last) | 
 
 
 
 
 | 247 | return true; | 
 
 
 
 
 | 248 |  | 
 
 
 
 
 | 249 | _ForwardIterator __next = __first; | 
 
 
 
 
 | 250 | for (++__next; __next != __last; __first = __next, (void)++__next) | 
 
 
 
 
 | 251 | if (__pred(*__next, *__first)) | 
 
 
 
 
 | 252 | return false; | 
 
 
 
 
 | 253 |  | 
 
 
 
 
 | 254 | return true; | 
 
 
 
 
 | 255 | } | 
 
 
 
 
 | 256 |  | 
 
 
 
 
 | 257 | // Determine if a sequence is sorted. | 
 
 
 
 
 | 258 | template<typename _InputIterator> | 
 
 
 
 
 | 259 | _GLIBCXX20_CONSTEXPR | 
 
 
 
 
 | 260 | inline bool | 
 
 
 
 
 | 261 | __check_sorted(const _InputIterator& __first, const _InputIterator& __last) | 
 
 
 
 
 | 262 | { | 
 
 
 
 
 | 263 | return __check_sorted_aux(__first, __last, | 
 
 
 
 
 | 264 | std::__iterator_category(__first)); | 
 
 
 
 
 | 265 | } | 
 
 
 
 
 | 266 |  | 
 
 
 
 
 | 267 | template<typename _InputIterator, typename _Predicate> | 
 
 
 
 
 | 268 | _GLIBCXX20_CONSTEXPR | 
 
 
 
 
 | 269 | inline bool | 
 
 
 
 
 | 270 | __check_sorted(const _InputIterator& __first, const _InputIterator& __last, | 
 
 
 
 
 | 271 | _Predicate __pred) | 
 
 
 
 
 | 272 | { | 
 
 
 
 
 | 273 | return __check_sorted_aux(__first, __last, __pred, | 
 
 
 
 
 | 274 | std::__iterator_category(__first)); | 
 
 
 
 
 | 275 | } | 
 
 
 
 
 | 276 |  | 
 
 
 
 
 | 277 | template<typename _InputIterator> | 
 
 
 
 
 | 278 | _GLIBCXX20_CONSTEXPR | 
 
 
 
 
 | 279 | inline bool | 
 
 
 
 
 | 280 | __check_sorted_set_aux(const _InputIterator& __first, | 
 
 
 
 
 | 281 | const _InputIterator& __last, | 
 
 
 
 
 | 282 | std::__true_type) | 
 
 
 
 
 | 283 | { return __check_sorted(__first, __last); } | 
 
 
 
 
 | 284 |  | 
 
 
 
 
 | 285 | template<typename _InputIterator> | 
 
 
 
 
 | 286 | _GLIBCXX20_CONSTEXPR | 
 
 
 
 
 | 287 | inline bool | 
 
 
 
 
 | 288 | __check_sorted_set_aux(const _InputIterator&, | 
 
 
 
 
 | 289 | const _InputIterator&, | 
 
 
 
 
 | 290 | std::__false_type) | 
 
 
 
 
 | 291 | { return true; } | 
 
 
 
 
 | 292 |  | 
 
 
 
 
 | 293 | template<typename _InputIterator, typename _Predicate> | 
 
 
 
 
 | 294 | _GLIBCXX20_CONSTEXPR | 
 
 
 
 
 | 295 | inline bool | 
 
 
 
 
 | 296 | __check_sorted_set_aux(const _InputIterator& __first, | 
 
 
 
 
 | 297 | const _InputIterator& __last, | 
 
 
 
 
 | 298 | _Predicate __pred, std::__true_type) | 
 
 
 
 
 | 299 | { return __check_sorted(__first, __last, __pred); } | 
 
 
 
 
 | 300 |  | 
 
 
 
 
 | 301 | template<typename _InputIterator, typename _Predicate> | 
 
 
 
 
 | 302 | _GLIBCXX20_CONSTEXPR | 
 
 
 
 
 | 303 | inline bool | 
 
 
 
 
 | 304 | __check_sorted_set_aux(const _InputIterator&, | 
 
 
 
 
 | 305 | const _InputIterator&, _Predicate, | 
 
 
 
 
 | 306 | std::__false_type) | 
 
 
 
 
 | 307 | { return true; } | 
 
 
 
 
 | 308 |  | 
 
 
 
 
 | 309 | // ... special variant used in std::merge, std::includes, std::set_*. | 
 
 
 
 
 | 310 | template<typename _InputIterator1, typename _InputIterator2> | 
 
 
 
 
 | 311 | _GLIBCXX20_CONSTEXPR | 
 
 
 
 
 | 312 | inline bool | 
 
 
 
 
 | 313 | __check_sorted_set(const _InputIterator1& __first, | 
 
 
 
 
 | 314 | const _InputIterator1& __last, | 
 
 
 
 
 | 315 | const _InputIterator2&) | 
 
 
 
 
 | 316 | { | 
 
 
 
 
 | 317 | typedef typename std::iterator_traits<_InputIterator1>::value_type | 
 
 
 
 
 | 318 | _ValueType1; | 
 
 
 
 
 | 319 | typedef typename std::iterator_traits<_InputIterator2>::value_type | 
 
 
 
 
 | 320 | _ValueType2; | 
 
 
 
 
 | 321 |  | 
 
 
 
 
 | 322 | typedef typename std::__are_same<_ValueType1, _ValueType2>::__type | 
 
 
 
 
 | 323 | _SameType; | 
 
 
 
 
 | 324 | return __check_sorted_set_aux(__first, __last, _SameType()); | 
 
 
 
 
 | 325 | } | 
 
 
 
 
 | 326 |  | 
 
 
 
 
 | 327 | template<typename _InputIterator1, typename _InputIterator2, | 
 
 
 
 
 | 328 | typename _Predicate> | 
 
 
 
 
 | 329 | _GLIBCXX20_CONSTEXPR | 
 
 
 
 
 | 330 | inline bool | 
 
 
 
 
 | 331 | __check_sorted_set(const _InputIterator1& __first, | 
 
 
 
 
 | 332 | const _InputIterator1& __last, | 
 
 
 
 
 | 333 | const _InputIterator2&, _Predicate __pred) | 
 
 
 
 
 | 334 | { | 
 
 
 
 
 | 335 | typedef typename std::iterator_traits<_InputIterator1>::value_type | 
 
 
 
 
 | 336 | _ValueType1; | 
 
 
 
 
 | 337 | typedef typename std::iterator_traits<_InputIterator2>::value_type | 
 
 
 
 
 | 338 | _ValueType2; | 
 
 
 
 
 | 339 |  | 
 
 
 
 
 | 340 | typedef typename std::__are_same<_ValueType1, _ValueType2>::__type | 
 
 
 
 
 | 341 | _SameType; | 
 
 
 
 
 | 342 | return __check_sorted_set_aux(__first, __last, __pred, _SameType()); | 
 
 
 
 
 | 343 | } | 
 
 
 
 
 | 344 |  | 
 
 
 
 
 | 345 | // _GLIBCXX_RESOLVE_LIB_DEFECTS | 
 
 
 
 
 | 346 | // 270. Binary search requirements overly strict | 
 
 
 
 
 | 347 | // Determine if a sequence is partitioned w.r.t. this element. | 
 
 
 
 
 | 348 | template<typename _ForwardIterator, typename _Tp> | 
 
 
 
 
 | 349 | _GLIBCXX20_CONSTEXPR | 
 
 
 
 
 | 350 | inline bool | 
 
 
 
 
 | 351 | __check_partitioned_lower(_ForwardIterator __first, | 
 
 
 
 
 | 352 | _ForwardIterator __last, const _Tp& __value) | 
 
 
 
 
 | 353 | { | 
 
 
 
 
 | 354 | while (__first != __last && *__first < __value) | 
 
 
 
 
 | 355 | ++__first; | 
 
 
 
 
 | 356 | if (__first != __last) | 
 
 
 
 
 | 357 | { | 
 
 
 
 
 | 358 | ++__first; | 
 
 
 
 
 | 359 | while (__first != __last && !(*__first < __value)) | 
 
 
 
 
 | 360 | ++__first; | 
 
 
 
 
 | 361 | } | 
 
 
 
 
 | 362 | return __first == __last; | 
 
 
 
 
 | 363 | } | 
 
 
 
 
 | 364 |  | 
 
 
 
 
 | 365 | template<typename _ForwardIterator, typename _Tp> | 
 
 
 
 
 | 366 | _GLIBCXX20_CONSTEXPR | 
 
 
 
 
 | 367 | inline bool | 
 
 
 
 
 | 368 | __check_partitioned_upper(_ForwardIterator __first, | 
 
 
 
 
 | 369 | _ForwardIterator __last, const _Tp& __value) | 
 
 
 
 
 | 370 | { | 
 
 
 
 
 | 371 | while (__first != __last && !(__value < *__first)) | 
 
 
 
 
 | 372 | ++__first; | 
 
 
 
 
 | 373 | if (__first != __last) | 
 
 
 
 
 | 374 | { | 
 
 
 
 
 | 375 | ++__first; | 
 
 
 
 
 | 376 | while (__first != __last && __value < *__first) | 
 
 
 
 
 | 377 | ++__first; | 
 
 
 
 
 | 378 | } | 
 
 
 
 
 | 379 | return __first == __last; | 
 
 
 
 
 | 380 | } | 
 
 
 
 
 | 381 |  | 
 
 
 
 
 | 382 | // Determine if a sequence is partitioned w.r.t. this element. | 
 
 
 
 
 | 383 | template<typename _ForwardIterator, typename _Tp, typename _Pred> | 
 
 
 
 
 | 384 | _GLIBCXX20_CONSTEXPR | 
 
 
 
 
 | 385 | inline bool | 
 
 
 
 
 | 386 | __check_partitioned_lower(_ForwardIterator __first, | 
 
 
 
 
 | 387 | _ForwardIterator __last, const _Tp& __value, | 
 
 
 
 
 | 388 | _Pred __pred) | 
 
 
 
 
 | 389 | { | 
 
 
 
 
 | 390 | while (__first != __last && bool(__pred(*__first, __value))) | 
 
 
 
 
 | 391 | ++__first; | 
 
 
 
 
 | 392 | if (__first != __last) | 
 
 
 
 
 | 393 | { | 
 
 
 
 
 | 394 | ++__first; | 
 
 
 
 
 | 395 | while (__first != __last && !bool(__pred(*__first, __value))) | 
 
 
 
 
 | 396 | ++__first; | 
 
 
 
 
 | 397 | } | 
 
 
 
 
 | 398 | return __first == __last; | 
 
 
 
 
 | 399 | } | 
 
 
 
 
 | 400 |  | 
 
 
 
 
 | 401 | template<typename _ForwardIterator, typename _Tp, typename _Pred> | 
 
 
 
 
 | 402 | _GLIBCXX20_CONSTEXPR | 
 
 
 
 
 | 403 | inline bool | 
 
 
 
 
 | 404 | __check_partitioned_upper(_ForwardIterator __first, | 
 
 
 
 
 | 405 | _ForwardIterator __last, const _Tp& __value, | 
 
 
 
 
 | 406 | _Pred __pred) | 
 
 
 
 
 | 407 | { | 
 
 
 
 
 | 408 | while (__first != __last && !bool(__pred(__value, *__first))) | 
 
 
 
 
 | 409 | ++__first; | 
 
 
 
 
 | 410 | if (__first != __last) | 
 
 
 
 
 | 411 | { | 
 
 
 
 
 | 412 | ++__first; | 
 
 
 
 
 | 413 | while (__first != __last && bool(__pred(__value, *__first))) | 
 
 
 
 
 | 414 | ++__first; | 
 
 
 
 
 | 415 | } | 
 
 
 
 
 | 416 | return __first == __last; | 
 
 
 
 
 | 417 | } | 
 
 
 
 
 | 418 |  | 
 
 
 
 
 | 419 | #if __cplusplus >= 201103L | 
 
 
 
 
 | 420 | struct _Irreflexive_checker | 
 
 
 
 
 | 421 | { | 
 
 
 
 
 | 422 | template<typename _It> | 
 
 
 
 
 | 423 | static typename std::iterator_traits<_It>::reference | 
 
 
 
 
 | 424 | __ref(); | 
 
 
 
 
 | 425 |  | 
 
 
 
 
 | 426 | template<typename _It, | 
 
 
 
 
 | 427 | typename = decltype(__ref<_It>() < __ref<_It>())> | 
 
 
 
 
 | 428 | _GLIBCXX20_CONSTEXPR | 
 
 
 
 
 | 429 | static bool | 
 
 
 
 
 | 430 | _S_is_valid(_It __it) | 
 
 
 
 
 | 431 | { return !(*__it < *__it); } | 
 
 
 
 
 | 432 |  | 
 
 
 
 
 | 433 | // Fallback method if operator doesn't exist. | 
 
 
 
 
 | 434 | template<typename... _Args> | 
 
 
 
 
 | 435 | _GLIBCXX20_CONSTEXPR | 
 
 
 
 
 | 436 | static bool | 
 
 
 
 
 | 437 | _S_is_valid(_Args...) | 
 
 
 
 
 | 438 | { return true; } | 
 
 
 
 
 | 439 |  | 
 
 
 
 
 | 440 | template<typename _It, typename _Pred, typename | 
 
 
 
 
 | 441 | = decltype(std::declval<_Pred>()(__ref<_It>(), __ref<_It>()))> | 
 
 
 
 
 | 442 | _GLIBCXX20_CONSTEXPR | 
 
 
 
 
 | 443 | static bool | 
 
 
 
 
 | 444 | _S_is_valid_pred(_It __it, _Pred __pred) | 
 
 
 
 
 | 445 | { return !__pred(*__it, *__it); } | 
 
 
 
 
 | 446 |  | 
 
 
 
 
 | 447 | // Fallback method if predicate can't be invoked. | 
 
 
 
 
 | 448 | template<typename... _Args> | 
 
 
 
 
 | 449 | _GLIBCXX20_CONSTEXPR | 
 
 
 
 
 | 450 | static bool | 
 
 
 
 
 | 451 | _S_is_valid_pred(_Args...) | 
 
 
 
 
 | 452 | { return true; } | 
 
 
 
 
 | 453 | }; | 
 
 
 
 
 | 454 |  | 
 
 
 
 
 | 455 | template<typename _Iterator> | 
 
 
 
 
 | 456 | _GLIBCXX20_CONSTEXPR | 
 
 
 
 
 | 457 | inline bool | 
 
 
 
 
 | 458 | __is_irreflexive(_Iterator __it) | 
 
 
 
 
 | 459 | { return _Irreflexive_checker::_S_is_valid(__it); } | 
 
 
 
 
 | 460 |  | 
 
 
 
 
 | 461 | template<typename _Iterator, typename _Pred> | 
 
 
 
 
 | 462 | _GLIBCXX20_CONSTEXPR | 
 
 
 
 
 | 463 | inline bool | 
 
 
 
 
 | 464 | __is_irreflexive_pred(_Iterator __it, _Pred __pred) | 
 
 
 
 
 | 465 | { return _Irreflexive_checker::_S_is_valid_pred(__it, __pred); } | 
 
 
 
 
 | 466 | #endif | 
 
 
 
 
 | 467 |  | 
 
 
 
 
 | 468 | } // namespace __gnu_debug | 
 
 
 
 
 | 469 |  | 
 
 
 
 
 | 470 | #endif |