00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef _STLP_DEBUG_H
00021 # define _STLP_DEBUG_H
00022
00023 # if defined (_STLP_ASSERTIONS) || defined (_STLP_DEBUG)
00024
00025 #ifndef _STLP_CONFIG_H
00026 # include <stl/_config.h>
00027 #endif
00028
00029 # if !defined (_STLP_EXTRA_OPERATORS_FOR_DEBUG) && \
00030 ( defined (_STLP_BASE_MATCH_BUG) || (defined (_STLP_MSVC) && _STLP_MSVC < 1100 ) )
00031 # define _STLP_EXTRA_OPERATORS_FOR_DEBUG
00032 # endif
00033
00034 # if !defined(_STLP_FILE__)
00035 # define _STLP_FILE__ __FILE__
00036 # endif
00037
00038 enum {
00039 _StlFormat_ERROR_RETURN,
00040 _StlFormat_ASSERTION_FAILURE,
00041 _StlFormat_VERBOSE_ASSERTION_FAILURE,
00042 _StlMsg_INVALID_ARGUMENT,
00043 _StlMsg_INVALID_CONTAINER,
00044 _StlMsg_EMPTY_CONTAINER,
00045 _StlMsg_ERASE_PAST_THE_END,
00046 _StlMsg_OUT_OF_BOUNDS,
00047 _StlMsg_NOT_OWNER,
00048 _StlMsg_INVALID_ITERATOR,
00049 _StlMsg_INVALID_LEFTHAND_ITERATOR,
00050 _StlMsg_INVALID_RIGHTHAND_ITERATOR,
00051 _StlMsg_DIFFERENT_OWNERS ,
00052 _StlMsg_NOT_DEREFERENCEABLE ,
00053 _StlMsg_INVALID_RANGE ,
00054 _StlMsg_NOT_IN_RANGE_1 ,
00055 _StlMsg_NOT_IN_RANGE_2 ,
00056 _StlMsg_INVALID_ADVANCE ,
00057 _StlMsg_SINGULAR_ITERATOR ,
00058
00059 _StlMsg_DBA_DELETED_TWICE ,
00060 _StlMsg_DBA_NEVER_ALLOCATED ,
00061 _StlMsg_DBA_TYPE_MISMATCH ,
00062 _StlMsg_DBA_SIZE_MISMATCH ,
00063 _StlMsg_DBA_UNDERRUN ,
00064 _StlMsg_DBA_OVERRUN ,
00065
00066 _StlMsg_AUTO_PTR_NULL ,
00067 _StlMsg_UNKNOWN
00068
00069 };
00070
00071
00072 # define _StlMsg_MAX 27
00073
00074 _STLP_BEGIN_NAMESPACE
00075
00076
00077
00078 struct __stl_debug_exception {
00079
00080 };
00081
00082 class _STLP_CLASS_DECLSPEC __owned_link;
00083 class _STLP_CLASS_DECLSPEC __owned_list;
00084
00085 template <class _Dummy>
00086 struct __stl_debug_engine {
00087
00088
00089
00090 static void _STLP_CALL _Message(const char * format_str, ...);
00091
00092
00093 static void _STLP_CALL _IndexedError(int __ind, const char* __f, int __l);
00094
00095
00096
00097
00098 static void _STLP_CALL _Assert(const char* __expr, const char* __f, int __l);
00099
00100
00101 static void _STLP_CALL _VerboseAssert(const char* __expr, int __error_ind, const char* __f, int __l);
00102
00103
00104
00105
00106 static void _STLP_CALL _Terminate();
00107
00108 # ifdef _STLP_DEBUG
00109
00110
00111
00112 static bool _STLP_CALL _Check_same_owner( const __owned_link& __i1,
00113 const __owned_link& __i2);
00114 static bool _STLP_CALL _Check_same_owner_or_null( const __owned_link& __i1,
00115 const __owned_link& __i2);
00116 static bool _STLP_CALL _Check_if_owner( const __owned_list*, const __owned_link&);
00117
00118 static void _STLP_CALL _Verify(const __owned_list*);
00119
00120 static void _STLP_CALL _Swap_owners(__owned_list&, __owned_list& );
00121
00122 static void _STLP_CALL _Invalidate_all(__owned_list*);
00123
00124 static void _STLP_CALL _Stamp_all(__owned_list*, __owned_list*);
00125
00126 static void _STLP_CALL _M_detach(__owned_list*, __owned_link*);
00127
00128 static void _STLP_CALL _M_attach(__owned_list*, __owned_link*);
00129
00130
00131 static void* _STLP_CALL _Get_container_ptr(const __owned_link*);
00132 # endif
00133
00134
00135 _STLP_STATIC_MEMBER_DECLSPEC static const char* _Message_table[_StlMsg_MAX];
00136 };
00137
00138
00139 # if defined (_STLP_USE_TEMPLATE_EXPORT)
00140 _STLP_EXPORT_TEMPLATE struct _STLP_CLASS_DECLSPEC __stl_debug_engine<bool>;
00141 # endif
00142
00143 typedef __stl_debug_engine<bool> __stl_debugger;
00144
00145 _STLP_END_NAMESPACE
00146
00147 # ifndef _STLP_ASSERT
00148 # define _STLP_ASSERT(expr) \
00149 if (!(expr)) {STLPORT::__stl_debugger::_Assert( # expr, _STLP_FILE__, __LINE__);}
00150 # endif
00151
00152 # endif
00153
00154
00155
00156 #if defined ( _STLP_DEBUG )
00157
00158 # ifndef _STLP_VERBOSE_ASSERT
00159
00160 # define _STLP_VERBOSE_ASSERT(expr,__diag_num) \
00161 if (!(expr)) { STLPORT::__stl_debugger::_VerboseAssert\
00162 ( # expr, __diag_num, _STLP_FILE__, __LINE__ ); \
00163 }
00164 # endif
00165
00166 # define _STLP_DEBUG_CHECK(expr) _STLP_ASSERT(expr)
00167 # define _STLP_DEBUG_DO(expr) expr;
00168
00169 # ifndef _STLP_VERBOSE_RETURN
00170 # define _STLP_VERBOSE_RETURN(__expr,__diag_num) if (!(__expr)) { \
00171 __stl_debugger::_IndexedError(__diag_num, __FILE__ , __LINE__); \
00172 return false; }
00173 # endif
00174
00175 # ifndef _STLP_VERBOSE_RETURN_0
00176 # define _STLP_VERBOSE_RETURN_0(__expr,__diag_num) if (!(__expr)) { \
00177 __stl_debugger::_IndexedError(__diag_num, __FILE__ , __LINE__); \
00178 return 0; }
00179 # endif
00180
00181 #if ! defined (_STLP_INTERNAL_THREADS_H)
00182 # include <stl/_threads.h>
00183 #endif
00184
00185 #ifndef _STLP_INTERNAL_ITERATOR_BASE_H
00186 # include <stl/_iterator_base.h>
00187 #endif
00188
00189 _STLP_BEGIN_NAMESPACE
00190
00191
00192 template <class _Iterator>
00193 inline bool _STLP_CALL __valid_range(const _Iterator& __i1 ,const _Iterator& __i2,
00194 const random_access_iterator_tag&) {
00195 return (__i1< __i2) || (__i1 == __i2);
00196 }
00197
00198 template <class _Iterator>
00199 inline bool _STLP_CALL __valid_range(const _Iterator& __i1 ,const _Iterator& __i2,
00200 const bidirectional_iterator_tag&) {
00201
00202 bool __dummy(__i1==__i2);
00203 return (__dummy==__dummy);
00204 }
00205
00206 template <class _Iterator>
00207 inline bool _STLP_CALL __valid_range(const _Iterator& __i1 ,const _Iterator& __i2, const forward_iterator_tag&) {
00208
00209 bool __dummy(__i1==__i2);
00210 return (__dummy==__dummy);
00211 }
00212
00213 template <class _Iterator>
00214 inline bool _STLP_CALL __valid_range(const _Iterator&,const _Iterator&, const input_iterator_tag&) {
00215 return true;
00216 }
00217
00218 template <class _Iterator>
00219 inline bool _STLP_CALL __valid_range(const _Iterator&,const _Iterator&, const output_iterator_tag&) {
00220 return true;
00221 }
00222
00223 template <class _Iterator>
00224 inline bool _STLP_CALL __valid_range(const _Iterator& __i1, const _Iterator& __i2) {
00225 return __valid_range(__i1,__i2,_STLP_ITERATOR_CATEGORY(__i1, _Iterator));
00226 }
00227
00228
00229 template <class _Iterator>
00230 inline bool _STLP_CALL __in_range(const _Iterator& _It, const _Iterator& __i1,
00231 const _Iterator& __i2) {
00232 return __valid_range(__i1,_It,_STLP_ITERATOR_CATEGORY(__i1, _Iterator)) &&
00233 __valid_range(_It,__i2,_STLP_ITERATOR_CATEGORY(_It, _Iterator));
00234 }
00235
00236 template <class _Iterator>
00237 inline bool _STLP_CALL __in_range(const _Iterator& __first, const _Iterator& __last,
00238 const _Iterator& __start, const _Iterator& __finish) {
00239 return __valid_range(__first,__last,_STLP_ITERATOR_CATEGORY(__first, _Iterator)) &&
00240 __valid_range(__start,__first,_STLP_ITERATOR_CATEGORY(__first, _Iterator)) &&
00241 __valid_range(__last,__finish,_STLP_ITERATOR_CATEGORY(__last, _Iterator));
00242 }
00243
00244
00245
00246
00247 class _STLP_CLASS_DECLSPEC __owned_link {
00248 public:
00249
00250 __owned_link() : _M_owner(0) {}
00251 __owned_link(const __owned_list* __c) : _M_owner(0), _M_next(0) {
00252 __stl_debugger::_M_attach(__CONST_CAST(__owned_list*,__c), this);
00253 }
00254 __owned_link(const __owned_link& __rhs): _M_owner(0) {
00255 __stl_debugger::_M_attach(__CONST_CAST(__owned_list*,__rhs._M_owner), this);
00256 }
00257 __owned_link& operator=(const __owned_link& __rhs) {
00258 __owned_list* __new_owner = __CONST_CAST(__owned_list*,__rhs._M_owner);
00259 __owned_list* __old_owner = _M_owner;
00260 if ( __old_owner != __new_owner ) {
00261 __stl_debugger::_M_detach(__old_owner, this);
00262 __stl_debugger::_M_attach(__new_owner, this);
00263 }
00264 return *this;
00265 }
00266 ~__owned_link() {
00267 __stl_debugger::_M_detach(_M_owner, this);
00268 _Invalidate();
00269 }
00270
00271 const __owned_list* _Owner() const {
00272 return _M_owner;
00273 }
00274 __owned_list* _Owner() {
00275 return _M_owner;
00276 }
00277 void _Set_owner(const __owned_list* __o) {
00278 _M_owner= __CONST_CAST(__owned_list*,__o);
00279 }
00280 bool _Valid() const {
00281 return _M_owner !=0;
00282 }
00283
00284 void _Invalidate() { _M_owner=0; _M_next = 0; }
00285 void _Link_to_self() { _M_next= 0; }
00286
00287 __owned_link* _Next() { return _M_next; }
00288 const __owned_link* _Next() const { return _M_next; }
00289
00290 public:
00291 __owned_list* _M_owner;
00292 __owned_link* _M_next;
00293 };
00294
00295
00296 class _STLP_CLASS_DECLSPEC __owned_list {
00297 public:
00298 __owned_list(const void* __o) {
00299
00300 _M_node._M_owner = __CONST_CAST(__owned_list*, __REINTERPRET_CAST(const __owned_list*,__o));
00301 _M_node._M_next=0;
00302 }
00303 ~__owned_list() {
00304
00305 _Invalidate_all();
00306
00307 _M_node._Invalidate();
00308 }
00309 const void* _Owner() const {
00310 return (const void*)_M_node._M_owner;
00311 }
00312 void* _Owner() {
00313 return (void*)_M_node._M_owner;
00314 }
00315 bool _Valid() const {
00316 return _M_node._M_owner!=0;
00317 }
00318 void _Invalidate() { _M_node._M_owner=0; }
00319
00320 __owned_link* _First() { return _M_node._Next(); }
00321 __owned_link* _Last() { return 0 ; }
00322
00323 const __owned_link* _First() const { return (__owned_link*)_M_node._M_next; }
00324 const __owned_link* _Last() const { return 0 ;}
00325
00326 void _Verify() const {
00327 __stl_debugger::_Verify(this);
00328 }
00329
00330 void _Swap_owners(__owned_list& __y) {
00331 __stl_debugger::_Swap_owners(*this, __y);
00332 }
00333
00334 void _Invalidate_all() {
00335 __stl_debugger::_Invalidate_all(this);
00336 }
00337
00338 mutable __owned_link _M_node;
00339
00340 mutable _STLP_mutex _M_lock;
00341
00342
00343 private:
00344
00345
00346 __owned_list(const __owned_list&){}
00347 void operator=(const __owned_list&) {}
00348
00349 friend class __owned_link;
00350 friend struct __stl_debug_engine<bool>;
00351 };
00352
00353
00354
00355
00356
00357
00358 template <class _Iterator>
00359 bool _STLP_CALL __check_range(const _Iterator&, const _Iterator&);
00360 template <class _Iterator>
00361 bool _STLP_CALL __check_range(const _Iterator&,
00362 const _Iterator&, const _Iterator&);
00363 template <class _Iterator>
00364 bool _STLP_CALL __check_range(const _Iterator&, const _Iterator& ,
00365 const _Iterator&, const _Iterator& );
00366
00367 template <class _Iterator>
00368 void _STLP_CALL __invalidate_range(const __owned_list* __base,
00369 const _Iterator& __first,
00370 const _Iterator& __last);
00371
00372 template <class _Iterator>
00373 void _STLP_CALL __invalidate_iterator(const __owned_list* __base,
00374 const _Iterator& __it);
00375
00376
00377
00378 inline bool _STLP_CALL
00379 __check_same_owner( const __owned_link& __i1, const __owned_link& __i2) {
00380 return __stl_debugger::_Check_same_owner(__i1,__i2);
00381 }
00382 inline bool _STLP_CALL
00383 __check_same_owner_or_null( const __owned_link& __i1, const __owned_link& __i2) {
00384 return __stl_debugger::_Check_same_owner_or_null(__i1,__i2);
00385 }
00386
00387 template <class _Iterator>
00388 inline bool _STLP_CALL __check_if_owner( const __owned_list* __owner,
00389 const _Iterator& __it) {
00390 return __stl_debugger::_Check_if_owner(__owner, (const __owned_link&)__it);
00391 }
00392
00393 _STLP_END_NAMESPACE
00394
00395 # endif
00396
00397 #if defined ( _STLP_ASSERTIONS )
00398
00399 # ifndef _STLP_ASSERT_MSG_TRAILER
00400 # define _STLP_ASSERT_MSG_TRAILER
00401 # endif
00402
00403
00404 # if !defined( _STLP_DEBUG_MESSAGE )
00405 # define __stl_debug_message __stl_debugger::_Message
00406 # else
00407 extern void __stl_debug_message(const char * format_str, ...);
00408 # endif
00409
00410
00411 # if !defined( _STLP_DEBUG_TERMINATE )
00412 # define __stl_debug_terminate __stl_debugger::_Terminate
00413 # else
00414 extern void __stl_debug_terminate(void);
00415 # endif
00416
00417 #endif
00418
00419 # if !defined (_STLP_LINK_TIME_INSTANTIATION)
00420 # include <stl/debug/_debug.c>
00421 # endif
00422
00423 #endif
00424
00425
00426
00427
00428