using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using JetBrains.Annotations;
#pragma warning disable 169
namespace Robust.Shared.Utility
{
///
/// Fixed size array stack allocation helpers.
///
///
///
/// This helper class can be used to work around the limitation that stackalloc
/// cannot be used with ref types.
///
///
/// To use, call it like so:
///
/// var span = FixedArray.Alloc32<object>(out _);
///
/// There is an out parameter that you should probably always discard (as shown in the example).
/// This is so that stack space is properly allocated in your stack frame.
///
///
/// Do NOT under ANY CIRCUMSTANCE return the span given up the stack in any way.
/// You will break the GC and stack and (worst of all) I will shed you.
///
///
/// This class cannot be used with variable size allocations.
/// Just allocate a we'll-never-need-more bound like 128 and slim it down.
///
///
[PublicAPI]
[SuppressMessage("ReSharper", "ArrangeObjectCreationWhenTypeNotEvident")]
internal static class FixedArray
{
public static Span Alloc2(out FixedArray2 discard)
{
discard = new();
return discard.AsSpan;
}
public static Span Alloc4(out FixedArray4 discard)
{
discard = new();
return discard.AsSpan;
}
public static Span Alloc8(out FixedArray8 discard)
{
discard = new();
return discard.AsSpan;
}
public static Span Alloc16(out FixedArray16 discard)
{
discard = new();
return discard.AsSpan;
}
public static Span Alloc32(out FixedArray32 discard)
{
discard = new();
return discard.AsSpan;
}
public static Span Alloc64(out FixedArray64 discard)
{
discard = new();
return discard.AsSpan;
}
public static Span Alloc128(out FixedArray128 discard)
{
discard = new();
return discard.AsSpan;
}
}
internal struct FixedArray2 : IEquatable>
{
public T _00;
public T _01;
public Span AsSpan => MemoryMarshal.CreateSpan(ref _00, 2);
internal FixedArray2(T x0, T x1)
{
_00 = x0;
_01 = x1;
}
public bool Equals(FixedArray2 other)
{
return EqualityComparer.Default.Equals(_00, other._00) &&
EqualityComparer.Default.Equals(_01, other._01);
}
public override bool Equals(object? obj)
{
return obj is FixedArray2 other && Equals(other);
}
public override int GetHashCode()
{
return HashCode.Combine(_00, _01);
}
}
internal struct FixedArray4 : IEquatable>
{
public T _00;
public T _01;
public T _02;
public T _03;
public Span AsSpan => MemoryMarshal.CreateSpan(ref _00, 4);
internal FixedArray4(T x0, T x1, T x2, T x3)
{
_00 = x0;
_01 = x1;
_02 = x2;
_03 = x3;
}
public bool Equals(FixedArray4 other)
{
return EqualityComparer.Default.Equals(_00, other._00) &&
EqualityComparer.Default.Equals(_01, other._01) &&
EqualityComparer.Default.Equals(_02, other._02) &&
EqualityComparer.Default.Equals(_03, other._03);
}
public override bool Equals(object? obj)
{
return obj is FixedArray4 other && Equals(other);
}
public override int GetHashCode()
{
return HashCode.Combine(_00, _01, _02, _03);
}
}
internal struct FixedArray8 : IEquatable>
{
public T _00;
public T _01;
public T _02;
public T _03;
public T _04;
public T _05;
public T _06;
public T _07;
public Span AsSpan => MemoryMarshal.CreateSpan(ref _00, 8);
internal FixedArray8(T x0, T x1, T x2, T x3, T x4, T x5, T x6, T x7)
{
_00 = x0;
_01 = x1;
_02 = x2;
_03 = x3;
_04 = x4;
_05 = x5;
_06 = x6;
_07 = x7;
}
public bool Equals(FixedArray8 other)
{
return EqualityComparer.Default.Equals(_00, other._00) &&
EqualityComparer.Default.Equals(_01, other._01) &&
EqualityComparer.Default.Equals(_02, other._02) &&
EqualityComparer.Default.Equals(_03, other._03) &&
EqualityComparer.Default.Equals(_04, other._04) &&
EqualityComparer.Default.Equals(_05, other._05) &&
EqualityComparer.Default.Equals(_06, other._06) &&
EqualityComparer.Default.Equals(_07, other._07);
}
public override bool Equals(object? obj)
{
return obj is FixedArray8 other && Equals(other);
}
public override int GetHashCode()
{
return HashCode.Combine(_00, _01, _02, _03, _04, _05, _06, _07);
}
}
internal struct FixedArray16
{
public T _00;
public T _01;
public T _02;
public T _03;
public T _04;
public T _05;
public T _06;
public T _07;
public T _08;
public T _09;
public T _10;
public T _11;
public T _12;
public T _13;
public T _14;
public T _15;
public Span AsSpan => MemoryMarshal.CreateSpan(ref _00, 16);
}
internal struct FixedArray32
{
public T _00;
public T _01;
public T _02;
public T _03;
public T _04;
public T _05;
public T _06;
public T _07;
public T _08;
public T _09;
public T _10;
public T _11;
public T _12;
public T _13;
public T _14;
public T _15;
public T _16;
public T _17;
public T _18;
public T _19;
public T _20;
public T _21;
public T _22;
public T _23;
public T _24;
public T _25;
public T _26;
public T _27;
public T _28;
public T _29;
public T _30;
public T _31;
public Span AsSpan => MemoryMarshal.CreateSpan(ref _00, 32);
}
internal struct FixedArray64
{
public T _00;
public T _01;
public T _02;
public T _03;
public T _04;
public T _05;
public T _06;
public T _07;
public T _08;
public T _09;
public T _10;
public T _11;
public T _12;
public T _13;
public T _14;
public T _15;
public T _16;
public T _17;
public T _18;
public T _19;
public T _20;
public T _21;
public T _22;
public T _23;
public T _24;
public T _25;
public T _26;
public T _27;
public T _28;
public T _29;
public T _30;
public T _31;
public T _32;
public T _33;
public T _34;
public T _35;
public T _36;
public T _37;
public T _38;
public T _39;
public T _40;
public T _41;
public T _42;
public T _43;
public T _44;
public T _45;
public T _46;
public T _47;
public T _48;
public T _49;
public T _50;
public T _51;
public T _52;
public T _53;
public T _54;
public T _55;
public T _56;
public T _57;
public T _58;
public T _59;
public T _60;
public T _61;
public T _62;
public T _63;
public Span AsSpan => MemoryMarshal.CreateSpan(ref _00, 64);
}
internal struct FixedArray128
{
public T _00;
public T _01;
public T _02;
public T _03;
public T _04;
public T _05;
public T _06;
public T _07;
public T _08;
public T _09;
public T _10;
public T _11;
public T _12;
public T _13;
public T _14;
public T _15;
public T _16;
public T _17;
public T _18;
public T _19;
public T _20;
public T _21;
public T _22;
public T _23;
public T _24;
public T _25;
public T _26;
public T _27;
public T _28;
public T _29;
public T _30;
public T _31;
public T _32;
public T _33;
public T _34;
public T _35;
public T _36;
public T _37;
public T _38;
public T _39;
public T _40;
public T _41;
public T _42;
public T _43;
public T _44;
public T _45;
public T _46;
public T _47;
public T _48;
public T _49;
public T _50;
public T _51;
public T _52;
public T _53;
public T _54;
public T _55;
public T _56;
public T _57;
public T _58;
public T _59;
public T _60;
public T _61;
public T _62;
public T _63;
public T _64;
public T _65;
public T _66;
public T _67;
public T _68;
public T _69;
public T _70;
public T _71;
public T _72;
public T _73;
public T _74;
public T _75;
public T _76;
public T _77;
public T _78;
public T _79;
public T _80;
public T _81;
public T _82;
public T _83;
public T _84;
public T _85;
public T _86;
public T _87;
public T _88;
public T _89;
public T _90;
public T _91;
public T _92;
public T _93;
public T _94;
public T _95;
public T _96;
public T _97;
public T _98;
public T _99;
public T _100;
public T _101;
public T _102;
public T _103;
public T _104;
public T _105;
public T _106;
public T _107;
public T _108;
public T _109;
public T _110;
public T _111;
public T _112;
public T _113;
public T _114;
public T _115;
public T _116;
public T _117;
public T _118;
public T _119;
public T _120;
public T _121;
public T _122;
public T _123;
public T _124;
public T _125;
public T _126;
public T _127;
public Span AsSpan => MemoryMarshal.CreateSpan(ref _00, 128);
}
}