1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-21 01:18:02 +02:00
Beef/IDE/mintest/minlib/src/System/Nullable.bf

451 lines
16 KiB
Beef
Raw Normal View History

2019-08-23 11:56:54 -07:00
using System.Reflection;
using System.Collections;
2019-08-23 11:56:54 -07:00
using System.Diagnostics;
namespace System
{
2019-11-21 08:23:18 -08:00
struct Nullable<T> where T : struct
2019-08-23 11:56:54 -07:00
{
2020-08-01 07:48:00 -07:00
T mValue;
bool mHasValue;
2020-08-01 07:48:00 -07:00
public this(T value)
2019-08-23 11:56:54 -07:00
{
mHasValue = true;
mValue = value;
}
public bool HasValue
{
2020-02-20 09:31:27 -08:00
[Inline]
2019-08-23 11:56:54 -07:00
get { return mHasValue; }
}
public T Value
{
2020-02-20 09:31:27 -08:00
[Inline]
2019-08-23 11:56:54 -07:00
get
{
if (!mHasValue)
{
2020-08-01 07:48:00 -07:00
Debug.FatalError("Value requested for null nullable.");
2019-08-23 11:56:54 -07:00
}
return mValue;
}
}
2020-08-01 07:48:00 -07:00
public ref T ValueRef
{
2020-02-20 09:31:27 -08:00
[Inline]
2020-08-01 07:48:00 -07:00
get mut
{
if (!mHasValue)
{
Debug.FatalError("Value requested for null nullable.");
}
return ref mValue;
}
}
2019-08-23 11:56:54 -07:00
public T GetValueOrDefault()
{
return mValue;
}
2020-08-01 07:48:00 -07:00
public bool TryGetValue(ref T outValue)
{
if (!mHasValue)
return false;
outValue = mValue;
return true;
}
2019-08-23 11:56:54 -07:00
public T GetValueOrDefault(T defaultmValue)
{
return mHasValue ? mValue : defaultmValue;
}
public override void ToString(String str)
{
if (mHasValue)
mValue.ToString(str);
else
str.Clear();
}
2020-08-01 07:48:00 -07:00
[Inline]
2019-08-23 11:56:54 -07:00
public static implicit operator Nullable<T>(T value)
{
2020-08-01 07:48:00 -07:00
Nullable<T> result;
2020-02-19 13:16:33 -08:00
result.mHasValue = true;
result.mValue = value;
return result;
2019-08-23 11:56:54 -07:00
}
2020-08-01 07:48:00 -07:00
[Inline]
2019-08-23 11:56:54 -07:00
public static explicit operator T(Nullable<T> value)
{
return value.mValue;
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
[Inline]
public static bool operator==(Nullable<T> lhs, T rhs)
{
if (!lhs.mHasValue) return false;
return lhs.mValue == rhs;
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
///
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
public static bool operator==<TOther>(Nullable<T> lhs, TOther rhs) where bool : operator T == TOther
{
if (!lhs.mHasValue) return false;
return lhs.mValue == rhs;
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
public static bool operator==<TOther>(TOther lhs, Nullable<T> rhs) where bool : operator TOther == T
{
if (!rhs.mHasValue) return false;
return lhs == rhs.mValue;
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
public static bool operator==<TOther>(Nullable<T> lhs, Nullable<TOther> rhs) where bool : operator T == TOther where TOther : struct
{
if ((!lhs.mHasValue) || (!rhs.mHasValue)) return !lhs.mHasValue && !rhs.mHasValue; // Only both being null results in 'true'
return lhs.mValue == rhs.mValue;
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
///
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
public static bool operator!=<TOther>(Nullable<T> lhs, TOther rhs) where bool : operator T != TOther
{
if (!lhs.mHasValue) return true;
return lhs.mValue != rhs;
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
public static bool operator!=<TOther>(TOther lhs, Nullable<T> rhs) where bool : operator TOther != T
{
if (!rhs.mHasValue) return true;
return lhs != rhs.mValue;
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
public static bool operator!=<TOther>(Nullable<T> lhs, Nullable<TOther> rhs) where bool : operator T != TOther where TOther : struct
{
if ((!lhs.mHasValue) || (!rhs.mHasValue)) return !(!lhs.mHasValue && !rhs.mHasValue); // Only both being null results in 'false'
return lhs.mValue != rhs.mValue;
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
///
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
public static bool operator< <TOther>(Nullable<T> lhs, TOther rhs) where bool : operator T < TOther
{
if (!lhs.mHasValue) return false;
return lhs.mValue < rhs;
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
public static bool operator< <TOther>(TOther lhs, Nullable<T> rhs) where bool : operator TOther < T
{
if (!rhs.mHasValue) return false;
return lhs < rhs.mValue;
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
public static bool operator< <TOther>(Nullable<T> lhs, Nullable<TOther> rhs) where bool : operator T < TOther where TOther : struct
{
if ((!lhs.mHasValue) || (!rhs.mHasValue)) return false;
return lhs.mValue < rhs.mValue;
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
///
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
public static bool operator<=<TOther>(Nullable<T> lhs, TOther rhs) where bool : operator T <= TOther
{
if (!lhs.mHasValue) return false;
return lhs.mValue <= rhs;
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
public static bool operator<=<TOther>(TOther lhs, Nullable<T> rhs) where bool : operator TOther <= T
{
if (!rhs.mHasValue) return false;
return lhs <= rhs.mValue;
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
public static bool operator<=<TOther>(Nullable<T> lhs, Nullable<TOther> rhs) where bool : operator T <= TOther where TOther : struct
{
if ((!lhs.mHasValue) || (!rhs.mHasValue)) return false;
return lhs.mValue <= rhs.mValue;
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
///
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
public static bool operator><TOther>(Nullable<T> lhs, TOther rhs) where bool : operator T > TOther
{
if (!lhs.mHasValue) return false;
return lhs.mValue > rhs;
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
public static bool operator><TOther>(TOther lhs, Nullable<T> rhs) where bool : operator TOther > T
{
if (!rhs.mHasValue) return false;
return lhs > rhs.mValue;
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
public static bool operator><TOther>(Nullable<T> lhs, Nullable<TOther> rhs) where bool : operator T > TOther where TOther : struct
{
if ((!lhs.mHasValue) || (!rhs.mHasValue)) return false;
return lhs.mValue > rhs.mValue;
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
///
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
public static bool operator>=<TOther>(Nullable<T> lhs, TOther rhs) where bool : operator T >= TOther
{
if (!lhs.mHasValue) return false;
return lhs.mValue >= rhs;
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
public static bool operator>=<TOther>(TOther lhs, Nullable<T> rhs) where bool : operator TOther >= T
{
if (!rhs.mHasValue) return false;
return lhs >= rhs.mValue;
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
public static bool operator>=<TOther>(Nullable<T> lhs, Nullable<TOther> rhs) where bool : operator T >= TOther where TOther : struct
{
if ((!lhs.mHasValue) || (!rhs.mHasValue)) return false;
return lhs.mValue >= rhs.mValue;
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
///
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
public static int operator<=><TOther>(Nullable<T> lhs, TOther rhs) where int : operator T <=> TOther
{
return lhs.mValue <=> rhs;
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
public static int operator<=><TOther>(TOther lhs, Nullable<T> rhs) where int : operator TOther <=> T
{
return lhs <=> rhs.mValue;
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
public static int operator<=><TOther>(Nullable<T> lhs, Nullable<TOther> rhs) where int : operator T <=> TOther where TOther : struct
{
return lhs.mValue <=> rhs.mValue;
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
///
2019-11-21 08:23:18 -08:00
2021-01-15 14:59:02 -08:00
public static TResult? operator+<TOther, TResult>(Nullable<T> lhs, TOther rhs) where TResult : operator T + TOther where TResult : struct
2020-08-01 07:48:00 -07:00
{
if (!lhs.mHasValue) return null;
return Nullable<TResult>(lhs.mValue + rhs);
}
2021-01-15 14:59:02 -08:00
public static TResult? operator+<TOther, TResult>(TOther lhs, Nullable<T> rhs) where TResult : operator TOther + T where TResult : struct
2020-08-01 07:48:00 -07:00
{
if (!rhs.mHasValue) return null;
return Nullable<TResult>(lhs + rhs.mValue);
}
2021-01-15 14:59:02 -08:00
public static TResult? operator+<TOther, TResult>(Nullable<T> lhs, Nullable<TOther> rhs) where TOther : struct where TResult : operator T + TOther where TResult : struct
2020-08-01 07:48:00 -07:00
{
if ((!lhs.mHasValue) || (!rhs.mHasValue)) return null;
return Nullable<TResult>(lhs.mValue + rhs.mValue);
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
///
2019-11-21 08:23:18 -08:00
2021-01-15 14:59:02 -08:00
public static TResult? operator-<TOther, TResult>(TOther lhs, Nullable<T> rhs) where TResult : operator TOther - T where TResult : struct
2020-08-01 07:48:00 -07:00
{
if (!rhs.mHasValue) return null;
return Nullable<TResult>(lhs - rhs.mValue);
}
2019-11-21 08:23:18 -08:00
2021-01-15 14:59:02 -08:00
public static TResult? operator-<TOther, TResult>(Nullable<T> lhs, TOther rhs) where TResult : operator T - TOther where TResult : struct
2020-08-01 07:48:00 -07:00
{
if (!lhs.mHasValue) return null;
return Nullable<TResult>(lhs.mValue - rhs);
}
2019-11-21 08:23:18 -08:00
2021-01-15 14:59:02 -08:00
public static TResult? operator-<TOther, TResult>(Nullable<T> lhs, Nullable<TOther> rhs) where TOther : struct where TResult : operator T - TOther where TResult : struct
2020-08-01 07:48:00 -07:00
{
if ((!lhs.mHasValue) || (!rhs.mHasValue)) return null;
return Nullable<TResult>(lhs.mValue - rhs.mValue);
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
//
2019-11-21 08:23:18 -08:00
2021-01-15 14:59:02 -08:00
public static TResult? operator*<TOther, TResult>(TOther lhs, Nullable<T> rhs) where TResult : operator TOther * T where TResult : struct
2020-08-01 07:48:00 -07:00
{
if (!rhs.mHasValue) return null;
return Nullable<TResult>(lhs * rhs.mValue);
}
2019-11-21 08:23:18 -08:00
2021-01-15 14:59:02 -08:00
public static TResult? operator*<TOther, TResult>(Nullable<T> lhs, TOther rhs) where TResult : operator T * TOther where TResult : struct
2020-08-01 07:48:00 -07:00
{
if (!lhs.mHasValue) return null;
return Nullable<TResult>(lhs.mValue * rhs);
}
2019-11-21 08:23:18 -08:00
2021-01-15 14:59:02 -08:00
public static TResult? operator*<TOther, TResult>(Nullable<T> lhs, Nullable<TOther> rhs) where TOther : struct where TResult : operator T * TOther where TResult : struct
2020-08-01 07:48:00 -07:00
{
if ((!lhs.mHasValue) || (!rhs.mHasValue)) return null;
return Nullable<TResult>(lhs.mValue * rhs.mValue);
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
//
2019-11-21 08:23:18 -08:00
2021-01-15 14:59:02 -08:00
public static TResult? operator/<TOther, TResult>(TOther lhs, Nullable<T> rhs) where TResult : operator TOther / T where TResult : struct
2020-08-01 07:48:00 -07:00
{
if (!rhs.mHasValue) return null;
return Nullable<TResult>(lhs / rhs.mValue);
}
2019-11-21 08:23:18 -08:00
2021-01-15 14:59:02 -08:00
public static TResult? operator/<TOther, TResult>(Nullable<T> lhs, TOther rhs) where TResult : operator T / TOther where TResult : struct
2020-08-01 07:48:00 -07:00
{
if (!lhs.mHasValue) return null;
return Nullable<TResult>(lhs.mValue / rhs);
}
2019-11-21 08:23:18 -08:00
2021-01-15 14:59:02 -08:00
public static TResult? operator/<TOther, TResult>(Nullable<T> lhs, Nullable<TOther> rhs) where TOther : struct where TResult : operator T / TOther where TResult : struct
2020-08-01 07:48:00 -07:00
{
if ((!lhs.mHasValue) || (!rhs.mHasValue)) return null;
return Nullable<TResult>(lhs.mValue / rhs.mValue);
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
//
2019-11-21 08:23:18 -08:00
2021-01-15 14:59:02 -08:00
public static TResult? operator%<TOther, TResult>(TOther lhs, Nullable<T> rhs) where TResult : operator TOther % T where TResult : struct
2020-08-01 07:48:00 -07:00
{
if (!rhs.mHasValue) return null;
return Nullable<TResult>(lhs % rhs.mValue);
}
2019-11-21 08:23:18 -08:00
2021-01-15 14:59:02 -08:00
public static TResult? operator%<TOther, TResult>(Nullable<T> lhs, TOther rhs) where TResult : operator T % TOther where TResult : struct
2020-08-01 07:48:00 -07:00
{
if (!lhs.mHasValue) return null;
return Nullable<TResult>(lhs.mValue % rhs);
}
2019-11-21 08:23:18 -08:00
2021-01-15 14:59:02 -08:00
public static TResult? operator%<TOther, TResult>(Nullable<T> lhs, Nullable<TOther> rhs) where TOther : struct where TResult : operator T % TOther where TResult : struct
2020-08-01 07:48:00 -07:00
{
if ((!lhs.mHasValue) || (!rhs.mHasValue)) return null;
return Nullable<TResult>(lhs.mValue % rhs.mValue);
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
//
2019-11-21 08:23:18 -08:00
2021-01-15 14:59:02 -08:00
public static TResult? operator^<TOther, TResult>(TOther lhs, Nullable<T> rhs) where TResult : operator TOther ^ T where TResult : struct
2020-08-01 07:48:00 -07:00
{
if (!rhs.mHasValue) return null;
return Nullable<TResult>(lhs ^ rhs.mValue);
}
2019-11-21 08:23:18 -08:00
2021-01-15 14:59:02 -08:00
public static TResult? operator^<TOther, TResult>(Nullable<T> lhs, TOther rhs) where TResult : operator T ^ TOther where TResult : struct
2020-08-01 07:48:00 -07:00
{
if (!lhs.mHasValue) return null;
return Nullable<TResult>(lhs.mValue ^ rhs);
}
2019-11-21 08:23:18 -08:00
2021-01-15 14:59:02 -08:00
public static TResult? operator^<TOther, TResult>(Nullable<T> lhs, Nullable<TOther> rhs) where TOther : struct where TResult : operator T ^ TOther where TResult : struct
2020-08-01 07:48:00 -07:00
{
if ((!lhs.mHasValue) || (!rhs.mHasValue)) return null;
return Nullable<TResult>(lhs.mValue ^ rhs.mValue);
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
//
2019-11-21 08:23:18 -08:00
2021-01-15 14:59:02 -08:00
public static TResult? operator&<TOther, TResult>(TOther lhs, Nullable<T> rhs) where TResult : operator TOther & T where TResult : struct
2020-08-01 07:48:00 -07:00
{
if (!rhs.mHasValue) return null;
return Nullable<TResult>(lhs & rhs.mValue);
}
2019-11-21 08:23:18 -08:00
2021-01-15 14:59:02 -08:00
public static TResult? operator&<TOther, TResult>(Nullable<T> lhs, TOther rhs) where TResult : operator T & TOther where TResult : struct
2020-08-01 07:48:00 -07:00
{
if (!lhs.mHasValue) return null;
return Nullable<TResult>(lhs.mValue & rhs);
}
2019-11-21 08:23:18 -08:00
2021-01-15 14:59:02 -08:00
public static TResult? operator&<TOther, TResult>(Nullable<T> lhs, Nullable<TOther> rhs) where TOther : struct where TResult : operator T & TOther where TResult : struct
2020-08-01 07:48:00 -07:00
{
if ((!lhs.mHasValue) || (!rhs.mHasValue)) return null;
return Nullable<TResult>(lhs.mValue & rhs.mValue);
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
//
2019-11-21 08:23:18 -08:00
2021-01-15 14:59:02 -08:00
public static TResult? operator|<TOther, TResult>(TOther lhs, Nullable<T> rhs) where TResult : operator TOther | T where TResult : struct
2020-08-01 07:48:00 -07:00
{
if (!rhs.mHasValue) return null;
return Nullable<TResult>(lhs | rhs.mValue);
}
2019-11-21 08:23:18 -08:00
2021-01-15 14:59:02 -08:00
public static TResult? operator|<TOther, TResult>(Nullable<T> lhs, TOther rhs) where TResult : operator T | TOther where TResult : struct
2020-08-01 07:48:00 -07:00
{
if (!lhs.mHasValue) return null;
return Nullable<TResult>(lhs.mValue | rhs);
}
2019-11-21 08:23:18 -08:00
2021-01-15 14:59:02 -08:00
public static TResult? operator|<TOther, TResult>(Nullable<T> lhs, Nullable<TOther> rhs) where TOther : struct where TResult : operator T | TOther where TResult : struct
2020-08-01 07:48:00 -07:00
{
if ((!lhs.mHasValue) || (!rhs.mHasValue)) return null;
return Nullable<TResult>(lhs.mValue | rhs.mValue);
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
//
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
public static T operator??(Nullable<T> lhs, T rhs)
2019-11-21 08:23:18 -08:00
{
2020-08-01 07:48:00 -07:00
return (lhs.mHasValue) ? lhs.mValue : rhs;
2019-11-21 08:23:18 -08:00
}
2021-01-15 14:59:02 -08:00
public static TResult? operator??<TOther, TResult>(TOther lhs, Nullable<T> rhs) where TResult : operator TOther ?? T where TResult : struct
2020-08-01 07:48:00 -07:00
{
if (!rhs.mHasValue) return null;
return Nullable<TResult>(lhs ?? rhs.mValue);
}
2019-11-21 08:23:18 -08:00
2021-01-15 14:59:02 -08:00
public static TResult? operator??<TOther, TResult>(Nullable<T> lhs, TOther rhs) where TResult : operator T ?? TOther where TResult : struct
2020-08-01 07:48:00 -07:00
{
if (!lhs.mHasValue) return null;
return Nullable<TResult>(lhs.mValue ?? rhs);
}
2019-11-21 08:23:18 -08:00
2021-01-15 14:59:02 -08:00
public static TResult? operator??<TOther, TResult>(Nullable<T> lhs, Nullable<TOther> rhs) where TOther : struct where TResult : operator T ?? TOther where TResult : struct
2020-08-01 07:48:00 -07:00
{
if ((!lhs.mHasValue) || (!rhs.mHasValue)) return null;
return Nullable<TResult>(lhs.mValue ?? rhs.mValue);
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
//
2019-11-21 08:23:18 -08:00
2021-01-15 14:59:02 -08:00
public static TResult? operator<< <TOther, TResult>(TOther lhs, Nullable<T> rhs) where TResult : operator TOther << T where TResult : struct
2020-08-01 07:48:00 -07:00
{
if (!rhs.mHasValue) return null;
return Nullable<TResult>(lhs << rhs.mValue);
}
2019-11-21 08:23:18 -08:00
2021-01-15 14:59:02 -08:00
public static TResult? operator<< <TOther, TResult>(Nullable<T> lhs, TOther rhs) where TResult : operator T << TOther where TResult : struct
2020-08-01 07:48:00 -07:00
{
if (!lhs.mHasValue) return null;
return Nullable<TResult>(lhs.mValue << rhs);
}
2021-01-15 14:59:02 -08:00
public static TResult? operator<< <TOther, TResult>(Nullable<T> lhs, Nullable<TOther> rhs) where TOther : struct where TResult : operator T << TOther where TResult : struct
2020-08-01 07:48:00 -07:00
{
if ((!lhs.mHasValue) || (!rhs.mHasValue)) return null;
return Nullable<TResult>(lhs.mValue << rhs.mValue);
}
2019-08-23 11:56:54 -07:00
}
2019-11-21 08:23:18 -08:00
2020-08-01 07:48:00 -07:00
extension Nullable<T> : IHashable where T : IHashable
{
public int GetHashCode()
{
if (!mHasValue)
return 0;
return mValue.GetHashCode();
}
}
2019-08-23 11:56:54 -07:00
}