Created
January 9, 2022 20:35
-
-
Save cbaggers/b5dd75d3eefe686912d71c22cb40ba7e to your computer and use it in GitHub Desktop.
ntuple thing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Runtime.CompilerServices; | |
using System.Runtime.InteropServices; | |
// Value Tuples that are blittable and so can be used in Unity's Jobs | |
// Replace with HashCode with System.HashCode when available | |
namespace Foo.Unmanaged | |
{ | |
public static class NTuple | |
{ | |
public static NTuple<A, B> New<A, B>(A item1, B item2) | |
where A : unmanaged | |
where B : unmanaged | |
{ | |
return new NTuple<A, B>(item1, item2); | |
} | |
public static NTuple<A, B, C> New<A, B, C>(A item1, B item2, C item3) | |
where A : unmanaged | |
where B : unmanaged | |
where C : unmanaged | |
{ | |
return new NTuple<A, B, C>(item1, item2, item3); | |
} | |
public static NTuple<A, B, C, D> New<A, B, C, D>(A item1, B item2, C item3, D item4) | |
where A : unmanaged | |
where B : unmanaged | |
where C : unmanaged | |
where D : unmanaged | |
{ | |
return new NTuple<A, B, C, D>(item1, item2, item3, item4); | |
} | |
public static NTuple<A, B, C, D, E> New<A, B, C, D, E>(A item1, B item2, C item3, D item4, E item5) | |
where A : unmanaged | |
where B : unmanaged | |
where C : unmanaged | |
where D : unmanaged | |
where E : unmanaged | |
{ | |
return new NTuple<A, B, C, D, E>(item1, item2, item3, item4, item5); | |
} | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
public struct NTuple<A, B> : IEquatable<NTuple<A, B>>, IEquatable<ValueTuple<A, B>> | |
where A : unmanaged | |
where B : unmanaged | |
{ | |
public A Item1; | |
public B Item2; | |
public NTuple(A item1, B item2) | |
{ | |
Item1 = item1; | |
Item2 = item2; | |
} | |
public bool Equals(NTuple<A, B> other) => | |
Item1.Equals(other.Item1) && | |
Item2.Equals(other.Item2); | |
public bool Equals(ValueTuple<A, B> other) => | |
Item1.Equals(other.Item1) && | |
Item2.Equals(other.Item2); | |
public override bool Equals(object obj) => (obj is NTuple<A, B> tuple) && Equals(tuple); | |
public static bool operator ==(NTuple<A, B> left, NTuple<A, B> right) => left.Equals(right); | |
public static bool operator !=(NTuple<A, B> left, NTuple<A, B> right) => !left.Equals(right); | |
public static bool operator ==(NTuple<A, B> left, ValueTuple<A, B> right) => left.Equals(right); | |
public static bool operator !=(NTuple<A, B> left, ValueTuple<A, B> right) => !left.Equals(right); | |
public static bool operator ==(ValueTuple<A, B> left, NTuple<A, B> right) => left.Equals(right); | |
public static bool operator !=(ValueTuple<A, B> left, NTuple<A, B> right) => !left.Equals(right); | |
public override int GetHashCode() => HashCode.Combine(Item1, Item2); | |
public static implicit operator ValueTuple<A, B>(NTuple<A, B> v) => new ValueTuple<A, B>(v.Item1, v.Item2); | |
public static implicit operator NTuple<A, B>(ValueTuple<A, B> v) => new NTuple<A, B>(v.Item1, v.Item2); | |
public void Deconstruct(out A item1, out B item2) | |
{ | |
item1 = Item1; | |
item2 = Item2; | |
} | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
public struct NTuple<A, B, C> : IEquatable<NTuple<A, B, C>>, IEquatable<ValueTuple<A, B, C>> | |
where A : unmanaged | |
where B : unmanaged | |
where C : unmanaged | |
{ | |
public A Item1; | |
public B Item2; | |
public C Item3; | |
public NTuple(A item1, B item2, C item3) | |
{ | |
Item1 = item1; | |
Item2 = item2; | |
Item3 = item3; | |
} | |
public bool Equals(NTuple<A, B, C> other) => | |
Item1.Equals(other.Item1) && | |
Item2.Equals(other.Item2) && | |
Item3.Equals(other.Item3); | |
public bool Equals(ValueTuple<A, B, C> other) => | |
Item1.Equals(other.Item1) && | |
Item2.Equals(other.Item2) && | |
Item3.Equals(other.Item3); | |
public override bool Equals(object obj) => (obj is NTuple<A, B, C> tuple) && Equals(tuple); | |
public static bool operator ==(NTuple<A, B, C> left, NTuple<A, B, C> right) => left.Equals(right); | |
public static bool operator !=(NTuple<A, B, C> left, NTuple<A, B, C> right) => !left.Equals(right); | |
public static bool operator ==(NTuple<A, B, C> left, ValueTuple<A, B, C> right) => left.Equals(right); | |
public static bool operator !=(NTuple<A, B, C> left, ValueTuple<A, B, C> right) => !left.Equals(right); | |
public static bool operator ==(ValueTuple<A, B, C> left, NTuple<A, B, C> right) => left.Equals(right); | |
public static bool operator !=(ValueTuple<A, B, C> left, NTuple<A, B, C> right) => !left.Equals(right); | |
public override int GetHashCode() => HashCode.Combine(Item1, Item2, Item3); | |
public static implicit operator ValueTuple<A, B, C>(NTuple<A, B, C> v) => | |
new ValueTuple<A, B, C>(v.Item1, v.Item2, v.Item3); | |
public static implicit operator NTuple<A, B, C>(ValueTuple<A, B, C> v) => | |
new NTuple<A, B, C>(v.Item1, v.Item2, v.Item3); | |
public void Deconstruct(out A item1, out B item2, out C item3) | |
{ | |
item1 = Item1; | |
item2 = Item2; | |
item3 = Item3; | |
} | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
public struct NTuple<A, B, C, D> : IEquatable<NTuple<A, B, C, D>>, IEquatable<ValueTuple<A, B, C, D>> | |
where A : unmanaged | |
where B : unmanaged | |
where C : unmanaged | |
where D : unmanaged | |
{ | |
public A Item1; | |
public B Item2; | |
public C Item3; | |
public D Item4; | |
public NTuple(A item1, B item2, C item3, D item4) | |
{ | |
Item1 = item1; | |
Item2 = item2; | |
Item3 = item3; | |
Item4 = item4; | |
} | |
public bool Equals(NTuple<A, B, C, D> other) => | |
Item1.Equals(other.Item1) && | |
Item2.Equals(other.Item2) && | |
Item3.Equals(other.Item3) && | |
Item4.Equals(other.Item4); | |
public bool Equals(ValueTuple<A, B, C, D> other) => | |
Item1.Equals(other.Item1) && | |
Item2.Equals(other.Item2) && | |
Item3.Equals(other.Item3) && | |
Item4.Equals(other.Item4); | |
public override bool Equals(object obj) => | |
(obj is NTuple<A, B, C, D> tuple) && Equals(tuple); | |
public static bool operator ==(NTuple<A, B, C, D> left, NTuple<A, B, C, D> right) => left.Equals(right); | |
public static bool operator !=(NTuple<A, B, C, D> left, NTuple<A, B, C, D> right) => !left.Equals(right); | |
public static bool operator ==(NTuple<A, B, C, D> left, ValueTuple<A, B, C, D> right) => left.Equals(right); | |
public static bool operator !=(NTuple<A, B, C, D> left, ValueTuple<A, B, C, D> right) => !left.Equals(right); | |
public static bool operator ==(ValueTuple<A, B, C, D> left, NTuple<A, B, C, D> right) => left.Equals(right); | |
public static bool operator !=(ValueTuple<A, B, C, D> left, NTuple<A, B, C, D> right) => !left.Equals(right); | |
public override int GetHashCode() => HashCode.Combine(Item1, Item2, Item3, Item4); | |
public static implicit operator ValueTuple<A, B, C, D>(NTuple<A, B, C, D> v) => | |
new ValueTuple<A, B, C, D>(v.Item1, v.Item2, v.Item3, v.Item4); | |
public static implicit operator NTuple<A, B, C, D>(ValueTuple<A, B, C, D> v) => | |
new NTuple<A, B, C, D>(v.Item1, v.Item2, v.Item3, v.Item4); | |
public void Deconstruct(out A item1, out B item2, out C item3, out D item4) | |
{ | |
item1 = Item1; | |
item2 = Item2; | |
item3 = Item3; | |
item4 = Item4; | |
} | |
} | |
[StructLayout(LayoutKind.Sequential)] | |
public struct NTuple<A, B, C, D, E> : IEquatable<NTuple<A, B, C, D, E>>, IEquatable<ValueTuple<A, B, C, D, E>> | |
where A : unmanaged | |
where B : unmanaged | |
where C : unmanaged | |
where D : unmanaged | |
where E : unmanaged | |
{ | |
public A Item1; | |
public B Item2; | |
public C Item3; | |
public D Item4; | |
public E Item5; | |
public NTuple(A item1, B item2, C item3, D item4, E item5) | |
{ | |
Item1 = item1; | |
Item2 = item2; | |
Item3 = item3; | |
Item4 = item4; | |
Item5 = item5; | |
} | |
public override bool Equals(object obj) => (obj is NTuple<A, B, C, D, E> tuple) && Equals(tuple); | |
public bool Equals(NTuple<A, B, C, D, E> other) => | |
Item1.Equals(other.Item1) && | |
Item2.Equals(other.Item2) && | |
Item3.Equals(other.Item3) && | |
Item4.Equals(other.Item4) && | |
Item5.Equals(other.Item5); | |
public bool Equals(ValueTuple<A, B, C, D, E> other) => | |
Item1.Equals(other.Item1) && | |
Item2.Equals(other.Item2) && | |
Item3.Equals(other.Item3) && | |
Item4.Equals(other.Item4) && | |
Item5.Equals(other.Item5); | |
public static bool operator ==(NTuple<A, B, C, D, E> left, NTuple<A, B, C, D, E> right) => left.Equals(right); | |
public static bool operator !=(NTuple<A, B, C, D, E> left, NTuple<A, B, C, D, E> right) => !left.Equals(right); | |
public static bool operator ==(NTuple<A, B, C, D, E> left, ValueTuple<A, B, C, D, E> right) => left.Equals(right); | |
public static bool operator !=(NTuple<A, B, C, D, E> left, ValueTuple<A, B, C, D, E> right) => !left.Equals(right); | |
public static bool operator ==(ValueTuple<A, B, C, D, E> left, NTuple<A, B, C, D, E> right) => left.Equals(right); | |
public static bool operator !=(ValueTuple<A, B, C, D, E> left, NTuple<A, B, C, D, E> right) => !left.Equals(right); | |
public override int GetHashCode() => HashCode.Combine(Item1, Item2, Item3, Item4, Item5); | |
public static implicit operator ValueTuple<A, B, C, D, E>(NTuple<A, B, C, D, E> v) => | |
new ValueTuple<A, B, C, D, E>(v.Item1, v.Item2, v.Item3, v.Item4, v.Item5); | |
public static implicit operator NTuple<A, B, C, D, E>(ValueTuple<A, B, C, D, E> v) => | |
new NTuple<A, B, C, D, E>(v.Item1, v.Item2, v.Item3, v.Item4, v.Item5); | |
public void Deconstruct(out A item1, out B item2, out C item3, out D item4, out E item5) | |
{ | |
item1 = Item1; | |
item2 = Item2; | |
item3 = Item3; | |
item4 = Item4; | |
item5 = Item5; | |
} | |
} | |
public static class HashCode | |
{ | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static int Combine<A,B>(A item1, B item2) | |
{ | |
return CombineHashCodes(item1.GetHashCode(), item2.GetHashCode()); | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static int Combine<A,B,C>(A item1, B item2, C item3) | |
{ | |
return CombineHashCodes(item1.GetHashCode(), item2.GetHashCode(), item3.GetHashCode()); | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static int Combine<A,B,C,D>(A item1, B item2, C item3, D item4) | |
{ | |
return CombineHashCodes(item1.GetHashCode(), item2.GetHashCode(), item3.GetHashCode(), item4.GetHashCode()); | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static int Combine<A,B,C,D,E>(A item1, B item2, C item3, D item4, E item5) | |
{ | |
return CombineHashCodes(item1.GetHashCode(), item2.GetHashCode(), item3.GetHashCode(), item4.GetHashCode(), item5.GetHashCode()); | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static int Combine<A,B,C,D,E,F>(A item1, B item2, C item3, D item4, E item5, F item6) | |
{ | |
return CombineHashCodes(item1.GetHashCode(), item2.GetHashCode(), item3.GetHashCode(), item4.GetHashCode(), item5.GetHashCode(), | |
item6.GetHashCode()); | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static int Combine<A,B,C,D,E,F,G>(A item1, B item2, C item3, D item4, E item5, F item6, G item7) | |
{ | |
return CombineHashCodes(item1.GetHashCode(), item2.GetHashCode(), item3.GetHashCode(), item4.GetHashCode(), item5.GetHashCode(), | |
item6.GetHashCode(), item7.GetHashCode()); | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static int Combine<A,B,C,D,E,F,G,H>(A item1, B item2, C item3, D item4, E item5, F item6, G item7, H item8) | |
{ | |
return CombineHashCodes(item1.GetHashCode(), item2.GetHashCode(), item3.GetHashCode(), item4.GetHashCode(), item5.GetHashCode(), | |
item6.GetHashCode(), item7.GetHashCode(), item8.GetHashCode()); | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static int Combine<A,B,C,D,E,F,G,H,I>(A item1, B item2, C item3, D item4, E item5, F item6, G item7, H item8, I item9) | |
{ | |
return CombineHashCodes(item1.GetHashCode(), item2.GetHashCode(), item3.GetHashCode(), item4.GetHashCode(), item5.GetHashCode(), | |
item6.GetHashCode(), item7.GetHashCode(), item8.GetHashCode(), item9.GetHashCode()); | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static int Combine<A,B,C,D,E,F,G,H,I,J>(A item1, B item2, C item3, D item4, E item5, F item6, G item7, H item8, I item9, J item10) | |
{ | |
return CombineHashCodes(item1.GetHashCode(), item2.GetHashCode(), item3.GetHashCode(), item4.GetHashCode(), item5.GetHashCode(), | |
item6.GetHashCode(), item7.GetHashCode(), item8.GetHashCode(), item9.GetHashCode(), item10.GetHashCode()); | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static int Combine<A,B,C,D,E,F,G,H,I,J,K>(A item1, B item2, C item3, D item4, E item5, F item6, G item7, H item8, I item9, J item10, K item11) | |
{ | |
return CombineHashCodes(item1.GetHashCode(), item2.GetHashCode(), item3.GetHashCode(), item4.GetHashCode(), item5.GetHashCode(), | |
item6.GetHashCode(), item7.GetHashCode(), item8.GetHashCode(), item9.GetHashCode(), item10.GetHashCode(), item11.GetHashCode()); | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static int CombineHashCodes(int h1, int h2) | |
{ | |
// https://stackoverflow.com/questions/1646807/quick-and-simple-hash-code-combinations | |
var hash = 17; | |
hash = hash * 31 + h1; | |
hash = hash * 31 + h2; | |
return hash; | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static int CombineHashCodes(int h1, int h2, int h3) | |
{ | |
return CombineHashCodes(CombineHashCodes(h1, h2), h3); | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static int CombineHashCodes(int h1, int h2, int h3, int h4) | |
{ | |
return CombineHashCodes(CombineHashCodes(h1, h2), CombineHashCodes(h3, h4)); | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5) | |
{ | |
return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), h5); | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6) | |
{ | |
return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), CombineHashCodes(h5, h6)); | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7) | |
{ | |
return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), CombineHashCodes(h5, h6, h7)); | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7, int h8) | |
{ | |
return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), CombineHashCodes(h5, h6, h7, h8)); | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7, int h8, int h9) | |
{ | |
return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), CombineHashCodes(h5, h6, h7, h8), h9); | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7, int h8, int h9, int h10) | |
{ | |
return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), CombineHashCodes(h5, h6, h7, h8), h9, h10); | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static int CombineHashCodes(int h1, int h2, int h3, int h4, int h5, int h6, int h7, int h8, int h9, int h10, int h11) | |
{ | |
return CombineHashCodes(CombineHashCodes(h1, h2, h3, h4), CombineHashCodes(h5, h6, h7, h8), h9, h10, h11); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment