// Copyright (c) 2014 Robert Rouhani and other contributors (see CONTRIBUTORS file). // Licensed under the MIT License - https://raw.github.com/Robmaister/SharpNav/master/LICENSE using System; using System.Runtime.InteropServices; namespace SharpNav { /// /// A reference to a in a . /// [StructLayout(LayoutKind.Sequential)] public struct CompactSpanReference : IEquatable { /// /// A "null" reference is one with a negative index. /// public static readonly CompactSpanReference Null = new CompactSpanReference(0, 0, -1); /// /// The X coordinate of the referenced span. /// public readonly int X; /// /// The Y coordinate of the referenced span. /// public readonly int Y; /// /// The index of the referenced span in the spans array. /// public readonly int Index; /// /// Initializes a new instance of the struct. /// /// The X coordinate. /// The Y coordinate. /// The index of the span in the spans array. public CompactSpanReference(int x, int y, int i) { this.X = x; this.Y = y; this.Index = i; } /// /// Compares two instances of for equality. /// /// /// If both references have a negative , they are considered equal, as both would be considered "null". /// /// A reference. /// Another reference. /// A value indicating whether the two references are equal. public static bool operator ==(CompactSpanReference left, CompactSpanReference right) { //A negative index is considered null. //these two cases quickly compare null references. bool leftNull = left.Index < 0, rightNull = right.Index < 0; if (leftNull && rightNull) return true; else if (leftNull ^ rightNull) return false; //if the references are not null, else if (left.X == right.X && left.Y == right.Y && left.Index == right.Index) return true; return false; } /// /// Compare two instances of for inequality. /// /// /// If both references have a negative , they are considered equal, as both would be considered "null". /// /// A reference. /// Another reference. /// A value indicating whether the two references are not equal. public static bool operator !=(CompactSpanReference left, CompactSpanReference right) { return !(left == right); } /// /// Compares this instance to another instance of for equality. /// /// Another instance of . /// A value indicating whether this instance and another instance are equal. public bool Equals(CompactSpanReference other) { return this == other; } /// /// Compares this instance to another object for equality. /// /// An object. /// A value indicating whether the object is equal to this instance. public override bool Equals(object obj) { CompactSpanReference? r = obj as CompactSpanReference?; if (r.HasValue) return this == r.Value; return false; } /// /// Gets a hash code unique to this instance. /// /// A hash code. public override int GetHashCode() { //TODO should "null" references all have the same hash? int hash = 27; hash = (13 * hash) + X.GetHashCode(); hash = (13 * hash) + Y.GetHashCode(); hash = (13 * hash) + Index.GetHashCode(); return hash; } } }