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



Generated on Mon Mar 10 15:32:46 2008 by  doxygen 1.5.1