namespace Ghost.Core; public readonly struct Handle : IEquatable> { public int ID { get => field - 1; } public int Generation { get => field - 1; } public Handle(int id, int generation) { ID = id + 1; Generation = generation + 1; } public static Handle Invalid => default; public readonly bool IsValid => this != Invalid; public readonly bool IsInvalid => this == Invalid; public readonly override int GetHashCode() { return ID + (Generation << 16); } public readonly override bool Equals(object? obj) { return obj is Handle id && Equals(id); } public override string ToString() { return $"Handle<{typeof(T).Name}>({ID}, {Generation})"; } public readonly bool Equals(Handle other) { return ID == other.ID && Generation == other.Generation; } public readonly int CompareTo(Handle other) { return ID.CompareTo(other.ID); } public static bool operator ==(Handle a, Handle b) { return a.Equals(b); } public static bool operator !=(Handle a, Handle b) { return !a.Equals(b); } } public readonly struct Identifier : IEquatable> { public int Value { get => field - 1; } public Identifier(int value) { Value = value + 1; } public static Identifier Invalid => default; public readonly bool IsValid => this != Invalid; public readonly bool IsInvalid => this == Invalid; public readonly override int GetHashCode() { return Value; } public readonly override bool Equals(object? obj) { return obj is Identifier id && Equals(id); } public override string ToString() { return $"Identifier<{typeof(T).Name}>({Value})"; } public readonly bool Equals(Identifier other) { return Value == other.Value; } public readonly int CompareTo(Identifier other) { return Value.CompareTo(other.Value); } public static bool operator ==(Identifier a, Identifier b) { return a.Equals(b); } public static bool operator !=(Identifier a, Identifier b) { return !a.Equals(b); } public static bool operator <(Identifier a, Identifier b) { return a.Value < b.Value; } public static bool operator >(Identifier a, Identifier b) { return a.Value > b.Value; } public static bool operator <=(Identifier a, Identifier b) { return a.Value <= b.Value; } public static bool operator >=(Identifier a, Identifier b) { return a.Value >= b.Value; } public static implicit operator int(Identifier id) => id.Value; public static implicit operator Identifier(int value) => new Identifier(value); } public readonly struct Key64 : IEquatable> { public ulong Value { get; } public Key64(ulong value) { Value = value; } public static Key64 Invalid => new(0); public bool IsValid => this != Invalid; public bool IsInvalid => this == Invalid; public readonly override int GetHashCode() { return Value.GetHashCode(); } public readonly bool Equals(Key64 other) { return Value == other.Value; } public readonly int CompareTo(Key64 other) { return Value.CompareTo(other.Value); } public readonly override bool Equals(object? obj) { return obj is Key64 id && Equals(id); } public override string ToString() { return Value.ToString("X16"); } public static bool operator ==(Key64 a, Key64 b) { return a.Equals(b); } public static bool operator !=(Key64 a, Key64 b) { return !a.Equals(b); } } public readonly struct Key128 : IEquatable> { public UInt128 Value { get; } public Key128(UInt128 value) { Value = value; } public static Key128 Invalid => new(0); public bool IsValid => this != Invalid; public bool IsInvalid => this == Invalid; public readonly override int GetHashCode() { return Value.GetHashCode(); } public readonly bool Equals(Key128 other) { return Value == other.Value; } public readonly int CompareTo(Key128 other) { return Value.CompareTo(other.Value); } public readonly override bool Equals(object? obj) { return obj is Key128 id && Equals(id); } public override string ToString() { return Value.ToString("X16"); } public static bool operator ==(Key128 a, Key128 b) { return a.Equals(b); } public static bool operator !=(Key128 a, Key128 b) { return !a.Equals(b); } }