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

#if !WASM
namespace user_rtx { using u = user_rtx;
#else
namespace user_rtx.wasm { using u = user_rtx.wasm;
#endif

/// <summary>
/// Volatile operations
/// </summary>
public static class volat {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

[u.returns_target]
public static bool Write( [u.volatile_access] ref bool location, bool value )
{
   Volatile.Write( ref location, value );
   return value;
}

[u.returns_true]
public static bool SetTrue( [u.volatile_access] ref bool location ) =>
   Write( ref location, true );

[u.returns_false]
public static bool Reset( [u.volatile_access][u.reset] ref bool location ) =>
   Write( ref location, false );

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

[u.returns_target]
public static int Write( [u.volatile_access] ref int location, int value )
{
   Volatile.Write( ref location, value );
   return value;
}
[u.returns_zero]
public static int Reset( [u.volatile_access][u.reset] ref int location ) =>
   Write( ref location, 0 );

[u.returns_target]
public static uint Write( [u.volatile_access] ref uint location, uint value )
{
   Volatile.Write( ref location, value );
   return value;
}
[u.returns_zero]
public static uint Reset( [u.volatile_access][u.reset] ref uint location ) =>
   Write( ref location, 0 );

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

[u.returns_target]
public static short Write( [u.volatile_access] ref short location, short value )
{
   Volatile.Write( ref location, value );
   return value;
}
[u.returns_zero]
public static short Reset( [u.volatile_access][u.reset] ref short location ) =>
   Write( ref location, 0 );

[u.returns_target]
public static ushort Write( [u.volatile_access] ref ushort location, ushort value )
{
   Volatile.Write( ref location, value );
   return value;
}
[u.returns_zero]
public static ushort Reset( [u.volatile_access][u.reset] ref ushort location ) =>
   Write( ref location, 0 );

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

[u.returns_target]
public static long Write( [u.volatile_access] ref long location, long value )
{
   Volatile.Write( ref location, value );
   return value;
}
[u.returns_zero]
public static long Reset( [u.volatile_access][u.reset] ref long location ) =>
   Write( ref location, 0 );

[u.returns_target]
public static ulong Write( [u.volatile_access] ref ulong location, ulong value )
{
   Volatile.Write( ref location, value );
   return value;
}
[u.returns_zero]
public static ulong Reset( [u.volatile_access][u.reset] ref ulong location ) =>
   Write( ref location, 0 );

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

[u.returns_target]
public static byte Write( [u.volatile_access] ref byte location, byte value )
{
   Volatile.Write( ref location, value );
   return value;
}
[u.returns_zero]
public static byte Reset( [u.volatile_access][u.reset] ref byte location ) =>
   Write( ref location, 0 );

[u.returns_target]
public static sbyte Write( [u.volatile_access] ref sbyte location, sbyte value )
{
   Volatile.Write( ref location, value );
   return value;
}
[u.returns_zero]
public static sbyte Reset( [u.volatile_access][u.reset] ref sbyte location ) =>
   Write( ref location, 0 );

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

[u.returns_target]
public static double Write( [u.volatile_access] ref double location, double value )
{
   Volatile.Write( ref location, value );
   return value;
}
[u.returns_zero]
public static double Reset( [u.volatile_access][u.reset] ref double location ) =>
   Write( ref location, 0 );

[u.returns_target]
public static float Write( [u.volatile_access] ref float location, float value )
{
   Volatile.Write( ref location, value );
   return value;
}
[u.returns_zero]
public static float Reset( [u.volatile_access][u.reset] ref float location ) =>
   Write( ref location, 0 );

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

[u.returns_target]
public static IntPtr Write( [u.volatile_access] ref IntPtr location, IntPtr value )
{
   Volatile.Write( ref location, value );
   return value;
}
[u.returns_zero]
public static IntPtr Reset( [u.volatile_access][u.reset] ref IntPtr location ) =>
   Write( ref location, default );

[u.returns_target]
public static UIntPtr Write( [u.volatile_access] ref UIntPtr location, UIntPtr value )
{
   Volatile.Write( ref location, value );
   return value;
}
[u.returns_zero]
public static UIntPtr Reset( [u.volatile_access][u.reset] ref UIntPtr location ) =>
   Write( ref location, default );

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

[u.returns_target]
public static T Write<T>( [u.volatile_access] ref T location, T value )
where T: class
{
   Volatile.Write( ref location, value );
   return value;
}

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

[u.returns_target]
public static T? WriteN<T>( [u.volatile_access] ref T? location, T? value )
where T: class
{
   Volatile.Write( ref location, value );
   return value;
}
[u.returns_null]
public static T? Reset<T>( [u.volatile_access][u.reset] ref T? location )
where T: class =>
   WriteN<T>( ref location, null );

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // volat

} // user_rtx (.wasm)
