//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
//
// CommonHelpers satellite library | Author: Sergei Y.Kitáev
//
// TYPIFIED POINTER HELPERS / 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 const T* HTPointer::GetNullValueC()
{
   return (const T*)HUnsafePtr::NullValue;
}

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

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

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

template<typename T>static const T* HTPointer::NullValueExchangeC(const T*% operand)
{
   return ExchangeC<T>( operand, GetNullValueC<T>() );
}

template<typename T>static const T* HTPointer::AllBitsValueExchangeC(const T*% operand)
{
   return ExchangeC<T>( operand, GetAllBitsValueC<T>() );
}

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

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

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

template<typename T>static const T* HTPointer::IsNullSubstitutionC( const T* value,
                                                                    const T* subst )
{
   return XValueSubstitutionC<T>( value, GetNullValueC<T>(), subst );
}

template<typename T>static const T* HTPointer::SubstiteNullValueC( const T*% operand,
                                                                    const T* subst )
{
   return SubstituteXValueС<T>( operand, GetNullValueC<T>(), subst );
}

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

template<typename T>static const T* HTPointer::AllBitsValueSubstitutionC( const T* value,
                                                                          const T* subst )
{
   return XValueSubstitutionС<T>( value, GetAllBitsValueC<T>(), subst );
}

template<typename T>static const T* HTPointer::SubstiteAllBitsValueC( const T*% operand,
                                                                      const T* subst )
{
   return SubstituteXValueC<T>( operand, GetAllBitsValueC<T>(), subst );
}

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

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

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

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

template<typename T>static const T* HTPointer::InterlockedExchangeC(
   $INOUT const T* volatile* pConstPointerOperand,
   const T* substutionConstPointerValue )
{
   return (const T*)HUnsafePtr::_InterlockedExchange(
      ($PPVOID)pConstPointerOperand, ($PVOID)substutionConstPointerValue );
}

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

template<typename T>static const T* HTPointer::InterlockedNullValueExchangeC(
   $INOUT const T* volatile* pConstPointerOperand )
{
   return InterlockedExchangeC<T>( pConstPointerOperand, GetNullValueC<T>() );
}

template<typename T>static const T* HTPointer::InterlockedAllBitsValueExchangeC(
   $INOUT const T* volatile* pConstPointerOperand )
{
   return InterlockedExchangeC<T>( pConstPointerOperand, GetAllBitsValueC<T>() );
}

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