libstdc++
|
00001 // Debugging support implementation -*- C++ -*- 00002 00003 // Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 00004 // Free Software Foundation, Inc. 00005 // 00006 // This file is part of the GNU ISO C++ Library. This library is free 00007 // software; you can redistribute it and/or modify it under the 00008 // terms of the GNU General Public License as published by the 00009 // Free Software Foundation; either version 3, or (at your option) 00010 // any later version. 00011 00012 // This library is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU General Public License for more details. 00016 00017 // Under Section 7 of GPL version 3, you are granted additional 00018 // permissions described in the GCC Runtime Library Exception, version 00019 // 3.1, as published by the Free Software Foundation. 00020 00021 // You should have received a copy of the GNU General Public License and 00022 // a copy of the GCC Runtime Library Exception along with this program; 00023 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00024 // <http://www.gnu.org/licenses/>. 00025 00026 /** @file debug/functions.h 00027 * This file is a GNU debug extension to the Standard C++ Library. 00028 */ 00029 00030 #ifndef _GLIBCXX_DEBUG_FUNCTIONS_H 00031 #define _GLIBCXX_DEBUG_FUNCTIONS_H 1 00032 00033 #include <bits/c++config.h> 00034 #include <bits/stl_iterator_base_types.h> // for iterator_traits, categories 00035 #include <bits/cpp_type_traits.h> // for __is_integer 00036 #include <debug/formatter.h> 00037 00038 namespace __gnu_debug 00039 { 00040 template<typename _Iterator, typename _Sequence> 00041 class _Safe_iterator; 00042 00043 // An arbitrary iterator pointer is not singular. 00044 inline bool 00045 __check_singular_aux(const void*) { return false; } 00046 00047 // We may have an iterator that derives from _Safe_iterator_base but isn't 00048 // a _Safe_iterator. 00049 template<typename _Iterator> 00050 inline bool 00051 __check_singular(_Iterator& __x) 00052 { return __check_singular_aux(&__x); } 00053 00054 /** Non-NULL pointers are nonsingular. */ 00055 template<typename _Tp> 00056 inline bool 00057 __check_singular(const _Tp* __ptr) 00058 { return __ptr == 0; } 00059 00060 /** Safe iterators know if they are singular. */ 00061 template<typename _Iterator, typename _Sequence> 00062 inline bool 00063 __check_singular(const _Safe_iterator<_Iterator, _Sequence>& __x) 00064 { return __x._M_singular(); } 00065 00066 /** Assume that some arbitrary iterator is dereferenceable, because we 00067 can't prove that it isn't. */ 00068 template<typename _Iterator> 00069 inline bool 00070 __check_dereferenceable(_Iterator&) 00071 { return true; } 00072 00073 /** Non-NULL pointers are dereferenceable. */ 00074 template<typename _Tp> 00075 inline bool 00076 __check_dereferenceable(const _Tp* __ptr) 00077 { return __ptr; } 00078 00079 /** Safe iterators know if they are singular. */ 00080 template<typename _Iterator, typename _Sequence> 00081 inline bool 00082 __check_dereferenceable(const _Safe_iterator<_Iterator, _Sequence>& __x) 00083 { return __x._M_dereferenceable(); } 00084 00085 /** If the distance between two random access iterators is 00086 * nonnegative, assume the range is valid. 00087 */ 00088 template<typename _RandomAccessIterator> 00089 inline bool 00090 __valid_range_aux2(const _RandomAccessIterator& __first, 00091 const _RandomAccessIterator& __last, 00092 std::random_access_iterator_tag) 00093 { return __last - __first >= 0; } 00094 00095 /** Can't test for a valid range with input iterators, because 00096 * iteration may be destructive. So we just assume that the range 00097 * is valid. 00098 */ 00099 template<typename _InputIterator> 00100 inline bool 00101 __valid_range_aux2(const _InputIterator&, const _InputIterator&, 00102 std::input_iterator_tag) 00103 { return true; } 00104 00105 /** We say that integral types for a valid range, and defer to other 00106 * routines to realize what to do with integral types instead of 00107 * iterators. 00108 */ 00109 template<typename _Integral> 00110 inline bool 00111 __valid_range_aux(const _Integral&, const _Integral&, std::__true_type) 00112 { return true; } 00113 00114 /** We have iterators, so figure out what kind of iterators that are 00115 * to see if we can check the range ahead of time. 00116 */ 00117 template<typename _InputIterator> 00118 inline bool 00119 __valid_range_aux(const _InputIterator& __first, 00120 const _InputIterator& __last, std::__false_type) 00121 { 00122 typedef typename std::iterator_traits<_InputIterator>::iterator_category 00123 _Category; 00124 return __valid_range_aux2(__first, __last, _Category()); 00125 } 00126 00127 /** Don't know what these iterators are, or if they are even 00128 * iterators (we may get an integral type for InputIterator), so 00129 * see if they are integral and pass them on to the next phase 00130 * otherwise. 00131 */ 00132 template<typename _InputIterator> 00133 inline bool 00134 __valid_range(const _InputIterator& __first, const _InputIterator& __last) 00135 { 00136 typedef typename std::__is_integer<_InputIterator>::__type _Integral; 00137 return __valid_range_aux(__first, __last, _Integral()); 00138 } 00139 00140 /** Safe iterators know how to check if they form a valid range. */ 00141 template<typename _Iterator, typename _Sequence> 00142 inline bool 00143 __valid_range(const _Safe_iterator<_Iterator, _Sequence>& __first, 00144 const _Safe_iterator<_Iterator, _Sequence>& __last) 00145 { return __first._M_valid_range(__last); } 00146 00147 /** Safe local iterators know how to check if they form a valid range. */ 00148 template<typename _Iterator, typename _Sequence> 00149 inline bool 00150 __valid_range(const _Safe_local_iterator<_Iterator, _Sequence>& __first, 00151 const _Safe_local_iterator<_Iterator, _Sequence>& __last) 00152 { return __first._M_valid_range(__last); } 00153 00154 /* Checks that [first, last) is a valid range, and then returns 00155 * __first. This routine is useful when we can't use a separate 00156 * assertion statement because, e.g., we are in a constructor. 00157 */ 00158 template<typename _InputIterator> 00159 inline _InputIterator 00160 __check_valid_range(const _InputIterator& __first, 00161 const _InputIterator& __last 00162 __attribute__((__unused__))) 00163 { 00164 __glibcxx_check_valid_range(__first, __last); 00165 return __first; 00166 } 00167 00168 /** Checks that __s is non-NULL or __n == 0, and then returns __s. */ 00169 template<typename _CharT, typename _Integer> 00170 inline const _CharT* 00171 __check_string(const _CharT* __s, 00172 const _Integer& __n __attribute__((__unused__))) 00173 { 00174 #ifdef _GLIBCXX_DEBUG_PEDANTIC 00175 __glibcxx_assert(__s != 0 || __n == 0); 00176 #endif 00177 return __s; 00178 } 00179 00180 /** Checks that __s is non-NULL and then returns __s. */ 00181 template<typename _CharT> 00182 inline const _CharT* 00183 __check_string(const _CharT* __s) 00184 { 00185 #ifdef _GLIBCXX_DEBUG_PEDANTIC 00186 __glibcxx_assert(__s != 0); 00187 #endif 00188 return __s; 00189 } 00190 00191 // Can't check if an input iterator sequence is sorted, because we 00192 // can't step through the sequence. 00193 template<typename _InputIterator> 00194 inline bool 00195 __check_sorted_aux(const _InputIterator&, const _InputIterator&, 00196 std::input_iterator_tag) 00197 { return true; } 00198 00199 // Can verify if a forward iterator sequence is in fact sorted using 00200 // std::__is_sorted 00201 template<typename _ForwardIterator> 00202 inline bool 00203 __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last, 00204 std::forward_iterator_tag) 00205 { 00206 if (__first == __last) 00207 return true; 00208 00209 _ForwardIterator __next = __first; 00210 for (++__next; __next != __last; __first = __next, ++__next) 00211 if (*__next < *__first) 00212 return false; 00213 00214 return true; 00215 } 00216 00217 // Can't check if an input iterator sequence is sorted, because we can't step 00218 // through the sequence. 00219 template<typename _InputIterator, typename _Predicate> 00220 inline bool 00221 __check_sorted_aux(const _InputIterator&, const _InputIterator&, 00222 _Predicate, std::input_iterator_tag) 00223 { return true; } 00224 00225 // Can verify if a forward iterator sequence is in fact sorted using 00226 // std::__is_sorted 00227 template<typename _ForwardIterator, typename _Predicate> 00228 inline bool 00229 __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last, 00230 _Predicate __pred, std::forward_iterator_tag) 00231 { 00232 if (__first == __last) 00233 return true; 00234 00235 _ForwardIterator __next = __first; 00236 for (++__next; __next != __last; __first = __next, ++__next) 00237 if (__pred(*__next, *__first)) 00238 return false; 00239 00240 return true; 00241 } 00242 00243 // Determine if a sequence is sorted. 00244 template<typename _InputIterator> 00245 inline bool 00246 __check_sorted(const _InputIterator& __first, const _InputIterator& __last) 00247 { 00248 typedef typename std::iterator_traits<_InputIterator>::iterator_category 00249 _Category; 00250 00251 // Verify that the < operator for elements in the sequence is a 00252 // StrictWeakOrdering by checking that it is irreflexive. 00253 __glibcxx_assert(__first == __last || !(*__first < *__first)); 00254 00255 return __check_sorted_aux(__first, __last, _Category()); 00256 } 00257 00258 template<typename _InputIterator, typename _Predicate> 00259 inline bool 00260 __check_sorted(const _InputIterator& __first, const _InputIterator& __last, 00261 _Predicate __pred) 00262 { 00263 typedef typename std::iterator_traits<_InputIterator>::iterator_category 00264 _Category; 00265 00266 // Verify that the predicate is StrictWeakOrdering by checking that it 00267 // is irreflexive. 00268 __glibcxx_assert(__first == __last || !__pred(*__first, *__first)); 00269 00270 return __check_sorted_aux(__first, __last, __pred, _Category()); 00271 } 00272 00273 template<typename _InputIterator> 00274 inline bool 00275 __check_sorted_set_aux(const _InputIterator& __first, 00276 const _InputIterator& __last, 00277 std::__true_type) 00278 { return __check_sorted(__first, __last); } 00279 00280 template<typename _InputIterator> 00281 inline bool 00282 __check_sorted_set_aux(const _InputIterator&, 00283 const _InputIterator&, 00284 std::__false_type) 00285 { return true; } 00286 00287 template<typename _InputIterator, typename _Predicate> 00288 inline bool 00289 __check_sorted_set_aux(const _InputIterator& __first, 00290 const _InputIterator& __last, 00291 _Predicate __pred, std::__true_type) 00292 { return __check_sorted(__first, __last, __pred); } 00293 00294 template<typename _InputIterator, typename _Predicate> 00295 inline bool 00296 __check_sorted_set_aux(const _InputIterator&, 00297 const _InputIterator&, _Predicate, 00298 std::__false_type) 00299 { return true; } 00300 00301 // ... special variant used in std::merge, std::includes, std::set_*. 00302 template<typename _InputIterator1, typename _InputIterator2> 00303 inline bool 00304 __check_sorted_set(const _InputIterator1& __first, 00305 const _InputIterator1& __last, 00306 const _InputIterator2&) 00307 { 00308 typedef typename std::iterator_traits<_InputIterator1>::value_type 00309 _ValueType1; 00310 typedef typename std::iterator_traits<_InputIterator2>::value_type 00311 _ValueType2; 00312 00313 typedef typename std::__are_same<_ValueType1, _ValueType2>::__type 00314 _SameType; 00315 return __check_sorted_set_aux(__first, __last, _SameType()); 00316 } 00317 00318 template<typename _InputIterator1, typename _InputIterator2, 00319 typename _Predicate> 00320 inline bool 00321 __check_sorted_set(const _InputIterator1& __first, 00322 const _InputIterator1& __last, 00323 const _InputIterator2&, _Predicate __pred) 00324 { 00325 typedef typename std::iterator_traits<_InputIterator1>::value_type 00326 _ValueType1; 00327 typedef typename std::iterator_traits<_InputIterator2>::value_type 00328 _ValueType2; 00329 00330 typedef typename std::__are_same<_ValueType1, _ValueType2>::__type 00331 _SameType; 00332 return __check_sorted_set_aux(__first, __last, __pred, _SameType()); 00333 } 00334 00335 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00336 // 270. Binary search requirements overly strict 00337 // Determine if a sequence is partitioned w.r.t. this element. 00338 template<typename _ForwardIterator, typename _Tp> 00339 inline bool 00340 __check_partitioned_lower(_ForwardIterator __first, 00341 _ForwardIterator __last, const _Tp& __value) 00342 { 00343 while (__first != __last && *__first < __value) 00344 ++__first; 00345 while (__first != __last && !(*__first < __value)) 00346 ++__first; 00347 return __first == __last; 00348 } 00349 00350 template<typename _ForwardIterator, typename _Tp> 00351 inline bool 00352 __check_partitioned_upper(_ForwardIterator __first, 00353 _ForwardIterator __last, const _Tp& __value) 00354 { 00355 while (__first != __last && !(__value < *__first)) 00356 ++__first; 00357 while (__first != __last && __value < *__first) 00358 ++__first; 00359 return __first == __last; 00360 } 00361 00362 // Determine if a sequence is partitioned w.r.t. this element. 00363 template<typename _ForwardIterator, typename _Tp, typename _Pred> 00364 inline bool 00365 __check_partitioned_lower(_ForwardIterator __first, 00366 _ForwardIterator __last, const _Tp& __value, 00367 _Pred __pred) 00368 { 00369 while (__first != __last && bool(__pred(*__first, __value))) 00370 ++__first; 00371 while (__first != __last && !bool(__pred(*__first, __value))) 00372 ++__first; 00373 return __first == __last; 00374 } 00375 00376 template<typename _ForwardIterator, typename _Tp, typename _Pred> 00377 inline bool 00378 __check_partitioned_upper(_ForwardIterator __first, 00379 _ForwardIterator __last, const _Tp& __value, 00380 _Pred __pred) 00381 { 00382 while (__first != __last && !bool(__pred(__value, *__first))) 00383 ++__first; 00384 while (__first != __last && bool(__pred(__value, *__first))) 00385 ++__first; 00386 return __first == __last; 00387 } 00388 } // namespace __gnu_debug 00389 00390 #endif