//*******************************************************************
//
// File: Asura_Platform_Atomic.h
//
// Created: 29 June 2007 DLH
//
// Description: 
//
//*******************************************************************

#ifndef __ASURA_PLATFORM_ATOMIC_H__
#define __ASURA_PLATFORM_ATOMIC_H__

// other libraries

// internal dependencies

// forward declarations

//*******************************************************************
// Constants
//*******************************************************************


//*******************************************************************
// Class Definitions
//*******************************************************************


//*******************************************************************
// Inline Function Definitions
//*******************************************************************

template< class T>
inline T* Asura_Atomic::CompareAndSwapPointer( T* volatile &ptPointer, T* pxCompare, T* pxSet)
{
	void** ppPointer = (void**)( &ptPointer);
	
	void* pSet = static_cast< void*>( pxSet);
	void* pCompare = static_cast< void*>( pxCompare);
	
	void* pOriginal = InterlockedCompareExchangePointer( ppPointer, pSet, pCompare);
	T* ptOriginal = static_cast< T*>( pOriginal);
	
	return( ptOriginal);
}

template< class T>
inline T* Asura_Atomic::ExchangePointer( T* volatile &ptPointer, T* ptNew)
{
	void** ppPointer = (void**)( &ptPointer);
	
	void* pNew = static_cast< void*>( ptNew);
	
	void* pOriginal = InterlockedExchangePointer( ppPointer, pNew);
	T* ptOriginal = static_cast< T*>( pOriginal);
	
	return( ptOriginal);
}

inline u_int Asura_Atomic::CompareAndSwap( u_int volatile &uPointer, const u_int uCompare, const u_int uSet)
{
	LONG* piPointer = (LONG*)( &uPointer);
	
	u_int uOriginal = InterlockedCompareExchange( piPointer, uSet, uCompare);
	
	return( uOriginal);
}

inline int Asura_Atomic::CompareAndSwap( int volatile &iPointer, const int iCompare, const int iSet)
{
	LONG* piPointer = (LONG*)( &iPointer);
	
	int iOriginal = InterlockedCompareExchange( piPointer, iSet, iCompare);
	
	return( iOriginal);
}

inline int Asura_Atomic::Increment( u_int volatile &uVariable)
{
	LONG* piVariable = (LONG*)&uVariable;
	return( InterlockedIncrement( piVariable));
}

inline int Asura_Atomic::Decrement( u_int volatile &uVariable)
{
	LONG* piVariable = (LONG*)&uVariable;
	return( InterlockedDecrement( piVariable));
}

inline int Asura_Atomic::Increment( int volatile &iVariable)
{
	LONG* piVariable = (LONG*)&iVariable;
	return( InterlockedIncrement( piVariable));
}

inline int Asura_Atomic::Decrement( int volatile &iVariable)
{
	LONG* piVariable = (LONG*)&iVariable;
	return( InterlockedDecrement( piVariable));
}

//*******************************************************************
//
// (c) 2006 Rebellion
//
// Warning: This computer program is protected by copyright law and 
// international treaties. Unauthorized reproduction or distribution
// of this program, or any portion of it, may result in severe civil and
// criminal penalties, and will be prosecuted to the maximum extent 
// possible under the law.
//
//*******************************************************************

#endif // __ASURA_PLATFORM_ATOMIC_H__
