//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
//
// CommonHelpers satellite library | Author: Sergei Y.Kitáev
//
// TYPIFIED POINTER HELPERS / NOT TO CONST. (TEMPLATE IMPLEMENTATION):
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#pragma once
#ifndef HTEMPLATES_IMPL_H
   #error "This header file is designed to be included only from 'HTemplates.Impl.h'."
#endif
namespace CommonHelpers {
//==================================================================================================

template<typename T>static T* HTPointer::GetNullValue()
{
   return (T*)HUnsafePtr::NullValue;
}

template<typename T>static T* HTPointer::GetAllBitsValue()
{
   return (T*)HUnsafePtr::AllBitsValue;
}

//==================================================================================================

template<typename T>static T* HTPointer::Exchange(T*% operand,T* value)
{
   T* prev=operand; operand=value; return prev;
}

template<typename T>static T* HTPointer::NullValueExchange(T*% operand)
{
   return Exchange<T>( operand, GetNullValue<T>() );
}

template<typename T>static T* HTPointer::AllBitsValueExchange(T*% operand)
{
   return Exchange<T>( operand, GetAllBitsValue<T>() );
}

//--------------------------------------------------------------------------------------------------

template<typename T>static void HTPointer::Swap(T*% operand_1,T*% operand_2)
{
   T* temp=operand_1; operand_1=operand_2; operand_2=temp;
}

//==================================================================================================

template<typename T>static T* HTPointer::IsNullSubstitution(T* value,T* subst)
{
   return XValueSubstitution<T>( value, GetNullValue<T>(), subst );
}

template<typename T>static T* HTPointer::SubstiteNullValue(T*% operand,T* subst)
{
   return SubstituteXValue<T>( operand, GetNullValue<T>(), subst );
}

//--------------------------------------------------------------------------------------------------

template<typename T>static T* HTPointer::AllBitsValueSubstitution(T* value,T* subst)
{
   return XValueSubstitution<T>( value, GetAllBitsValue<T>(), subst );
}

template<typename T>static T* HTPointer::SubstiteAllBitsValue(T*% operand,T* subst)
{
   return SubstituteXValue<T>( operand, GetAllBitsValue<T>(), subst );
}

//--------------------------------------------------------------------------------------------------

template<typename T>static T* HTPointer::XValueSubstitution(T* value,T* xValue,T* subst)
{
   return value!=xValue ? value : subst;
}

template<typename T>static T* HTPointer::SubstituteXValue(T*% operand,T* xValue,T* subst)
{
   return operand!=xValue ? operand : operand=subst;
}

//==================================================================================================

template<typename T>static T* HTPointer::_InterlockedExchange(
   $INOUT T* volatile* pPointerOperand, T* substutionPointerValue )
{
   return (T*)HUnsafePtr::_InterlockedExchange(
      ($PPVOID)pPointerOperand, substutionPointerValue );
}

//--------------------------------------------------------------------------------------------------

template<typename T>static T* HTPointer::InterlockedNullValueExchange(
   $INOUT T* volatile* pPointerOperand )
{
   return _InterlockedExchange<T>( pPointerOperand, GetNullValue<T>() );
}

template<typename T>static T* HTPointer::InterlockedAllBitsValueExchange(
   $INOUT T* volatile* pPointerOperand )
{
   return _InterlockedExchange<T>( pPointerOperand, GetAllBitsValue<T>() );
}

//==================================================================================================
} // CommonHelpers
