2019-12-29 05:16:14 +00:00
|
|
|
|
using System;
|
|
|
|
|
|
|
|
|
|
namespace MoonTools.FastCollections
|
2019-12-29 04:40:44 +00:00
|
|
|
|
{
|
|
|
|
|
public static unsafe class MemoryHelper
|
|
|
|
|
{
|
|
|
|
|
public static void Copy(uint* src, uint* dest, int count)
|
|
|
|
|
{
|
|
|
|
|
for (; count != 0; count--) *dest++ = *src++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void Fill(uint* p, int count, uint value)
|
|
|
|
|
{
|
|
|
|
|
for (; count != 0; count--) *p++ = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void And(uint* p, uint* q, uint* result, int count)
|
|
|
|
|
{
|
|
|
|
|
for (; count != 0; count--) *result++ = *p++ & *q++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void Or(uint* p, uint* q, uint* result, int count)
|
|
|
|
|
{
|
|
|
|
|
for (; count != 0; count--) *result++ = *p++ | *q++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void Not(uint* p, uint* result, int count)
|
|
|
|
|
{
|
|
|
|
|
for (; count != 0; count--) *result++ = ~*p++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static bool Equal(uint* p, uint* q, int count)
|
|
|
|
|
{
|
|
|
|
|
for (; count != 0; count--) if (*p++ != *q++) { return false; }
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static bool NotEqual(uint* p, uint* q, int count)
|
|
|
|
|
{
|
|
|
|
|
for (; count != 0; count--) if (*p++ == *q++) { return false; }
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-29 05:16:14 +00:00
|
|
|
|
public unsafe struct BitSet512 : IEquatable<BitSet512>
|
2019-12-29 04:40:44 +00:00
|
|
|
|
{
|
|
|
|
|
public static BitSet512 Zero { get; } = new BitSet512(0);
|
|
|
|
|
public static BitSet512 Ones { get; } = new BitSet512(uint.MaxValue);
|
|
|
|
|
|
|
|
|
|
private const int _uintLength = 16;
|
|
|
|
|
|
|
|
|
|
private fixed uint _buffer[_uintLength];
|
|
|
|
|
|
|
|
|
|
public BitSet512(uint value)
|
|
|
|
|
{
|
|
|
|
|
fixed (uint* p = _buffer) MemoryHelper.Fill(p, _uintLength, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public BitSet512(uint* src)
|
|
|
|
|
{
|
|
|
|
|
fixed (uint* dest = _buffer) MemoryHelper.Copy(src, dest, _uintLength);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static BitSet512 operator &(BitSet512 a, BitSet512 b)
|
|
|
|
|
{
|
|
|
|
|
var tmp = stackalloc uint[_uintLength];
|
|
|
|
|
MemoryHelper.And(a._buffer, b._buffer, tmp, _uintLength);
|
|
|
|
|
return new BitSet512(tmp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static BitSet512 operator |(BitSet512 a, BitSet512 b)
|
|
|
|
|
{
|
|
|
|
|
var tmp = stackalloc uint[_uintLength];
|
|
|
|
|
MemoryHelper.Or(a._buffer, b._buffer, tmp, _uintLength);
|
|
|
|
|
return new BitSet512(tmp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static BitSet512 operator ~(BitSet512 a)
|
|
|
|
|
{
|
|
|
|
|
var tmp = stackalloc uint[_uintLength];
|
|
|
|
|
MemoryHelper.Not(a._buffer, tmp, _uintLength);
|
|
|
|
|
return new BitSet512(tmp);
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-29 05:16:14 +00:00
|
|
|
|
public static bool operator ==(BitSet512 left, BitSet512 right)
|
|
|
|
|
{
|
|
|
|
|
return left.Equals(right);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static bool operator !=(BitSet512 left, BitSet512 right)
|
|
|
|
|
{
|
|
|
|
|
return !(left == right);
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-29 04:40:44 +00:00
|
|
|
|
public BitSet512 Set(int index)
|
|
|
|
|
{
|
|
|
|
|
var tmp = stackalloc uint[_uintLength];
|
|
|
|
|
fixed (uint* p = _buffer) MemoryHelper.Copy(p, tmp, _uintLength);
|
|
|
|
|
tmp[index / 32] |= (uint)(1 << index % 32);
|
|
|
|
|
return new BitSet512(tmp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public BitSet512 UnSet(int index)
|
|
|
|
|
{
|
|
|
|
|
var tmp = stackalloc uint[_uintLength];
|
|
|
|
|
fixed (uint* p = _buffer) MemoryHelper.Copy(p, tmp, _uintLength);
|
|
|
|
|
tmp[index / 32] &= ~(uint)(1 << index % 32);
|
|
|
|
|
return new BitSet512(tmp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool Get(int bitIndex)
|
|
|
|
|
{
|
2019-12-29 05:16:14 +00:00
|
|
|
|
var bitInt = (uint)(1 << bitIndex % 32);
|
|
|
|
|
return (_buffer[bitIndex / 32] & bitInt) == bitInt;
|
2019-12-29 04:40:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool AllTrue()
|
|
|
|
|
{
|
2019-12-29 05:16:14 +00:00
|
|
|
|
return this == Ones;
|
2019-12-29 04:40:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool AllFalse()
|
|
|
|
|
{
|
2019-12-29 05:16:14 +00:00
|
|
|
|
return this == Zero;
|
2019-12-29 04:40:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static BitSet512 BitwiseAnd(BitSet512 left, BitSet512 right)
|
|
|
|
|
{
|
|
|
|
|
return left & right;
|
|
|
|
|
}
|
2019-12-29 05:16:14 +00:00
|
|
|
|
|
|
|
|
|
public static BitSet512 BitwiseOr(BitSet512 left, BitSet512 right)
|
|
|
|
|
{
|
|
|
|
|
return left | right;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static BitSet512 OnesComplement(BitSet512 bitSet)
|
|
|
|
|
{
|
|
|
|
|
return ~bitSet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override bool Equals(object obj)
|
|
|
|
|
{
|
|
|
|
|
return obj is BitSet512 set && Equals(set);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool Equals(BitSet512 other)
|
|
|
|
|
{
|
|
|
|
|
fixed (uint* p = _buffer) return MemoryHelper.Equal(p, other._buffer, _uintLength);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override int GetHashCode()
|
|
|
|
|
{
|
|
|
|
|
var hc = 0;
|
|
|
|
|
for (var i = 0; i < _uintLength; i++)
|
|
|
|
|
{
|
|
|
|
|
hc ^= _buffer[i].GetHashCode();
|
|
|
|
|
}
|
|
|
|
|
return hc;
|
|
|
|
|
}
|
2019-12-29 04:40:44 +00:00
|
|
|
|
}
|
|
|
|
|
}
|