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

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

//**************************************************************************************************
/// <summary>
/// </summary>
public static partial class HIntPtr {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public static readonly IntPtr
   MinusOneValue = (IntPtr)(-1);

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

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

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

public static IntPtr MinusOneValueExchange([HVolatileAccess] ref IntPtr operand)
{
   return Exchange(ref operand,MinusOneValue);
}

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

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

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

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

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

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

public static IntPtr MinusOneValueSubstitution(IntPtr value,IntPtr subst)
{
   return XValueSubstitution(value,MinusOneValue,subst);
}

public static IntPtr SubstituteMinusOneValue([HVolatileAccess] ref IntPtr operand,IntPtr subst)
{
   return SubstituteXValue(ref operand,MinusOneValue,subst);
}

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

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

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

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

/// <exception cref="NotSupportedException" />
public static string ToNormalString(IntPtr value)
{
   switch (HPlatform.Bitness)
   {
   case 32: return HInt32.ToNormalString( (Int32)value );
   case 64: return HInt64.ToNormalString( (Int64)value );
   }
   throw HPlatform.CreateNotSupportedOperationException();
}

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

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

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // HIntPtr
//**************************************************************************************************

} // CommonHelpers (.WASM)
