using System.Collections; using System.Collections.Generic; namespace NTERA.Engine { public class Variable : IEnumerable> { public string Name { get; } public ValueType Type { get; } protected Dictionary Dictionary { get; } = new Dictionary(new ZeroIntegerArrayEqualityComparer()); public Variable(string name, ValueType type) { Name = name; Type = type; } public virtual Value this[params int[] index] { get { if (Dictionary.TryGetValue(index, out var value)) return value; return Type == ValueType.String ? new Value("") : new Value(0d); } set => Dictionary[index] = value; } public IEnumerator> GetEnumerator() { return Dictionary.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)Dictionary).GetEnumerator(); } } public class ZeroIntegerArrayEqualityComparer : IEqualityComparer { public bool Equals(int[] x, int[] y) { if (x == null && y != null || y == null && x != null) return false; if (x == null || x.Length == 0) x = new[] { 0 }; if (y == null || y.Length == 0) y = new[] { 0 }; int xNonZeroLength = x.Length; int yNonZeroLength = y.Length; for (; xNonZeroLength > 0; xNonZeroLength--) { if (x[xNonZeroLength - 1] != 0) break; } for (; yNonZeroLength > 0; yNonZeroLength--) { if (y[yNonZeroLength - 1] != 0) break; } if (xNonZeroLength != yNonZeroLength) { return false; } for (int i = 0; i < xNonZeroLength; i++) { if (x[i] != y[i]) { return false; } } return true; } public int GetHashCode(int[] obj) { if (obj.Length == 0) return 17 * 23; //equal to int[] { 0 } int nonZeroLength = obj.Length; for (; nonZeroLength > 0; nonZeroLength--) { if (obj[nonZeroLength - 1] != 0) break; } int result = 17; for (int i = 0; i < nonZeroLength; i++) { unchecked { result = result * 23 + obj[i]; } } return result; } } }