//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// 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

/// <summary>
/// Array helpers
/// </summary>
public static class array {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/// <exception cref="EElementNotFound" />
public static int VerifyIndexOfResult( int idx ) =>
   idx >= 0 ? idx : throw new EElementNotFound();

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

public static T[]? FromSingleValueOrNull<T>( T? value )
where T: class =>
   value != null ? new T[]{ value } : null;

public static T[]? FromSingleValueOrEmpty<T>( T? value )
where T: class =>
   value != null ? new T[]{ value } : new T[ 0 ];

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

public static T[]? FromSingleValueOrNullNV<T>( T? value )
where T: struct =>
   value.HasValue ? new T[]{ value.Value } : null;

public static T[]? FromSingleValueOrEmptyNV<T>( T? value )
where T: struct =>
   value.HasValue ? new T[]{ value.Value } : new T[ 0 ];

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

public static bool Contains<T>( T[] array, T value )
{
   u.array_argcheck.ZeroBased( array, nameof(array) );
   return value!=null && u.type.ImplementsInterface<IComparable>( typeof(T) ) ?
      Array.BinarySearch( array, value ) >= 0 :
      Array.IndexOf( array, value ) >= 0;
}
public static bool Contains<T>( T[] array, T value, int startIndex )
{
   u.array_argcheck.ZeroBased( array, nameof(array) );
   return value!=null && u.type.ImplementsInterface<IComparable>( typeof(T) ) ?
      Array.BinarySearch( array, startIndex, array.GetLength( 0 )-startIndex, value ) >= 0 :
      Array.IndexOf( array, value, startIndex ) >= 0;
}
public static bool Contains<T>( T[] array, T value, int startIndex, int count )
{
   u.array_argcheck.ZeroBased( array, nameof(array) );
   return value!=null && u.type.ImplementsInterface<IComparable>( typeof(T) ) ?
      Array.BinarySearch( array, startIndex, count, value ) >= 0 :
      Array.IndexOf( array, value, startIndex, count ) >= 0;
}

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

public static bool Contains_O( Array array, object? value )
{
   u.array_argcheck.ZeroBased( array, nameof(array) );
   return value!=null && u.type.ImplementsInterface<IComparable>( value.GetType() ) ?
      Array.BinarySearch( array, value ) >= 0 :
      Array.IndexOf( array, value ) >= 0;
}
public static bool Contains_O( Array array, object? value, int startIndex )
{
   u.array_argcheck.ZeroBased( array, nameof(array) );
   return value!=null && u.type.ImplementsInterface<IComparable>( value.GetType() ) ?
      Array.BinarySearch( array, startIndex, array.GetLength( 0 ), value ) >= 0 :
      Array.IndexOf( array, value, startIndex ) >= 0;
}
public static bool Contains_O( Array array, object? value, int startIndex, int count )
{
   u.array_argcheck.ZeroBased( array, nameof(array) );
   return value!=null && u.type.ImplementsInterface<IComparable>( value.GetType() ) ?
      Array.BinarySearch( array, startIndex, array.GetLength( 0 )-startIndex, value ) >= 0 :
      Array.IndexOf( array, value, startIndex, count ) >= 0;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // array

} // user_rtx (.wasm)
