//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// 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>
/// Argument checking
/// </summary>
public static partial class arg_check {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/// <summary>
/// Not-null checking for usage with nullable reference or value
/// </summary>
/// <exception cref="ArgumentNullException" />
public static T NN<T>( T? value, string paramName )
where T: notnull =>
   value ?? throw new ArgumentNullException(
      NN( paramName, nameof(paramName) ) );

/// <exception cref="ArgumentException" />
/// <summary>
/// Not-null checking of value-array elements, for usage with array of nullable reference or nullable values
/// </summary>
public static T?[] NotNulls<T>( T?[] values, string paramName )
where T: notnull =>
   values ??
      throw arg_check_errors.ARRAY_OF_NOT_NULL_VALUES_WAS_EXPECTED( paramName );

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

/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static T NotZero<T>( T value, string paramName )
where T: struct, IEquatable<T> =>
   !value.Equals( default ) ? value :
      throw u.arg_check_errors.NONZERO_VALUE_WAS_EXPECTED( paramName );

/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static T NotZeroB<T>( T value, string paramName )
where T: struct =>
   !value.Equals( default ) ? value :
      throw u.arg_check_errors.NONZERO_VALUE_WAS_EXPECTED( paramName );

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

/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static T NotNegative<T>( T value, string paramName )
where T: struct, IComparable<T> =>
   value.CompareTo( default ) >= 0 ? value :
      throw u.arg_check_errors.NONNEGATIVE_NUMBER_WAS_EXPECTED( paramName );

/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static T Positive<T>( T value, string paramName )
where T: struct, IComparable<T> =>
   value.CompareTo( default ) > 0 ? value :
      throw u.arg_check_errors.POSITIVE_NUMBER_WAS_EXPECTED( paramName );

/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static T InRange<T>( T value, T from, T to, string paramName )
where T: struct, IComparable<T> =>
   u.val.IsBetween( value, from, to ) ? value :
      throw u.arg_check_errors.NOT_IN_RANGE( paramName, from, to );

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

/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static int NotNegative( int value, string paramName ) =>
   value >= 0 ? value :
      throw u.arg_check_errors.NONNEGATIVE_NUMBER_WAS_EXPECTED( paramName );

/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static int Positive( int value, string paramName ) =>
   value > 0 ? value :
      throw u.arg_check_errors.POSITIVE_NUMBER_WAS_EXPECTED( paramName );

/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static int InRange( int value, int from, int to, string paramName ) =>
   u.val.IsBetween( value, from, to ) ? value :
      throw u.arg_check_errors.NOT_IN_RANGE( paramName, from, to );

/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static int GE( int value, int lower, string paramName ) =>
   value >= lower ? value :
      throw u.arg_check_errors.NOT_GREATER_THAN_OR_EQUAL_TO( paramName, lower );
/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static int GT( int value, int xLower, string paramName ) =>
   value > xLower ? value :
      throw u.arg_check_errors.NOT_GREATER_THAN( paramName, xLower );

/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static int LE( int value, int upper, string paramName ) =>
   value <= upper ? value :
      throw u.arg_check_errors.NOT_LESS_THAN_OR_EQUAL_TO( paramName, upper );
/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static int LT( int value, int xUpper, string paramName ) =>
   value < xUpper ? value :
      throw u.arg_check_errors.NOT_LESS_THAN( paramName, xUpper );

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

/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static double NotNegative( double value, string paramName ) =>
   value >= 0 ? value :
      throw u.arg_check_errors.NONNEGATIVE_NUMBER_WAS_EXPECTED( paramName );

/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static double Positive( double value, string paramName ) =>
   value > 0 ? value :
      throw u.arg_check_errors.POSITIVE_NUMBER_WAS_EXPECTED( paramName );

/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static double InRange( double value, double from, double to, string paramName ) =>
   u.val.IsBetween( value, from, to ) ? value :
      throw u.arg_check_errors.NOT_IN_RANGE( paramName, from, to );

/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static double GE( double value, double lower, string paramName ) =>
   value >= lower ? value :
      throw u.arg_check_errors.NOT_GREATER_THAN_OR_EQUAL_TO( paramName, lower );
/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static double GT( double value, double xLower, string paramName ) =>
   value > xLower ? value :
      throw u.arg_check_errors.NOT_GREATER_THAN( paramName, xLower );

/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static double LE( double value, double upper, string paramName ) =>
   value <= upper ? value :
      throw u.arg_check_errors.NOT_LESS_THAN_OR_EQUAL_TO( paramName, upper );
/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static double LT( double value, double xUpper, string paramName ) =>
   value < xUpper ? value :
      throw u.arg_check_errors.NOT_LESS_THAN( paramName, xUpper );

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

/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static decimal NotNegative( decimal value, string paramName ) =>
   value >= 0 ? value :
      throw u.arg_check_errors.NONNEGATIVE_NUMBER_WAS_EXPECTED( paramName );

/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static decimal Positive( decimal value, string paramName ) =>
   value > 0 ? value :
      throw u.arg_check_errors.POSITIVE_NUMBER_WAS_EXPECTED( paramName );

/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static decimal InRange( decimal value, decimal from, decimal to, string paramName ) =>
   u.val.IsBetween( value, from, to ) ? value :
      throw u.arg_check_errors.NOT_IN_RANGE( paramName, from, to );

/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static decimal GE( decimal value, decimal lower, string paramName ) =>
   value >= lower ? value :
      throw u.arg_check_errors.NOT_GREATER_THAN_OR_EQUAL_TO( paramName, lower );
/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static decimal GT( decimal value, decimal xLower, string paramName ) =>
   value > xLower ? value :
      throw u.arg_check_errors.NOT_GREATER_THAN( paramName, xLower );

/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static decimal LE( decimal value, decimal upper, string paramName ) =>
   value <= upper ? value :
      throw u.arg_check_errors.NOT_LESS_THAN_OR_EQUAL_TO( paramName, upper );
/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static decimal LT( decimal value, decimal xUpper, string paramName ) =>
   value < xUpper ? value :
      throw u.arg_check_errors.NOT_LESS_THAN( paramName, xUpper );

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

/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static TimeSpan NotNegative( TimeSpan value, string paramName ) =>
   value >= TimeSpan.Zero ? value :
      throw u.arg_check_errors.NONNEGATIVE_NUMBER_WAS_EXPECTED( paramName );

/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static TimeSpan Positive( TimeSpan value, string paramName ) =>
   value > TimeSpan.Zero ? value :
      throw u.arg_check_errors.POSITIVE_NUMBER_WAS_EXPECTED( paramName );

/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static TimeSpan InRange( TimeSpan value, TimeSpan from, TimeSpan to, string paramName ) =>
   u.val.IsBetween( value, from, to ) ? value :
      throw u.arg_check_errors.NOT_IN_RANGE( paramName, from, to );

/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static TimeSpan GE( TimeSpan value, TimeSpan lower, string paramName ) =>
   value >= lower ? value :
      throw u.arg_check_errors.NOT_GREATER_THAN_OR_EQUAL_TO( paramName, lower );
/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static TimeSpan GT( TimeSpan value, TimeSpan xLower, string paramName ) =>
   value > xLower ? value :
      throw u.arg_check_errors.NOT_GREATER_THAN( paramName, xLower );

/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static TimeSpan LE( TimeSpan value, TimeSpan upper, string paramName ) =>
   value <= upper ? value :
      throw u.arg_check_errors.NOT_LESS_THAN_OR_EQUAL_TO( paramName, upper );
/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static TimeSpan LT( TimeSpan value, TimeSpan xUpper, string paramName ) =>
   value < xUpper ? value :
      throw u.arg_check_errors.NOT_LESS_THAN( paramName, xUpper );

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

/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static DateTime InRange( DateTime value, DateTime from, DateTime to, string paramName ) =>
   u.val.IsBetween( value, from, to ) ? value :
      throw u.arg_check_errors.NOT_IN_RANGE( paramName, from, to );

/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static DateTime GE( DateTime value, DateTime lower, string paramName ) =>
   value >= lower ? value :
      throw u.arg_check_errors.NOT_GREATER_THAN_OR_EQUAL_TO( paramName, lower );
/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static DateTime GT( DateTime value, DateTime xLower, string paramName ) =>
   value > xLower ? value :
      throw u.arg_check_errors.NOT_GREATER_THAN( paramName, xLower );

/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static DateTime LE( DateTime value, DateTime upper, string paramName ) =>
   value <= upper ? value :
      throw u.arg_check_errors.NOT_LESS_THAN_OR_EQUAL_TO( paramName, upper );
/// <exception cref="ArgumentOutOfRangeException" />
[u.returns_source]
public static DateTime LT( DateTime value, DateTime xUpper, string paramName ) =>
   value < xUpper ? value :
      throw u.arg_check_errors.NOT_LESS_THAN( paramName, xUpper );

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // arg_check

} // user_rtx (.wasm)
