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

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

static partial class ops {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public static bool IsBetween<T>( T value, T lowerBound, T upperBound )
where T: IComparable<T> =>
   value.CompareTo( lowerBound )>=0 && value.CompareTo( upperBound )<=0;

public static bool IsExBetween<T>( T value, T lowerBound, T upperBound )
where T: IComparable<T> =>
   value.CompareTo( lowerBound )>0 && value.CompareTo( upperBound )<0;

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

/// <exception cref="ArgumentException" />
[u.failure_as_minus_1]
public static int IndexOf<T>( T val, params T[] values )
{
   u.array_argcheck.ZeroBased( values, nameof(values) );
   for ( int i=0; i<values.Length; i++ )
      if ( object.Equals( val, values[i] ) )
         return i;
   return -1;
}

/// <exception cref="ArgumentException" />
[u.strict_result]
public static int StrictIndexOf<T>( T val, params T[] values ) =>
   VerifyArgListIndexOf( IndexOf( val, values ) );

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

/// <exception cref="ArgumentException" />
public static bool IsOneOf<T>( T val, params T[] values ) =>
   IndexOf<T>( val, values ) >= 0;

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

[u.returns_previous]
public static T Exchange<T>( ref T location, T value )
{
   T prev=location; location=value; return prev;
}

[u.returns_previous]
public static T? ExchangeN<T>( ref T? location, T? value )
{
   T? prev=location; location=value; return prev;
}

[u.returns_previous]
public static T? NullExchange<T>( ref T? location )
where T: class =>
   ExchangeN<T>( ref location, null );

[u.returns_previous]
public static T? DefaultExchange<T>( ref T? location ) =>
   ExchangeN<T>( ref location, default );

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

public static T ValueSubst<T>( T value, T comparand, T subst ) =>
   object.Equals( value, comparand ) ? subst : value;

public static T ReplaceValue<T>( ref T location, T comparand, T subst ) =>
   object.Equals( location, comparand ) ? location=subst : location;

public static T? ValueSubstN<T>( T? value, T? comparand, T? subst ) =>
   object.Equals( value, comparand ) ? subst : value;

public static T? ReplaceValueN<T>( ref T? location, T? comparand, T? subst ) =>
   object.Equals( location, comparand ) ? location=subst : location;

[u.returns_target]
public static T? ReplaceNull<T>( ref T? location, T? subst )
{
   if ( location == null )
      location = subst;
   return location;
}

public static bool IfReplaceNull<T>( ref T? location, T? subst )
{
   if ( location != null )
      return false;
   location = subst;
   return true;
}

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

public static T? Or<T>( params T?[] values )
{
   foreach ( T? v in values )
      if ( v != null )
         return v;
   return default;
}

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

public static T NewIfNull<T>( ref T? location )
where T: class, new() =>
   location != null ? location : new T();

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // ops

} // user_rtx (.wasm)
