forked from cgvr/DeltaVR
		
	
		
			
				
	
	
		
			124 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			124 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using System;
 | 
						|
using System.Collections.Generic;
 | 
						|
using System.Diagnostics;
 | 
						|
 | 
						|
namespace Asset_Cleaner {
 | 
						|
    readonly struct Option<T> : IEquatable<Option<T>>, IComparable<Option<T>> {
 | 
						|
        // ReSharper disable once StaticMemberInGenericType
 | 
						|
        static readonly bool IsValueType;
 | 
						|
 | 
						|
        public bool HasValue { get; }
 | 
						|
 | 
						|
        T Value { get; }
 | 
						|
 | 
						|
        public static implicit operator Option<T>(T arg) {
 | 
						|
            if (!IsValueType) return ReferenceEquals(arg, null) ? new Option<T>() : new Option<T>(arg, true);
 | 
						|
#if M_WARN
 | 
						|
            if (arg.Equals(default(T))) 
 | 
						|
                Warn.Warning($"{arg} has default value");
 | 
						|
#endif
 | 
						|
            return new Option<T>(arg, true);
 | 
						|
        }
 | 
						|
 | 
						|
        static Option() {
 | 
						|
            IsValueType = typeof(T).IsValueType;
 | 
						|
        }
 | 
						|
 | 
						|
        public void GetOrFail(out T value) {
 | 
						|
            if (!TryGet(out value))
 | 
						|
                Fail($"Option<{typeof(T).Name}> has no value");
 | 
						|
        }
 | 
						|
 | 
						|
        public T GetOrFail() {
 | 
						|
            if (!TryGet(out var value))
 | 
						|
                Fail($"Option<{typeof(T).Name}> has no value");
 | 
						|
            return value;
 | 
						|
        }
 | 
						|
 | 
						|
        [Conditional("DEBUG1")]
 | 
						|
        static void Fail(string format = null) {
 | 
						|
            throw new Exception(format);
 | 
						|
        }
 | 
						|
 | 
						|
        public bool TryGet(out T value) {
 | 
						|
            if (!HasValue) {
 | 
						|
                value = default(T);
 | 
						|
                return false;
 | 
						|
            }
 | 
						|
 | 
						|
            value = Value;
 | 
						|
            return true;
 | 
						|
        }
 | 
						|
 | 
						|
        internal Option(T value, bool hasValue) {
 | 
						|
            Value = value;
 | 
						|
            HasValue = hasValue;
 | 
						|
        }
 | 
						|
 | 
						|
        public T ValueOr(T alternative) {
 | 
						|
            return HasValue ? Value : alternative;
 | 
						|
        }
 | 
						|
 | 
						|
        // for debug purposes
 | 
						|
        public override string ToString() {
 | 
						|
            if (!HasValue) return "None";
 | 
						|
 | 
						|
            return Value == null ? "Some(null)" : $"Some({Value})";
 | 
						|
        }
 | 
						|
 | 
						|
        #region eq comparers boilerplate
 | 
						|
 | 
						|
        public bool Equals(Option<T> other) {
 | 
						|
            if (!HasValue && !other.HasValue)
 | 
						|
                return true;
 | 
						|
 | 
						|
            if (HasValue && other.HasValue)
 | 
						|
                return EqualityComparer<T>.Default.Equals(Value, other.Value);
 | 
						|
 | 
						|
            return false;
 | 
						|
        }
 | 
						|
 | 
						|
        public override bool Equals(object obj) {
 | 
						|
            return obj is Option<T> && Equals((Option<T>) obj);
 | 
						|
        }
 | 
						|
 | 
						|
        public static bool operator ==(Option<T> left, Option<T> right) {
 | 
						|
            return left.Equals(right);
 | 
						|
        }
 | 
						|
 | 
						|
        public static bool operator !=(Option<T> left, Option<T> right) {
 | 
						|
            return !left.Equals(right);
 | 
						|
        }
 | 
						|
 | 
						|
        public override int GetHashCode() {
 | 
						|
            if (!HasValue) return 0;
 | 
						|
 | 
						|
            return IsValueType || Value != null ? Value.GetHashCode() : 1;
 | 
						|
        }
 | 
						|
 | 
						|
        public int CompareTo(Option<T> other) {
 | 
						|
            if (HasValue && !other.HasValue) return 1;
 | 
						|
            if (!HasValue && other.HasValue) return -1;
 | 
						|
 | 
						|
            return Comparer<T>.Default.Compare(Value, other.Value);
 | 
						|
        }
 | 
						|
 | 
						|
        public static bool operator <(Option<T> left, Option<T> right) {
 | 
						|
            return left.CompareTo(right) < 0;
 | 
						|
        }
 | 
						|
 | 
						|
        public static bool operator <=(Option<T> left, Option<T> right) {
 | 
						|
            return left.CompareTo(right) <= 0;
 | 
						|
        }
 | 
						|
 | 
						|
        public static bool operator >(Option<T> left, Option<T> right) {
 | 
						|
            return left.CompareTo(right) > 0;
 | 
						|
        }
 | 
						|
 | 
						|
        public static bool operator >=(Option<T> left, Option<T> right) {
 | 
						|
            return left.CompareTo(right) >= 0;
 | 
						|
        }
 | 
						|
 | 
						|
        #endregion
 | 
						|
    }
 | 
						|
} |