//////////////////////////////////////////////////////////////////////////////
//
// Asura_Mem.h
//
// Copyright (c) 2006 Rebellion. All rights reserved.
//
// Description:
//
//     wrappers for stdlib memory functions
//
//////////////////////////////////////////////////////////////////////////////

// B E G I N   F I L E   W R A P P E R ///////////////////////////////////////

#ifdef ASURA_USE_PRAGMA_ONCE
    #pragma once
#endif

#ifndef ___ASURA_MEM_H___
#define ___ASURA_MEM_H___ 1

//////////////////////////////////////////////////////////////////////////////
// Class declaration...
//////////////////////////////////////////////////////////////////////////////
class Asura_Mem
{
public:
    // Replacement for memcmp
	static int Compare(const void* pMem1, const void* pMem2, size_t uBytes);

	// Replacement for memcpy
	static void* Copy(void* pDest, const void* pSrc, size_t uBytes);

	// Replacement for memcpy, when faster version might not work due to restrictions
	static void* SafeCopy(void* pDest, const void* pSrc, size_t uBytes);

	// Use this instead of Copy when the ranges are overlapping.
	static void* Move(void* pDest, const void* pSrc, size_t uBytes);

	// Replacement for memset
	static void* Set(void* pMem, int iChar, size_t uCount);

	// Pre-fetch data function...
	static void PreFetchData(const void* pData, const u_int uNumBytes);

private:
	// Private variables...
#if defined(ASURA_SUPPORT_COMMAND_CONSOLE) && defined(ASURA_DEBUG_VARIABLE_SYSTEM)
	static bool	s_bEnablePrefetch;
#endif	//defined(ASURA_SUPPORT_COMMAND_CONSOLE) && defined(ASURA_DEBUG_VARIABLE_SYSTEM)

#if _DEBUG && defined(ASURA_ASSERT)
	// Validation functions...
	static void Check_Compare(const void* pMem1, const void* pMem2, size_t uBytes);
	static void Check_Copy(void* pDest, const void* pSrc, size_t uBytes);
	static void Check_SafeCopy(void* pDest, const void* pSrc, size_t uBytes);
	static void Check_Move(void* pDest, const void* pSrc, size_t uBytes);
	static void Check_Set(void* pMem, int iChar, size_t uCount);
#endif

	// Platform replacement for memcmp
	static int   Platform_Compare(const void* pMem1, const void* pMem2, size_t uBytes);

	// Platform replacement for memcpy
	static void* Platform_Copy(void* pDest, const void* pSrc, size_t uBytes);

	// Platform replacement for safe memcpy
	static void* Platform_SafeCopy(void* pDest, const void* pSrc, size_t uBytes);

	// Platform replacement for memmove
	static void* Platform_Move(void* pDest, const void* pSrc, size_t uBytes);

	// Platform replacement for memset
	static void* Platform_Set(void* pMem, int iChar, size_t uCount);

	// Platform pre-fetch function...
	static void Platform_PreFetchData(const void* pData, const u_int uNumBytes);
};

//////////////////////////////////////////////////////////////////////////////
// Inlined functions...
//////////////////////////////////////////////////////////////////////////////
inline int Asura_Mem::Compare(const void* pMem1, const void* pMem2, size_t uBytes)
{
#if _DEBUG && defined(ASURA_ASSERT)
	Check_Compare( pMem1, pMem2, uBytes );
#endif
	return Platform_Compare( pMem1, pMem2, uBytes );
}

inline void* Asura_Mem::Copy(void* pDest, const void* pSrc, size_t uBytes)
{
#if _DEBUG && defined(ASURA_ASSERT)
	Check_Copy( pDest, pSrc, uBytes );
#endif
	return Platform_Copy( pDest, pSrc, uBytes );
}

inline void* Asura_Mem::SafeCopy(void* pDest, const void* pSrc, size_t uBytes)
{
#if _DEBUG && defined(ASURA_ASSERT)
	Check_SafeCopy( pDest, pSrc, uBytes );
#endif
	return Platform_SafeCopy( pDest, pSrc, uBytes );
}

inline void* Asura_Mem::Move(void* pDest, const void* pSrc, size_t uBytes)
{
#if _DEBUG && defined(ASURA_ASSERT)
	Check_Move( pDest, pSrc, uBytes );
#endif
	return Platform_Move( pDest, pSrc, uBytes );
}

inline void* Asura_Mem::Set(void* pMem, int iChar, size_t uCount)
{
#if _DEBUG && defined(ASURA_ASSERT)
	Check_Set( pMem, iChar, uCount );
#endif
	return Platform_Set( pMem, iChar, uCount );
}

inline void Asura_Mem::PreFetchData(const void* pData, const u_int uNumBytes)
{
#if defined(ASURA_SUPPORT_COMMAND_CONSOLE) && defined(ASURA_DEBUG_VARIABLE_SYSTEM)
	if(s_bEnablePrefetch)
#endif	//defined(ASURA_SUPPORT_COMMAND_CONSOLE) && defined(ASURA_DEBUG_VARIABLE_SYSTEM)
	{
		Platform_PreFetchData(pData, uNumBytes);
	}
}


//////////////////////////////////////////////////////////////////////////////
// Platform specific implementations...
//////////////////////////////////////////////////////////////////////////////
#include "Core/Memory/Asura_Platform_Mem.h"


// E N D   F I L E   W R A P P E R ///////////////////////////////////////////

#endif // #ifndef ___ASURA_MEM_H___


/// End of file. ///
