// RuntimeForStatic base library | C+- (SysRoutine) | Author: Sergei Y.Kitáev
#include "Precompiled.h"
#include "SharedIncludes.h"
namespace RuntimeForStatic {
//==================================================================================================

bool $Handle::IsValid(HANDLE value,bool isOfInvalidHandleValueCategory)
{
   return isOfInvalidHandleValueCategory ? value != INVALID_HANDLE_VALUE : $BOOL( value );
}

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

HANDLE $Handle::Exchange(HANDLE& location,HANDLE value) $ret_previous
{
   return $subst::Exchange( location, value );
}
HANDLE $Handle::CompareExchange(HANDLE& location,HANDLE exchange,HANDLE comparand)
{
   return $subst::CompareExchange( location, exchange, comparand );
}

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

HANDLE $Handle::SetNull(HANDLE& target) $ret_target
{
   return target = nullptr;
}
HANDLE $Handle::SetInvalidValue(HANDLE& target) $ret_target
{
   return target = INVALID_HANDLE_VALUE;
}

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

HANDLE $Handle::NullExchange(HANDLE& location) $ret_previous
{
   return $subst::NullExchange( location );
}
HANDLE $Handle::InvalidValueExchange(HANDLE& location) $ret_previous
{
   return $subst::Exchange( location, INVALID_HANDLE_VALUE );
}

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

HANDLE $Handle::Read($A,HANDLE volatile* pSource)
{
   return $Interlocked::ReadPointer($ci, pSource );
}
HANDLE $Handle::Write($A,HANDLE volatile* pTarget,HANDLE value) $ret_target
{
   return $Interlocked::WritePointer($ci, pTarget, value );
}

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

HANDLE $Handle::Exchange($A,HANDLE volatile* pLocation,HANDLE value) $ret_previous
{
   return $Interlocked::ExchangePointer($ci, pLocation, value );
}
HANDLE $Handle::CompareExchange($A, HANDLE volatile* pLocation,
                                    HANDLE exchange, HANDLE comparand )
{
   return $Interlocked::CompareExchangePointer($ci, pLocation, exchange, comparand );
}

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

HANDLE $Handle::SetNull($A,HANDLE volatile* pTarget) $ret_target
{
   return Write($ci, pTarget, nullptr );
}
HANDLE $Handle::SetInvalidValue($A,HANDLE volatile* pTarget) $ret_target
{
   return Write($ci, pTarget, INVALID_HANDLE_VALUE );
}

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

HANDLE $Handle::NullExchange($A,HANDLE volatile* pLocation) $ret_previous
{
   return Exchange($ci, pLocation, nullptr );
}
HANDLE $Handle::InvalidValueExchange($A,HANDLE volatile* pLocation) $ret_previous
{
   return Exchange($ci, pLocation, INVALID_HANDLE_VALUE );
}

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

bool $Handle::Close(HANDLE& handle) $last_error
{
   return Close( handle, false );
}
bool $Handle::Close(HANDLE& handle,bool isOfInvalidHandleValueCategory) $last_error
{
   bool rslt = DoClose( handle, isOfInvalidHandleValueCategory );
   handle = isOfInvalidHandleValueCategory ? INVALID_HANDLE_VALUE : nullptr;
   return rslt;
}

bool $Handle::Close($OA,HANDLE volatile* pHandle) $last_error
{
   return Close($ci, pHandle, false );
}
bool $Handle::Close($OA,HANDLE volatile* pHandle,bool isOfInvalidHandleValueCategory) $last_error
{
   $$VERIFY_POINTER_ARG( pHandle );
   HANDLE handle = Exchange($, pHandle,
      isOfInvalidHandleValueCategory ? INVALID_HANDLE_VALUE : nullptr );
   return DoClose( handle, isOfInvalidHandleValueCategory );
}

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

bool $Handle::DoClose(HANDLE handle,bool isOfInvalidHandleValueCategory) $last_error
{
   return !IsValid( handle, isOfInvalidHandleValueCategory ) || ::CloseHandle( handle ) ?
      $SUCCEED_LE() : $SET_FROM_SYSTEM_LE();
}

//==================================================================================================
} // RuntimeForStatic
