49 #define REPLACE(what, with)\
50 else if(!wcsncmp(src, (what), ARRAY_SIZE(what)-1))\
52 src += ARRAY_SIZE(what)-1-1; \
53 wcscpy_s(dst, ARRAY_SIZE(with), (with));\
54 dst += ARRAY_SIZE(with)-1;\
57 else if(!wcsncmp(src, (what), ARRAY_SIZE(what)-1))\
59 src += ARRAY_SIZE(what)-1-1;\
61 #define STRIP_NESTED(what)\
62 else if(!wcsncmp(src, (what), ARRAY_SIZE(what)-1))\
65 if(src != name && src[-1] == ',')\
67 src += ARRAY_SIZE(what)-1;\
69 ENSURE(nesting == 0);\
86 const wchar_t* src = name-1;
123 else if(!wcsncmp(src, L
"::_Node", 7))
127 if(src != name && src[-1] !=
' ')
131 REPLACE(L
"unsigned short", L
"u16")
132 REPLACE(L
"unsigned int", L
"size_t")
133 REPLACE(L
"unsigned __int64", L
"u64")
141 REPLACE(L
"std::_List_nod", L
"list")
142 REPLACE(L
"std::_Tree_nod", L
"map")
143 REPLACE(L
"std::basic_string<char, ", L
"string<")
144 REPLACE(L
"std::basic_string<__wchar_t, ", L
"wstring<")
145 REPLACE(L
"std::basic_string<unsigned short, ", L
"wstring<")
146 STRIP(L
"std::char_traits<char>, ")
147 STRIP(L
"std::char_traits<unsigned short>, ")
148 STRIP(L
"std::char_traits<__wchar_t>, ")
149 STRIP(L
"std::_Tmap_traits")
150 STRIP(L
"std::_Tset_traits")
212 template<
class Container>
227 const u8* p = (
const u8*)&*it;
236 #if STL_DINKUMWARE == 405
238 bool IsValid(
size_t el_size)
const
240 const size_t el_per_bucket = ElementsPerBucket(el_size);
242 if(_Myoff >= el_per_bucket)
245 if(_Mysize > _Mapsize * el_per_bucket)
253 struct Iterator :
public iterator
260 size_t CurrentIndex()
const
266 Iterator& it = *(Iterator*)&stl_it;
268 const size_t currentIndex = it.CurrentIndex();
269 const u8* p = container.GetNthElement(currentIndex, el_size);
275 static size_t ElementsPerBucket(
size_t el_size)
277 return std::max(16u / el_size, (
size_t)1u);
280 const u8* GetNthElement(
size_t i,
size_t el_size)
const
282 const size_t el_per_bucket = ElementsPerBucket(el_size);
283 const size_t bucket_idx = i / el_per_bucket;
284 ENSURE(bucket_idx < _Mapsize);
285 const size_t idx_in_bucket = i - bucket_idx * el_per_bucket;
286 ENSURE(idx_in_bucket < el_per_bucket);
287 const u8** map = (
const u8**)_Map;
288 const u8* bucket = map[bucket_idx];
289 const u8* p = bucket + idx_in_bucket*el_size;
302 #if STL_DINKUMWARE == 405
304 template<
class _Traits>
305 struct Any_tree :
public std::_Tree<_Traits>
311 bool IsValid(
size_t UNUSED(el_size))
const
316 size_t NumElements(
size_t UNUSED(el_size))
const
321 static const u8* DereferenceAndAdvance(iterator& stl_it,
size_t el_size)
323 struct Iterator :
public const_iterator
325 _Nodeptr
Node()
const
330 void SetNode(_Nodeptr node)
336 Iterator& it = *(Iterator*)&stl_it;
337 _Nodeptr node = it.Node();
338 const u8* p = (
const u8*)&*it;
341 if(_Isnil(node, el_size))
345 _Nodeptr _Pnode = _Right(node);
346 if(!_Isnil(_Pnode, el_size))
348 while(!_Isnil(_Left(_Pnode), el_size))
349 _Pnode = _Left(_Pnode);
354 while (!_Isnil(_Pnode = _Parent(node), el_size) && node == _Right(_Pnode))
365 static _Charref _Isnil(_Nodeptr _Pnode,
size_t el_size)
367 const u8* p = (
const u8*)&_Pnode->_Isnil;
368 p += el_size -
sizeof(value_type);
375 struct Any_map :
public Any_tree<std::_Tmap_traits<int, int, std::less<int>, std::allocator<std::pair<const int, int> >, false> >
380 struct Any_multimap :
public Any_map
385 struct Any_set:
public Any_tree<std::_Tset_traits<int, std::less<int>, std::allocator<int>, false> >
390 struct Any_multiset:
public Any_set
402 if(size() > capacity())
405 if(&front() > &back())
410 #if STL_DINKUMWARE == 405
418 return ((
u8*)_Mylast - (
u8*)_Myfirst) * el_size;
423 struct Iterator :
public const_iterator
425 void Advance(
size_t numBytes)
427 (
u8*&)_Myptr += numBytes;
431 Iterator& it = *(Iterator*)&stl_it;
432 const u8* p = (
const u8*)&*it;
441 #if STL_DINKUMWARE == 405
445 bool IsValid(
size_t el_size)
const
448 if(_Myres < (16/el_size)-1)
484 typedef typename T::iterator iterator;
485 iterator& stl_it = *(iterator*)it_mem;
486 return T::DereferenceAndAdvance(stl_it, el_size);
498 if(el_count > 0x1000000)
504 const u8* front = (
const u8*)&*t.begin();
522 typedef typename T::iterator iterator;
523 typedef typename T::const_iterator const_iterator;
528 el_count = t.NumElements(el_size);
534 el_iterator = stl_iterator<T>;
539 new(it_mem) const_iterator(t.begin());
550 size_t el_size,
size_t* el_count,
DebugStlIterator* el_iterator,
void* it_mem)
552 #if MSC_VERSION >= 1400
563 bool handled =
false, IsValid =
false;
564 #define CONTAINER(name, type_name_pattern)\
565 else if(match_wildcard(type_name, type_name_pattern))\
568 IsValid = get_container_info<Any_##name>(*(Any_##name*)p, size, el_size, *el_count, *el_iterator, it_mem);\
570 #define STD_CONTAINER(name) CONTAINER(name, L"std::" WIDEN(#name) L"<*>")
576 #define STRINGIZE2(id) # id
577 #define STRINGIZE(id) STRINGIZE2(id)
584 #if STL_DINKUMWARE == 405
595 CONTAINER(queue, L
"std::queue<*,std::deque<*> >")
596 CONTAINER(stack, L
"std::stack<*,std::deque<*> >")
const Status STL_CNT_UNSUPPORTED
size_t NumElements(size_t el_size) const
#define UNUSED(param)
mark a function parameter as unused and avoid the corresponding compiler warning. ...
static bool IsContainerValid(const T &t, size_t el_count)
const Status STL_CNT_INVALID
bool IsValid(size_t el_size) const
static const u8 * DereferenceAndAdvance(typename Container::iterator &it, size_t el_size)
wchar_t * debug_stl_simplify_name(wchar_t *name)
reduce complicated STL symbol names to human-readable form.
bool get_container_info(const T &t, size_t size, size_t el_size, size_t &el_count, DebugStlIterator &el_iterator, void *it_mem)
#define ENSURE(expr)
ensure the expression <expr> evaluates to non-zero.
Status debug_stl_get_container_info(const wchar_t *type_name, const u8 *p, size_t size, size_t el_size, size_t *el_count, DebugStlIterator *el_iterator, void *it_mem)
prepare to enumerate the elements of arbitrarily typed STL containers.
const u8 * stl_iterator(void *it_mem, size_t el_size)
#define UNUSED2(param)
mark a function local variable or parameter as unused and avoid the corresponding compiler warning...
LIB_API int debug_IsPointerBogus(const void *p)
check if a pointer appears to be totally invalid.
static const StatusDefinition debugStlStatusDefinitions[]
#define CONTAINER(name, type_name_pattern)
#define STRIP_NESTED(what)
i64 Status
Error handling system.
#define STD_CONTAINER(name)
#define T(string_literal)
#define REPLACE(what, with)
#define STATUS_ADD_DEFINITIONS(definitions)
add a module's array of StatusDefinition to the list.
const size_t DEBUG_STL_MAX_ITERATOR_SIZE
no STL iterator is larger than this; see below.
bool IsValid(size_t el_size) const
const u8 *(* DebugStlIterator)(void *internal, size_t el_size)
abstraction of all STL iterators used by debug_stl.
const Status STL_CNT_UNKNOWN