Will effect all tests as the byte order of components would change.
Could also have properties which fall at the original offsets and give different names to ABCD
/// <summary>
/// A single <see cref="System.Numerics.Vector{double}"/> or dual <see cref="System.Numerics.Vector4"/>.
/// Contains 4 <see cref="Vector4Half"/>
/// </summary>
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Explicit, Size = Vector8Float.Size)]
public struct Vector8Float
{
const int Size = sizeof(float) * 8;
/// <summary>
/// 4 Doubles
/// </summary>
[System.Runtime.InteropServices.FieldOffset(00)]
public System.Numerics.Vector<double> Vector;
/// <summary>
/// 4 Floats
/// </summary>
[System.Runtime.InteropServices.FieldOffset(00)]
public System.Numerics.Vector4 High;
[System.Runtime.InteropServices.FieldOffset(00)]
public float D;
[System.Runtime.InteropServices.FieldOffset(04)]
public float A;
[System.Runtime.InteropServices.FieldOffset(08)]
public float B;
[System.Runtime.InteropServices.FieldOffset(12)]
public float C;
/// <summary>
/// 4 Floats
/// </summary>
[System.Runtime.InteropServices.FieldOffset(16)]
public System.Numerics.Vector4 Low;
[System.Runtime.InteropServices.FieldOffset(16)]
public float W;
[System.Runtime.InteropServices.FieldOffset(20)]
public float X;
[System.Runtime.InteropServices.FieldOffset(24)]
public float Y;
[System.Runtime.InteropServices.FieldOffset(28)]
public float Z;
/// <summary>
/// 4 Halfs
/// </summary>
[System.Runtime.InteropServices.FieldOffset(00)]
public Vector4Half P;
/// <summary>
/// 4 Halfs
/// </summary>
[System.Runtime.InteropServices.FieldOffset(08)]
public Vector4Half Q;
/// <summary>
/// 4 Halfs
/// </summary>
[System.Runtime.InteropServices.FieldOffset(16)]
public Vector4Half R;
/// <summary>
/// 4 Halfs
/// </summary>
[System.Runtime.InteropServices.FieldOffset(24)]
public Vector4Half S;
/// <summary>
/// Gets or Sets the Raw Binary data assoicated with the instance (32 bytes)
/// </summary>
public System.Span<byte> RawBytes
{
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
get { return System.Runtime.InteropServices.MemoryMarshal.CreateSpan(ref System.Runtime.CompilerServices.Unsafe.As<System.Numerics.Vector<double>, byte>(ref Vector), Vector8Float.Size); }
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
set { value.CopyTo(RawBytes); }
}
/// <summary>
/// Access elements by offset
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public float this[int index]
{
get
{
switch (index)
{
case 0: return D;
case 1: return A;
case 2: return B;
case 3: return C;
case 4: return W;
case 5: return X;
case 6: return Y;
case 7: return Z;
default: throw new System.ArgumentOutOfRangeException(nameof(index));
}
}
}
public Vector8Float(float[] eight) : this()
{
//Todo profile if the runtime optomizes load asm for this or if RawBytes copy is better
//High = new System.Numerics.Vector4(eight[0], eight[1], eight[2], eight[3]);
//Low = new System.Numerics.Vector4(eight[4], eight[5], eight[6], eight[7]);
//Warning these are shifted [0] = 3,
//This means we have to change the variables used in the arc / circle math because/
//they depend on a predefined order abcdwxyz
//this order is dabcwxyz
var c = System.Runtime.InteropServices.MemoryMarshal.CreateSpan(ref System.Runtime.CompilerServices.Unsafe.As<float, byte>(ref eight[0]), eight.Length * sizeof(float));
c.CopyTo(RawBytes);
}
/// <summary>
/// </summary>
/// <param name="four"></param>
public Vector8Float(double[] four) : this()
{
High = Low = default;
Vector = new System.Numerics.Vector<double>(four);
}
/// <summary>
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <param name="w"></param>
public Vector8Float(double x, double y, double z, double w)
: this(new double[] { x, y, z, w }) { }
/// <summary>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="c"></param>
/// <param name="d"></param>
public Vector8Float(float a, float b, float c, float d)
: this(new float[] { a, b, c, d }) { }
/// <summary>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="c"></param>
/// <param name="d"></param>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <param name="w"></param>
public Vector8Float(float a, float b, float c, float d, float x, float y, float z, float w) :
this(new float[] { a, b, c, d, x, y, z, w }) { }
/// <summary>
///
/// </summary>
/// <param name="high"></param>
/// <param name="low"></param>
public Vector8Float(System.Numerics.Vector4 high, System.Numerics.Vector4 low) : this()
{
Vector = default;
High = high;
Low = low;
}
public override string ToString()=> string.Join(" ", High.ToString(), Low.ToString());
}