1 : // debug heap support header for Microsoft
2 : #pragma once
3 : #ifndef _XDEBUG_
4 : #define _XDEBUG_
5 : #ifndef RC_INVOKED
6 : #include <yvals.h>
7 :
8 : #ifdef _MSC_VER
9 : #pragma pack(push,_CRT_PACKING)
10 : #pragma warning(push,3)
11 : #endif /* _MSC_VER */
12 :
13 : _STD_BEGIN
14 : struct _DebugHeapTag_t
15 : { // placement new tag type to select debug CRT heap
16 : int _Type;
17 : };
18 : _STD_END
19 :
20 : // SUPPORT FOR DEBUG HEAP
21 :
22 : #if defined(_DEBUG)
23 : #define _NEW_CRT new(std::_DebugHeapTag_func(), __FILE__, __LINE__)
24 : #define _DELETE_CRT(ptr) std::_DebugHeapDelete(ptr)
25 : #define _DELETE_CRT_VEC(ptr) std::_DebugHeapDelete((void *)ptr)
26 : #define _STRING_CRT _DebugHeapString
27 :
28 : #include <crtdbg.h>
29 : #include <xmemory>
30 : #include <xstring>
31 :
32 : _Ret_bytecap_(_Size) _MRTIMP2 void * __cdecl operator new(size_t _Size,
33 : const std::_DebugHeapTag_t&, _In_opt_z_ char *, int)
34 : _THROW_BAD_ALLOC; // allocate from the debug CRT heap
35 :
36 : _Ret_bytecap_(_Size) _MRTIMP2 void * __cdecl operator new[](size_t _Size,
37 : const std::_DebugHeapTag_t&, _In_opt_z_ char *, int)
38 : _THROW_BAD_ALLOC; // allocate array from the debug CRT heap
39 :
40 : _MRTIMP2 void __cdecl operator delete(void *,
41 : const std::_DebugHeapTag_t&, _In_opt_z_ char *, int)
42 : _THROW0(); // delete if new for debug CRT heap fails
43 :
44 : _MRTIMP2 void __cdecl operator delete[](void *,
45 : const std::_DebugHeapTag_t&, _In_opt_z_ char *, int)
46 : _THROW0(); // delete if array new for debug CRT heap fails
47 :
48 : _STD_BEGIN
49 :
50 : _MRTIMP2 const _DebugHeapTag_t& __cdecl _DebugHeapTag_func();
51 :
52 : // TEMPLATE FUNCTION _DebugHeapDelete
53 : template<class _Ty>
54 : void __CLRCALL_OR_CDECL _DebugHeapDelete(_Ty *_Ptr)
55 29 : { // delete from the debug CRT heap even if operator delete exists
56 29 : if (_Ptr != 0)
57 : { // worth deleting
58 20 : _Ptr->~_Ty();
59 : // delete as _NORMAL_BLOCK, not _CRT_BLOCK, since we might have
60 : // facets allocated by normal new.
61 29 : free(_Ptr);
62 : }
63 29 : }
64 :
65 : // TEMPLATE CLASS _DebugHeapAllocator
66 : template<class _Ty>
67 : class _DebugHeapAllocator
68 : : public allocator<_Ty>
69 : { // an allocator which uses the debug CRT heap
70 : public:
71 :
72 : template<class _Other>
73 : struct rebind
74 : { // convert _DebugHeapAllocator<_Ty> to _DebugHeapAllocator<_Other>
75 : typedef typename _DebugHeapAllocator<_Other> other;
76 : };
77 :
78 : typename allocator<_Ty>::pointer __CLRCALL_OR_CDECL allocate(typename allocator<_Ty>::size_type _Count, const void *)
79 : { // check for integer overflow
80 : if (_Count <= 0)
81 : _Count = 0;
82 : else if (((size_t)(-1) / _Count) < sizeof(_Ty))
83 : _THROW_NCEE(std::bad_alloc, NULL);
84 :
85 : // allocate array of _Count elements, ignore hint
86 : return ((_Ty *)_NEW_CRT char[_Count * sizeof(_Ty)]);
87 : }
88 :
89 : typename allocator<_Ty>::pointer __CLR_OR_THIS_CALL allocate(typename allocator<_Ty>::size_type _Count)
90 0 : { // check for integer overflow
91 0 : if (_Count <= 0)
92 0 : _Count = 0;
93 0 : else if (((size_t)(-1) / _Count) < sizeof(_Ty))
94 0 : _THROW_NCEE(std::bad_alloc, NULL);
95 :
96 : // allocate array of _Count elements
97 0 : return ((_Ty *)_NEW_CRT char[_Count * sizeof(_Ty)]);
98 0 : }
99 :
100 : void __CLR_OR_THIS_CALL deallocate(typename allocator<_Ty>::pointer _Ptr, typename allocator<_Ty>::size_type)
101 0 : { // deallocate object at _Ptr, ignore size
102 0 : _DELETE_CRT_VEC(_Ptr);
103 0 : }
104 : };
105 :
106 : template class _CRTIMP2_PURE _DebugHeapAllocator<char>;
107 :
108 : // CLASS _DebugHeapString
109 : class _CRTIMP2_PURE _DebugHeapString
110 : : public basic_string<char, char_traits<char>, _DebugHeapAllocator<char> >
111 : { // a version of std::string allocated on the debug CRT heap
112 : public:
113 : typedef _DebugHeapString _Myt;
114 : typedef basic_string<char, char_traits<char>, _DebugHeapAllocator<char> >
115 : _Mybase;
116 : typedef char _Elem;
117 :
118 : __CLR_OR_THIS_CALL _DebugHeapString()
119 : : _Mybase()
120 : { // construct empty string
121 : }
122 :
123 : __CLR_OR_THIS_CALL _DebugHeapString(const _Myt& _Right)
124 : : _Mybase(_Right)
125 : { // construct by copying _Right
126 : }
127 :
128 : __CLR_OR_THIS_CALL _DebugHeapString(const _Elem *_Ptr)
129 : : _Mybase(_Ptr)
130 : { // construct from [_Ptr, <null>)
131 : }
132 :
133 : __CLR_OR_THIS_CALL _DebugHeapString(const string &_Str)
134 : : _Mybase(_Str.c_str())
135 : { // construct from std::string
136 : }
137 :
138 : __CLR_OR_THIS_CALL operator string() const
139 10 : { // convert to a string
140 10 : return (string(c_str()));
141 10 : }
142 : };
143 : _STD_END
144 :
145 : #else /* defined(_DEBUG) */
146 : #define _NEW_CRT new
147 : #define _DELETE_CRT(ptr) delete (ptr)
148 : #define _DELETE_CRT_VEC(ptr) delete[] (ptr)
149 : #define _STRING_CRT string
150 : #endif /* defined(_DEBUG) */
151 :
152 :
153 : #ifdef _MSC_VER
154 : #pragma warning(pop)
155 : #pragma pack(pop)
156 : #endif /* _MSC_VER */
157 :
158 :
159 : #endif /* RC_INVOKED */
160 : #endif /* _XDEBUG_ */
161 :
162 : /*
163 : * Copyright (c) 1992-2007 by P.J. Plauger. ALL RIGHTS RESERVED.
164 : * Consult your license regarding permissions and restrictions.
165 : V5.03:0009 */
|