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}