//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// CommonHelpers satellite library | Author: Sergei Y.Kitáev
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
using System;
using System.Threading;

#if !WASM
namespace CommonHelpers {
#else
namespace CommonHelpers.WASM {
#endif

//**************************************************************************************************
/// <summary>
/// </summary>
[CLSCompliant(false)]
public static partial class HUIntPtr {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public static readonly UIntPtr
   AllBitsValue = (UIntPtr)(-1);

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

public static UIntPtr Exchange([HVolatileAccess] ref UIntPtr operand,UIntPtr value)
{
   UIntPtr prev = Thread.VolatileRead( ref operand );
   Thread.VolatileWrite( ref operand, value );
   return prev;
}

public static UIntPtr ZeroValueExchange([HVolatileAccess] ref UIntPtr operand)
{
   return Exchange(ref operand,UIntPtr.Zero);
}

public static UIntPtr AllBitsValueExchange([HVolatileAccess] ref UIntPtr operand)
{
   return Exchange(ref operand,AllBitsValue);
}

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

public static void Swap( [HVolatileAccess] ref UIntPtr operand_1,
                         [HVolatileAccess] ref UIntPtr operand_2 )
{
   UIntPtr temp = Thread.VolatileRead( ref operand_1 );
   Thread.VolatileWrite( ref operand_1, Thread.VolatileRead(ref operand_2) );
   Thread.VolatileWrite( ref operand_2, temp );
}

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

public static UIntPtr ZeroValueSubstitution(UIntPtr value,UIntPtr subst)
{
   return XValueSubstitution(value,UIntPtr.Zero,subst);
}

public static UIntPtr SubstiteZeroValue([HVolatileAccess] ref UIntPtr operand,UIntPtr subst)
{
   return SubstituteXValue(ref operand,UIntPtr.Zero,subst);
} 

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

public static UIntPtr AllBitsValueSubstitution(UIntPtr value,UIntPtr subst)
{
   return XValueSubstitution(value,AllBitsValue,subst);
}

public static UIntPtr SubstituteAllBitsValue([HVolatileAccess] ref UIntPtr operand,UIntPtr subst)
{
   return SubstituteXValue(ref operand,AllBitsValue,subst);
}

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

public static UIntPtr XValueSubstitution(UIntPtr value,UIntPtr xValue,UIntPtr subst)
{
   return HOps.XValueSubstitution(value,xValue,subst);
}

public static UIntPtr SubstituteXValue( [HVolatileAccess] ref UIntPtr operand,
                                        UIntPtr xValue, UIntPtr subst )
{
   UIntPtr op = Thread.VolatileRead( ref operand );
   if ( op == xValue ) return op;
   return HVolatile.Write( ref operand, subst );
}

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

/// <exception cref="NotSupportedException" />
public static string ToNormalString(UIntPtr value)
{
   switch (HPlatform.Bitness)
   {
   case 32: return HUInt32.ToNormalString( (UInt32)value );
   case 64: return HUInt64.ToNormalString( (UInt64)value );
   }
   throw HPlatform.CreateNotSupportedOperationException();
}

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

public static string ToHexString(UIntPtr value)
{
   return ToHexString(value,false);
}

/// <exception cref="NotSupportedException" />
public static string ToHexString(UIntPtr value,bool withPrefix)
{
   switch (HPlatform.Bitness)
   {
   case 32: return HUInt32.ToHexString( (UInt32)value, withPrefix );
   case 64: return HUInt64.ToHexString( (UInt64)value, withPrefix );
   }
   throw HPlatform.CreateNotSupportedOperationException();
}

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

static HUIntPtr()
{
   CommonHelpers_Core.Access();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // HUIntPtr
//**************************************************************************************************

} // CommonHelpers (.WASM)
