Variable.cs 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. namespace NTERA.Engine
  4. {
  5. public class Variable : IEnumerable<KeyValuePair<int[], Value>>
  6. {
  7. public string Name { get; }
  8. public ValueType Type { get; }
  9. protected Dictionary<int[], Value> Dictionary { get; } = new Dictionary<int[], Value>(new ZeroIntegerArrayEqualityComparer());
  10. public Variable(string name, ValueType type)
  11. {
  12. Name = name;
  13. Type = type;
  14. }
  15. public virtual Value this[params int[] index]
  16. {
  17. get
  18. {
  19. if (Dictionary.TryGetValue(index, out var value))
  20. return value;
  21. return Type == ValueType.String ? new Value("") : new Value(0d);
  22. }
  23. set => Dictionary[index] = value;
  24. }
  25. public IEnumerator<KeyValuePair<int[], Value>> GetEnumerator()
  26. {
  27. return Dictionary.GetEnumerator();
  28. }
  29. IEnumerator IEnumerable.GetEnumerator()
  30. {
  31. return ((IEnumerable)Dictionary).GetEnumerator();
  32. }
  33. }
  34. public class ZeroIntegerArrayEqualityComparer : IEqualityComparer<int[]>
  35. {
  36. public bool Equals(int[] x, int[] y)
  37. {
  38. if (x == null && y != null
  39. || y == null && x != null)
  40. return false;
  41. if (x == null || x.Length == 0)
  42. x = new[] { 0 };
  43. if (y == null || y.Length == 0)
  44. y = new[] { 0 };
  45. int xNonZeroLength = x.Length;
  46. int yNonZeroLength = y.Length;
  47. for (; xNonZeroLength > 0; xNonZeroLength--)
  48. {
  49. if (x[xNonZeroLength - 1] != 0)
  50. break;
  51. }
  52. for (; yNonZeroLength > 0; yNonZeroLength--)
  53. {
  54. if (y[yNonZeroLength - 1] != 0)
  55. break;
  56. }
  57. if (xNonZeroLength != yNonZeroLength)
  58. {
  59. return false;
  60. }
  61. for (int i = 0; i < xNonZeroLength; i++)
  62. {
  63. if (x[i] != y[i])
  64. {
  65. return false;
  66. }
  67. }
  68. return true;
  69. }
  70. public int GetHashCode(int[] obj)
  71. {
  72. if (obj.Length == 0)
  73. return 17 * 23; //equal to int[] { 0 }
  74. int nonZeroLength = obj.Length;
  75. for (; nonZeroLength > 0; nonZeroLength--)
  76. {
  77. if (obj[nonZeroLength - 1] != 0)
  78. break;
  79. }
  80. int result = 17;
  81. for (int i = 0; i < nonZeroLength; i++)
  82. {
  83. unchecked
  84. {
  85. result = result * 23 + obj[i];
  86. }
  87. }
  88. return result;
  89. }
  90. }
  91. }