epoc32/include/tools/stlport/stl/debug/_debug.c
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:33:34 +0100 (2010-03-31)
branchSymbian3
changeset 4 837f303aceeb
parent 3 e1b950c65cb4
permissions -rw-r--r--
Current Symbian^3 public API header files (from PDK 3.0.h)
This is the epoc32/include tree with the "platform" subtrees removed, and
all but a selected few mbg and rsg files removed.
     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_C
    21 #define _STLP_DEBUG_C
    22 
    23 #if defined (_STLP_DEBUG)
    24 #if defined (_STLP_THREADS)
    25 #  if !defined (_STLP_NEED_MUTABLE)
    26 #    define _STLP_ACQUIRE_LOCK(_Lock) _Lock._M_acquire_lock();
    27 #    define _STLP_RELEASE_LOCK(_Lock) _Lock._M_release_lock();
    28 #  else
    29 #    define _STLP_ACQUIRE_LOCK(_Lock) ((_STLP_mutex&)_Lock)._M_acquire_lock();
    30 #    define _STLP_RELEASE_LOCK(_Lock) ((_STLP_mutex&)_Lock)._M_release_lock();
    31 #  endif /* _STLP_NEED_MUTABLE */
    32 #else
    33 #  define _STLP_ACQUIRE_LOCK(_Lock)
    34 #  define _STLP_RELEASE_LOCK(_Lock)
    35 #endif /* _STLP_THREADS */
    36 
    37 _STLP_BEGIN_NAMESPACE
    38 _STLP_MOVE_TO_PRIV_NAMESPACE
    39 
    40 //==========================================================
    41 //  global non-inline functions
    42 //==========================================================
    43 // [ i1, i2)
    44 #if !defined (__DMC__)
    45 template <class _Iterator>
    46 inline bool  _STLP_CALL
    47 __in_range_aux(const _Iterator& __it, const _Iterator& __first,
    48                const _Iterator& __last, const random_access_iterator_tag &) {
    49     return ( __it >= __first &&
    50              __it < __last);
    51 }
    52 #endif
    53 
    54 template <class _Iterator1, class _Iterator>
    55 #if defined (_STLP_MSVC) && (_STLP_MSVC >= 1100)
    56 inline bool _STLP_CALL  __in_range_aux(_Iterator1 __it, const _Iterator& __first,
    57 #else
    58 inline bool _STLP_CALL  __in_range_aux(const _Iterator1& __it, const _Iterator& __first,
    59 #endif
    60                                        const _Iterator& __last, const forward_iterator_tag &) {
    61   _Iterator1 __i(__first);
    62   for (;  __i != __last && __i != __it; ++__i);
    63   return (__i != __last);
    64 }
    65 
    66 #if defined (_STLP_NONTEMPL_BASE_MATCH_BUG)
    67 template <class _Iterator1, class _Iterator>
    68 inline bool  _STLP_CALL
    69 __in_range_aux(const _Iterator1& __it, const _Iterator& __first,
    70                const _Iterator& __last, const bidirectional_iterator_tag &) {
    71   _Iterator1 __i(__first);
    72   for (;  __i != __last && __i != __it; ++__i);
    73   return (__i != __last);
    74 }
    75 #endif
    76 
    77 template <class _Iterator>
    78 bool _STLP_CALL __check_range_aux(const _Iterator& __first, const _Iterator& __last,
    79                                   const __false_type& /*_IsIntegral*/) {
    80   _STLP_VERBOSE_RETURN(__valid_range(__first,__last), _StlMsg_INVALID_RANGE )
    81   return true;
    82 }
    83 
    84 template <class _Integral>
    85 bool _STLP_CALL __check_range_aux(_Integral /*__first*/, _Integral /*__last*/,
    86                                   const __true_type& /*_IsIntegral*/)
    87 { return true; }
    88 
    89 template <class _Iterator>
    90 bool _STLP_CALL  __check_range(const _Iterator& __first, const _Iterator& __last) {
    91   typedef typename _IsIntegral<_Iterator>::_Ret _Integral;
    92   return __check_range_aux(__first, __last, _Integral());
    93 }
    94 
    95 template <class _Iterator>
    96 bool _STLP_CALL  __check_range(const _Iterator& __it,
    97                                const _Iterator& __start, const _Iterator& __finish) {
    98   _STLP_VERBOSE_RETURN(__in_range(__it, __start, __finish),
    99                        _StlMsg_NOT_IN_RANGE_1)
   100   return true;
   101 }
   102 
   103 template <class _Iterator>
   104 bool _STLP_CALL  __check_range(const _Iterator& __first, const _Iterator& __last,
   105                                const _Iterator& __start, const _Iterator& __finish) {
   106   _STLP_VERBOSE_RETURN(__in_range(__first, __last, __start, __finish),
   107                        _StlMsg_NOT_IN_RANGE_2)
   108   return true;
   109 }
   110 
   111 template <class _Tp>
   112 bool _STLP_CALL __check_ptr_range(const _Tp* __first, const _Tp* __last) {
   113   _STLP_VERBOSE_RETURN((__first != 0 || __last == 0), _StlMsg_INVALID_ARGUMENT)
   114   _STLP_VERBOSE_RETURN(__valid_range(__first, __last, random_access_iterator_tag()),
   115                        _StlMsg_INVALID_RANGE)
   116   return true;
   117 }
   118 
   119 //===============================================================
   120 template <class _Iterator>
   121 void _STLP_CALL __invalidate_range(const __owned_list* __base,
   122                                    const _Iterator& __first,
   123                                    const _Iterator& __last) {
   124   typedef __owned_link _L_type;
   125   _STLP_ACQUIRE_LOCK(__base->_M_lock)
   126   _L_type* __prev = __CONST_CAST(_L_type*, &__base->_M_node);
   127   _L_type* __pos = __prev->_M_next;
   128 
   129   while (__pos != 0) {
   130     if (!(&__first == __STATIC_CAST(_Iterator*, __pos) || &__last == __STATIC_CAST(_Iterator*, __pos)) &&
   131         __in_range_aux(__STATIC_CAST(_Iterator*, __pos)->_M_iterator,
   132                        __first._M_iterator, __last._M_iterator,
   133                        _STLP_ITERATOR_CATEGORY(__first, _Iterator))) {
   134       __pos->_M_owner = 0;
   135       __prev->_M_next = __pos->_M_next;
   136     }
   137     else {
   138       __prev = __pos;
   139     }
   140     __pos = __prev->_M_next;
   141   }
   142   _STLP_RELEASE_LOCK(__base->_M_lock)
   143 }
   144 
   145 template <class _Iterator>
   146 void _STLP_CALL __invalidate_iterator(const __owned_list* __base,
   147                                       const _Iterator& __it) {
   148   typedef __owned_link   _L_type;
   149   _STLP_ACQUIRE_LOCK(__base->_M_lock)
   150   _L_type* __prev = __CONST_CAST(_L_type*, &__base->_M_node);
   151   _L_type* __pos = __prev->_M_next;
   152   while (__pos != 0) {
   153     // this requires safe iterators to be derived from __owned_link
   154     if ((__pos != __STATIC_CAST(const _L_type*, &__it)) &&
   155         (__STATIC_CAST(_Iterator*, __pos)->_M_iterator == __it._M_iterator)) {
   156       __pos->_M_owner = 0;
   157       __prev->_M_next = __pos->_M_next;
   158     }
   159     else {
   160       __prev = __pos;
   161     }
   162     __pos = __prev->_M_next;
   163   }
   164   _STLP_RELEASE_LOCK(__base->_M_lock)
   165 }
   166 
   167 template <class _Iterator>
   168 void _STLP_CALL  __change_range_owner(const _Iterator& __first,
   169                                       const _Iterator& __last,
   170                                       const __owned_list* __dst) {
   171   if (__first._Owner() == __dst)
   172     return;
   173 
   174   typedef __owned_link _L_type;
   175   // Check __stl_debug_engine<_Dummy>::_Swap_owners comments to see why there is no lock here
   176   //_STLP_ACQUIRE_LOCK(__base->_M_lock)
   177   __owned_list *__base = __CONST_CAST(__owned_list*, __first._Owner());
   178   _L_type* __src_prev = &__base->_M_node;
   179   _L_type* __pos = __src_prev->_M_next;
   180   _L_type* __dst_prev = __CONST_CAST(_L_type*, &__dst->_M_node);
   181 
   182   while (__pos != 0) {
   183     if (!(&__first == __STATIC_CAST(_Iterator*, __pos) || &__last == __STATIC_CAST(_Iterator*, __pos)) &&
   184         __in_range_aux(__STATIC_CAST(_Iterator*, __pos)->_M_iterator,
   185                        __first._M_iterator, __last._M_iterator,
   186                        _STLP_ITERATOR_CATEGORY(__first, _Iterator))) {
   187       __pos->_M_owner = __CONST_CAST(__owned_list*, __dst);
   188       //remove __pos from __base:
   189       __src_prev->_M_next = __pos->_M_next;
   190       //add __pos to __dst:
   191       __pos->_M_next = __dst_prev->_M_next;
   192       __dst_prev->_M_next = __pos;
   193     }
   194     else {
   195       __src_prev = __pos;
   196     }
   197     __pos = __src_prev->_M_next;
   198   }
   199   //_STLP_RELEASE_LOCK(__base->_M_lock)
   200 }
   201 
   202 template <class _Iterator>
   203 void _STLP_CALL __change_ite_owner(const _Iterator& __it,
   204                                    const __owned_list* __dst) {
   205   if (__it._Owner() == __dst)
   206     return;
   207 
   208   typedef __owned_link _L_type;
   209   // Check __stl_debug_engine<_Dummy>::_Swap_owners comments to see why there is no lock here
   210   //_STLP_ACQUIRE_LOCK(__base->_M_lock)
   211   __owned_list *__base = __CONST_CAST(__owned_list*, __it._Owner());
   212   _L_type* __prev = &__base->_M_node;
   213   _L_type* __pos = __prev->_M_next;
   214   _L_type* __dst_prev = __CONST_CAST(_L_type*, &__dst->_M_node);
   215 
   216   while (__pos != 0) {
   217     // this requires safe iterators to be derived from __owned_link
   218     if ((__pos != __STATIC_CAST(const _L_type*, &__it)) &&
   219         (__STATIC_CAST(_Iterator*, __pos)->_M_iterator == __it._M_iterator)) {
   220       __pos->_M_owner = __CONST_CAST(__owned_list*, __dst);
   221       //remove __pos from __base:
   222       __prev->_M_next = __pos->_M_next;
   223       //add __pos to __dst:
   224       __pos->_M_next = __dst_prev->_M_next;
   225       __dst_prev->_M_next = __pos;
   226     }
   227     else {
   228       __prev = __pos;
   229     }
   230     __pos = __prev->_M_next;
   231   }
   232   //_STLP_RELEASE_LOCK(__base->_M_lock)
   233 }
   234 
   235 _STLP_MOVE_TO_STD_NAMESPACE
   236 _STLP_END_NAMESPACE
   237 
   238 #endif /* _STLP_DEBUG */
   239 
   240 #if defined (_STLP_EXPOSE_GLOBALS_IMPLEMENTATION)
   241 
   242 #  ifndef _STLP_INTERNAL_CSTDLIB
   243 #    include <stl/_cstdlib.h>
   244 #  endif
   245 
   246 //==========================================================
   247 // .c section
   248 //  owned_list non-inline methods and global functions
   249 //==========================================================
   250 
   251 #  if defined (_STLP_ASSERTIONS)
   252 
   253 _STLP_BEGIN_NAMESPACE
   254 _STLP_MOVE_TO_PRIV_NAMESPACE
   255 
   256 #    if !defined (_STLP_STRING_LITERAL)
   257 #      define _STLP_STRING_LITERAL(__x) __x
   258 #    endif
   259 
   260 #    if defined (_STLP_USE_WIDE_INTERFACE)
   261 // note: WinCE needs this to format single-byte strings in __stl_debug_engine::_Message
   262 #      define _STLP_PERCENT_S "%hs"
   263 #    else
   264 #      define _STLP_PERCENT_S "%s"
   265 #    endif /* _STLP_USE_WIDE_INTERFACE */
   266 
   267 #    define _STLP_MESSAGE_TABLE_BODY = { \
   268 _STLP_STRING_LITERAL("\n" _STLP_PERCENT_S "(%d): STL error: " _STLP_PERCENT_S "\n"), \
   269 _STLP_STRING_LITERAL(_STLP_PERCENT_S "(%d): STL assertion failure : " _STLP_PERCENT_S "\n" _STLP_ASSERT_MSG_TRAILER), \
   270 _STLP_STRING_LITERAL("\n" _STLP_PERCENT_S "(%d): STL error : " _STLP_PERCENT_S "\n" _STLP_PERCENT_S "(%d): STL assertion failure:     " _STLP_PERCENT_S " \n" _STLP_ASSERT_MSG_TRAILER), \
   271 _STLP_STRING_LITERAL("Invalid argument to operation (see operation documentation)"),                  \
   272 _STLP_STRING_LITERAL("Taking an iterator out of destroyed (or otherwise corrupted) container"),       \
   273 _STLP_STRING_LITERAL("Trying to extract an object out from empty container"),\
   274 _STLP_STRING_LITERAL("Past-the-end iterator could not be erased"),  \
   275 _STLP_STRING_LITERAL("Index out of bounds"),  \
   276 _STLP_STRING_LITERAL("Container doesn't own the iterator"),  \
   277 _STLP_STRING_LITERAL("Container is owner of the iterator, but should not"),  \
   278 _STLP_STRING_LITERAL("Uninitialized or invalidated (by mutating operation) iterator used"),  \
   279 _STLP_STRING_LITERAL("Uninitialized or invalidated (by mutating operation) lefthand iterator in expression"),  \
   280 _STLP_STRING_LITERAL("Uninitialized or invalidated (by mutating operation) righthand iterator in expression"),  \
   281 _STLP_STRING_LITERAL("Iterators used in expression are from different owners"),  \
   282 _STLP_STRING_LITERAL("Iterator could not be dereferenced (past-the-end ?)"),  \
   283 _STLP_STRING_LITERAL("Range [first,last) is invalid"),  \
   284 _STLP_STRING_LITERAL("Iterator is not in range [first,last)"),  \
   285 _STLP_STRING_LITERAL("Range [first,last) is not in range [start,finish)"),  \
   286 _STLP_STRING_LITERAL("The advance would produce invalid iterator"),  \
   287 _STLP_STRING_LITERAL("Iterator is singular (advanced beyond the bounds ?)"),  \
   288 _STLP_STRING_LITERAL("Invalid strict weak ordering predicate, if pred(a, b) then we should have !pred(b, a)"), \
   289 _STLP_STRING_LITERAL("Invalid equivalent predicate, if pred(a, b) then we should have pred(b, a)"), \
   290 _STLP_STRING_LITERAL("Memory block deallocated twice"),  \
   291 _STLP_STRING_LITERAL("Deallocating a block that was never allocated"),  \
   292 _STLP_STRING_LITERAL("Deallocating a memory block allocated for another type"),  \
   293 _STLP_STRING_LITERAL("Size of block passed to deallocate() doesn't match block size"),  \
   294 _STLP_STRING_LITERAL("Pointer underrun - safety margin at front of memory block overwritten"),  \
   295 _STLP_STRING_LITERAL("Pointer overrrun - safety margin at back of memory block overwritten"),   \
   296 _STLP_STRING_LITERAL("Attempt to dereference null pointer returned by auto_ptr::get()"),   \
   297 _STLP_STRING_LITERAL("Memory allocation function returned a wrongly align memory block"),   \
   298 _STLP_STRING_LITERAL("Unknown problem") \
   299   }
   300 
   301 #    if (_STLP_STATIC_TEMPLATE_DATA > 0)
   302 template <class _Dummy>
   303 const char* __stl_debug_engine<_Dummy>::_Message_table[_StlMsg_MAX]  _STLP_MESSAGE_TABLE_BODY;
   304 
   305 #      if (defined (__CYGWIN__) || defined (__MINGW32__)) && \
   306            defined (_STLP_USE_DYNAMIC_LIB) && !defined (__BUILDING_STLPORT)
   307 /*
   308  * Under cygwin, when STLport is used as a shared library, the id needs
   309  * to be specified as imported otherwise they will be duplicated in the
   310  * calling executable.
   311  */
   312 _STLP_TEMPLATE_NULL
   313 _STLP_DECLSPEC const char* __stl_debug_engine<bool>::_Message_table[_StlMsg_MAX];
   314 #      endif
   315 
   316 #    else
   317 __DECLARE_INSTANCE(const char*, __stl_debug_engine<bool>::_Message_table[_StlMsg_MAX],
   318                    _STLP_MESSAGE_TABLE_BODY);
   319 #    endif
   320 
   321 #    undef _STLP_STRING_LITERAL
   322 #    undef _STLP_PERCENT_S
   323 
   324 _STLP_MOVE_TO_STD_NAMESPACE
   325 _STLP_END_NAMESPACE
   326 
   327 // abort()
   328 #  ifndef _STLP_INTERNAL_CSTDLIB
   329 #    include <stl/_cstdlib.h>
   330 #  endif
   331 
   332 #  if !defined (_STLP_DEBUG_MESSAGE)
   333 #    ifndef _STLP_INTERNAL_CSTDARG
   334 #      include <stl/_cstdarg.h>
   335 #    endif
   336 #    ifndef _STLP_INTERNAL_CSTDIO
   337 #      include <stl/_cstdio.h>
   338 #    endif
   339 #    if defined (_STLP_DEBUG_MODE_THROWS) && !defined (_STLP_RANGE_ERRORS_H)
   340 #      include <stl/_range_errors.h>
   341 #    endif
   342 
   343 _STLP_BEGIN_NAMESPACE
   344 _STLP_MOVE_TO_PRIV_NAMESPACE
   345 
   346 template <class _Dummy>
   347 void _STLP_CALL
   348 __stl_debug_engine<_Dummy>::_Message(const char * __format_str, ...) {
   349   STLPORT_CSTD::va_list __args;
   350   va_start( __args, __format_str );
   351 
   352 #      if !defined (_STLP_DEBUG_MODE_THROWS)
   353 #        if defined (_STLP_USE_WIDE_INTERFACE)
   354   TCHAR __buffer[512];
   355   int _convert = strlen(__format_str) + 1;
   356   LPWSTR _lpw = (LPWSTR)alloca(_convert * sizeof(wchar_t));
   357   _lpw[0] = '\0';
   358   MultiByteToWideChar(GetACP(), 0, __format_str, -1, _lpw, _convert);
   359   wvsprintf(__buffer, _lpw, __args);
   360   _STLP_WINCE_TRACE(__buffer);
   361 #        elif defined (_STLP_WIN32) && (defined(_STLP_MSVC) || defined (__ICL))
   362   char __buffer [4096];
   363 
   364 #          if !defined (_STLP_USE_SAFE_STRING_FUNCTIONS)
   365   vsnprintf(__buffer, _STLP_ARRAY_SIZE(__buffer), __format_str, __args);
   366 #          else
   367   vsnprintf_s(__buffer, _STLP_ARRAY_SIZE(__buffer), _TRUNCATE, __format_str, __args);
   368 #          endif
   369 
   370   OutputDebugStringA(__buffer);
   371 
   372 #        elif defined (__amigaos__)
   373   STLPORT_CSTD::vfprintf(stderr, __format_str, (char *)__args);
   374 #        else
   375   STLPORT_CSTD::vfprintf(stderr, __format_str, __args);
   376 #        endif
   377 #      else
   378   char __buffer[4096];
   379 
   380 #        if defined (_STLP_USE_SAFE_STRING_FUNCTIONS)
   381   vsnprintf_s(__buffer, _STLP_ARRAY_SIZE(__buffer), _TRUNCATE, __format_str, __args);
   382 #        elif defined (_STLP_WIN32) && (defined(_STLP_MSVC) || defined (__ICL))
   383   vsnprintf(__buffer, _STLP_ARRAY_SIZE(__buffer), __format_str, __args);
   384 #        else
   385   vsprintf(__buffer, __format_str, __args);
   386 #        endif
   387 #      endif
   388 
   389 #      ifdef _STLP_DEBUG_MESSAGE_POST
   390   _STLP_DEBUG_MESSAGE_POST
   391 #      endif
   392 
   393   va_end(__args);
   394 
   395 #      if defined (_STLP_DEBUG_MODE_THROWS)
   396   __stl_throw_runtime_error(__buffer);
   397 #      endif
   398 }
   399 
   400 _STLP_MOVE_TO_STD_NAMESPACE
   401 _STLP_END_NAMESPACE
   402 
   403 #    else
   404 _STLP_BEGIN_NAMESPACE
   405 _STLP_MOVE_TO_PRIV_NAMESPACE
   406 template <class _Dummy>
   407 void _STLP_CALL
   408 __stl_debug_engine<_Dummy>::_Message(const char * __format_str, ...)
   409 {}
   410 _STLP_MOVE_TO_STD_NAMESPACE
   411 _STLP_END_NAMESPACE
   412 #    endif /* _STLP_DEBUG_MESSAGE */
   413 
   414 _STLP_BEGIN_NAMESPACE
   415 _STLP_MOVE_TO_PRIV_NAMESPACE
   416 
   417 template <class _Dummy>
   418 void _STLP_CALL
   419 __stl_debug_engine<_Dummy>::_IndexedError(int __error_ind, const char* __f, int __l) {
   420   __stl_debug_message(_Message_table[_StlFormat_ERROR_RETURN],
   421                       __f, __l, _Message_table[__error_ind]);
   422 }
   423 
   424 template <class _Dummy>
   425 void _STLP_CALL
   426 __stl_debug_engine<_Dummy>::_VerboseAssert(const char* __expr, int __error_ind, const char* __f, int __l) {
   427   __stl_debug_message(_Message_table[_StlFormat_VERBOSE_ASSERTION_FAILURE],
   428                       __f, __l, _Message_table[__error_ind], __f, __l, __expr);
   429   __stl_debug_terminate();
   430 }
   431 
   432 template <class _Dummy>
   433 void _STLP_CALL
   434 __stl_debug_engine<_Dummy>::_Assert(const char* __expr, const char* __f, int __l) {
   435   __stl_debug_message(_Message_table[_StlFormat_ASSERTION_FAILURE],__f, __l, __expr);
   436   __stl_debug_terminate();
   437 }
   438 
   439 // if exceptions are present, sends unique exception
   440 // if not, calls abort() to terminate
   441 template <class _Dummy>
   442 void _STLP_CALL
   443 __stl_debug_engine<_Dummy>::_Terminate()
   444 { _STLP_ABORT(); }
   445 
   446 _STLP_MOVE_TO_STD_NAMESPACE
   447 _STLP_END_NAMESPACE
   448 
   449 #  endif /* _STLP_ASSERTIONS */
   450 
   451 #  if defined (_STLP_DEBUG)
   452 
   453 _STLP_BEGIN_NAMESPACE
   454 _STLP_MOVE_TO_PRIV_NAMESPACE
   455 
   456 //==========================================================
   457 //  owned_list non-inline methods
   458 //==========================================================
   459 
   460 template <class _Dummy>
   461 void  _STLP_CALL
   462 __stl_debug_engine<_Dummy>::_Invalidate_all(__owned_list* __l) {
   463   _STLP_ACQUIRE_LOCK(__l->_M_lock);
   464   _Stamp_all(__l, 0);
   465   __l->_M_node._M_next =0;
   466   _STLP_RELEASE_LOCK(__l->_M_lock);
   467 }
   468 
   469 // boris : this is unasafe routine; should be used from within critical section only !
   470 template <class _Dummy>
   471 void  _STLP_CALL
   472 __stl_debug_engine<_Dummy>::_Stamp_all(__owned_list* __l, __owned_list* __o) {
   473   // crucial
   474   if (__l->_M_node._M_owner) {
   475     for (__owned_link*  __pos = (__owned_link*)__l->_M_node._M_next;
   476       __pos != 0; __pos = (__owned_link*)__pos->_M_next) {
   477       _STLP_ASSERT(__pos->_Owner()== __l)
   478       __pos->_M_owner=__o;
   479     }
   480   }
   481 }
   482 
   483 template <class _Dummy>
   484 void  _STLP_CALL
   485 __stl_debug_engine<_Dummy>::_Verify(const __owned_list* __l) {
   486   _STLP_ACQUIRE_LOCK(__l->_M_lock);
   487   if (__l) {
   488     _STLP_ASSERT(__l->_M_node._Owner() != 0)
   489     for (__owned_link* __pos = (__owned_link*)__l->_M_node._M_next;
   490          __pos != 0; __pos = (__owned_link*)__pos->_M_next) {
   491       _STLP_ASSERT(__pos->_Owner()== __l)
   492     }
   493   }
   494   _STLP_RELEASE_LOCK(__l->_M_lock);
   495 }
   496 
   497 template <class _Dummy>
   498 void _STLP_CALL
   499 __stl_debug_engine<_Dummy>::_Swap_owners(__owned_list& __x, __owned_list& __y) {
   500   /*
   501    *  according to the standard : --no swap() function invalidates any references,
   502    *  pointers,  or  iterators referring to the elements of the containers being swapped.
   503    */
   504 
   505   __owned_link* __tmp;
   506 
   507   /*
   508    * boris : there is a deadlock potential situation here if we lock two containers sequentially.
   509    * As user is supposed to provide its own synchronization around swap() ( it is unsafe to do any container/iterator access
   510    * in parallel with swap()), we just do not use any locking at all -- that behaviour is closer to non-debug version
   511    */
   512 
   513   __tmp = __x._M_node._M_next;
   514 
   515   _Stamp_all(&__x, &__y);
   516   _Stamp_all(&__y, &__x);
   517 
   518   __x._M_node._M_next = __y._M_node._M_next;
   519   __y._M_node._M_next = __tmp;
   520 }
   521 
   522 template <class _Dummy>
   523 void _STLP_CALL
   524 __stl_debug_engine<_Dummy>::_Set_owner(__owned_list& __src, __owned_list& __dst) {
   525   if (&__src == &__dst)
   526     return;
   527 
   528   // Check __stl_debug_engine<_Dummy>::_Swap_owners comments to see why there is no lock here
   529   typedef __owned_link _L_type;
   530   _L_type* __prev = &__src._M_node;
   531   _L_type* __pos = __prev->_M_next;
   532 
   533   while (__pos != 0) {
   534     __pos->_M_owner = &__dst;
   535     __prev = __pos;
   536     __pos = __prev->_M_next;
   537   }
   538   __prev->_M_next = __dst._M_node._M_next;
   539   __dst._M_node._M_next = __src._M_node._M_next;
   540   __src._M_node._M_next = 0;
   541 }
   542 
   543 template <class _Dummy>
   544 void _STLP_CALL
   545 __stl_debug_engine<_Dummy>::_M_detach(__owned_list* __l, __owned_link* __c_node) {
   546   if (__l  != 0) {
   547 
   548     _STLP_VERBOSE_ASSERT(__l->_Owner()!=0, _StlMsg_INVALID_CONTAINER)
   549 
   550     _STLP_ACQUIRE_LOCK(__l->_M_lock)
   551       // boris : re-test the condition in case someone else already deleted us
   552       if(__c_node->_M_owner != 0) {
   553         __owned_link* __prev, *__next;
   554 
   555         for (__prev = &__l->_M_node; (__next = __prev->_M_next) != __c_node;
   556              __prev = __next) {
   557           _STLP_ASSERT(__next && __next->_Owner() == __l)
   558             }
   559 
   560         __prev->_M_next = __c_node->_M_next;
   561         __c_node->_M_owner=0;
   562       }
   563     _STLP_RELEASE_LOCK(__l->_M_lock)
   564   }
   565 }
   566 
   567 template <class _Dummy>
   568 void _STLP_CALL
   569 __stl_debug_engine<_Dummy>::_M_attach(__owned_list* __l, __owned_link* __c_node) {
   570   if (__l ==0) {
   571     (__c_node)->_M_owner = 0;
   572   } else {
   573     _STLP_VERBOSE_ASSERT(__l->_Owner()!=0, _StlMsg_INVALID_CONTAINER)
   574     _STLP_ACQUIRE_LOCK(__l->_M_lock)
   575     __c_node->_M_owner = __l;
   576     __c_node->_M_next = __l->_M_node._M_next;
   577     __l->_M_node._M_next = __c_node;
   578     _STLP_RELEASE_LOCK(__l->_M_lock)
   579   }
   580 }
   581 
   582 template <class _Dummy>
   583 void* _STLP_CALL
   584 __stl_debug_engine<_Dummy>::_Get_container_ptr(const __owned_link* __l) {
   585   const __owned_list* __owner    = __l->_Owner();
   586   _STLP_VERBOSE_RETURN_0(__owner != 0, _StlMsg_INVALID_ITERATOR)
   587   void* __ret = __CONST_CAST(void*,__owner->_Owner());
   588   _STLP_VERBOSE_RETURN_0(__ret !=0, _StlMsg_INVALID_CONTAINER)
   589   return __ret;
   590 }
   591 
   592 template <class _Dummy>
   593 bool _STLP_CALL
   594 __stl_debug_engine<_Dummy>::_Check_same_owner(const __owned_link& __i1,
   595                                               const __owned_link& __i2) {
   596   _STLP_VERBOSE_RETURN(__i1._Valid(), _StlMsg_INVALID_LEFTHAND_ITERATOR)
   597   _STLP_VERBOSE_RETURN(__i2._Valid(), _StlMsg_INVALID_RIGHTHAND_ITERATOR)
   598   _STLP_VERBOSE_RETURN((__i1._Owner() == __i2._Owner()), _StlMsg_DIFFERENT_OWNERS)
   599   return true;
   600 }
   601 
   602 template <class _Dummy>
   603 bool _STLP_CALL
   604 __stl_debug_engine<_Dummy>::_Check_same_or_null_owner(const __owned_link& __i1,
   605                                                       const __owned_link& __i2) {
   606   _STLP_VERBOSE_RETURN(__i1._Owner() == __i2._Owner(), _StlMsg_DIFFERENT_OWNERS)
   607   return true;
   608 }
   609 
   610 template <class _Dummy>
   611 bool _STLP_CALL
   612 __stl_debug_engine<_Dummy>::_Check_if_owner( const __owned_list * __l, const __owned_link& __it) {
   613   const __owned_list* __owner_ptr = __it._Owner();
   614   _STLP_VERBOSE_RETURN(__owner_ptr != 0, _StlMsg_INVALID_ITERATOR)
   615   _STLP_VERBOSE_RETURN(__l == __owner_ptr, _StlMsg_NOT_OWNER)
   616   return true;
   617 }
   618 
   619 template <class _Dummy>
   620 bool _STLP_CALL
   621 __stl_debug_engine<_Dummy>::_Check_if_not_owner( const __owned_list * __l, const __owned_link& __it) {
   622   const __owned_list* __owner_ptr = __it._Owner();
   623   _STLP_VERBOSE_RETURN(__owner_ptr != 0, _StlMsg_INVALID_ITERATOR)
   624   _STLP_VERBOSE_RETURN(__l != __owner_ptr, _StlMsg_SHOULD_NOT_OWNER)
   625   return true;
   626 }
   627 
   628 _STLP_MOVE_TO_STD_NAMESPACE
   629 _STLP_END_NAMESPACE
   630 
   631 #  endif /* _STLP_DEBUG */
   632 
   633 #endif /* if defined (EXPOSE_GLOBALS_IMPLEMENTATION) */
   634 
   635 #endif /* header guard */
   636 
   637 // Local Variables:
   638 // mode:C++
   639 // End: