using System; using System.Collections.Generic; using System.Linq; namespace UnityEngine.Rendering { /// /// IBitArray interface. /// public interface IBitArray { /// Gets the capacity of this BitArray. This is the number of bits that are usable. uint capacity { get; } /// Return `true` if all the bits of this BitArray are set to 0. Returns `false` otherwise. bool allFalse { get; } /// Return `true` if all the bits of this BitArray are set to 1. Returns `false` otherwise. bool allTrue { get; } /// /// An indexer that allows access to the bit at a given index. This provides both read and write access. /// /// Index of the bit. /// State of the bit at the provided index. bool this[uint index] { get; set; } /// Writes the bits in the array in a human-readable form. This is as a string of 0s and 1s packed by 8 bits. This is useful for debugging. string humanizedData { get; } /// /// Perform an AND bitwise operation between this BitArray and the one you pass into the function and return the result. Both BitArrays must have the same capacity. This will not change current BitArray values. /// /// BitArray with which to the And operation. /// The resulting bit array. IBitArray BitAnd(IBitArray other); /// /// Perform an OR bitwise operation between this BitArray and the one you pass into the function and return the result. Both BitArrays must have the same capacity. This will not change current BitArray values. /// /// BitArray with which to the Or operation. /// The resulting bit array. IBitArray BitOr(IBitArray other); /// /// Return the BitArray with every bit inverted. /// /// The resulting bit array. IBitArray BitNot(); } // /!\ Important for serialization: // Serialization helper will rely on the name of the struct type. // In order to work, it must be BitArrayN where N is the capacity without suffix. /// /// Bit array of size 8. /// [Serializable] [System.Diagnostics.DebuggerDisplay("{this.GetType().Name} {humanizedData}")] public struct BitArray8 : IBitArray { [SerializeField] byte data; /// Number of elements in the bit array. public uint capacity => 8u; /// True if all bits are 0. public bool allFalse => data == 0u; /// True if all bits are 1. public bool allTrue => data == byte.MaxValue; /// Returns the bit array in a human readable form. public string humanizedData => String.Format("{0, " + capacity + "}", Convert.ToString(data, 2)).Replace(' ', '0'); /// /// Returns the state of the bit at a specific index. /// /// Index of the bit. /// State of the bit at the provided index. public bool this[uint index] { get => BitArrayUtilities.Get8(index, data); set => BitArrayUtilities.Set8(index, ref data, value); } /// /// Constructor. /// /// Initialization value. public BitArray8(byte initValue) => data = initValue; /// /// Constructor. /// /// List of indices where bits should be set to true. public BitArray8(IEnumerable bitIndexTrue) { data = (byte)0u; if (bitIndexTrue == null) return; for (int index = bitIndexTrue.Count() - 1; index >= 0; --index) { uint bitIndex = bitIndexTrue.ElementAt(index); if (bitIndex >= capacity) continue; data |= (byte)(1u << (int)bitIndex); } } /// /// Bit-wise Not operator /// /// Bit array with which to do the operation. /// The resulting bit array. public static BitArray8 operator ~(BitArray8 a) => new BitArray8((byte)~a.data); /// /// Bit-wise Or operator /// /// First bit array. /// Second bit array. /// The resulting bit array. public static BitArray8 operator |(BitArray8 a, BitArray8 b) => new BitArray8((byte)(a.data | b.data)); /// /// Bit-wise And operator /// /// First bit array. /// Second bit array. /// The resulting bit array. public static BitArray8 operator &(BitArray8 a, BitArray8 b) => new BitArray8((byte)(a.data & b.data)); /// /// Bit-wise And /// /// Bit array with which to do the operation. /// The resulting bit array. public IBitArray BitAnd(IBitArray other) => this & (BitArray8)other; /// /// Bit-wise Or /// /// Bit array with which to do the operation. /// The resulting bit array. public IBitArray BitOr(IBitArray other) => this | (BitArray8)other; /// /// Bit-wise Not /// /// The resulting bit array. public IBitArray BitNot() => ~this; /// /// Equality operator. /// /// First bit array. /// Second bit array. /// True if both bit arrays are equals. public static bool operator ==(BitArray8 a, BitArray8 b) => a.data == b.data; /// /// Inequality operator. /// /// First bit array. /// Second bit array. /// True if the bit arrays are not equals. public static bool operator !=(BitArray8 a, BitArray8 b) => a.data != b.data; /// /// Equality operator. /// /// Bit array to compare to. /// True if the provided bit array is equal to this.. public override bool Equals(object obj) => obj is BitArray8 ba8 && ba8.data == data; /// /// Get the hashcode of the bit array. /// /// Hashcode of the bit array. public override int GetHashCode() => 1768953197 + data.GetHashCode(); } /// /// Bit array of size 16. /// [Serializable] [System.Diagnostics.DebuggerDisplay("{this.GetType().Name} {humanizedData}")] public struct BitArray16 : IBitArray { [SerializeField] ushort data; /// Number of elements in the bit array. public uint capacity => 16u; /// True if all bits are 0. public bool allFalse => data == 0u; /// True if all bits are 1. public bool allTrue => data == ushort.MaxValue; /// Returns the bit array in a human readable form. public string humanizedData => System.Text.RegularExpressions.Regex.Replace(String.Format("{0, " + capacity + "}", Convert.ToString(data, 2)).Replace(' ', '0'), ".{8}", "$0.").TrimEnd('.'); /// /// Returns the state of the bit at a specific index. /// /// Index of the bit. /// State of the bit at the provided index. public bool this[uint index] { get => BitArrayUtilities.Get16(index, data); set => BitArrayUtilities.Set16(index, ref data, value); } /// /// Constructor. /// /// Initialization value. public BitArray16(ushort initValue) => data = initValue; /// /// Constructor. /// /// List of indices where bits should be set to true. public BitArray16(IEnumerable bitIndexTrue) { data = (ushort)0u; if (bitIndexTrue == null) return; for (int index = bitIndexTrue.Count() - 1; index >= 0; --index) { uint bitIndex = bitIndexTrue.ElementAt(index); if (bitIndex >= capacity) continue; data |= (ushort)(1u << (int)bitIndex); } } /// /// Bit-wise Not operator /// /// Bit array with which to do the operation. /// The resulting bit array. public static BitArray16 operator ~(BitArray16 a) => new BitArray16((ushort)~a.data); /// /// Bit-wise Or operator /// /// First bit array. /// Second bit array. /// The resulting bit array. public static BitArray16 operator |(BitArray16 a, BitArray16 b) => new BitArray16((ushort)(a.data | b.data)); /// /// Bit-wise And operator /// /// First bit array. /// Second bit array. /// The resulting bit array. public static BitArray16 operator &(BitArray16 a, BitArray16 b) => new BitArray16((ushort)(a.data & b.data)); /// /// Bit-wise And /// /// Bit array with which to do the operation. /// The resulting bit array. public IBitArray BitAnd(IBitArray other) => this & (BitArray16)other; /// /// Bit-wise Or /// /// Bit array with which to do the operation. /// The resulting bit array. public IBitArray BitOr(IBitArray other) => this | (BitArray16)other; /// /// Bit-wise Not /// /// The resulting bit array. public IBitArray BitNot() => ~this; /// /// Equality operator. /// /// First bit array. /// Second bit array. /// True if both bit arrays are equals. public static bool operator ==(BitArray16 a, BitArray16 b) => a.data == b.data; /// /// Inequality operator. /// /// First bit array. /// Second bit array. /// True if the bit arrays are not equals. public static bool operator !=(BitArray16 a, BitArray16 b) => a.data != b.data; /// /// Equality operator. /// /// Bit array to compare to. /// True if the provided bit array is equal to this.. public override bool Equals(object obj) => obj is BitArray16 ba16 && ba16.data == data; /// /// Get the hashcode of the bit array. /// /// Hashcode of the bit array. public override int GetHashCode() => 1768953197 + data.GetHashCode(); } /// /// Bit array of size 32. /// [Serializable] [System.Diagnostics.DebuggerDisplay("{this.GetType().Name} {humanizedData}")] public struct BitArray32 : IBitArray { [SerializeField] uint data; /// Number of elements in the bit array. public uint capacity => 32u; /// True if all bits are 0. public bool allFalse => data == 0u; /// True if all bits are 1. public bool allTrue => data == uint.MaxValue; string humanizedVersion => Convert.ToString(data, 2); /// Returns the bit array in a human readable form. public string humanizedData => System.Text.RegularExpressions.Regex.Replace(String.Format("{0, " + capacity + "}", Convert.ToString(data, 2)).Replace(' ', '0'), ".{8}", "$0.").TrimEnd('.'); /// /// Returns the state of the bit at a specific index. /// /// Index of the bit. /// State of the bit at the provided index. public bool this[uint index] { get => BitArrayUtilities.Get32(index, data); set => BitArrayUtilities.Set32(index, ref data, value); } /// /// Constructor. /// /// Initialization value. public BitArray32(uint initValue) => data = initValue; /// /// Constructor. /// /// List of indices where bits should be set to true. public BitArray32(IEnumerable bitIndexTrue) { data = 0u; if (bitIndexTrue == null) return; for (int index = bitIndexTrue.Count() - 1; index >= 0; --index) { uint bitIndex = bitIndexTrue.ElementAt(index); if (bitIndex >= capacity) continue; data |= 1u << (int)bitIndex; } } /// /// Bit-wise And /// /// Bit array with which to do the operation. /// The resulting bit array. public IBitArray BitAnd(IBitArray other) => this & (BitArray32)other; /// /// Bit-wise Or /// /// Bit array with which to do the operation. /// The resulting bit array. public IBitArray BitOr(IBitArray other) => this | (BitArray32)other; /// /// Bit-wise Not /// /// The resulting bit array. public IBitArray BitNot() => ~this; /// /// Bit-wise Not operator /// /// Bit array with which to do the operation. /// The resulting bit array. public static BitArray32 operator ~(BitArray32 a) => new BitArray32(~a.data); /// /// Bit-wise Or operator /// /// First bit array. /// Second bit array. /// The resulting bit array. public static BitArray32 operator |(BitArray32 a, BitArray32 b) => new BitArray32(a.data | b.data); /// /// Bit-wise And operator /// /// First bit array. /// Second bit array. /// The resulting bit array. public static BitArray32 operator &(BitArray32 a, BitArray32 b) => new BitArray32(a.data & b.data); /// /// Equality operator. /// /// First bit array. /// Second bit array. /// True if both bit arrays are equals. public static bool operator ==(BitArray32 a, BitArray32 b) => a.data == b.data; /// /// Inequality operator. /// /// First bit array. /// Second bit array. /// True if the bit arrays are not equals. public static bool operator !=(BitArray32 a, BitArray32 b) => a.data != b.data; /// /// Equality operator. /// /// Bit array to compare to. /// True if the provided bit array is equal to this.. public override bool Equals(object obj) => obj is BitArray32 ba32 && ba32.data == data; /// /// Get the hashcode of the bit array. /// /// Hashcode of the bit array. public override int GetHashCode() => 1768953197 + data.GetHashCode(); } /// /// Bit array of size 64. /// [Serializable] [System.Diagnostics.DebuggerDisplay("{this.GetType().Name} {humanizedData}")] public struct BitArray64 : IBitArray { [SerializeField] ulong data; /// Number of elements in the bit array. public uint capacity => 64u; /// True if all bits are 0. public bool allFalse => data == 0uL; /// True if all bits are 1. public bool allTrue => data == ulong.MaxValue; /// Returns the bit array in a human readable form. public string humanizedData => System.Text.RegularExpressions.Regex.Replace(String.Format("{0, " + capacity + "}", Convert.ToString((long)data, 2)).Replace(' ', '0'), ".{8}", "$0.").TrimEnd('.'); /// /// Returns the state of the bit at a specific index. /// /// Index of the bit. /// State of the bit at the provided index. public bool this[uint index] { get => BitArrayUtilities.Get64(index, data); set => BitArrayUtilities.Set64(index, ref data, value); } /// /// Constructor. /// /// Initialization value. public BitArray64(ulong initValue) => data = initValue; /// /// Constructor. /// /// List of indices where bits should be set to true. public BitArray64(IEnumerable bitIndexTrue) { data = 0L; if (bitIndexTrue == null) return; for (int index = bitIndexTrue.Count() - 1; index >= 0; --index) { uint bitIndex = bitIndexTrue.ElementAt(index); if (bitIndex >= capacity) continue; data |= 1uL << (int)bitIndex; } } /// /// Bit-wise Not operator /// /// Bit array with which to do the operation. /// The resulting bit array. public static BitArray64 operator ~(BitArray64 a) => new BitArray64(~a.data); /// /// Bit-wise Or operator /// /// First bit array. /// Second bit array. /// The resulting bit array. public static BitArray64 operator |(BitArray64 a, BitArray64 b) => new BitArray64(a.data | b.data); /// /// Bit-wise And operator /// /// First bit array. /// Second bit array. /// The resulting bit array. public static BitArray64 operator &(BitArray64 a, BitArray64 b) => new BitArray64(a.data & b.data); /// /// Bit-wise And /// /// Bit array with which to do the operation. /// The resulting bit array. public IBitArray BitAnd(IBitArray other) => this & (BitArray64)other; /// /// Bit-wise Or /// /// Bit array with which to do the operation. /// The resulting bit array. public IBitArray BitOr(IBitArray other) => this | (BitArray64)other; /// /// Bit-wise Not /// /// The resulting bit array. public IBitArray BitNot() => ~this; /// /// Equality operator. /// /// First bit array. /// Second bit array. /// True if both bit arrays are equals. public static bool operator ==(BitArray64 a, BitArray64 b) => a.data == b.data; /// /// Inequality operator. /// /// First bit array. /// Second bit array. /// True if the bit arrays are not equals. public static bool operator !=(BitArray64 a, BitArray64 b) => a.data != b.data; /// /// Equality operator. /// /// Bit array to compare to. /// True if the provided bit array is equal to this.. public override bool Equals(object obj) => obj is BitArray64 ba64 && ba64.data == data; /// /// Get the hashcode of the bit array. /// /// Hashcode of the bit array. public override int GetHashCode() => 1768953197 + data.GetHashCode(); } /// /// Bit array of size 128. /// [Serializable] [System.Diagnostics.DebuggerDisplay("{this.GetType().Name} {humanizedData}")] public struct BitArray128 : IBitArray { [SerializeField] ulong data1; [SerializeField] ulong data2; /// Number of elements in the bit array. public uint capacity => 128u; /// True if all bits are 0. public bool allFalse => data1 == 0uL && data2 == 0uL; /// True if all bits are 1. public bool allTrue => data1 == ulong.MaxValue && data2 == ulong.MaxValue; /// Returns the bit array in a human readable form. public string humanizedData => System.Text.RegularExpressions.Regex.Replace(String.Format("{0, " + 64u + "}", Convert.ToString((long)data2, 2)).Replace(' ', '0'), ".{8}", "$0.") + System.Text.RegularExpressions.Regex.Replace(String.Format("{0, " + 64u + "}", Convert.ToString((long)data1, 2)).Replace(' ', '0'), ".{8}", "$0.").TrimEnd('.'); /// /// Returns the state of the bit at a specific index. /// /// Index of the bit. /// State of the bit at the provided index. public bool this[uint index] { get => index < 64u ? (data1 & (1uL << (int)index)) != 0uL : (data2 & (1uL << (int)(index - 64u))) != 0uL; set { if (index < 64u) data1 = (value ? (data1 | (1uL << (int)index)) : (data1 & ~(1uL << (int)index))); else data2 = (value ? (data2 | (1uL << (int)(index - 64u))) : (data2 & ~(1uL << (int)(index - 64u)))); } } /// /// Constructor. /// /// Initialization value 1. /// Initialization value 2. public BitArray128(ulong initValue1, ulong initValue2) { data1 = initValue1; data2 = initValue2; } /// /// Constructor. /// /// List of indices where bits should be set to true. public BitArray128(IEnumerable bitIndexTrue) { data1 = data2 = 0uL; if (bitIndexTrue == null) return; for (int index = bitIndexTrue.Count() - 1; index >= 0; --index) { uint bitIndex = bitIndexTrue.ElementAt(index); if (bitIndex < 64u) data1 |= 1uL << (int)bitIndex; else if (bitIndex < capacity) data2 |= 1uL << (int)(bitIndex - 64u); } } /// /// Bit-wise Not operator /// /// First bit array. /// The resulting bit array. public static BitArray128 operator ~(BitArray128 a) => new BitArray128(~a.data1, ~a.data2); /// /// Bit-wise Or operator /// /// First bit array. /// Second bit array. /// The resulting bit array. public static BitArray128 operator |(BitArray128 a, BitArray128 b) => new BitArray128(a.data1 | b.data1, a.data2 | b.data2); /// /// Bit-wise And operator /// /// First bit array. /// Second bit array. /// The resulting bit array. public static BitArray128 operator &(BitArray128 a, BitArray128 b) => new BitArray128(a.data1 & b.data1, a.data2 & b.data2); /// /// Bit-wise And /// /// Bit array with which to do the operation. /// The resulting bit array. public IBitArray BitAnd(IBitArray other) => this & (BitArray128)other; /// /// Bit-wise Or /// /// Bit array with which to do the operation. /// The resulting bit array. public IBitArray BitOr(IBitArray other) => this | (BitArray128)other; /// /// Bit-wise Not /// /// The resulting bit array. public IBitArray BitNot() => ~this; /// /// Equality operator. /// /// First bit array. /// Second bit array. /// True if both bit arrays are equals. public static bool operator ==(BitArray128 a, BitArray128 b) => a.data1 == b.data1 && a.data2 == b.data2; /// /// Inequality operator. /// /// First bit array. /// Second bit array. /// True if the bit arrays are not equals. public static bool operator !=(BitArray128 a, BitArray128 b) => a.data1 != b.data1 || a.data2 != b.data2; /// /// Equality operator. /// /// Bit array to compare to. /// True if the provided bit array is equal to this.. public override bool Equals(object obj) => obj is BitArray128 ba128 && data1.Equals(ba128.data1) && data2.Equals(ba128.data2); /// /// Get the hashcode of the bit array. /// /// Hashcode of the bit array. public override int GetHashCode() { var hashCode = 1755735569; hashCode = hashCode * -1521134295 + data1.GetHashCode(); hashCode = hashCode * -1521134295 + data2.GetHashCode(); return hashCode; } } /// /// Bit array of size 256. /// [Serializable] [System.Diagnostics.DebuggerDisplay("{this.GetType().Name} {humanizedData}")] public struct BitArray256 : IBitArray { [SerializeField] ulong data1; [SerializeField] ulong data2; [SerializeField] ulong data3; [SerializeField] ulong data4; /// Number of elements in the bit array. public uint capacity => 256u; /// True if all bits are 0. public bool allFalse => data1 == 0uL && data2 == 0uL && data3 == 0uL && data4 == 0uL; /// True if all bits are 1. public bool allTrue => data1 == ulong.MaxValue && data2 == ulong.MaxValue && data3 == ulong.MaxValue && data4 == ulong.MaxValue; /// Returns the bit array in a human readable form. public string humanizedData => System.Text.RegularExpressions.Regex.Replace(String.Format("{0, " + 64u + "}", Convert.ToString((long)data4, 2)).Replace(' ', '0'), ".{8}", "$0.") + System.Text.RegularExpressions.Regex.Replace(String.Format("{0, " + 64u + "}", Convert.ToString((long)data3, 2)).Replace(' ', '0'), ".{8}", "$0.") + System.Text.RegularExpressions.Regex.Replace(String.Format("{0, " + 64u + "}", Convert.ToString((long)data2, 2)).Replace(' ', '0'), ".{8}", "$0.") + System.Text.RegularExpressions.Regex.Replace(String.Format("{0, " + 64u + "}", Convert.ToString((long)data1, 2)).Replace(' ', '0'), ".{8}", "$0.").TrimEnd('.'); /// /// Returns the state of the bit at a specific index. /// /// Index of the bit. /// State of the bit at the provided index. public bool this[uint index] { get => BitArrayUtilities.Get256(index, data1, data2, data3, data4); set => BitArrayUtilities.Set256(index, ref data1, ref data2, ref data3, ref data4, value); } /// /// Constructor. /// /// Initialization value 1. /// Initialization value 2. /// Initialization value 3. /// Initialization value 4. public BitArray256(ulong initValue1, ulong initValue2, ulong initValue3, ulong initValue4) { data1 = initValue1; data2 = initValue2; data3 = initValue3; data4 = initValue4; } /// /// Constructor. /// /// List of indices where bits should be set to true. public BitArray256(IEnumerable bitIndexTrue) { data1 = data2 = data3 = data4 = 0uL; if (bitIndexTrue == null) return; for (int index = bitIndexTrue.Count() - 1; index >= 0; --index) { uint bitIndex = bitIndexTrue.ElementAt(index); if (bitIndex < 64u) data1 |= 1uL << (int)bitIndex; else if (bitIndex < 128u) data2 |= 1uL << (int)(bitIndex - 64u); else if (bitIndex < 192u) data3 |= 1uL << (int)(bitIndex - 128u); else if (bitIndex < capacity) data4 |= 1uL << (int)(bitIndex - 192u); } } /// /// Bit-wise Not operator /// /// Bit array with which to do the operation. /// The resulting bit array. public static BitArray256 operator ~(BitArray256 a) => new BitArray256(~a.data1, ~a.data2, ~a.data3, ~a.data4); /// /// Bit-wise Or operator /// /// First bit array. /// Second bit array. /// The resulting bit array. public static BitArray256 operator |(BitArray256 a, BitArray256 b) => new BitArray256(a.data1 | b.data1, a.data2 | b.data2, a.data3 | b.data3, a.data4 | b.data4); /// /// Bit-wise And operator /// /// First bit array. /// Second bit array. /// The resulting bit array. public static BitArray256 operator &(BitArray256 a, BitArray256 b) => new BitArray256(a.data1 & b.data1, a.data2 & b.data2, a.data3 & b.data3, a.data4 & b.data4); /// /// Bit-wise And /// /// Bit array with which to do the operation. /// The resulting bit array. public IBitArray BitAnd(IBitArray other) => this & (BitArray256)other; /// /// Bit-wise Or /// /// Bit array with which to do the operation. /// The resulting bit array. public IBitArray BitOr(IBitArray other) => this | (BitArray256)other; /// /// Bit-wise Not /// /// The resulting bit array. public IBitArray BitNot() => ~this; /// /// Equality operator. /// /// First bit array. /// Second bit array. /// True if both bit arrays are equals. public static bool operator ==(BitArray256 a, BitArray256 b) => a.data1 == b.data1 && a.data2 == b.data2 && a.data3 == b.data3 && a.data4 == b.data4; /// /// Inequality operator. /// /// First bit array. /// Second bit array. /// True if the bit arrays are not equals. public static bool operator !=(BitArray256 a, BitArray256 b) => a.data1 != b.data1 || a.data2 != b.data2 || a.data3 != b.data3 || a.data4 != b.data4; /// /// Equality operator. /// /// Bit array to compare to. /// True if the provided bit array is equal to this.. public override bool Equals(object obj) => obj is BitArray256 ba256 && data1.Equals(ba256.data1) && data2.Equals(ba256.data2) && data3.Equals(ba256.data3) && data4.Equals(ba256.data4); /// /// Get the hashcode of the bit array. /// /// Hashcode of the bit array. public override int GetHashCode() { var hashCode = 1870826326; hashCode = hashCode * -1521134295 + data1.GetHashCode(); hashCode = hashCode * -1521134295 + data2.GetHashCode(); hashCode = hashCode * -1521134295 + data3.GetHashCode(); hashCode = hashCode * -1521134295 + data4.GetHashCode(); return hashCode; } } /// /// Bit array utility class. /// public static class BitArrayUtilities { //written here to not duplicate the serialized accessor and runtime accessor /// /// Get a bit at a specific index. /// /// Bit index. /// Bit array data. /// The value of the bit at the specific index. public static bool Get8(uint index, byte data) => (data & (1u << (int)index)) != 0u; /// /// Get a bit at a specific index. /// /// Bit index. /// Bit array data. /// The value of the bit at the specific index. public static bool Get16(uint index, ushort data) => (data & (1u << (int)index)) != 0u; /// /// Get a bit at a specific index. /// /// Bit index. /// Bit array data. /// The value of the bit at the specific index. public static bool Get32(uint index, uint data) => (data & (1u << (int)index)) != 0u; /// /// Get a bit at a specific index. /// /// Bit index. /// Bit array data. /// The value of the bit at the specific index. public static bool Get64(uint index, ulong data) => (data & (1uL << (int)index)) != 0uL; /// /// Get a bit at a specific index. /// /// Bit index. /// Bit array data 1. /// Bit array data 2. /// The value of the bit at the specific index. public static bool Get128(uint index, ulong data1, ulong data2) => index < 64u ? (data1 & (1uL << (int)index)) != 0uL : (data2 & (1uL << (int)(index - 64u))) != 0uL; /// /// Get a bit at a specific index. /// /// Bit index. /// Bit array data 1. /// Bit array data 2. /// Bit array data 3. /// Bit array data 4. /// The value of the bit at the specific index. public static bool Get256(uint index, ulong data1, ulong data2, ulong data3, ulong data4) => index < 128u ? index < 64u ? (data1 & (1uL << (int)index)) != 0uL : (data2 & (1uL << (int)(index - 64u))) != 0uL : index < 192u ? (data3 & (1uL << (int)(index - 128u))) != 0uL : (data4 & (1uL << (int)(index - 192u))) != 0uL; /// /// Set a bit at a specific index. /// /// Bit index. /// Bit array data. /// Value to set the bit to. public static void Set8(uint index, ref byte data, bool value) => data = (byte)(value ? (data | (1u << (int)index)) : (data & ~(1u << (int)index))); /// /// Set a bit at a specific index. /// /// Bit index. /// Bit array data. /// Value to set the bit to. public static void Set16(uint index, ref ushort data, bool value) => data = (ushort)(value ? (data | (1u << (int)index)) : (data & ~(1u << (int)index))); /// /// Set a bit at a specific index. /// /// Bit index. /// Bit array data. /// Value to set the bit to. public static void Set32(uint index, ref uint data, bool value) => data = (value ? (data | (1u << (int)index)) : (data & ~(1u << (int)index))); /// /// Set a bit at a specific index. /// /// Bit index. /// Bit array data. /// Value to set the bit to. public static void Set64(uint index, ref ulong data, bool value) => data = (value ? (data | (1uL << (int)index)) : (data & ~(1uL << (int)index))); /// /// Set a bit at a specific index. /// /// Bit index. /// Bit array data 1. /// Bit array data 2. /// Value to set the bit to. public static void Set128(uint index, ref ulong data1, ref ulong data2, bool value) { if (index < 64u) data1 = (value ? (data1 | (1uL << (int)index)) : (data1 & ~(1uL << (int)index))); else data2 = (value ? (data2 | (1uL << (int)(index - 64u))) : (data2 & ~(1uL << (int)(index - 64u)))); } /// /// Set a bit at a specific index. /// /// Bit index. /// Bit array data 1. /// Bit array data 2. /// Bit array data 3. /// Bit array data 4. /// Value to set the bit to. public static void Set256(uint index, ref ulong data1, ref ulong data2, ref ulong data3, ref ulong data4, bool value) { if (index < 64u) data1 = (value ? (data1 | (1uL << (int)index)) : (data1 & ~(1uL << (int)index))); else if (index < 128u) data2 = (value ? (data2 | (1uL << (int)(index - 64u))) : (data2 & ~(1uL << (int)(index - 64u)))); else if (index < 192u) data3 = (value ? (data3 | (1uL << (int)(index - 64u))) : (data3 & ~(1uL << (int)(index - 128u)))); else data4 = (value ? (data4 | (1uL << (int)(index - 64u))) : (data4 & ~(1uL << (int)(index - 192u)))); } } }