A game about forced loneliness, made by TACStudios
1using System; 2using System.Collections.Generic; 3using System.Linq; 4 5namespace UnityEngine.Rendering 6{ 7 /// <summary> 8 /// IBitArray interface. 9 /// </summary> 10 public interface IBitArray 11 { 12 /// <summary>Gets the capacity of this BitArray. This is the number of bits that are usable.</summary> 13 uint capacity { get; } 14 /// <summary>Return `true` if all the bits of this BitArray are set to 0. Returns `false` otherwise.</summary> 15 bool allFalse { get; } 16 /// <summary>Return `true` if all the bits of this BitArray are set to 1. Returns `false` otherwise.</summary> 17 bool allTrue { get; } 18 /// <summary> 19 /// An indexer that allows access to the bit at a given index. This provides both read and write access. 20 /// </summary> 21 /// <param name="index">Index of the bit.</param> 22 /// <value>State of the bit at the provided index.</value> 23 bool this[uint index] { get; set; } 24 /// <summary>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.</summary> 25 string humanizedData { get; } 26 27 /// <summary> 28 /// 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. 29 /// </summary> 30 /// <param name="other">BitArray with which to the And operation.</param> 31 /// <returns>The resulting bit array.</returns> 32 IBitArray BitAnd(IBitArray other); 33 /// <summary> 34 /// 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. 35 /// </summary> 36 /// <param name="other">BitArray with which to the Or operation.</param> 37 /// <returns>The resulting bit array.</returns> 38 IBitArray BitOr(IBitArray other); 39 /// <summary> 40 /// Return the BitArray with every bit inverted. 41 /// </summary> 42 /// <returns>The resulting bit array.</returns> 43 IBitArray BitNot(); 44 } 45 46 // /!\ Important for serialization: 47 // Serialization helper will rely on the name of the struct type. 48 // In order to work, it must be BitArrayN where N is the capacity without suffix. 49 50 /// <summary> 51 /// Bit array of size 8. 52 /// </summary> 53 [Serializable] 54 [System.Diagnostics.DebuggerDisplay("{this.GetType().Name} {humanizedData}")] 55 public struct BitArray8 : IBitArray 56 { 57 [SerializeField] 58 byte data; 59 60 /// <summary>Number of elements in the bit array.</summary> 61 public uint capacity => 8u; 62 /// <summary>True if all bits are 0.</summary> 63 public bool allFalse => data == 0u; 64 /// <summary>True if all bits are 1.</summary> 65 public bool allTrue => data == byte.MaxValue; 66 /// <summary>Returns the bit array in a human readable form.</summary> 67 public string humanizedData => String.Format("{0, " + capacity + "}", Convert.ToString(data, 2)).Replace(' ', '0'); 68 69 /// <summary> 70 /// Returns the state of the bit at a specific index. 71 /// </summary> 72 /// <param name="index">Index of the bit.</param> 73 /// <value>State of the bit at the provided index.</value> 74 public bool this[uint index] 75 { 76 get => BitArrayUtilities.Get8(index, data); 77 set => BitArrayUtilities.Set8(index, ref data, value); 78 } 79 80 /// <summary> 81 /// Constructor. 82 /// </summary> 83 /// <param name="initValue">Initialization value.</param> 84 public BitArray8(byte initValue) => data = initValue; 85 /// <summary> 86 /// Constructor. 87 /// </summary> 88 /// <param name="bitIndexTrue">List of indices where bits should be set to true.</param> 89 public BitArray8(IEnumerable<uint> bitIndexTrue) 90 { 91 data = (byte)0u; 92 if (bitIndexTrue == null) 93 return; 94 for (int index = bitIndexTrue.Count() - 1; index >= 0; --index) 95 { 96 uint bitIndex = bitIndexTrue.ElementAt(index); 97 if (bitIndex >= capacity) continue; 98 data |= (byte)(1u << (int)bitIndex); 99 } 100 } 101 102 /// <summary> 103 /// Bit-wise Not operator 104 /// </summary> 105 /// <param name="a">Bit array with which to do the operation.</param> 106 /// <returns>The resulting bit array.</returns> 107 public static BitArray8 operator ~(BitArray8 a) => new BitArray8((byte)~a.data); 108 /// <summary> 109 /// Bit-wise Or operator 110 /// </summary> 111 /// <param name="a">First bit array.</param> 112 /// <param name="b">Second bit array.</param> 113 /// <returns>The resulting bit array.</returns> 114 public static BitArray8 operator |(BitArray8 a, BitArray8 b) => new BitArray8((byte)(a.data | b.data)); 115 /// <summary> 116 /// Bit-wise And operator 117 /// </summary> 118 /// <param name="a">First bit array.</param> 119 /// <param name="b">Second bit array.</param> 120 /// <returns>The resulting bit array.</returns> 121 public static BitArray8 operator &(BitArray8 a, BitArray8 b) => new BitArray8((byte)(a.data & b.data)); 122 123 /// <summary> 124 /// Bit-wise And 125 /// </summary> 126 /// <param name="other">Bit array with which to do the operation.</param> 127 /// <returns>The resulting bit array.</returns> 128 public IBitArray BitAnd(IBitArray other) => this & (BitArray8)other; 129 /// <summary> 130 /// Bit-wise Or 131 /// </summary> 132 /// <param name="other">Bit array with which to do the operation.</param> 133 /// <returns>The resulting bit array.</returns> 134 public IBitArray BitOr(IBitArray other) => this | (BitArray8)other; 135 /// <summary> 136 /// Bit-wise Not 137 /// </summary> 138 /// <returns>The resulting bit array.</returns> 139 public IBitArray BitNot() => ~this; 140 141 /// <summary> 142 /// Equality operator. 143 /// </summary> 144 /// <param name="a">First bit array.</param> 145 /// <param name="b">Second bit array.</param> 146 /// <returns>True if both bit arrays are equals.</returns> 147 public static bool operator ==(BitArray8 a, BitArray8 b) => a.data == b.data; 148 /// <summary> 149 /// Inequality operator. 150 /// </summary> 151 /// <param name="a">First bit array.</param> 152 /// <param name="b">Second bit array.</param> 153 /// <returns>True if the bit arrays are not equals.</returns> 154 public static bool operator !=(BitArray8 a, BitArray8 b) => a.data != b.data; 155 /// <summary> 156 /// Equality operator. 157 /// </summary> 158 /// <param name="obj">Bit array to compare to.</param> 159 /// <returns>True if the provided bit array is equal to this..</returns> 160 public override bool Equals(object obj) => obj is BitArray8 ba8 && ba8.data == data; 161 /// <summary> 162 /// Get the hashcode of the bit array. 163 /// </summary> 164 /// <returns>Hashcode of the bit array.</returns> 165 public override int GetHashCode() => 1768953197 + data.GetHashCode(); 166 } 167 168 /// <summary> 169 /// Bit array of size 16. 170 /// </summary> 171 [Serializable] 172 [System.Diagnostics.DebuggerDisplay("{this.GetType().Name} {humanizedData}")] 173 public struct BitArray16 : IBitArray 174 { 175 [SerializeField] 176 ushort data; 177 178 /// <summary>Number of elements in the bit array.</summary> 179 public uint capacity => 16u; 180 /// <summary>True if all bits are 0.</summary> 181 public bool allFalse => data == 0u; 182 /// <summary>True if all bits are 1.</summary> 183 public bool allTrue => data == ushort.MaxValue; 184 /// <summary>Returns the bit array in a human readable form.</summary> 185 public string humanizedData => System.Text.RegularExpressions.Regex.Replace(String.Format("{0, " + capacity + "}", Convert.ToString(data, 2)).Replace(' ', '0'), ".{8}", "$0.").TrimEnd('.'); 186 187 /// <summary> 188 /// Returns the state of the bit at a specific index. 189 /// </summary> 190 /// <param name="index">Index of the bit.</param> 191 /// <value>State of the bit at the provided index.</value> 192 public bool this[uint index] 193 { 194 get => BitArrayUtilities.Get16(index, data); 195 set => BitArrayUtilities.Set16(index, ref data, value); 196 } 197 198 /// <summary> 199 /// Constructor. 200 /// </summary> 201 /// <param name="initValue">Initialization value.</param> 202 public BitArray16(ushort initValue) => data = initValue; 203 /// <summary> 204 /// Constructor. 205 /// </summary> 206 /// <param name="bitIndexTrue">List of indices where bits should be set to true.</param> 207 208 public BitArray16(IEnumerable<uint> bitIndexTrue) 209 { 210 data = (ushort)0u; 211 if (bitIndexTrue == null) 212 return; 213 for (int index = bitIndexTrue.Count() - 1; index >= 0; --index) 214 { 215 uint bitIndex = bitIndexTrue.ElementAt(index); 216 if (bitIndex >= capacity) continue; 217 data |= (ushort)(1u << (int)bitIndex); 218 } 219 } 220 221 /// <summary> 222 /// Bit-wise Not operator 223 /// </summary> 224 /// <param name="a">Bit array with which to do the operation.</param> 225 /// <returns>The resulting bit array.</returns> 226 public static BitArray16 operator ~(BitArray16 a) => new BitArray16((ushort)~a.data); 227 /// <summary> 228 /// Bit-wise Or operator 229 /// </summary> 230 /// <param name="a">First bit array.</param> 231 /// <param name="b">Second bit array.</param> 232 /// <returns>The resulting bit array.</returns> 233 public static BitArray16 operator |(BitArray16 a, BitArray16 b) => new BitArray16((ushort)(a.data | b.data)); 234 /// <summary> 235 /// Bit-wise And operator 236 /// </summary> 237 /// <param name="a">First bit array.</param> 238 /// <param name="b">Second bit array.</param> 239 /// <returns>The resulting bit array.</returns> 240 public static BitArray16 operator &(BitArray16 a, BitArray16 b) => new BitArray16((ushort)(a.data & b.data)); 241 242 /// <summary> 243 /// Bit-wise And 244 /// </summary> 245 /// <param name="other">Bit array with which to do the operation.</param> 246 /// <returns>The resulting bit array.</returns> 247 public IBitArray BitAnd(IBitArray other) => this & (BitArray16)other; 248 /// <summary> 249 /// Bit-wise Or 250 /// </summary> 251 /// <param name="other">Bit array with which to do the operation.</param> 252 /// <returns>The resulting bit array.</returns> 253 public IBitArray BitOr(IBitArray other) => this | (BitArray16)other; 254 /// <summary> 255 /// Bit-wise Not 256 /// </summary> 257 /// <returns>The resulting bit array.</returns> 258 public IBitArray BitNot() => ~this; 259 260 /// <summary> 261 /// Equality operator. 262 /// </summary> 263 /// <param name="a">First bit array.</param> 264 /// <param name="b">Second bit array.</param> 265 /// <returns>True if both bit arrays are equals.</returns> 266 public static bool operator ==(BitArray16 a, BitArray16 b) => a.data == b.data; 267 /// <summary> 268 /// Inequality operator. 269 /// </summary> 270 /// <param name="a">First bit array.</param> 271 /// <param name="b">Second bit array.</param> 272 /// <returns>True if the bit arrays are not equals.</returns> 273 public static bool operator !=(BitArray16 a, BitArray16 b) => a.data != b.data; 274 /// <summary> 275 /// Equality operator. 276 /// </summary> 277 /// <param name="obj">Bit array to compare to.</param> 278 /// <returns>True if the provided bit array is equal to this..</returns> 279 public override bool Equals(object obj) => obj is BitArray16 ba16 && ba16.data == data; 280 /// <summary> 281 /// Get the hashcode of the bit array. 282 /// </summary> 283 /// <returns>Hashcode of the bit array.</returns> 284 public override int GetHashCode() => 1768953197 + data.GetHashCode(); 285 } 286 287 /// <summary> 288 /// Bit array of size 32. 289 /// </summary> 290 [Serializable] 291 [System.Diagnostics.DebuggerDisplay("{this.GetType().Name} {humanizedData}")] 292 public struct BitArray32 : IBitArray 293 { 294 [SerializeField] 295 uint data; 296 297 /// <summary>Number of elements in the bit array.</summary> 298 public uint capacity => 32u; 299 /// <summary>True if all bits are 0.</summary> 300 public bool allFalse => data == 0u; 301 /// <summary>True if all bits are 1.</summary> 302 public bool allTrue => data == uint.MaxValue; 303 string humanizedVersion => Convert.ToString(data, 2); 304 /// <summary>Returns the bit array in a human readable form.</summary> 305 public string humanizedData => System.Text.RegularExpressions.Regex.Replace(String.Format("{0, " + capacity + "}", Convert.ToString(data, 2)).Replace(' ', '0'), ".{8}", "$0.").TrimEnd('.'); 306 307 /// <summary> 308 /// Returns the state of the bit at a specific index. 309 /// </summary> 310 /// <param name="index">Index of the bit.</param> 311 /// <value>State of the bit at the provided index.</value> 312 public bool this[uint index] 313 { 314 get => BitArrayUtilities.Get32(index, data); 315 set => BitArrayUtilities.Set32(index, ref data, value); 316 } 317 318 /// <summary> 319 /// Constructor. 320 /// </summary> 321 /// <param name="initValue">Initialization value.</param> 322 public BitArray32(uint initValue) => data = initValue; 323 /// <summary> 324 /// Constructor. 325 /// </summary> 326 /// <param name="bitIndexTrue">List of indices where bits should be set to true.</param> 327 328 public BitArray32(IEnumerable<uint> bitIndexTrue) 329 { 330 data = 0u; 331 if (bitIndexTrue == null) 332 return; 333 for (int index = bitIndexTrue.Count() - 1; index >= 0; --index) 334 { 335 uint bitIndex = bitIndexTrue.ElementAt(index); 336 if (bitIndex >= capacity) continue; 337 data |= 1u << (int)bitIndex; 338 } 339 } 340 341 /// <summary> 342 /// Bit-wise And 343 /// </summary> 344 /// <param name="other">Bit array with which to do the operation.</param> 345 /// <returns>The resulting bit array.</returns> 346 public IBitArray BitAnd(IBitArray other) => this & (BitArray32)other; 347 /// <summary> 348 /// Bit-wise Or 349 /// </summary> 350 /// <param name="other">Bit array with which to do the operation.</param> 351 /// <returns>The resulting bit array.</returns> 352 public IBitArray BitOr(IBitArray other) => this | (BitArray32)other; 353 /// <summary> 354 /// Bit-wise Not 355 /// </summary> 356 /// <returns>The resulting bit array.</returns> 357 public IBitArray BitNot() => ~this; 358 359 /// <summary> 360 /// Bit-wise Not operator 361 /// </summary> 362 /// <param name="a">Bit array with which to do the operation.</param> 363 /// <returns>The resulting bit array.</returns> 364 public static BitArray32 operator ~(BitArray32 a) => new BitArray32(~a.data); 365 /// <summary> 366 /// Bit-wise Or operator 367 /// </summary> 368 /// <param name="a">First bit array.</param> 369 /// <param name="b">Second bit array.</param> 370 /// <returns>The resulting bit array.</returns> 371 public static BitArray32 operator |(BitArray32 a, BitArray32 b) => new BitArray32(a.data | b.data); 372 /// <summary> 373 /// Bit-wise And operator 374 /// </summary> 375 /// <param name="a">First bit array.</param> 376 /// <param name="b">Second bit array.</param> 377 /// <returns>The resulting bit array.</returns> 378 public static BitArray32 operator &(BitArray32 a, BitArray32 b) => new BitArray32(a.data & b.data); 379 380 /// <summary> 381 /// Equality operator. 382 /// </summary> 383 /// <param name="a">First bit array.</param> 384 /// <param name="b">Second bit array.</param> 385 /// <returns>True if both bit arrays are equals.</returns> 386 public static bool operator ==(BitArray32 a, BitArray32 b) => a.data == b.data; 387 /// <summary> 388 /// Inequality operator. 389 /// </summary> 390 /// <param name="a">First bit array.</param> 391 /// <param name="b">Second bit array.</param> 392 /// <returns>True if the bit arrays are not equals.</returns> 393 public static bool operator !=(BitArray32 a, BitArray32 b) => a.data != b.data; 394 /// <summary> 395 /// Equality operator. 396 /// </summary> 397 /// <param name="obj">Bit array to compare to.</param> 398 /// <returns>True if the provided bit array is equal to this..</returns> 399 public override bool Equals(object obj) => obj is BitArray32 ba32 && ba32.data == data; 400 /// <summary> 401 /// Get the hashcode of the bit array. 402 /// </summary> 403 /// <returns>Hashcode of the bit array.</returns> 404 public override int GetHashCode() => 1768953197 + data.GetHashCode(); 405 } 406 407 /// <summary> 408 /// Bit array of size 64. 409 /// </summary> 410 [Serializable] 411 [System.Diagnostics.DebuggerDisplay("{this.GetType().Name} {humanizedData}")] 412 public struct BitArray64 : IBitArray 413 { 414 [SerializeField] 415 ulong data; 416 417 /// <summary>Number of elements in the bit array.</summary> 418 public uint capacity => 64u; 419 /// <summary>True if all bits are 0.</summary> 420 public bool allFalse => data == 0uL; 421 /// <summary>True if all bits are 1.</summary> 422 public bool allTrue => data == ulong.MaxValue; 423 /// <summary>Returns the bit array in a human readable form.</summary> 424 public string humanizedData => System.Text.RegularExpressions.Regex.Replace(String.Format("{0, " + capacity + "}", Convert.ToString((long)data, 2)).Replace(' ', '0'), ".{8}", "$0.").TrimEnd('.'); 425 426 /// <summary> 427 /// Returns the state of the bit at a specific index. 428 /// </summary> 429 /// <param name="index">Index of the bit.</param> 430 /// <value>State of the bit at the provided index.</value> 431 public bool this[uint index] 432 { 433 get => BitArrayUtilities.Get64(index, data); 434 set => BitArrayUtilities.Set64(index, ref data, value); 435 } 436 437 /// <summary> 438 /// Constructor. 439 /// </summary> 440 /// <param name="initValue">Initialization value.</param> 441 public BitArray64(ulong initValue) => data = initValue; 442 /// <summary> 443 /// Constructor. 444 /// </summary> 445 /// <param name="bitIndexTrue">List of indices where bits should be set to true.</param> 446 447 public BitArray64(IEnumerable<uint> bitIndexTrue) 448 { 449 data = 0L; 450 if (bitIndexTrue == null) 451 return; 452 for (int index = bitIndexTrue.Count() - 1; index >= 0; --index) 453 { 454 uint bitIndex = bitIndexTrue.ElementAt(index); 455 if (bitIndex >= capacity) continue; 456 data |= 1uL << (int)bitIndex; 457 } 458 } 459 460 /// <summary> 461 /// Bit-wise Not operator 462 /// </summary> 463 /// <param name="a">Bit array with which to do the operation.</param> 464 /// <returns>The resulting bit array.</returns> 465 public static BitArray64 operator ~(BitArray64 a) => new BitArray64(~a.data); 466 /// <summary> 467 /// Bit-wise Or operator 468 /// </summary> 469 /// <param name="a">First bit array.</param> 470 /// <param name="b">Second bit array.</param> 471 /// <returns>The resulting bit array.</returns> 472 public static BitArray64 operator |(BitArray64 a, BitArray64 b) => new BitArray64(a.data | b.data); 473 /// <summary> 474 /// Bit-wise And operator 475 /// </summary> 476 /// <param name="a">First bit array.</param> 477 /// <param name="b">Second bit array.</param> 478 /// <returns>The resulting bit array.</returns> 479 public static BitArray64 operator &(BitArray64 a, BitArray64 b) => new BitArray64(a.data & b.data); 480 481 /// <summary> 482 /// Bit-wise And 483 /// </summary> 484 /// <param name="other">Bit array with which to do the operation.</param> 485 /// <returns>The resulting bit array.</returns> 486 public IBitArray BitAnd(IBitArray other) => this & (BitArray64)other; 487 /// <summary> 488 /// Bit-wise Or 489 /// </summary> 490 /// <param name="other">Bit array with which to do the operation.</param> 491 /// <returns>The resulting bit array.</returns> 492 public IBitArray BitOr(IBitArray other) => this | (BitArray64)other; 493 /// <summary> 494 /// Bit-wise Not 495 /// </summary> 496 /// <returns>The resulting bit array.</returns> 497 public IBitArray BitNot() => ~this; 498 499 /// <summary> 500 /// Equality operator. 501 /// </summary> 502 /// <param name="a">First bit array.</param> 503 /// <param name="b">Second bit array.</param> 504 /// <returns>True if both bit arrays are equals.</returns> 505 public static bool operator ==(BitArray64 a, BitArray64 b) => a.data == b.data; 506 /// <summary> 507 /// Inequality operator. 508 /// </summary> 509 /// <param name="a">First bit array.</param> 510 /// <param name="b">Second bit array.</param> 511 /// <returns>True if the bit arrays are not equals.</returns> 512 public static bool operator !=(BitArray64 a, BitArray64 b) => a.data != b.data; 513 /// <summary> 514 /// Equality operator. 515 /// </summary> 516 /// <param name="obj">Bit array to compare to.</param> 517 /// <returns>True if the provided bit array is equal to this..</returns> 518 public override bool Equals(object obj) => obj is BitArray64 ba64 && ba64.data == data; 519 /// <summary> 520 /// Get the hashcode of the bit array. 521 /// </summary> 522 /// <returns>Hashcode of the bit array.</returns> 523 public override int GetHashCode() => 1768953197 + data.GetHashCode(); 524 } 525 526 /// <summary> 527 /// Bit array of size 128. 528 /// </summary> 529 [Serializable] 530 [System.Diagnostics.DebuggerDisplay("{this.GetType().Name} {humanizedData}")] 531 public struct BitArray128 : IBitArray 532 { 533 [SerializeField] 534 ulong data1; 535 [SerializeField] 536 ulong data2; 537 538 /// <summary>Number of elements in the bit array.</summary> 539 public uint capacity => 128u; 540 /// <summary>True if all bits are 0.</summary> 541 public bool allFalse => data1 == 0uL && data2 == 0uL; 542 /// <summary>True if all bits are 1.</summary> 543 public bool allTrue => data1 == ulong.MaxValue && data2 == ulong.MaxValue; 544 /// <summary>Returns the bit array in a human readable form.</summary> 545 public string humanizedData => 546 System.Text.RegularExpressions.Regex.Replace(String.Format("{0, " + 64u + "}", Convert.ToString((long)data2, 2)).Replace(' ', '0'), ".{8}", "$0.") 547 + System.Text.RegularExpressions.Regex.Replace(String.Format("{0, " + 64u + "}", Convert.ToString((long)data1, 2)).Replace(' ', '0'), ".{8}", "$0.").TrimEnd('.'); 548 549 /// <summary> 550 /// Returns the state of the bit at a specific index. 551 /// </summary> 552 /// <param name="index">Index of the bit.</param> 553 /// <value>State of the bit at the provided index.</value> 554 public bool this[uint index] 555 { 556 get => index < 64u 557 ? (data1 & (1uL << (int)index)) != 0uL 558 : (data2 & (1uL << (int)(index - 64u))) != 0uL; 559 560 set 561 { 562 if (index < 64u) 563 data1 = (value ? (data1 | (1uL << (int)index)) : (data1 & ~(1uL << (int)index))); 564 else 565 data2 = (value ? (data2 | (1uL << (int)(index - 64u))) : (data2 & ~(1uL << (int)(index - 64u)))); 566 } 567 } 568 569 /// <summary> 570 /// Constructor. 571 /// </summary> 572 /// <param name="initValue1">Initialization value 1.</param> 573 /// <param name="initValue2">Initialization value 2.</param> 574 public BitArray128(ulong initValue1, ulong initValue2) 575 { 576 data1 = initValue1; 577 data2 = initValue2; 578 } 579 580 /// <summary> 581 /// Constructor. 582 /// </summary> 583 /// <param name="bitIndexTrue">List of indices where bits should be set to true.</param> 584 585 public BitArray128(IEnumerable<uint> bitIndexTrue) 586 { 587 data1 = data2 = 0uL; 588 if (bitIndexTrue == null) 589 return; 590 for (int index = bitIndexTrue.Count() - 1; index >= 0; --index) 591 { 592 uint bitIndex = bitIndexTrue.ElementAt(index); 593 if (bitIndex < 64u) 594 data1 |= 1uL << (int)bitIndex; 595 else if (bitIndex < capacity) 596 data2 |= 1uL << (int)(bitIndex - 64u); 597 } 598 } 599 600 /// <summary> 601 /// Bit-wise Not operator 602 /// </summary> 603 /// <param name="a">First bit array.</param> 604 /// <returns>The resulting bit array.</returns> 605 public static BitArray128 operator ~(BitArray128 a) => new BitArray128(~a.data1, ~a.data2); 606 /// <summary> 607 /// Bit-wise Or operator 608 /// </summary> 609 /// <param name="a">First bit array.</param> 610 /// <param name="b">Second bit array.</param> 611 /// <returns>The resulting bit array.</returns> 612 public static BitArray128 operator |(BitArray128 a, BitArray128 b) => new BitArray128(a.data1 | b.data1, a.data2 | b.data2); 613 /// <summary> 614 /// Bit-wise And operator 615 /// </summary> 616 /// <param name="a">First bit array.</param> 617 /// <param name="b">Second bit array.</param> 618 /// <returns>The resulting bit array.</returns> 619 public static BitArray128 operator &(BitArray128 a, BitArray128 b) => new BitArray128(a.data1 & b.data1, a.data2 & b.data2); 620 621 /// <summary> 622 /// Bit-wise And 623 /// </summary> 624 /// <param name="other">Bit array with which to do the operation.</param> 625 /// <returns>The resulting bit array.</returns> 626 public IBitArray BitAnd(IBitArray other) => this & (BitArray128)other; 627 /// <summary> 628 /// Bit-wise Or 629 /// </summary> 630 /// <param name="other">Bit array with which to do the operation.</param> 631 /// <returns>The resulting bit array.</returns> 632 public IBitArray BitOr(IBitArray other) => this | (BitArray128)other; 633 /// <summary> 634 /// Bit-wise Not 635 /// </summary> 636 /// <returns>The resulting bit array.</returns> 637 public IBitArray BitNot() => ~this; 638 639 /// <summary> 640 /// Equality operator. 641 /// </summary> 642 /// <param name="a">First bit array.</param> 643 /// <param name="b">Second bit array.</param> 644 /// <returns>True if both bit arrays are equals.</returns> 645 public static bool operator ==(BitArray128 a, BitArray128 b) => a.data1 == b.data1 && a.data2 == b.data2; 646 /// <summary> 647 /// Inequality operator. 648 /// </summary> 649 /// <param name="a">First bit array.</param> 650 /// <param name="b">Second bit array.</param> 651 /// <returns>True if the bit arrays are not equals.</returns> 652 public static bool operator !=(BitArray128 a, BitArray128 b) => a.data1 != b.data1 || a.data2 != b.data2; 653 /// <summary> 654 /// Equality operator. 655 /// </summary> 656 /// <param name="obj">Bit array to compare to.</param> 657 /// <returns>True if the provided bit array is equal to this..</returns> 658 public override bool Equals(object obj) => obj is BitArray128 ba128 && data1.Equals(ba128.data1) && data2.Equals(ba128.data2); 659 /// <summary> 660 /// Get the hashcode of the bit array. 661 /// </summary> 662 /// <returns>Hashcode of the bit array.</returns> 663 public override int GetHashCode() 664 { 665 var hashCode = 1755735569; 666 hashCode = hashCode * -1521134295 + data1.GetHashCode(); 667 hashCode = hashCode * -1521134295 + data2.GetHashCode(); 668 return hashCode; 669 } 670 } 671 672 /// <summary> 673 /// Bit array of size 256. 674 /// </summary> 675 [Serializable] 676 [System.Diagnostics.DebuggerDisplay("{this.GetType().Name} {humanizedData}")] 677 public struct BitArray256 : IBitArray 678 { 679 [SerializeField] 680 ulong data1; 681 [SerializeField] 682 ulong data2; 683 [SerializeField] 684 ulong data3; 685 [SerializeField] 686 ulong data4; 687 688 /// <summary>Number of elements in the bit array.</summary> 689 public uint capacity => 256u; 690 /// <summary>True if all bits are 0.</summary> 691 public bool allFalse => data1 == 0uL && data2 == 0uL && data3 == 0uL && data4 == 0uL; 692 /// <summary>True if all bits are 1.</summary> 693 public bool allTrue => data1 == ulong.MaxValue && data2 == ulong.MaxValue && data3 == ulong.MaxValue && data4 == ulong.MaxValue; 694 /// <summary>Returns the bit array in a human readable form.</summary> 695 public string humanizedData => 696 System.Text.RegularExpressions.Regex.Replace(String.Format("{0, " + 64u + "}", Convert.ToString((long)data4, 2)).Replace(' ', '0'), ".{8}", "$0.") 697 + System.Text.RegularExpressions.Regex.Replace(String.Format("{0, " + 64u + "}", Convert.ToString((long)data3, 2)).Replace(' ', '0'), ".{8}", "$0.") 698 + System.Text.RegularExpressions.Regex.Replace(String.Format("{0, " + 64u + "}", Convert.ToString((long)data2, 2)).Replace(' ', '0'), ".{8}", "$0.") 699 + System.Text.RegularExpressions.Regex.Replace(String.Format("{0, " + 64u + "}", Convert.ToString((long)data1, 2)).Replace(' ', '0'), ".{8}", "$0.").TrimEnd('.'); 700 701 /// <summary> 702 /// Returns the state of the bit at a specific index. 703 /// </summary> 704 /// <param name="index">Index of the bit.</param> 705 /// <value>State of the bit at the provided index.</value> 706 public bool this[uint index] 707 { 708 get => BitArrayUtilities.Get256(index, data1, data2, data3, data4); 709 set => BitArrayUtilities.Set256(index, ref data1, ref data2, ref data3, ref data4, value); 710 } 711 712 /// <summary> 713 /// Constructor. 714 /// </summary> 715 /// <param name="initValue1">Initialization value 1.</param> 716 /// <param name="initValue2">Initialization value 2.</param> 717 /// <param name="initValue3">Initialization value 3.</param> 718 /// <param name="initValue4">Initialization value 4.</param> 719 public BitArray256(ulong initValue1, ulong initValue2, ulong initValue3, ulong initValue4) 720 { 721 data1 = initValue1; 722 data2 = initValue2; 723 data3 = initValue3; 724 data4 = initValue4; 725 } 726 727 /// <summary> 728 /// Constructor. 729 /// </summary> 730 /// <param name="bitIndexTrue">List of indices where bits should be set to true.</param> 731 public BitArray256(IEnumerable<uint> bitIndexTrue) 732 { 733 data1 = data2 = data3 = data4 = 0uL; 734 if (bitIndexTrue == null) 735 return; 736 for (int index = bitIndexTrue.Count() - 1; index >= 0; --index) 737 { 738 uint bitIndex = bitIndexTrue.ElementAt(index); 739 if (bitIndex < 64u) 740 data1 |= 1uL << (int)bitIndex; 741 else if (bitIndex < 128u) 742 data2 |= 1uL << (int)(bitIndex - 64u); 743 else if (bitIndex < 192u) 744 data3 |= 1uL << (int)(bitIndex - 128u); 745 else if (bitIndex < capacity) 746 data4 |= 1uL << (int)(bitIndex - 192u); 747 } 748 } 749 750 /// <summary> 751 /// Bit-wise Not operator 752 /// </summary> 753 /// <param name="a">Bit array with which to do the operation.</param> 754 /// <returns>The resulting bit array.</returns> 755 public static BitArray256 operator ~(BitArray256 a) => new BitArray256(~a.data1, ~a.data2, ~a.data3, ~a.data4); 756 /// <summary> 757 /// Bit-wise Or operator 758 /// </summary> 759 /// <param name="a">First bit array.</param> 760 /// <param name="b">Second bit array.</param> 761 /// <returns>The resulting bit array.</returns> 762 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); 763 /// <summary> 764 /// Bit-wise And operator 765 /// </summary> 766 /// <param name="a">First bit array.</param> 767 /// <param name="b">Second bit array.</param> 768 /// <returns>The resulting bit array.</returns> 769 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); 770 771 /// <summary> 772 /// Bit-wise And 773 /// </summary> 774 /// <param name="other">Bit array with which to do the operation.</param> 775 /// <returns>The resulting bit array.</returns> 776 public IBitArray BitAnd(IBitArray other) => this & (BitArray256)other; 777 /// <summary> 778 /// Bit-wise Or 779 /// </summary> 780 /// <param name="other">Bit array with which to do the operation.</param> 781 /// <returns>The resulting bit array.</returns> 782 public IBitArray BitOr(IBitArray other) => this | (BitArray256)other; 783 /// <summary> 784 /// Bit-wise Not 785 /// </summary> 786 /// <returns>The resulting bit array.</returns> 787 public IBitArray BitNot() => ~this; 788 789 /// <summary> 790 /// Equality operator. 791 /// </summary> 792 /// <param name="a">First bit array.</param> 793 /// <param name="b">Second bit array.</param> 794 /// <returns>True if both bit arrays are equals.</returns> 795 public static bool operator ==(BitArray256 a, BitArray256 b) => a.data1 == b.data1 && a.data2 == b.data2 && a.data3 == b.data3 && a.data4 == b.data4; 796 /// <summary> 797 /// Inequality operator. 798 /// </summary> 799 /// <param name="a">First bit array.</param> 800 /// <param name="b">Second bit array.</param> 801 /// <returns>True if the bit arrays are not equals.</returns> 802 public static bool operator !=(BitArray256 a, BitArray256 b) => a.data1 != b.data1 || a.data2 != b.data2 || a.data3 != b.data3 || a.data4 != b.data4; 803 /// <summary> 804 /// Equality operator. 805 /// </summary> 806 /// <param name="obj">Bit array to compare to.</param> 807 /// <returns>True if the provided bit array is equal to this..</returns> 808 public override bool Equals(object obj) 809 => obj is BitArray256 ba256 810 && data1.Equals(ba256.data1) 811 && data2.Equals(ba256.data2) 812 && data3.Equals(ba256.data3) 813 && data4.Equals(ba256.data4); 814 /// <summary> 815 /// Get the hashcode of the bit array. 816 /// </summary> 817 /// <returns>Hashcode of the bit array.</returns> 818 public override int GetHashCode() 819 { 820 var hashCode = 1870826326; 821 hashCode = hashCode * -1521134295 + data1.GetHashCode(); 822 hashCode = hashCode * -1521134295 + data2.GetHashCode(); 823 hashCode = hashCode * -1521134295 + data3.GetHashCode(); 824 hashCode = hashCode * -1521134295 + data4.GetHashCode(); 825 return hashCode; 826 } 827 } 828 829 /// <summary> 830 /// Bit array utility class. 831 /// </summary> 832 public static class BitArrayUtilities 833 { 834 //written here to not duplicate the serialized accessor and runtime accessor 835 836 /// <summary> 837 /// Get a bit at a specific index. 838 /// </summary> 839 /// <param name="index">Bit index.</param> 840 /// <param name="data">Bit array data.</param> 841 /// <returns>The value of the bit at the specific index.</returns> 842 public static bool Get8(uint index, byte data) => (data & (1u << (int)index)) != 0u; 843 /// <summary> 844 /// Get a bit at a specific index. 845 /// </summary> 846 /// <param name="index">Bit index.</param> 847 /// <param name="data">Bit array data.</param> 848 /// <returns>The value of the bit at the specific index.</returns> 849 public static bool Get16(uint index, ushort data) => (data & (1u << (int)index)) != 0u; 850 /// <summary> 851 /// Get a bit at a specific index. 852 /// </summary> 853 /// <param name="index">Bit index.</param> 854 /// <param name="data">Bit array data.</param> 855 /// <returns>The value of the bit at the specific index.</returns> 856 public static bool Get32(uint index, uint data) => (data & (1u << (int)index)) != 0u; 857 /// <summary> 858 /// Get a bit at a specific index. 859 /// </summary> 860 /// <param name="index">Bit index.</param> 861 /// <param name="data">Bit array data.</param> 862 /// <returns>The value of the bit at the specific index.</returns> 863 public static bool Get64(uint index, ulong data) => (data & (1uL << (int)index)) != 0uL; 864 /// <summary> 865 /// Get a bit at a specific index. 866 /// </summary> 867 /// <param name="index">Bit index.</param> 868 /// <param name="data1">Bit array data 1.</param> 869 /// <param name="data2">Bit array data 2.</param> 870 /// <returns>The value of the bit at the specific index.</returns> 871 public static bool Get128(uint index, ulong data1, ulong data2) 872 => index < 64u 873 ? (data1 & (1uL << (int)index)) != 0uL 874 : (data2 & (1uL << (int)(index - 64u))) != 0uL; 875 /// <summary> 876 /// Get a bit at a specific index. 877 /// </summary> 878 /// <param name="index">Bit index.</param> 879 /// <param name="data1">Bit array data 1.</param> 880 /// <param name="data2">Bit array data 2.</param> 881 /// <param name="data3">Bit array data 3.</param> 882 /// <param name="data4">Bit array data 4.</param> 883 /// <returns>The value of the bit at the specific index.</returns> 884 public static bool Get256(uint index, ulong data1, ulong data2, ulong data3, ulong data4) 885 => index < 128u 886 ? index < 64u 887 ? (data1 & (1uL << (int)index)) != 0uL 888 : (data2 & (1uL << (int)(index - 64u))) != 0uL 889 : index < 192u 890 ? (data3 & (1uL << (int)(index - 128u))) != 0uL 891 : (data4 & (1uL << (int)(index - 192u))) != 0uL; 892 893 /// <summary> 894 /// Set a bit at a specific index. 895 /// </summary> 896 /// <param name="index">Bit index.</param> 897 /// <param name="data">Bit array data.</param> 898 /// <param name="value">Value to set the bit to.</param> 899 public static void Set8(uint index, ref byte data, bool value) => data = (byte)(value ? (data | (1u << (int)index)) : (data & ~(1u << (int)index))); 900 /// <summary> 901 /// Set a bit at a specific index. 902 /// </summary> 903 /// <param name="index">Bit index.</param> 904 /// <param name="data">Bit array data.</param> 905 /// <param name="value">Value to set the bit to.</param> 906 public static void Set16(uint index, ref ushort data, bool value) => data = (ushort)(value ? (data | (1u << (int)index)) : (data & ~(1u << (int)index))); 907 /// <summary> 908 /// Set a bit at a specific index. 909 /// </summary> 910 /// <param name="index">Bit index.</param> 911 /// <param name="data">Bit array data.</param> 912 /// <param name="value">Value to set the bit to.</param> 913 public static void Set32(uint index, ref uint data, bool value) => data = (value ? (data | (1u << (int)index)) : (data & ~(1u << (int)index))); 914 /// <summary> 915 /// Set a bit at a specific index. 916 /// </summary> 917 /// <param name="index">Bit index.</param> 918 /// <param name="data">Bit array data.</param> 919 /// <param name="value">Value to set the bit to.</param> 920 public static void Set64(uint index, ref ulong data, bool value) => data = (value ? (data | (1uL << (int)index)) : (data & ~(1uL << (int)index))); 921 /// <summary> 922 /// Set a bit at a specific index. 923 /// </summary> 924 /// <param name="index">Bit index.</param> 925 /// <param name="data1">Bit array data 1.</param> 926 /// <param name="data2">Bit array data 2.</param> 927 /// <param name="value">Value to set the bit to.</param> 928 public static void Set128(uint index, ref ulong data1, ref ulong data2, bool value) 929 { 930 if (index < 64u) 931 data1 = (value ? (data1 | (1uL << (int)index)) : (data1 & ~(1uL << (int)index))); 932 else 933 data2 = (value ? (data2 | (1uL << (int)(index - 64u))) : (data2 & ~(1uL << (int)(index - 64u)))); 934 } 935 936 /// <summary> 937 /// Set a bit at a specific index. 938 /// </summary> 939 /// <param name="index">Bit index.</param> 940 /// <param name="data1">Bit array data 1.</param> 941 /// <param name="data2">Bit array data 2.</param> 942 /// <param name="data3">Bit array data 3.</param> 943 /// <param name="data4">Bit array data 4.</param> 944 /// <param name="value">Value to set the bit to.</param> 945 public static void Set256(uint index, ref ulong data1, ref ulong data2, ref ulong data3, ref ulong data4, bool value) 946 { 947 if (index < 64u) 948 data1 = (value ? (data1 | (1uL << (int)index)) : (data1 & ~(1uL << (int)index))); 949 else if (index < 128u) 950 data2 = (value ? (data2 | (1uL << (int)(index - 64u))) : (data2 & ~(1uL << (int)(index - 64u)))); 951 else if (index < 192u) 952 data3 = (value ? (data3 | (1uL << (int)(index - 64u))) : (data3 & ~(1uL << (int)(index - 128u)))); 953 else 954 data4 = (value ? (data4 | (1uL << (int)(index - 64u))) : (data4 & ~(1uL << (int)(index - 192u)))); 955 } 956 } 957}