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

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

/// <summary>
/// List helpers
/// </summary>
public static class list {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public static T? FirstOrNull<T>( IList<T> list )
where T: class =>
   list.Count > 0 ? list[ 0 ] : null;

public static T? FirstOrNullV<T>( IList<T> list )
where T: struct =>
   list.Count > 0 ? list[ 0 ] : null;

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

public static T? SecondOrNull<T>( IList<T> list )
where T: class =>
   list.Count > 1 ? list[ 1 ] : null;

public static T? SecondOrNullV<T>( IList<T> list )
where T: struct =>
   list.Count > 1 ? list[ 1 ] : null;

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

public static T? LastOrNull<T>( IList<T> list )
where T: class
{
   int count = list.Count;
   return count > 0 ? list[ count-1 ] : null;
}

public static T? LastOrNullV<T>( IList<T> list )
where T: struct
{
   int count = list.Count;
   return count > 0 ? list[ count-1 ] : null;
}

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

[u.returns_target]
public static List<T> AddRange<T>( List<T> list, params T[] elements )
{
   foreach ( var elem in elements )
      list.Add( elem );
   return list;
}

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

/// <exception cref="ArgumentException" />
public static bool RemoveLast<T>( List<T> list, bool throwIfEmpty=true )
where T: class
{
   int count = list.Count;
   if ( !VerifyRemoveLast( count, throwIfEmpty ) )
      return false;
   list.RemoveAt( count - 1 );
   return true;
}

/// <exception cref="ArgumentException" />
public static bool RemoveLastV<T>( List<T> list, bool throwIfEmpty=true )
where T: struct
{
   int count = list.Count;
   if ( !VerifyRemoveLast( count, throwIfEmpty ) )
      return false;
   list.RemoveAt( count - 1 );
   return true;
}

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

/// <exception cref="ArgumentException" />
static bool VerifyRemoveLast( int count, bool throwIfEmpty ) =>
   count > 0 ? true :
      throwIfEmpty ? throw new ArgumentException(
         "Attempt to remove last element from empty list has occured.",
         "list" ) :
      false;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // list

} // user_rtx (.wasm)
