00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef _GLIBCXX_DEBUG_DEBUG_H
00032 #define _GLIBCXX_DEBUG_DEBUG_H 1
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #define _GLIBCXX_DEBUG_VERIFY(_Condition,_ErrorMessage) \
00044 do { \
00045 if (! (_Condition)) \
00046 ::__gnu_debug::_Error_formatter::_M_at(__FILE__, __LINE__) \
00047 ._ErrorMessage._M_error(); \
00048 } while (false)
00049
00050
00051 #define __glibcxx_check_valid_range(_First,_Last) \
00052 _GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__valid_range(_First, _Last), \
00053 _M_message(::__gnu_debug::__msg_valid_range) \
00054 ._M_iterator(_First, #_First) \
00055 ._M_iterator(_Last, #_Last))
00056
00057
00058
00059
00060
00061
00062
00063
00064 #define __glibcxx_check_insert(_Position) \
00065 _GLIBCXX_DEBUG_VERIFY(!_Position._M_singular(), \
00066 _M_message(::__gnu_debug::__msg_insert_singular) \
00067 ._M_sequence(*this, "this") \
00068 ._M_iterator(_Position, #_Position)); \
00069 _GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \
00070 _M_message(::__gnu_debug::__msg_insert_different) \
00071 ._M_sequence(*this, "this") \
00072 ._M_iterator(_Position, #_Position))
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087 #define __glibcxx_check_insert_range(_Position,_First,_Last) \
00088 __glibcxx_check_valid_range(_First,_Last); \
00089 _GLIBCXX_DEBUG_VERIFY(!_Position._M_singular(), \
00090 _M_message(::__gnu_debug::__msg_insert_singular) \
00091 ._M_sequence(*this, "this") \
00092 ._M_iterator(_Position, #_Position)); \
00093 _GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \
00094 _M_message(::__gnu_debug::__msg_insert_different) \
00095 ._M_sequence(*this, "this") \
00096 ._M_iterator(_Position, #_Position))
00097
00098
00099
00100
00101
00102 #define __glibcxx_check_erase(_Position) \
00103 _GLIBCXX_DEBUG_VERIFY(_Position._M_dereferenceable(), \
00104 _M_message(::__gnu_debug::__msg_erase_bad) \
00105 ._M_sequence(*this, "this") \
00106 ._M_iterator(_Position, #_Position)); \
00107 _GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \
00108 _M_message(::__gnu_debug::__msg_erase_different) \
00109 ._M_sequence(*this, "this") \
00110 ._M_iterator(_Position, #_Position))
00111
00112
00113
00114
00115
00116 #define __glibcxx_check_erase_range(_First,_Last) \
00117 __glibcxx_check_valid_range(_First,_Last); \
00118 _GLIBCXX_DEBUG_VERIFY(_First._M_attached_to(this), \
00119 _M_message(::__gnu_debug::__msg_erase_different) \
00120 ._M_sequence(*this, "this") \
00121 ._M_iterator(_First, #_First) \
00122 ._M_iterator(_Last, #_Last))
00123
00124
00125 #define __glibcxx_check_subscript(_N) \
00126 _GLIBCXX_DEBUG_VERIFY(_N < this->size(), \
00127 _M_message(::__gnu_debug::__msg_subscript_oob) \
00128 ._M_sequence(*this, "this") \
00129 ._M_integer(_N, #_N) \
00130 ._M_integer(this->size(), "size"))
00131
00132
00133 #define __glibcxx_check_nonempty() \
00134 _GLIBCXX_DEBUG_VERIFY(! this->empty(), \
00135 _M_message(::__gnu_debug::__msg_empty) \
00136 ._M_sequence(*this, "this"))
00137
00138
00139
00140 #define __glibcxx_check_strict_weak_ordering(_First,_Last) \
00141 _GLIBCXX_DEBUG_ASSERT(_First == _Last || !(*_First < *_First))
00142
00143
00144
00145 #define __glibcxx_check_strict_weak_ordering_pred(_First,_Last,_Pred) \
00146 _GLIBCXX_DEBUG_ASSERT(_First == _Last || !_Pred(*_First, *_First))
00147
00148
00149
00150 #define __glibcxx_check_sorted(_First,_Last) \
00151 __glibcxx_check_valid_range(_First,_Last); \
00152 __glibcxx_check_strict_weak_ordering(_First,_Last); \
00153 _GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_sorted(_First, _Last), \
00154 _M_message(::__gnu_debug::__msg_unsorted) \
00155 ._M_iterator(_First, #_First) \
00156 ._M_iterator(_Last, #_Last))
00157
00158
00159
00160 #define __glibcxx_check_sorted_pred(_First,_Last,_Pred) \
00161 __glibcxx_check_valid_range(_First,_Last); \
00162 __glibcxx_check_strict_weak_ordering_pred(_First,_Last,_Pred); \
00163 _GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_sorted(_First, _Last, _Pred), \
00164 _M_message(::__gnu_debug::__msg_unsorted_pred) \
00165 ._M_iterator(_First, #_First) \
00166 ._M_iterator(_Last, #_Last) \
00167 ._M_string(#_Pred))
00168
00169
00170
00171 #define __glibcxx_check_partitioned(_First,_Last,_Value) \
00172 __glibcxx_check_valid_range(_First,_Last); \
00173 _GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_partitioned(_First, _Last, \
00174 _Value), \
00175 _M_message(::__gnu_debug::__msg_unpartitioned) \
00176 ._M_iterator(_First, #_First) \
00177 ._M_iterator(_Last, #_Last) \
00178 ._M_string(#_Value))
00179
00180
00181
00182 #define __glibcxx_check_partitioned_pred(_First,_Last,_Value,_Pred) \
00183 __glibcxx_check_valid_range(_First,_Last); \
00184 _GLIBCXX_DEBUG_VERIFY(::__gnu_debug::__check_partitioned(_First, _Last, \
00185 _Value, _Pred), \
00186 _M_message(::__gnu_debug::__msg_unpartitioned_pred) \
00187 ._M_iterator(_First, #_First) \
00188 ._M_iterator(_Last, #_Last) \
00189 ._M_string(#_Pred) \
00190 ._M_string(#_Value))
00191
00192
00193 #define __glibcxx_check_heap(_First,_Last) \
00194 __glibcxx_check_valid_range(_First,_Last); \
00195 _GLIBCXX_DEBUG_VERIFY(::std::__is_heap(_First, _Last), \
00196 _M_message(::__gnu_debug::__msg_not_heap) \
00197 ._M_iterator(_First, #_First) \
00198 ._M_iterator(_Last, #_Last))
00199
00200
00201
00202 #define __glibcxx_check_heap_pred(_First,_Last,_Pred) \
00203 __glibcxx_check_valid_range(_First,_Last); \
00204 _GLIBCXX_DEBUG_VERIFY(::std::__is_heap(_First, _Last, _Pred), \
00205 _M_message(::__gnu_debug::__msg_not_heap_pred) \
00206 ._M_iterator(_First, #_First) \
00207 ._M_iterator(_Last, #_Last) \
00208 ._M_string(#_Pred))
00209
00210 #ifdef _GLIBCXX_DEBUG_PEDANTIC
00211 # define __glibcxx_check_string(_String) _GLIBCXX_DEBUG_ASSERT(_String != 0)
00212 # define __glibcxx_check_string_len(_String,_Len) \
00213 _GLIBCXX_DEBUG_ASSERT(_String != 0 || _Len == 0)
00214 #else
00215 # define __glibcxx_check_string(_String)
00216 # define __glibcxx_check_string_len(_String,_Len)
00217 #endif
00218
00219
00220
00221
00222
00223
00224
00225
00226 #ifdef _GLIBCXX_DEBUG
00227 # define _GLIBCXX_DEBUG_ASSERT(_Condition) assert(_Condition)
00228
00229 # ifdef _GLIBXX_DEBUG_PEDANTIC
00230 # define _GLIBCXX_DEBUG_PEDASSERT(_Condition) assert(_Condition)
00231 # else
00232 # define _GLIBCXX_DEBUG_PEDASSERT(_Condition)
00233 # endif
00234
00235 # define __glibcxx_requires_cond(_Cond,_Msg) _GLIBCXX_DEBUG_VERIFY(_Cond,_Msg)
00236 # define __glibcxx_requires_valid_range(_First,_Last) \
00237 __glibcxx_check_valid_range(_First,_Last)
00238 # define __glibcxx_requires_sorted(_First,_Last) \
00239 __glibcxx_check_sorted(_First,_Last)
00240 # define __glibcxx_requires_sorted_pred(_First,_Last,_Pred) \
00241 __glibcxx_check_sorted_pred(_First,_Last,_Pred)
00242 # define __glibcxx_requires_partitioned(_First,_Last,_Value) \
00243 __glibcxx_check_partitioned(_First,_Last,_Value)
00244 # define __glibcxx_requires_partitioned_pred(_First,_Last,_Value,_Pred) \
00245 __glibcxx_check_partitioned_pred(_First,_Last,_Value,_Pred)
00246 # define __glibcxx_requires_heap(_First,_Last) \
00247 __glibcxx_check_heap(_First,_Last)
00248 # define __glibcxx_requires_heap_pred(_First,_Last,_Pred) \
00249 __glibcxx_check_heap_pred(_First,_Last,_Pred)
00250 # define __glibcxx_requires_nonempty() __glibcxx_check_nonempty()
00251 # define __glibcxx_requires_string(_String) __glibcxx_check_string(_String)
00252 # define __glibcxx_requires_string_len(_String,_Len) \
00253 __glibcxx_check_string_len(_String,_Len)
00254 # define __glibcxx_requires_subscript(_N) __glibcxx_check_subscript(_N)
00255 #else
00256 # define _GLIBCXX_DEBUG_ASSERT(_Condition)
00257 # define _GLIBCXX_DEBUG_PEDASSERT(_Condition)
00258 # define __glibcxx_requires_cond(_Cond,_Msg)
00259 # define __glibcxx_requires_valid_range(_First,_Last)
00260 # define __glibcxx_requires_sorted(_First,_Last)
00261 # define __glibcxx_requires_sorted_pred(_First,_Last,_Pred)
00262 # define __glibcxx_requires_partitioned(_First,_Last,_Value)
00263 # define __glibcxx_requires_partitioned_pred(_First,_Last,_Value,_Pred)
00264 # define __glibcxx_requires_heap(_First,_Last)
00265 # define __glibcxx_requires_heap_pred(_First,_Last,_Pred)
00266 # define __glibcxx_requires_nonempty()
00267 # define __glibcxx_requires_string(_String)
00268 # define __glibcxx_requires_string_len(_String,_Len)
00269 # define __glibcxx_requires_subscript(_N)
00270 #endif
00271
00272 #include <cassert>
00273
00274 #include <stddef.h>
00275 #include <bits/stl_iterator_base_types.h>
00276 #include <bits/type_traits.h>
00277
00278 namespace __gnu_debug
00279 {
00280 template<typename _Iterator, typename _Sequence>
00281 class _Safe_iterator;
00282
00283
00284 inline bool
00285 __check_singular_aux(const void*) { return false; }
00286
00287
00288
00289 template<typename _Iterator>
00290 inline bool
00291 __check_singular(_Iterator& __x)
00292 { return __gnu_debug::__check_singular_aux(&__x); }
00293
00294
00295 template<typename _Tp>
00296 inline bool
00297 __check_singular(const _Tp* __ptr)
00298 { return __ptr == 0; }
00299
00300
00301 template<typename _Iterator, typename _Sequence>
00302 inline bool
00303 __check_singular(const _Safe_iterator<_Iterator, _Sequence>& __x)
00304 { return __x._M_singular(); }
00305
00306
00307
00308 template<typename _Iterator>
00309 inline bool
00310 __check_dereferenceable(_Iterator&)
00311 { return true; }
00312
00313
00314 template<typename _Tp>
00315 inline bool
00316 __check_dereferenceable(const _Tp* __ptr)
00317 { return __ptr; }
00318
00319
00320 template<typename _Iterator, typename _Sequence>
00321 inline bool
00322 __check_dereferenceable(const _Safe_iterator<_Iterator, _Sequence>& __x)
00323 { return __x._M_dereferenceable(); }
00324
00325
00326
00327
00328 template<typename _RandomAccessIterator>
00329 inline bool
00330 __valid_range_aux2(const _RandomAccessIterator& __first,
00331 const _RandomAccessIterator& __last,
00332 std::random_access_iterator_tag)
00333 { return __last - __first >= 0; }
00334
00335
00336
00337
00338
00339 template<typename _InputIterator>
00340 inline bool
00341 __valid_range_aux2(const _InputIterator&, const _InputIterator&,
00342 std::input_iterator_tag)
00343 { return true; }
00344
00345
00346
00347
00348
00349 template<typename _Integral>
00350 inline bool
00351 __valid_range_aux(const _Integral&, const _Integral&, __true_type)
00352 { return true; }
00353
00354
00355
00356
00357 template<typename _InputIterator>
00358 inline bool
00359 __valid_range_aux(const _InputIterator& __first,
00360 const _InputIterator& __last, __false_type)
00361 {
00362 typedef typename std::iterator_traits<_InputIterator>::iterator_category
00363 _Category;
00364 return __gnu_debug::__valid_range_aux2(__first, __last, _Category());
00365 }
00366
00367
00368
00369
00370
00371
00372 template<typename _InputIterator>
00373 inline bool
00374 __valid_range(const _InputIterator& __first, const _InputIterator& __last)
00375 {
00376 typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
00377 return __gnu_debug::__valid_range_aux(__first, __last, _Integral());
00378 }
00379
00380
00381 template<typename _Iterator, typename _Sequence>
00382 inline bool
00383 __valid_range(const _Safe_iterator<_Iterator, _Sequence>& __first,
00384 const _Safe_iterator<_Iterator, _Sequence>& __last)
00385 { return __first._M_valid_range(__last); }
00386
00387
00388
00389
00390
00391 template<typename _InputIterator>
00392 inline _InputIterator
00393 __check_valid_range(const _InputIterator& __first,
00394 const _InputIterator& __last)
00395 {
00396 _GLIBCXX_DEBUG_ASSERT(__gnu_debug::__valid_range(__first, __last));
00397 return __first;
00398 }
00399
00400
00401 template<typename _CharT, typename _Integer>
00402 inline const _CharT*
00403 __check_string(const _CharT* __s, const _Integer& __n)
00404 {
00405 #ifdef _GLIBCXX_DEBUG_PEDANTIC
00406 _GLIBCXX_DEBUG_ASSERT(__s != 0 || __n == 0);
00407 #endif
00408 return __s;
00409 }
00410
00411
00412 template<typename _CharT>
00413 inline const _CharT*
00414 __check_string(const _CharT* __s)
00415 {
00416 #ifdef _GLIBCXX_DEBUG_PEDANTIC
00417 _GLIBCXX_DEBUG_ASSERT(__s != 0);
00418 #endif
00419 return __s;
00420 }
00421
00422
00423
00424 template<typename _InputIterator>
00425 inline bool
00426 __check_sorted_aux(const _InputIterator&, const _InputIterator&,
00427 std::input_iterator_tag)
00428 { return true; }
00429
00430
00431
00432 template<typename _ForwardIterator>
00433 inline bool
00434 __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last,
00435 std::forward_iterator_tag)
00436 {
00437 if (__first == __last)
00438 return true;
00439
00440 _ForwardIterator __next = __first;
00441 for (++__next; __next != __last; __first = __next, ++__next) {
00442 if (*__next < *__first)
00443 return false;
00444 }
00445
00446 return true;
00447 }
00448
00449
00450
00451 template<typename _InputIterator, typename _Predicate>
00452 inline bool
00453 __check_sorted_aux(const _InputIterator&, const _InputIterator&,
00454 _Predicate, std::input_iterator_tag)
00455 { return true; }
00456
00457
00458
00459 template<typename _ForwardIterator, typename _Predicate>
00460 inline bool
00461 __check_sorted_aux(_ForwardIterator __first, _ForwardIterator __last,
00462 _Predicate __pred, std::forward_iterator_tag)
00463 {
00464 if (__first == __last)
00465 return true;
00466
00467 _ForwardIterator __next = __first;
00468 for (++__next; __next != __last; __first = __next, ++__next) {
00469 if (__pred(*__next, *__first))
00470 return false;
00471 }
00472
00473 return true;
00474 }
00475
00476
00477 template<typename _InputIterator>
00478 inline bool
00479 __check_sorted(const _InputIterator& __first, const _InputIterator& __last)
00480 {
00481 typedef typename std::iterator_traits<_InputIterator>::iterator_category
00482 _Category;
00483 return __gnu_debug::__check_sorted_aux(__first, __last, _Category());
00484 }
00485
00486 template<typename _InputIterator, typename _Predicate>
00487 inline bool
00488 __check_sorted(const _InputIterator& __first, const _InputIterator& __last,
00489 _Predicate __pred)
00490 {
00491 typedef typename std::iterator_traits<_InputIterator>::iterator_category
00492 _Category;
00493 return __gnu_debug::__check_sorted_aux(__first, __last, __pred,
00494 _Category());
00495 }
00496
00497
00498
00499
00500 template<typename _ForwardIterator, typename _Tp>
00501 inline bool
00502 __check_partitioned(_ForwardIterator __first, _ForwardIterator __last,
00503 const _Tp& __value)
00504 {
00505 while (__first != __last && *__first < __value)
00506 ++__first;
00507 while (__first != __last && !(*__first < __value))
00508 ++__first;
00509 return __first == __last;
00510 }
00511
00512
00513 template<typename _ForwardIterator, typename _Tp, typename _Pred>
00514 inline bool
00515 __check_partitioned(_ForwardIterator __first, _ForwardIterator __last,
00516 const _Tp& __value, _Pred __pred)
00517 {
00518 while (__first != __last && __pred(*__first, __value))
00519 ++__first;
00520 while (__first != __last && !__pred(*__first, __value))
00521 ++__first;
00522 return __first == __last;
00523 }
00524 }
00525
00526 #ifdef _GLIBCXX_DEBUG
00527
00528 # include <debug/formatter.h>
00529 #endif
00530
00531 #endif