// debug heap support header for Microsoft
#pragma once
#ifndef _XDEBUG_
#define _XDEBUG_
#ifndef RC_INVOKED
#include <yvals.h>

 #pragma pack(push,_CRT_PACKING)
 #pragma warning(push,3)

 #pragma push_macro("new")
  #undef new
 #pragma push_macro("free")
  #undef free

_STD_BEGIN
struct _DebugHeapTag_t
	{	// placement new tag type to select debug CRT heap
	int _Type;
	};
_STD_END

		// SUPPORT FOR DEBUG HEAP

 #if defined(_DEBUG)
   #define _NEW_CRT				new(_STD _DebugHeapTag_func(), __FILE__, __LINE__)
   #define _DELETE_CRT(ptr)		_STD _DebugHeapDelete(ptr)
   #define _DELETE_CRT_VEC(ptr)	_STD _DebugHeapDelete((void *)ptr)

  #include <crtdbg.h>
  #include <xmemory>

_Ret_bytecap_(_Size) _MRTIMP2 void * __cdecl operator new(size_t _Size,
	const _STD _DebugHeapTag_t&, _In_opt_z_ char *, int)
		_THROW_BAD_ALLOC;	// allocate from the debug CRT heap

_Ret_bytecap_(_Size) _MRTIMP2 void * __cdecl operator new[](size_t _Size,
	const _STD _DebugHeapTag_t&, _In_opt_z_ char *, int)
		_THROW_BAD_ALLOC;	// allocate array from the debug CRT heap

_MRTIMP2 void __cdecl operator delete(void *,
	const _STD _DebugHeapTag_t&, _In_opt_z_ char *, int)
		_THROW0();	// delete if new for debug CRT heap fails

_MRTIMP2 void __cdecl operator delete[](void *,
	const _STD _DebugHeapTag_t&, _In_opt_z_ char *, int)
		_THROW0();	// delete if array new for debug CRT heap fails

_STD_BEGIN

_MRTIMP2 const _DebugHeapTag_t& __cdecl _DebugHeapTag_func();

		// TEMPLATE FUNCTION _DebugHeapDelete
template<class _Ty>
	void __CLRCALL_OR_CDECL _DebugHeapDelete(_Ty *_Ptr)
	{	// delete from the debug CRT heap even if operator delete exists
	if (_Ptr != 0)
		{	// worth deleting
		_Ptr->~_Ty();
		// delete as _NORMAL_BLOCK, not _CRT_BLOCK, since we might have
		// facets allocated by normal new.
		free(_Ptr);
		}
	}

_STD_END

  #else /* defined(_DEBUG) */
   #define _NEW_CRT				new
   #define _DELETE_CRT(ptr)		delete (ptr)
   #define _DELETE_CRT_VEC(ptr)	delete[] (ptr)
  #endif /* defined(_DEBUG) */

 #pragma pop_macro("new")
 #pragma pop_macro("free")

 #pragma warning(pop)
 #pragma pack(pop)


#endif /* RC_INVOKED */
#endif  /* _XDEBUG_ */

/*
 * Copyright (c) 1992-2007 by P.J. Plauger.  ALL RIGHTS RESERVED.
 * Consult your license regarding permissions and restrictions.
 V5.03:0009 */
