ReactOS  0.4.13-dev-99-g7e18b6d
_debug.h
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 1997
4  * Moscow Center for SPARC Technology
5  *
6  * Copyright (c) 1999
7  * Boris Fomitchev
8  *
9  * This material is provided "as is", with absolutely no warranty expressed
10  * or implied. Any use is at your own risk.
11  *
12  * Permission to use or copy this software for any purpose is hereby granted
13  * without fee, provided the above notices are retained on all copies.
14  * Permission to modify the code and to distribute modified code is granted,
15  * provided the above notices are retained, and a notice that the code was
16  * modified is included with the above copyright notice.
17  *
18  */
19 
20 #ifndef _STLP_DEBUG_H
21 #define _STLP_DEBUG_H
22 
23 #if (defined (_STLP_DEBUG) || defined (_STLP_DEBUG_ALLOC)) && \
24  !defined (_STLP_ASSERTIONS)
25 # define _STLP_ASSERTIONS 1
26 #endif
27 
28 #if defined (_STLP_ASSERTIONS)
29 
30 # if !defined (_STLP_FILE__)
31 # define _STLP_FILE__ __FILE__
32 # endif
33 
35 
37 
38 enum {
39  //General errors
40  _StlFormat_ERROR_RETURN,
41  _StlFormat_ASSERTION_FAILURE,
42  _StlFormat_VERBOSE_ASSERTION_FAILURE,
43  _StlMsg_INVALID_ARGUMENT,
44  //Container/Iterator related errors
45  _StlMsg_INVALID_CONTAINER,
46  _StlMsg_EMPTY_CONTAINER,
47  _StlMsg_ERASE_PAST_THE_END,
48  _StlMsg_OUT_OF_BOUNDS,
49  _StlMsg_NOT_OWNER,
50  _StlMsg_SHOULD_NOT_OWNER,
51  _StlMsg_INVALID_ITERATOR,
52  _StlMsg_INVALID_LEFTHAND_ITERATOR,
53  _StlMsg_INVALID_RIGHTHAND_ITERATOR,
54  _StlMsg_DIFFERENT_OWNERS ,
55  _StlMsg_NOT_DEREFERENCEABLE ,
56  _StlMsg_INVALID_RANGE ,
57  _StlMsg_NOT_IN_RANGE_1 ,
58  _StlMsg_NOT_IN_RANGE_2 ,
59  _StlMsg_INVALID_ADVANCE ,
60  _StlMsg_SINGULAR_ITERATOR ,
61  //Bad predicate for sorting
62  _StlMsg_INVALID_STRICT_WEAK_PREDICATE,
63  _StlMsg_INVALID_EQUIVALENT_PREDICATE,
64  // debug alloc messages
65  _StlMsg_DBA_DELETED_TWICE ,
66  _StlMsg_DBA_NEVER_ALLOCATED ,
67  _StlMsg_DBA_TYPE_MISMATCH ,
68  _StlMsg_DBA_SIZE_MISMATCH ,
69  _StlMsg_DBA_UNDERRUN ,
70  _StlMsg_DBA_OVERRUN ,
71  // auto_ptr messages
72  _StlMsg_AUTO_PTR_NULL ,
73  //Memory alignent message
74  _StlMsg_WRONG_MEMORY_ALIGNMENT,
75  _StlMsg_UNKNOWN
76  /* _StlMsg_MAX */
77 };
78 
79 /* have to hardcode that ;() */
80 # define _StlMsg_MAX 31
81 
82 class __owned_link;
83 class __owned_list;
84 
85 # if defined (_STLP_DEBUG_MODE_THROWS)
86 # define _STLP_MESSAGE_NORETURN _STLP_FUNCTION_THROWS
87 # else
88 # define _STLP_MESSAGE_NORETURN
89 # endif
90 
91 template <class _Dummy>
92 class __stl_debug_engine {
93 public:
94  // Basic routine to report any debug message
95  // Use _STLP_DEBUG_MESSAGE to override
96  static void _STLP_MESSAGE_NORETURN _STLP_CALL _Message(const char * format_str, ...);
97 
98  // Micsellanous function to report indexed error message
99  static void _STLP_CALL _IndexedError(int __ind, const char* __f, int __l);
100 
101  // Basic assertion report mechanism.
102  // Reports failed assertion via __stl_debug_message and calls _Terminate
103  // if _STLP_DEBUG_TERMINATE is specified, calls __stl_debug_terminate instead
104  static void _STLP_CALL _Assert(const char* __expr, const char* __f, int __l);
105 
106  // The same, with additional diagnostics
107  static void _STLP_CALL _VerboseAssert(const char* __expr, int __error_ind, const char* __f, int __l);
108 
109  // If exceptions are present, sends unique exception
110  // If not, calls _STLP_ABORT() to terminate
111  // Use _STLP_DEBUG_TERMINATE to override
112  static void _STLP_CALL _Terminate();
113 
114 # if defined (_STLP_DEBUG)
115  // owned_list/link delegate non-inline functions here
116 
117  static bool _STLP_CALL _Check_same_owner( const __owned_link& __i1,
118  const __owned_link& __i2);
119  static bool _STLP_CALL _Check_same_or_null_owner( const __owned_link& __i1,
120  const __owned_link& __i2);
121  static bool _STLP_CALL _Check_if_owner( const __owned_list*, const __owned_link&);
122 
123  static bool _STLP_CALL _Check_if_not_owner( const __owned_list*, const __owned_link&);
124 
125  static void _STLP_CALL _Verify(const __owned_list*);
126 
127  static void _STLP_CALL _Swap_owners(__owned_list&, __owned_list&);
128 
129  static void _STLP_CALL _Invalidate_all(__owned_list*);
130 
131  static void _STLP_CALL _Set_owner(__owned_list& /*src*/, __owned_list& /*dst*/);
132 
133  static void _STLP_CALL _Stamp_all(__owned_list*, __owned_list*);
134 
135  static void _STLP_CALL _M_detach(__owned_list*, __owned_link*);
136 
137  static void _STLP_CALL _M_attach(__owned_list*, __owned_link*);
138 
139  // accessor : check and get pointer to the container
140  static void* _STLP_CALL _Get_container_ptr(const __owned_link*);
141 # endif
142 
143  // debug messages and formats
144  static const char* _Message_table[_StlMsg_MAX];
145 };
146 
147 # undef _STLP_MESSAGE_NORETURN
148 
149 # if defined (_STLP_USE_TEMPLATE_EXPORT)
150 _STLP_EXPORT_TEMPLATE_CLASS __stl_debug_engine<bool>;
151 # endif
152 
153 typedef __stl_debug_engine<bool> __stl_debugger;
154 
156 
158 
159 # if !defined (_STLP_ASSERT)
160 # define _STLP_ASSERT(expr) \
161  if (!(expr)) { _STLP_PRIV __stl_debugger::_Assert( # expr, _STLP_FILE__, __LINE__); }
162 # endif
163 
164 #else
165 # define _STLP_ASSERT(expr)
166 #endif
167 
168 // this section is for _STLP_DEBUG only
169 #if defined (_STLP_DEBUG)
170 
171 # if !defined (_STLP_VERBOSE_ASSERT)
172 // fbp : new form not requiring ";"
173 # define _STLP_VERBOSE_ASSERT(expr, __diag_num) \
174  if (!(expr)) { _STLP_PRIV __stl_debugger::_VerboseAssert\
175  ( # expr, _STLP_PRIV __diag_num, _STLP_FILE__, __LINE__ ); \
176  }
177 # endif
178 
179 # define _STLP_DEBUG_CHECK(expr) _STLP_ASSERT(expr)
180 
181 # if (_STLP_DEBUG_LEVEL == _STLP_STANDARD_DBG_LEVEL)
182 # define _STLP_STD_DEBUG_CHECK(expr) _STLP_DEBUG_CHECK(expr)
183 # else
184 # define _STLP_STD_DEBUG_CHECK(expr)
185 # endif
186 
187 # if !defined (_STLP_VERBOSE_RETURN)
188 # define _STLP_VERBOSE_RETURN(__expr,__diag_num) if (!(__expr)) { \
189  _STLP_PRIV __stl_debugger::_IndexedError(__diag_num, _STLP_FILE__ , __LINE__); \
190  return false; }
191 # endif
192 
193 # if !defined (_STLP_VERBOSE_RETURN_0)
194 # define _STLP_VERBOSE_RETURN_0(__expr,__diag_num) if (!(__expr)) { \
195  _STLP_PRIV __stl_debugger::_IndexedError(__diag_num, _STLP_FILE__, __LINE__); \
196  return 0; }
197 # endif
198 
199 # ifndef _STLP_INTERNAL_THREADS_H
200 # include <stl/_threads.h>
201 # endif
202 
203 # ifndef _STLP_INTERNAL_ITERATOR_BASE_H
204 # include <stl/_iterator_base.h>
205 # endif
206 
207 # ifndef _STLP_TYPE_TRAITS_H
208 # include <stl/type_traits.h>
209 # endif
210 
212 
214 
215 /*
216  * Special debug iterator traits having an additionnal static member
217  * method _Check. It is used by the slist debug implementation to check
218  * the special before_begin iterator.
219  */
220 template <class _Traits>
221 struct _DbgTraits : _Traits {
222  typedef _DbgTraits<typename _Traits::_ConstTraits> _ConstTraits;
223  typedef _DbgTraits<typename _Traits::_NonConstTraits> _NonConstTraits;
224 
225  template <class _Iterator>
226  static bool _Check(const _Iterator&) {return true;}
227 };
228 
229 //=============================================================
230 template <class _Iterator>
231 inline bool _STLP_CALL __valid_range(const _Iterator& __i1 ,const _Iterator& __i2,
233 { return (__i1 < __i2) || (__i1 == __i2); }
234 
235 template <class _Iterator>
236 inline bool _STLP_CALL __valid_range(const _Iterator& __i1 ,const _Iterator& __i2,
238  // check if comparable
239  bool __dummy(__i1==__i2);
240  return (__dummy==__dummy);
241 }
242 
243 template <class _Iterator>
244 inline bool _STLP_CALL __valid_range(const _Iterator& __i1 ,const _Iterator& __i2,
245  const forward_iterator_tag&) {
246  // check if comparable
247  bool __dummy(__i1==__i2);
248  return (__dummy==__dummy);
249 }
250 
251 template <class _Iterator>
252 inline bool _STLP_CALL __valid_range(const _Iterator&,const _Iterator&,
253  const input_iterator_tag&)
254 { return true; }
255 
256 template <class _Iterator>
257 inline bool _STLP_CALL __valid_range(const _Iterator&,const _Iterator&,
258  const output_iterator_tag&)
259 { return true; }
260 
261 template <class _Iterator>
262 inline bool _STLP_CALL __valid_range(const _Iterator& __i1, const _Iterator& __i2)
263 { return __valid_range(__i1,__i2,_STLP_ITERATOR_CATEGORY(__i1, _Iterator)); }
264 
265 // Note : that means in range [i1, i2].
266 template <class _Iterator>
267 inline bool _STLP_CALL stlp_in_range(const _Iterator& _It,
268  const _Iterator& __i1, const _Iterator& __i2)
269 { return __valid_range(__i1,_It) && __valid_range(_It,__i2); }
270 
271 template <class _Iterator>
272 inline bool _STLP_CALL stlp_in_range(const _Iterator& __first, const _Iterator& __last,
273  const _Iterator& __start, const _Iterator& __finish)
274 { return __valid_range(__first,__last) && __valid_range(__start,__first) && __valid_range(__last,__finish); }
275 
276 //==========================================================
277 class _STLP_CLASS_DECLSPEC __owned_link {
278 public:
279  // Note: This and the following special defines for compiling under Windows CE under ARM
280  // is needed for correctly using _STLP_DEBUG mode. This comes from a bug in the ARM
281  // compiler where checked iterators that are passed by value call _M_attach with the wrong
282  // this pointer and calling _M_detach can't find the correct pointer to the __owned_link.
283  // This is circumvented by managing a _M_self pointer that points to the correct value.
284  // Ugly but works.
285 #if defined(_STLP_WCE) && defined(_ARM_)
286  __owned_link() : _M_self(this), _M_owner(0) {}
287  __owned_link(const __owned_list* __c) : _M_self(this), _M_owner(0), _M_next(0)
288  { __stl_debugger::_M_attach(__CONST_CAST(__owned_list*,__c), this); }
289  __owned_link(const __owned_link& __rhs): _M_self(this), _M_owner(0)
290  { __stl_debugger::_M_attach(__CONST_CAST(__owned_list*,__rhs._M_owner), this); }
291 #else
292  __owned_link() : _M_owner(0) {}
293  __owned_link(const __owned_list* __c) : _M_owner(0), _M_next(0)
294  { __stl_debugger::_M_attach(__CONST_CAST(__owned_list*,__c), this); }
295  __owned_link(const __owned_link& __rhs): _M_owner(0)
296  { __stl_debugger::_M_attach(__CONST_CAST(__owned_list*,__rhs._M_owner), this); }
297 #endif
298  __owned_link& operator=(const __owned_link& __rhs) {
299  __owned_list* __new_owner = __CONST_CAST(__owned_list*,__rhs._M_owner);
300  __owned_list* __old_owner = _M_owner;
301  if ( __old_owner != __new_owner ) {
302  __stl_debugger::_M_detach(__old_owner, this);
303  __stl_debugger::_M_attach(__new_owner, this);
304  }
305  return *this;
306  }
307 #if defined(_STLP_WCE) && defined(_ARM_)
308  ~__owned_link() {
309  __stl_debugger::_M_detach(_M_owner, _M_self);
310  _Invalidate();
311  }
312 #else
313  ~__owned_link() {
314  __stl_debugger::_M_detach(_M_owner, this);
315  _Invalidate();
316  }
317 #endif
318 
319  const __owned_list* _Owner() const { return _M_owner; }
320  __owned_list* _Owner() { return _M_owner; }
321  void _Set_owner(const __owned_list* __o) { _M_owner= __CONST_CAST(__owned_list*,__o); }
322  bool _Valid() const { return _M_owner != 0; }
323  void _Invalidate() { _M_owner = 0; _M_next = 0; }
324  void _Link_to_self() { _M_next = 0; }
325 
326  __owned_link* _Next() { return _M_next; }
327  const __owned_link* _Next() const { return _M_next; }
328 
329 public:
330 #if defined(_STLP_WCE) && defined(_ARM_)
331  __owned_link* _M_self;
332 #endif
333 
334  __owned_list* _M_owner;
335  __owned_link* _M_next;
336 };
337 
338 
339 class _STLP_CLASS_DECLSPEC __owned_list {
340 public:
341  __owned_list(void* __o) {
342  // fprintf(stderr, "__owned_list(): %p\n",(void*)this);
343  _M_node._M_owner = __REINTERPRET_CAST(__owned_list*,__o);
344  _M_node._M_next = 0;
345  }
346  ~__owned_list() {
347  // fprintf(stderr, "~__owned_list(): %p\n",(void*)this);
348  _Invalidate_all();
349  // that prevents detach
350  _M_node._Invalidate();
351  }
352  const void* _Owner() const { return (const void*)_M_node._M_owner; }
353  void* _Owner() { return (void*)_M_node._M_owner; }
354  bool _Valid() const { return _M_node._M_owner != 0; }
355  void _Invalidate() { _M_node._M_owner = 0; }
356 
357  __owned_link* _First() { return _M_node._Next(); }
358  __owned_link* _Last() { return 0 ; }
359 
360  const __owned_link* _First() const { return (__owned_link*)_M_node._M_next; }
361  const __owned_link* _Last() const { return 0 ;}
362 
363  void _Verify() const { __stl_debugger::_Verify(this); }
364  void _Swap_owners(__owned_list& __y) { __stl_debugger::_Swap_owners(*this, __y); }
365  void _Invalidate_all() { __stl_debugger::_Invalidate_all(this); }
366  void _Set_owner(__owned_list& __y) { __stl_debugger::_Set_owner(*this, __y); }
367 
368  mutable __owned_link _M_node;
369  mutable _STLP_mutex _M_lock;
370 
371 private:
372  // should never be called, should be left not implemented,
373  // but some compilers complain about it ;(
374  __owned_list(const __owned_list&){}
375  __owned_list& operator = (const __owned_list&) { return *this; }
376 
377  friend class __owned_link;
378  friend class __stl_debug_engine<bool>;
379 };
380 
381 
382 //==========================================================
383 
384 // forward declaratioins
385 
386 template <class _Iterator>
387 bool _STLP_CALL __check_range(const _Iterator&, const _Iterator&);
388 template <class _Iterator>
389 bool _STLP_CALL __check_range(const _Iterator&,
390  const _Iterator&, const _Iterator&);
391 template <class _Iterator>
392 bool _STLP_CALL __check_range(const _Iterator&, const _Iterator& ,
393  const _Iterator&, const _Iterator& );
394 template <class _Tp>
395 bool _STLP_CALL __check_ptr_range(const _Tp*, const _Tp*);
396 
397 template <class _Iterator>
398 void _STLP_CALL __invalidate_range(const __owned_list* __base,
399  const _Iterator& __first,
400  const _Iterator& __last);
401 
402 template <class _Iterator>
403 void _STLP_CALL __invalidate_iterator(const __owned_list* __base,
404  const _Iterator& __it);
405 
406 template <class _Iterator>
407 void _STLP_CALL __change_range_owner(const _Iterator& __first,
408  const _Iterator& __last,
409  const __owned_list* __dst);
410 
411 template <class _Iterator>
412 void _STLP_CALL __change_ite_owner(const _Iterator& __it,
413  const __owned_list* __dst);
414 
415 //============================================================
416 inline bool _STLP_CALL
417 __check_same_owner(const __owned_link& __i1, const __owned_link& __i2)
418 { return __stl_debugger::_Check_same_owner(__i1,__i2); }
419 
420 inline bool _STLP_CALL
421 __check_same_or_null_owner(const __owned_link& __i1, const __owned_link& __i2)
422 { return __stl_debugger::_Check_same_or_null_owner(__i1,__i2); }
423 
424 template <class _Iterator>
425 inline bool _STLP_CALL __check_if_owner( const __owned_list* __owner,
426  const _Iterator& __it)
427 { return __stl_debugger::_Check_if_owner(__owner, (const __owned_link&)__it); }
428 
429 template <class _Iterator>
430 inline bool _STLP_CALL __check_if_not_owner( const __owned_list* __owner,
431  const _Iterator& __it)
432 { return __stl_debugger::_Check_if_not_owner(__owner, (const __owned_link&)__it); }
433 
435 
437 
438 #else
439 # define _STLP_VERBOSE_ASSERT(expr, diagnostic)
440 # define _STLP_DEBUG_CHECK(expr)
441 #endif /* _STLP_DEBUG */
442 
443 #if defined (_STLP_ASSERTIONS)
444 
445 # if !defined (_STLP_ASSERT_MSG_TRAILER)
446 # define _STLP_ASSERT_MSG_TRAILER
447 # endif
448 
449 // dwa 12/30/98 - if _STLP_DEBUG_MESSAGE is defined, the user can supply own definition.
450 # if !defined (_STLP_DEBUG_MESSAGE)
451 # define __stl_debug_message __stl_debugger::_Message
452 # else
453 extern void __stl_debug_message(const char * format_str, ...);
454 # endif
455 
456 // fbp: if _STLP_DEBUG_TERMINATE is defined, the user can supply own definition.
457 # if !defined (_STLP_DEBUG_TERMINATE)
458 # define __stl_debug_terminate __stl_debugger::_Terminate
459 # else
460 extern void __stl_debug_terminate();
461 # endif
462 
463 #endif
464 
465 #if defined (_STLP_ASSERTIONS) && !defined (_STLP_LINK_TIME_INSTANTIATION)
466 # include <stl/debug/_debug.c>
467 #endif
468 
469 #endif /* DEBUG_H */
470 
471 // Local Variables:
472 // mode:C++
473 // End:
#define _STLP_ITERATOR_CATEGORY(_It, _Tp)
#define __c
Definition: schilyio.h:209
#define _STLP_MOVE_TO_PRIV_NAMESPACE
Definition: features.h:524
_STLP_INLINE_LOOP _InputIter __last
Definition: _algo.h:68
typedef bool(CARDLIBPROC *pCanDragProc)(CardRegion &stackobj
#define _STLP_MOVE_TO_STD_NAMESPACE
Definition: features.h:525
#define _STLP_EXPORT_TEMPLATE_CLASS
Definition: features.h:987
_STLP_MOVE_TO_PRIV_NAMESPACE const _InputIterator const input_iterator_tag &_InputIterator __it(__first)
#define _STLP_CLASS_DECLSPEC
Definition: features.h:983
#define __REINTERPRET_CAST(__x, __y)
Definition: features.h:586
#define __CONST_CAST(__x, __y)
Definition: features.h:584
#define _STLP_END_NAMESPACE
Definition: features.h:503
#define _STLP_BEGIN_NAMESPACE
Definition: features.h:501
#define _STLP_CALL
Definition: _bc.h:131