1// Debugging support implementation -*- C++ -*- 2 3// Copyright (C) 2003-2013 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/c++config.h> 33#include <bits/stl_iterator_base_types.h> // for iterator_traits, categories and 34 // _Iter_base 35#include <bits/cpp_type_traits.h> // for __is_integer 36#include <debug/formatter.h> 37 38namespace __gnu_debug 39{ 40 template<typename _Iterator, typename _Sequence> 41 class _Safe_iterator; 42 43 // An arbitrary iterator pointer is not singular. 44 inline bool 45 __check_singular_aux(const void*) { return false; } 46 47 // We may have an iterator that derives from _Safe_iterator_base but isn't 48 // a _Safe_iterator. 49 template<typename _Iterator> 50 inline bool 51 __check_singular(_Iterator& __x) 52 { return __check_singular_aux(&__x); } 53 54 /** Non-NULL pointers are nonsingular. */ 55 template<typename _Tp> 56 inline bool 57 __check_singular(const _Tp* __ptr) 58 { return __ptr == 0; } 59 60 /** Safe iterators know if they are singular. */ 61 template<typename _Iterator, typename _Sequence> 62 inline bool 63 __check_singular(const _Safe_iterator<_Iterator, _Sequence>& __x) 64 { return __x._M_singular(); } 65 66 /** Assume that some arbitrary iterator is dereferenceable, because we 67 can't prove that it isn't. */ 68 template<typename _Iterator> 69 inline bool 70 __check_dereferenceable(_Iterator&) 71 { return true; } 72 73 /** Non-NULL pointers are dereferenceable. */ 74 template<typename _Tp> 75 inline bool 76 __check_dereferenceable(const _Tp* __ptr) 77 { return __ptr; } 78 79 /** Safe iterators know if they are singular. */ 80 template<typename _Iterator, typename _Sequence> 81 inline bool 82 __check_dereferenceable(const _Safe_iterator<_Iterator, _Sequence>& __x) 83 { return __x._M_dereferenceable(); } 84 85 /** If the distance between two random access iterators is 86 * nonnegative, assume the range is valid. 87 */ 88 template<typename _RandomAccessIterator> 89 inline bool 90 __valid_range_aux2(const _RandomAccessIterator& __first, 91 const _RandomAccessIterator& __last, 92 std::random_access_iterator_tag) 93 { return __last - __first >= 0; } 94 95 /** Can't test for a valid range with input iterators, because 96 * iteration may be destructive. So we just assume that the range 97 * is valid. 98 */ 99 template<typename _InputIterator> 100 inline bool 101 __valid_range_aux2(const _InputIterator&, const _InputIterator&, 102 std::input_iterator_tag) 103 { return true; } 104 105 /** We say that integral types for a valid range, and defer to other 106 * routines to realize what to do with integral types instead of 107 * iterators. 108 */ 109 template<typename _Integral> 110 inline bool 111 __valid_range_aux(const _Integral&, const _Integral&, std::__true_type) 112 { return true; } 113 114 /** We have iterators, so figure out what kind of iterators that are 115 * to see if we can check the range ahead of time. 116 */ 117 template<typename _InputIterator> 118 inline bool 119 __valid_range_aux(const _InputIterator& __first, 120 const _InputIterator& __last, std::__false_type) 121 { return __valid_range_aux2(__first, __last, 122 std::__iterator_category(__first)); } 123 124 /** Don't know what these iterators are, or if they are even 125 * iterators (we may get an integral type for InputIterator), so 126 * see if they are integral and pass them on to the next phase 127 * otherwise. 128 */ 129 template<typename _InputIterator> 130 inline bool 131 __valid_range(const _InputIterator& __first, const _InputIterator& __last) 132 { 133 typedef typename std::__is_integer<_InputIterator>::__type _Integral; 134 return __valid_range_aux(__first, __last, _Integral()); 135 } 136 137 /** Safe iterators know how to check if they form a valid range. */ 138 template<typename _Iterator, typename _Sequence> 139 inline bool 140 __valid_range(const _Safe_iterator<_Iterator, _Sequence>& __first, 141 const _Safe_iterator<_Iterator, _Sequence>& __last) 142 { return __first._M_valid_range(__last); } 143 144 /** Safe local iterators know how to check if they form a valid range. */ 145 template<typename _Iterator, typename _Sequence> 146 inline bool 147 __valid_range(const _Safe_local_iterator<_Iterator, _Sequence>& __first, 148 const _Safe_local_iterator<_Iterator, _Sequence>& __last) 149 { return __first._M_valid_range(__last); } 150 151 /* Checks that [first, last) is a valid range, and then returns 152 * __first. This routine is useful when we can't use a separate 153 * assertion statement because, e.g., we are in a constructor. 154 */ 155 template<typename _InputIterator> 156 inline _InputIterator 157 __check_valid_range(const _InputIterator& __first, 158 const _InputIterator& __last 159 __attribute__((__unused__))) 160 { 161 __glibcxx_check_valid_range(__first, __last); 162 return __first; 163 } 164 165 /** Checks that __s is non-NULL or __n == 0, and then returns __s. */ 166 template<typename _CharT, typename _Integer> 167 inline const _CharT* 168 __check_string(const _CharT* __s, 169 const _Integer& __n __attribute__((__unused__))) 170 { 171#ifdef _GLIBCXX_DEBUG_PEDANTIC 172 __glibcxx_assert(__s != 0 || __n == 0); 173#endif 174 return __s; 175 } 176 177 /** Checks that __s is non-NULL and then returns __s. */ 178 template<typename _CharT> 179 inline const _CharT* 180 __check_string(const _CharT* __s) 181 { 182#ifdef _GLIBCXX_DEBUG_PEDANTIC 183 __glibcxx_assert(__s != 0); 184#endif 185 return __s; 186 } 187 188 // Can't check if an input iterator sequence is sorted, because we 189 // can't step through the sequence. 190 template<typename _InputIterator> 191 inline bool 192 __check_sorted_aux(const _InputIterator&, const _InputIterator&, 193 std::input_iterator_tag) 194 { return true; } 195 196 // Can verify if a forward iterator sequence is in fact sorted using 197 // std::__is_sorted 198 template<typename _ForwardIterator> 199 inline bool 200 __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last, 201 std::forward_iterator_tag) 202 { 203 if (__first == __last) 204 return true; 205 206 _ForwardIterator __next = __first; 207 for (++__next; __next != __last; __first = __next, ++__next) 208 if (*__next < *__first) 209 return false; 210 211 return true; 212 } 213 214 // For performance reason, as the iterator range has been validated, check on 215 // random access safe iterators is done using the base iterator. 216 template<typename _Iterator, typename _Sequence> 217 inline bool 218 __check_sorted_aux(const _Safe_iterator<_Iterator, _Sequence>& __first, 219 const _Safe_iterator<_Iterator, _Sequence>& __last, 220 std::random_access_iterator_tag __tag) 221 { return __check_sorted_aux(__first.base(), __last.base(), __tag); } 222 223 // Can't check if an input iterator sequence is sorted, because we can't step 224 // through the sequence. 225 template<typename _InputIterator, typename _Predicate> 226 inline bool 227 __check_sorted_aux(const _InputIterator&, const _InputIterator&, 228 _Predicate, std::input_iterator_tag) 229 { return true; } 230 231 // Can verify if a forward iterator sequence is in fact sorted using 232 // std::__is_sorted 233 template<typename _ForwardIterator, typename _Predicate> 234 inline bool 235 __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last, 236 _Predicate __pred, std::forward_iterator_tag) 237 { 238 if (__first == __last) 239 return true; 240 241 _ForwardIterator __next = __first; 242 for (++__next; __next != __last; __first = __next, ++__next) 243 if (__pred(*__next, *__first)) 244 return false; 245 246 return true; 247 } 248 249 // For performance reason, as the iterator range has been validated, check on 250 // random access safe iterators is done using the base iterator. 251 template<typename _Iterator, typename _Sequence, 252 typename _Predicate> 253 inline bool 254 __check_sorted_aux(const _Safe_iterator<_Iterator, _Sequence>& __first, 255 const _Safe_iterator<_Iterator, _Sequence>& __last, 256 _Predicate __pred, 257 std::random_access_iterator_tag __tag) 258 { return __check_sorted_aux(__first.base(), __last.base(), __pred, __tag); } 259 260 // Determine if a sequence is sorted. 261 template<typename _InputIterator> 262 inline bool 263 __check_sorted(const _InputIterator& __first, const _InputIterator& __last) 264 { 265 // Verify that the < operator for elements in the sequence is a 266 // StrictWeakOrdering by checking that it is irreflexive. 267 __glibcxx_assert(__first == __last || !(*__first < *__first)); 268 269 return __check_sorted_aux(__first, __last, 270 std::__iterator_category(__first)); 271 } 272 273 template<typename _InputIterator, typename _Predicate> 274 inline bool 275 __check_sorted(const _InputIterator& __first, const _InputIterator& __last, 276 _Predicate __pred) 277 { 278 // Verify that the predicate is StrictWeakOrdering by checking that it 279 // is irreflexive. 280 __glibcxx_assert(__first == __last || !__pred(*__first, *__first)); 281 282 return __check_sorted_aux(__first, __last, __pred, 283 std::__iterator_category(__first)); 284 } 285 286 template<typename _InputIterator> 287 inline bool 288 __check_sorted_set_aux(const _InputIterator& __first, 289 const _InputIterator& __last, 290 std::__true_type) 291 { return __check_sorted(__first, __last); } 292 293 template<typename _InputIterator> 294 inline bool 295 __check_sorted_set_aux(const _InputIterator&, 296 const _InputIterator&, 297 std::__false_type) 298 { return true; } 299 300 template<typename _InputIterator, typename _Predicate> 301 inline bool 302 __check_sorted_set_aux(const _InputIterator& __first, 303 const _InputIterator& __last, 304 _Predicate __pred, std::__true_type) 305 { return __check_sorted(__first, __last, __pred); } 306 307 template<typename _InputIterator, typename _Predicate> 308 inline bool 309 __check_sorted_set_aux(const _InputIterator&, 310 const _InputIterator&, _Predicate, 311 std::__false_type) 312 { return true; } 313 314 // ... special variant used in std::merge, std::includes, std::set_*. 315 template<typename _InputIterator1, typename _InputIterator2> 316 inline bool 317 __check_sorted_set(const _InputIterator1& __first, 318 const _InputIterator1& __last, 319 const _InputIterator2&) 320 { 321 typedef typename std::iterator_traits<_InputIterator1>::value_type 322 _ValueType1; 323 typedef typename std::iterator_traits<_InputIterator2>::value_type 324 _ValueType2; 325 326 typedef typename std::__are_same<_ValueType1, _ValueType2>::__type 327 _SameType; 328 return __check_sorted_set_aux(__first, __last, _SameType()); 329 } 330 331 template<typename _InputIterator1, typename _InputIterator2, 332 typename _Predicate> 333 inline bool 334 __check_sorted_set(const _InputIterator1& __first, 335 const _InputIterator1& __last, 336 const _InputIterator2&, _Predicate __pred) 337 { 338 typedef typename std::iterator_traits<_InputIterator1>::value_type 339 _ValueType1; 340 typedef typename std::iterator_traits<_InputIterator2>::value_type 341 _ValueType2; 342 343 typedef typename std::__are_same<_ValueType1, _ValueType2>::__type 344 _SameType; 345 return __check_sorted_set_aux(__first, __last, __pred, _SameType()); 346 } 347 348 template<typename _ForwardIterator, typename _Tp> 349 inline bool 350 __check_partitioned_lower_aux(_ForwardIterator __first, 351 _ForwardIterator __last, const _Tp& __value, 352 std::forward_iterator_tag) 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 // For performance reason, as the iterator range has been validated, check on 366 // random access safe iterators is done using the base iterator. 367 template<typename _Iterator, typename _Sequence, typename _Tp> 368 inline bool 369 __check_partitioned_lower_aux( 370 const _Safe_iterator<_Iterator, _Sequence>& __first, 371 const _Safe_iterator<_Iterator, _Sequence>& __last, 372 const _Tp& __value, 373 std::random_access_iterator_tag __tag) 374 { 375 return __check_partitioned_lower_aux(__first.base(), __last.base(), 376 __value, __tag); 377 } 378 379 // _GLIBCXX_RESOLVE_LIB_DEFECTS 380 // 270. Binary search requirements overly strict 381 // Determine if a sequence is partitioned w.r.t. this element. 382 template<typename _ForwardIterator, typename _Tp> 383 inline bool 384 __check_partitioned_lower(_ForwardIterator __first, 385 _ForwardIterator __last, const _Tp& __value) 386 { 387 return __check_partitioned_lower_aux(__first, __last, __value, 388 std::__iterator_category(__first)); 389 } 390 391 template<typename _ForwardIterator, typename _Tp> 392 inline bool 393 __check_partitioned_upper_aux(_ForwardIterator __first, 394 _ForwardIterator __last, const _Tp& __value, 395 std::forward_iterator_tag) 396 { 397 while (__first != __last && !(__value < *__first)) 398 ++__first; 399 if (__first != __last) 400 { 401 ++__first; 402 while (__first != __last && __value < *__first) 403 ++__first; 404 } 405 return __first == __last; 406 } 407 408 // For performance reason, as the iterator range has been validated, check on 409 // random access safe iterators is done using the base iterator. 410 template<typename _Iterator, typename _Sequence, typename _Tp> 411 inline bool 412 __check_partitioned_upper_aux( 413 const _Safe_iterator<_Iterator, _Sequence>& __first, 414 const _Safe_iterator<_Iterator, _Sequence>& __last, 415 const _Tp& __value, 416 std::random_access_iterator_tag __tag) 417 { 418 return __check_partitioned_upper_aux(__first.base(), __last.base(), 419 __value, __tag); 420 } 421 422 template<typename _ForwardIterator, typename _Tp> 423 inline bool 424 __check_partitioned_upper(_ForwardIterator __first, 425 _ForwardIterator __last, const _Tp& __value) 426 { 427 return __check_partitioned_upper_aux(__first, __last, __value, 428 std::__iterator_category(__first)); 429 } 430 431 template<typename _ForwardIterator, typename _Tp, typename _Pred> 432 inline bool 433 __check_partitioned_lower_aux(_ForwardIterator __first, 434 _ForwardIterator __last, const _Tp& __value, 435 _Pred __pred, 436 std::forward_iterator_tag) 437 { 438 while (__first != __last && bool(__pred(*__first, __value))) 439 ++__first; 440 if (__first != __last) 441 { 442 ++__first; 443 while (__first != __last && !bool(__pred(*__first, __value))) 444 ++__first; 445 } 446 return __first == __last; 447 } 448 449 // For performance reason, as the iterator range has been validated, check on 450 // random access safe iterators is done using the base iterator. 451 template<typename _Iterator, typename _Sequence, 452 typename _Tp, typename _Pred> 453 inline bool 454 __check_partitioned_lower_aux( 455 const _Safe_iterator<_Iterator, _Sequence>& __first, 456 const _Safe_iterator<_Iterator, _Sequence>& __last, 457 const _Tp& __value, _Pred __pred, 458 std::random_access_iterator_tag __tag) 459 { 460 return __check_partitioned_lower_aux(__first.base(), __last.base(), 461 __value, __pred, __tag); 462 } 463 464 // Determine if a sequence is partitioned w.r.t. this element. 465 template<typename _ForwardIterator, typename _Tp, typename _Pred> 466 inline bool 467 __check_partitioned_lower(_ForwardIterator __first, 468 _ForwardIterator __last, const _Tp& __value, 469 _Pred __pred) 470 { 471 return __check_partitioned_lower_aux(__first, __last, __value, __pred, 472 std::__iterator_category(__first)); 473 } 474 475 template<typename _ForwardIterator, typename _Tp, typename _Pred> 476 inline bool 477 __check_partitioned_upper_aux(_ForwardIterator __first, 478 _ForwardIterator __last, const _Tp& __value, 479 _Pred __pred, 480 std::forward_iterator_tag) 481 { 482 while (__first != __last && !bool(__pred(__value, *__first))) 483 ++__first; 484 if (__first != __last) 485 { 486 ++__first; 487 while (__first != __last && bool(__pred(__value, *__first))) 488 ++__first; 489 } 490 return __first == __last; 491 } 492 493 // For performance reason, as the iterator range has been validated, check on 494 // random access safe iterators is done using the base iterator. 495 template<typename _Iterator, typename _Sequence, 496 typename _Tp, typename _Pred> 497 inline bool 498 __check_partitioned_upper_aux( 499 const _Safe_iterator<_Iterator, _Sequence>& __first, 500 const _Safe_iterator<_Iterator, _Sequence>& __last, 501 const _Tp& __value, _Pred __pred, 502 std::random_access_iterator_tag __tag) 503 { 504 return __check_partitioned_upper_aux(__first.base(), __last.base(), 505 __value, __pred, __tag); 506 } 507 508 template<typename _ForwardIterator, typename _Tp, typename _Pred> 509 inline bool 510 __check_partitioned_upper(_ForwardIterator __first, 511 _ForwardIterator __last, const _Tp& __value, 512 _Pred __pred) 513 { 514 return __check_partitioned_upper_aux(__first, __last, __value, __pred, 515 std::__iterator_category(__first)); 516 } 517 518 // Helper struct to detect random access safe iterators. 519 template<typename _Iterator> 520 struct __is_safe_random_iterator 521 { 522 enum { __value = 0 }; 523 typedef std::__false_type __type; 524 }; 525 526 template<typename _Iterator, typename _Sequence> 527 struct __is_safe_random_iterator<_Safe_iterator<_Iterator, _Sequence> > 528 : std::__are_same<std::random_access_iterator_tag, 529 typename std::iterator_traits<_Iterator>:: 530 iterator_category> 531 { }; 532 533 template<typename _Iterator> 534 struct _Siter_base 535 : std::_Iter_base<_Iterator, __is_safe_random_iterator<_Iterator>::__value> 536 { }; 537 538 /** Helper function to extract base iterator of random access safe iterator 539 in order to reduce performance impact of debug mode. Limited to random 540 access iterator because it is the only category for which it is possible 541 to check for correct iterators order in the __valid_range function 542 thanks to the < operator. 543 */ 544 template<typename _Iterator> 545 inline typename _Siter_base<_Iterator>::iterator_type 546 __base(_Iterator __it) 547 { return _Siter_base<_Iterator>::_S_base(__it); } 548} // namespace __gnu_debug 549 550#endif 551