Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygen_debug.h
Go to the documentation of this file.
00001 /* 00002 * 00003 * Copyright (c) 1997 00004 * Moscow Center for SPARC Technology 00005 * 00006 * Copyright (c) 1999 00007 * Boris Fomitchev 00008 * 00009 * This material is provided "as is", with absolutely no warranty expressed 00010 * or implied. Any use is at your own risk. 00011 * 00012 * Permission to use or copy this software for any purpose is hereby granted 00013 * without fee, provided the above notices are retained on all copies. 00014 * Permission to modify the code and to distribute modified code is granted, 00015 * provided the above notices are retained, and a notice that the code was 00016 * modified is included with the above copyright notice. 00017 * 00018 */ 00019 00020 #ifndef _STLP_DEBUG_H 00021 #define _STLP_DEBUG_H 00022 00023 #if (defined (_STLP_DEBUG) || defined (_STLP_DEBUG_ALLOC)) && \ 00024 !defined (_STLP_ASSERTIONS) 00025 # define _STLP_ASSERTIONS 1 00026 #endif 00027 00028 #if defined (_STLP_ASSERTIONS) 00029 00030 # if !defined (_STLP_FILE__) 00031 # define _STLP_FILE__ __FILE__ 00032 # endif 00033 00034 _STLP_BEGIN_NAMESPACE 00035 00036 _STLP_MOVE_TO_PRIV_NAMESPACE 00037 00038 enum { 00039 //General errors 00040 _StlFormat_ERROR_RETURN, 00041 _StlFormat_ASSERTION_FAILURE, 00042 _StlFormat_VERBOSE_ASSERTION_FAILURE, 00043 _StlMsg_INVALID_ARGUMENT, 00044 //Container/Iterator related errors 00045 _StlMsg_INVALID_CONTAINER, 00046 _StlMsg_EMPTY_CONTAINER, 00047 _StlMsg_ERASE_PAST_THE_END, 00048 _StlMsg_OUT_OF_BOUNDS, 00049 _StlMsg_NOT_OWNER, 00050 _StlMsg_SHOULD_NOT_OWNER, 00051 _StlMsg_INVALID_ITERATOR, 00052 _StlMsg_INVALID_LEFTHAND_ITERATOR, 00053 _StlMsg_INVALID_RIGHTHAND_ITERATOR, 00054 _StlMsg_DIFFERENT_OWNERS , 00055 _StlMsg_NOT_DEREFERENCEABLE , 00056 _StlMsg_INVALID_RANGE , 00057 _StlMsg_NOT_IN_RANGE_1 , 00058 _StlMsg_NOT_IN_RANGE_2 , 00059 _StlMsg_INVALID_ADVANCE , 00060 _StlMsg_SINGULAR_ITERATOR , 00061 //Bad predicate for sorting 00062 _StlMsg_INVALID_STRICT_WEAK_PREDICATE, 00063 _StlMsg_INVALID_EQUIVALENT_PREDICATE, 00064 // debug alloc messages 00065 _StlMsg_DBA_DELETED_TWICE , 00066 _StlMsg_DBA_NEVER_ALLOCATED , 00067 _StlMsg_DBA_TYPE_MISMATCH , 00068 _StlMsg_DBA_SIZE_MISMATCH , 00069 _StlMsg_DBA_UNDERRUN , 00070 _StlMsg_DBA_OVERRUN , 00071 // auto_ptr messages 00072 _StlMsg_AUTO_PTR_NULL , 00073 //Memory alignent message 00074 _StlMsg_WRONG_MEMORY_ALIGNMENT, 00075 _StlMsg_UNKNOWN 00076 /* _StlMsg_MAX */ 00077 }; 00078 00079 /* have to hardcode that ;() */ 00080 # define _StlMsg_MAX 31 00081 00082 class __owned_link; 00083 class __owned_list; 00084 00085 # if defined (_STLP_DEBUG_MODE_THROWS) 00086 # define _STLP_MESSAGE_NORETURN _STLP_FUNCTION_THROWS 00087 # else 00088 # define _STLP_MESSAGE_NORETURN 00089 # endif 00090 00091 template <class _Dummy> 00092 class __stl_debug_engine { 00093 public: 00094 // Basic routine to report any debug message 00095 // Use _STLP_DEBUG_MESSAGE to override 00096 static void _STLP_MESSAGE_NORETURN _STLP_CALL _Message(const char * format_str, ...); 00097 00098 // Micsellanous function to report indexed error message 00099 static void _STLP_CALL _IndexedError(int __ind, const char* __f, int __l); 00100 00101 // Basic assertion report mechanism. 00102 // Reports failed assertion via __stl_debug_message and calls _Terminate 00103 // if _STLP_DEBUG_TERMINATE is specified, calls __stl_debug_terminate instead 00104 static void _STLP_CALL _Assert(const char* __expr, const char* __f, int __l); 00105 00106 // The same, with additional diagnostics 00107 static void _STLP_CALL _VerboseAssert(const char* __expr, int __error_ind, const char* __f, int __l); 00108 00109 // If exceptions are present, sends unique exception 00110 // If not, calls _STLP_ABORT() to terminate 00111 // Use _STLP_DEBUG_TERMINATE to override 00112 static void _STLP_CALL _Terminate(); 00113 00114 # if defined (_STLP_DEBUG) 00115 // owned_list/link delegate non-inline functions here 00116 00117 static bool _STLP_CALL _Check_same_owner( const __owned_link& __i1, 00118 const __owned_link& __i2); 00119 static bool _STLP_CALL _Check_same_or_null_owner( const __owned_link& __i1, 00120 const __owned_link& __i2); 00121 static bool _STLP_CALL _Check_if_owner( const __owned_list*, const __owned_link&); 00122 00123 static bool _STLP_CALL _Check_if_not_owner( const __owned_list*, const __owned_link&); 00124 00125 static void _STLP_CALL _Verify(const __owned_list*); 00126 00127 static void _STLP_CALL _Swap_owners(__owned_list&, __owned_list&); 00128 00129 static void _STLP_CALL _Invalidate_all(__owned_list*); 00130 00131 static void _STLP_CALL _Set_owner(__owned_list& /*src*/, __owned_list& /*dst*/); 00132 00133 static void _STLP_CALL _Stamp_all(__owned_list*, __owned_list*); 00134 00135 static void _STLP_CALL _M_detach(__owned_list*, __owned_link*); 00136 00137 static void _STLP_CALL _M_attach(__owned_list*, __owned_link*); 00138 00139 // accessor : check and get pointer to the container 00140 static void* _STLP_CALL _Get_container_ptr(const __owned_link*); 00141 # endif 00142 00143 // debug messages and formats 00144 static const char* _Message_table[_StlMsg_MAX]; 00145 }; 00146 00147 # undef _STLP_MESSAGE_NORETURN 00148 00149 # if defined (_STLP_USE_TEMPLATE_EXPORT) 00150 _STLP_EXPORT_TEMPLATE_CLASS __stl_debug_engine<bool>; 00151 # endif 00152 00153 typedef __stl_debug_engine<bool> __stl_debugger; 00154 00155 _STLP_MOVE_TO_STD_NAMESPACE 00156 00157 _STLP_END_NAMESPACE 00158 00159 # if !defined (_STLP_ASSERT) 00160 # define _STLP_ASSERT(expr) \ 00161 if (!(expr)) { _STLP_PRIV __stl_debugger::_Assert( # expr, _STLP_FILE__, __LINE__); } 00162 # endif 00163 00164 #else 00165 # define _STLP_ASSERT(expr) 00166 #endif 00167 00168 // this section is for _STLP_DEBUG only 00169 #if defined (_STLP_DEBUG) 00170 00171 # if !defined (_STLP_VERBOSE_ASSERT) 00172 // fbp : new form not requiring ";" 00173 # define _STLP_VERBOSE_ASSERT(expr, __diag_num) \ 00174 if (!(expr)) { _STLP_PRIV __stl_debugger::_VerboseAssert\ 00175 ( # expr, _STLP_PRIV __diag_num, _STLP_FILE__, __LINE__ ); \ 00176 } 00177 # endif 00178 00179 # define _STLP_DEBUG_CHECK(expr) _STLP_ASSERT(expr) 00180 00181 # if (_STLP_DEBUG_LEVEL == _STLP_STANDARD_DBG_LEVEL) 00182 # define _STLP_STD_DEBUG_CHECK(expr) _STLP_DEBUG_CHECK(expr) 00183 # else 00184 # define _STLP_STD_DEBUG_CHECK(expr) 00185 # endif 00186 00187 # if !defined (_STLP_VERBOSE_RETURN) 00188 # define _STLP_VERBOSE_RETURN(__expr,__diag_num) if (!(__expr)) { \ 00189 _STLP_PRIV __stl_debugger::_IndexedError(__diag_num, _STLP_FILE__ , __LINE__); \ 00190 return false; } 00191 # endif 00192 00193 # if !defined (_STLP_VERBOSE_RETURN_0) 00194 # define _STLP_VERBOSE_RETURN_0(__expr,__diag_num) if (!(__expr)) { \ 00195 _STLP_PRIV __stl_debugger::_IndexedError(__diag_num, _STLP_FILE__, __LINE__); \ 00196 return 0; } 00197 # endif 00198 00199 # ifndef _STLP_INTERNAL_THREADS_H 00200 # include <stl/_threads.h> 00201 # endif 00202 00203 # ifndef _STLP_INTERNAL_ITERATOR_BASE_H 00204 # include <stl/_iterator_base.h> 00205 # endif 00206 00207 # ifndef _STLP_TYPE_TRAITS_H 00208 # include <stl/type_traits.h> 00209 # endif 00210 00211 _STLP_BEGIN_NAMESPACE 00212 00213 _STLP_MOVE_TO_PRIV_NAMESPACE 00214 00215 /* 00216 * Special debug iterator traits having an additionnal static member 00217 * method _Check. It is used by the slist debug implementation to check 00218 * the special before_begin iterator. 00219 */ 00220 template <class _Traits> 00221 struct _DbgTraits : _Traits { 00222 typedef _DbgTraits<typename _Traits::_ConstTraits> _ConstTraits; 00223 typedef _DbgTraits<typename _Traits::_NonConstTraits> _NonConstTraits; 00224 00225 template <class _Iterator> 00226 static bool _Check(const _Iterator&) {return true;} 00227 }; 00228 00229 //============================================================= 00230 template <class _Iterator> 00231 inline bool _STLP_CALL __valid_range(const _Iterator& __i1 ,const _Iterator& __i2, 00232 const random_access_iterator_tag&) 00233 { return (__i1 < __i2) || (__i1 == __i2); } 00234 00235 template <class _Iterator> 00236 inline bool _STLP_CALL __valid_range(const _Iterator& __i1 ,const _Iterator& __i2, 00237 const bidirectional_iterator_tag&) { 00238 // check if comparable 00239 bool __dummy(__i1==__i2); 00240 return (__dummy==__dummy); 00241 } 00242 00243 template <class _Iterator> 00244 inline bool _STLP_CALL __valid_range(const _Iterator& __i1 ,const _Iterator& __i2, 00245 const forward_iterator_tag&) { 00246 // check if comparable 00247 bool __dummy(__i1==__i2); 00248 return (__dummy==__dummy); 00249 } 00250 00251 template <class _Iterator> 00252 inline bool _STLP_CALL __valid_range(const _Iterator&,const _Iterator&, 00253 const input_iterator_tag&) 00254 { return true; } 00255 00256 template <class _Iterator> 00257 inline bool _STLP_CALL __valid_range(const _Iterator&,const _Iterator&, 00258 const output_iterator_tag&) 00259 { return true; } 00260 00261 template <class _Iterator> 00262 inline bool _STLP_CALL __valid_range(const _Iterator& __i1, const _Iterator& __i2) 00263 { return __valid_range(__i1,__i2,_STLP_ITERATOR_CATEGORY(__i1, _Iterator)); } 00264 00265 // Note : that means in range [i1, i2]. 00266 template <class _Iterator> 00267 inline bool _STLP_CALL stlp_in_range(const _Iterator& _It, 00268 const _Iterator& __i1, const _Iterator& __i2) 00269 { return __valid_range(__i1,_It) && __valid_range(_It,__i2); } 00270 00271 template <class _Iterator> 00272 inline bool _STLP_CALL stlp_in_range(const _Iterator& __first, const _Iterator& __last, 00273 const _Iterator& __start, const _Iterator& __finish) 00274 { return __valid_range(__first,__last) && __valid_range(__start,__first) && __valid_range(__last,__finish); } 00275 00276 //========================================================== 00277 class _STLP_CLASS_DECLSPEC __owned_link { 00278 public: 00279 // Note: This and the following special defines for compiling under Windows CE under ARM 00280 // is needed for correctly using _STLP_DEBUG mode. This comes from a bug in the ARM 00281 // compiler where checked iterators that are passed by value call _M_attach with the wrong 00282 // this pointer and calling _M_detach can't find the correct pointer to the __owned_link. 00283 // This is circumvented by managing a _M_self pointer that points to the correct value. 00284 // Ugly but works. 00285 #if defined(_STLP_WCE) && defined(_ARM_) 00286 __owned_link() : _M_self(this), _M_owner(0) {} 00287 __owned_link(const __owned_list* __c) : _M_self(this), _M_owner(0), _M_next(0) 00288 { __stl_debugger::_M_attach(__CONST_CAST(__owned_list*,__c), this); } 00289 __owned_link(const __owned_link& __rhs): _M_self(this), _M_owner(0) 00290 { __stl_debugger::_M_attach(__CONST_CAST(__owned_list*,__rhs._M_owner), this); } 00291 #else 00292 __owned_link() : _M_owner(0) {} 00293 __owned_link(const __owned_list* __c) : _M_owner(0), _M_next(0) 00294 { __stl_debugger::_M_attach(__CONST_CAST(__owned_list*,__c), this); } 00295 __owned_link(const __owned_link& __rhs): _M_owner(0) 00296 { __stl_debugger::_M_attach(__CONST_CAST(__owned_list*,__rhs._M_owner), this); } 00297 #endif 00298 __owned_link& operator=(const __owned_link& __rhs) { 00299 __owned_list* __new_owner = __CONST_CAST(__owned_list*,__rhs._M_owner); 00300 __owned_list* __old_owner = _M_owner; 00301 if ( __old_owner != __new_owner ) { 00302 __stl_debugger::_M_detach(__old_owner, this); 00303 __stl_debugger::_M_attach(__new_owner, this); 00304 } 00305 return *this; 00306 } 00307 #if defined(_STLP_WCE) && defined(_ARM_) 00308 ~__owned_link() { 00309 __stl_debugger::_M_detach(_M_owner, _M_self); 00310 _Invalidate(); 00311 } 00312 #else 00313 ~__owned_link() { 00314 __stl_debugger::_M_detach(_M_owner, this); 00315 _Invalidate(); 00316 } 00317 #endif 00318 00319 const __owned_list* _Owner() const { return _M_owner; } 00320 __owned_list* _Owner() { return _M_owner; } 00321 void _Set_owner(const __owned_list* __o) { _M_owner= __CONST_CAST(__owned_list*,__o); } 00322 bool _Valid() const { return _M_owner != 0; } 00323 void _Invalidate() { _M_owner = 0; _M_next = 0; } 00324 void _Link_to_self() { _M_next = 0; } 00325 00326 __owned_link* _Next() { return _M_next; } 00327 const __owned_link* _Next() const { return _M_next; } 00328 00329 public: 00330 #if defined(_STLP_WCE) && defined(_ARM_) 00331 __owned_link* _M_self; 00332 #endif 00333 00334 __owned_list* _M_owner; 00335 __owned_link* _M_next; 00336 }; 00337 00338 00339 class _STLP_CLASS_DECLSPEC __owned_list { 00340 public: 00341 __owned_list(void* __o) { 00342 // fprintf(stderr, "__owned_list(): %p\n",(void*)this); 00343 _M_node._M_owner = __REINTERPRET_CAST(__owned_list*,__o); 00344 _M_node._M_next = 0; 00345 } 00346 ~__owned_list() { 00347 // fprintf(stderr, "~__owned_list(): %p\n",(void*)this); 00348 _Invalidate_all(); 00349 // that prevents detach 00350 _M_node._Invalidate(); 00351 } 00352 const void* _Owner() const { return (const void*)_M_node._M_owner; } 00353 void* _Owner() { return (void*)_M_node._M_owner; } 00354 bool _Valid() const { return _M_node._M_owner != 0; } 00355 void _Invalidate() { _M_node._M_owner = 0; } 00356 00357 __owned_link* _First() { return _M_node._Next(); } 00358 __owned_link* _Last() { return 0 ; } 00359 00360 const __owned_link* _First() const { return (__owned_link*)_M_node._M_next; } 00361 const __owned_link* _Last() const { return 0 ;} 00362 00363 void _Verify() const { __stl_debugger::_Verify(this); } 00364 void _Swap_owners(__owned_list& __y) { __stl_debugger::_Swap_owners(*this, __y); } 00365 void _Invalidate_all() { __stl_debugger::_Invalidate_all(this); } 00366 void _Set_owner(__owned_list& __y) { __stl_debugger::_Set_owner(*this, __y); } 00367 00368 mutable __owned_link _M_node; 00369 mutable _STLP_mutex _M_lock; 00370 00371 private: 00372 // should never be called, should be left not implemented, 00373 // but some compilers complain about it ;( 00374 __owned_list(const __owned_list&){} 00375 __owned_list& operator = (const __owned_list&) { return *this; } 00376 00377 friend class __owned_link; 00378 friend class __stl_debug_engine<bool>; 00379 }; 00380 00381 00382 //========================================================== 00383 00384 // forward declaratioins 00385 00386 template <class _Iterator> 00387 bool _STLP_CALL __check_range(const _Iterator&, const _Iterator&); 00388 template <class _Iterator> 00389 bool _STLP_CALL __check_range(const _Iterator&, 00390 const _Iterator&, const _Iterator&); 00391 template <class _Iterator> 00392 bool _STLP_CALL __check_range(const _Iterator&, const _Iterator& , 00393 const _Iterator&, const _Iterator& ); 00394 template <class _Tp> 00395 bool _STLP_CALL __check_ptr_range(const _Tp*, const _Tp*); 00396 00397 template <class _Iterator> 00398 void _STLP_CALL __invalidate_range(const __owned_list* __base, 00399 const _Iterator& __first, 00400 const _Iterator& __last); 00401 00402 template <class _Iterator> 00403 void _STLP_CALL __invalidate_iterator(const __owned_list* __base, 00404 const _Iterator& __it); 00405 00406 template <class _Iterator> 00407 void _STLP_CALL __change_range_owner(const _Iterator& __first, 00408 const _Iterator& __last, 00409 const __owned_list* __dst); 00410 00411 template <class _Iterator> 00412 void _STLP_CALL __change_ite_owner(const _Iterator& __it, 00413 const __owned_list* __dst); 00414 00415 //============================================================ 00416 inline bool _STLP_CALL 00417 __check_same_owner(const __owned_link& __i1, const __owned_link& __i2) 00418 { return __stl_debugger::_Check_same_owner(__i1,__i2); } 00419 00420 inline bool _STLP_CALL 00421 __check_same_or_null_owner(const __owned_link& __i1, const __owned_link& __i2) 00422 { return __stl_debugger::_Check_same_or_null_owner(__i1,__i2); } 00423 00424 template <class _Iterator> 00425 inline bool _STLP_CALL __check_if_owner( const __owned_list* __owner, 00426 const _Iterator& __it) 00427 { return __stl_debugger::_Check_if_owner(__owner, (const __owned_link&)__it); } 00428 00429 template <class _Iterator> 00430 inline bool _STLP_CALL __check_if_not_owner( const __owned_list* __owner, 00431 const _Iterator& __it) 00432 { return __stl_debugger::_Check_if_not_owner(__owner, (const __owned_link&)__it); } 00433 00434 _STLP_MOVE_TO_STD_NAMESPACE 00435 00436 _STLP_END_NAMESPACE 00437 00438 #else 00439 # define _STLP_VERBOSE_ASSERT(expr, diagnostic) 00440 # define _STLP_DEBUG_CHECK(expr) 00441 #endif /* _STLP_DEBUG */ 00442 00443 #if defined (_STLP_ASSERTIONS) 00444 00445 # if !defined (_STLP_ASSERT_MSG_TRAILER) 00446 # define _STLP_ASSERT_MSG_TRAILER 00447 # endif 00448 00449 // dwa 12/30/98 - if _STLP_DEBUG_MESSAGE is defined, the user can supply own definition. 00450 # if !defined (_STLP_DEBUG_MESSAGE) 00451 # define __stl_debug_message __stl_debugger::_Message 00452 # else 00453 extern void __stl_debug_message(const char * format_str, ...); 00454 # endif 00455 00456 // fbp: if _STLP_DEBUG_TERMINATE is defined, the user can supply own definition. 00457 # if !defined (_STLP_DEBUG_TERMINATE) 00458 # define __stl_debug_terminate __stl_debugger::_Terminate 00459 # else 00460 extern void __stl_debug_terminate(); 00461 # endif 00462 00463 #endif 00464 00465 #if defined (_STLP_ASSERTIONS) && !defined (_STLP_LINK_TIME_INSTANTIATION) 00466 # include <stl/debug/_debug.c> 00467 #endif 00468 00469 #endif /* DEBUG_H */ 00470 00471 // Local Variables: 00472 // mode:C++ 00473 // End: Generated on Sat May 26 2012 04:28:24 for ReactOS by
1.7.6.1
|