179 lines
5.4 KiB
C#
179 lines
5.4 KiB
C#
|
using System.Numerics;
|
|||
|
|
|||
|
namespace Encompass.Collections
|
|||
|
{
|
|||
|
public static class BitSet1024Builder
|
|||
|
{
|
|||
|
public static BitSet1024 Zeroes()
|
|||
|
{
|
|||
|
return new BitSet1024(Vector256Builder.Zeroes(), Vector256Builder.Zeroes(), Vector256Builder.Zeroes(), Vector256Builder.Zeroes());
|
|||
|
}
|
|||
|
|
|||
|
public static BitSet1024 Ones()
|
|||
|
{
|
|||
|
return new BitSet1024(Vector256Builder.Ones(), Vector256Builder.Ones(), Vector256Builder.Ones(), Vector256Builder.Ones());
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public static class Vector256Builder
|
|||
|
{
|
|||
|
static readonly uint[] zeroes = new uint[8]; // max size of a Vector<T> is 8 uints
|
|||
|
static readonly uint[] ones = new uint[8] { uint.MaxValue, uint.MaxValue, uint.MaxValue, uint.MaxValue, uint.MaxValue, uint.MaxValue, uint.MaxValue, uint.MaxValue };
|
|||
|
static uint[] builderInts = new uint[8];
|
|||
|
|
|||
|
private static void ResetBuilder()
|
|||
|
{
|
|||
|
for (var i = 0; i < 8; i++)
|
|||
|
{
|
|||
|
builderInts[i] = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public static Vector<uint> Zeroes()
|
|||
|
{
|
|||
|
return new Vector<uint>(zeroes);
|
|||
|
}
|
|||
|
|
|||
|
public static Vector<uint> Ones()
|
|||
|
{
|
|||
|
return new Vector<uint>(ones);
|
|||
|
}
|
|||
|
|
|||
|
public static Vector<uint> Build(int index)
|
|||
|
{
|
|||
|
if (index > 255) { throw new System.ArgumentOutOfRangeException(nameof(index)); }
|
|||
|
ResetBuilder();
|
|||
|
builderInts[index / 32] |= (uint)(1 << (index % 32));
|
|||
|
return new Vector<uint>(builderInts);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public struct BitSet1024
|
|||
|
{
|
|||
|
public Vector<uint> A { get; }
|
|||
|
public Vector<uint> B { get; }
|
|||
|
public Vector<uint> C { get; }
|
|||
|
public Vector<uint> D { get; }
|
|||
|
|
|||
|
internal BitSet1024(Vector<uint> a, Vector<uint> b, Vector<uint> c, Vector<uint> d)
|
|||
|
{
|
|||
|
A = a;
|
|||
|
B = b;
|
|||
|
C = c;
|
|||
|
D = d;
|
|||
|
}
|
|||
|
|
|||
|
public BitSet1024 And(BitSet1024 other)
|
|||
|
{
|
|||
|
return new BitSet1024(A & other.A, B & other.B, C & other.C, D & other.D);
|
|||
|
}
|
|||
|
|
|||
|
public BitSet1024 Or(BitSet1024 other)
|
|||
|
{
|
|||
|
return new BitSet1024(A | other.A, B | other.B, C | other.C, D | other.D);
|
|||
|
}
|
|||
|
|
|||
|
public BitSet1024 Not()
|
|||
|
{
|
|||
|
return new BitSet1024(~A, ~B, ~C, ~D);
|
|||
|
}
|
|||
|
|
|||
|
public BitSet1024 Set(int index)
|
|||
|
{
|
|||
|
if (index < 256)
|
|||
|
{
|
|||
|
return new BitSet1024(A | Vector256Builder.Build(index % 256), B, C, D);
|
|||
|
}
|
|||
|
else if (index < 512)
|
|||
|
{
|
|||
|
return new BitSet1024(A, B | Vector256Builder.Build(index % 256), C, D);
|
|||
|
}
|
|||
|
else if (index < 768)
|
|||
|
{
|
|||
|
return new BitSet1024(A, B, C | Vector256Builder.Build(index % 256), D);
|
|||
|
}
|
|||
|
else if (index < 1024)
|
|||
|
{
|
|||
|
return new BitSet1024(A, B, C, D | Vector256Builder.Build(index % 256));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
throw new System.ArgumentOutOfRangeException(nameof(index));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public BitSet1024 UnSet(int index)
|
|||
|
{
|
|||
|
if (index < 256)
|
|||
|
{
|
|||
|
return new BitSet1024(A & ~Vector256Builder.Build(index % 256), B, C, D);
|
|||
|
}
|
|||
|
else if (index < 512)
|
|||
|
{
|
|||
|
return new BitSet1024(A, B & ~Vector256Builder.Build(index % 256), C, D);
|
|||
|
}
|
|||
|
else if (index < 768)
|
|||
|
{
|
|||
|
return new BitSet1024(A, B, C & ~Vector256Builder.Build(index % 256), D);
|
|||
|
}
|
|||
|
else if (index < 1024)
|
|||
|
{
|
|||
|
return new BitSet1024(A, B, C, D & ~Vector256Builder.Build(index % 256));
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
throw new System.ArgumentOutOfRangeException(nameof(index));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public bool Get(int index)
|
|||
|
{
|
|||
|
var vectorIndex = index % 256;
|
|||
|
if (index < 256)
|
|||
|
{
|
|||
|
return (A[vectorIndex / 32] & (uint)(1 << vectorIndex % 32)) != 0;
|
|||
|
}
|
|||
|
else if (index < 512)
|
|||
|
{
|
|||
|
return (B[vectorIndex / 32] & (uint)(1 << vectorIndex % 32)) != 0;
|
|||
|
}
|
|||
|
else if (index < 768)
|
|||
|
{
|
|||
|
return (C[vectorIndex / 32] & (uint)(1 << vectorIndex % 32)) != 0;
|
|||
|
}
|
|||
|
else if (index < 1024)
|
|||
|
{
|
|||
|
return (D[vectorIndex / 32] & (uint)(1 << vectorIndex % 32)) != 0;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
throw new System.ArgumentOutOfRangeException(nameof(index));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public bool AllTrue()
|
|||
|
{
|
|||
|
for (var i = 0; i < 8; i++)
|
|||
|
{
|
|||
|
if (A[i] != uint.MaxValue) { return false; }
|
|||
|
if (B[i] != uint.MaxValue) { return false; }
|
|||
|
if (C[i] != uint.MaxValue) { return false; }
|
|||
|
if (D[i] != uint.MaxValue) { return false; }
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
public bool AllFalse()
|
|||
|
{
|
|||
|
for (var i = 0; i < 8; i++)
|
|||
|
{
|
|||
|
if (A[i] != 0) { return false; }
|
|||
|
if (B[i] != 0) { return false; }
|
|||
|
if (C[i] != 0) { return false; }
|
|||
|
if (D[i] != 0) { return false; }
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|