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     {    // delete from the debug CRT heap even if operator delete exists
56     if (_Ptr != 0)
57         {    // worth deleting
58         _Ptr->~_Ty();
59         // delete as _NORMAL_BLOCK, not _CRT_BLOCK, since we might have
60         // facets allocated by normal new.
61         free(_Ptr);
62         }
63     }
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))
Lines 83 ... 92 are skipped.
93         else if (((size_t)(-1) / _Count) < sizeof(_Ty))
94             _THROW_NCEE(std::bad_alloc, NULL);
95
96             // allocate array of _Count elements
97         return ((_Ty *)_NEW_CRT char[_Count * sizeof(_Ty)]);
98         }
99
100     void __CLR_OR_THIS_CALL deallocate(typename allocator<_Ty>::pointer _Ptr, typename allocator<_Ty>::size_type)
101         {    // deallocate object at _Ptr, ignore size
102         _DELETE_CRT_VEC(_Ptr);
103         }
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         {    // convert to a string
140         return (string(c_str()));
141         }
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 */
166