Last active
December 21, 2019 18:12
-
-
Save paavohuhtala/f5732220c3b6e39daeb92405d027736f to your computer and use it in GitHub Desktop.
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
[StructLayout(LayoutKind.Sequential)] | |
public struct BitArray512<TEnum> : IEquatable<BitArray512<TEnum>> | |
{ | |
private ulong _a0; | |
private ulong _a1; | |
private ulong _a2; | |
private ulong _a3; | |
private ulong _a4; | |
private ulong _a5; | |
private ulong _a6; | |
private ulong _a7; | |
private int _setBits; | |
public static readonly int Length = Enum.GetValues(typeof(TEnum)).Length; | |
public bool AnyBitSet | |
{ | |
get => SetBitsCount > 0; | |
} | |
public int SetBitsCount | |
{ | |
get | |
{ | |
if (_setBits == -1) | |
{ | |
_setBits = (int) CountSetBits(); | |
} | |
return _setBits; | |
} | |
} | |
public void Set(int bit, bool value) | |
{ | |
var byteOffset = bit >> 3; // bit / 8 | |
var bitOffset = bit & 7; // bit % 8 | |
unsafe | |
{ | |
var pointer = (byte*) Unsafe.AsPointer(ref this); | |
if (value) | |
{ | |
*(pointer + byteOffset) |= (byte) (1 << bitOffset); | |
} | |
else | |
{ | |
*(pointer + byteOffset) &= (byte) ~(1 << bitOffset); | |
} | |
} | |
_setBits = -1; | |
} | |
public bool Get(int bit) | |
{ | |
var byteOffset = bit >> 3; // bit / 8 | |
var bitOffset = bit & 7; // bit % 8 | |
unsafe | |
{ | |
var pointer = (byte*) Unsafe.AsPointer(ref this); | |
return (*(pointer + byteOffset) & (1 << bitOffset)) > 0; | |
} | |
} | |
public void SetAll(bool value) | |
{ | |
var byteOffset = 0; | |
var remainingBits = Length; | |
unsafe | |
{ | |
var pointerLong = (ulong*) Unsafe.AsPointer(ref this); | |
var targetLong = value ? ulong.MaxValue : 0; | |
while (remainingBits >= 64) | |
{ | |
*pointerLong = targetLong; | |
pointerLong++; | |
byteOffset += 8; | |
remainingBits -= 64; | |
} | |
for (var i = byteOffset; i < remainingBits; i++) | |
{ | |
Set(i, value); | |
} | |
} | |
if (value) | |
{ | |
_setBits = Length; | |
} | |
else | |
{ | |
_setBits = 0; | |
} | |
} | |
private int CountSetBits() | |
{ | |
return BitOperations.PopCount(_a0) + | |
BitOperations.PopCount(_a1) + | |
BitOperations.PopCount(_a2) + | |
BitOperations.PopCount(_a3) + | |
BitOperations.PopCount(_a4) + | |
BitOperations.PopCount(_a5) + | |
BitOperations.PopCount(_a6) + | |
BitOperations.PopCount(_a7); | |
} | |
public BitArray512<TEnum> And(BitArray512<TEnum> other) | |
{ | |
return new BitArray512<TEnum> { | |
_a0 = _a0 & other._a0, | |
_a1 = _a1 & other._a1, | |
_a2 = _a2 & other._a2, | |
_a3 = _a3 & other._a3, | |
_a4 = _a4 & other._a4, | |
_a5 = _a5 & other._a5, | |
_a6 = _a6 & other._a6, | |
_a7 = _a7 & other._a7 | |
}; | |
} | |
public bool Equals(BitArray512<TEnum> other) | |
{ | |
return | |
_a0 == other._a0 && | |
_a1 == other._a1 && | |
_a2 == other._a2 && | |
_a3 == other._a3 && | |
_a4 == other._a4 && | |
_a5 == other._a5 && | |
_a6 == other._a6 && | |
_a7 == other._a7; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment