Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
BitArray.cs
Go to the documentation of this file.
6
7namespace System.Collections;
8
10[TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
12{
14 {
15 private readonly BitArray _bitArray;
16
17 private int _index;
18
19 private readonly int _version;
20
21 private bool _currentElement;
22
23 public object Current
24 {
25 get
26 {
27 if ((uint)_index >= (uint)_bitArray.m_length)
28 {
30 }
31 return _currentElement;
32 }
33 }
34
36 {
37 _bitArray = bitArray;
38 _index = -1;
39 _version = bitArray._version;
40 }
41
42 public object Clone()
43 {
44 return MemberwiseClone();
45 }
46
47 public bool MoveNext()
48 {
50 {
52 }
53 if (_index < _bitArray.m_length - 1)
54 {
55 _index++;
57 return true;
58 }
60 return false;
61 }
62
63 public void Reset()
64 {
66 {
68 }
69 _index = -1;
70 }
71
80 }
81
82 private int[] m_array;
83
84 private int m_length;
85
86 private int _version;
87
88 public bool this[int index]
89 {
90 get
91 {
92 return Get(index);
93 }
94 set
95 {
96 Set(index, value);
97 }
98 }
99
100 public int Length
101 {
102 get
103 {
104 return m_length;
105 }
106 set
107 {
108 if (value < 0)
109 {
111 }
112 int int32ArrayLengthFromBitLength = GetInt32ArrayLengthFromBitLength(value);
113 if (int32ArrayLengthFromBitLength > m_array.Length || int32ArrayLengthFromBitLength + 256 < m_array.Length)
114 {
115 Array.Resize(ref m_array, int32ArrayLengthFromBitLength);
116 }
117 if (value > m_length)
118 {
119 int num = m_length - 1 >> 5;
120 Div32Rem(m_length, out var remainder);
121 if (remainder > 0)
122 {
123 m_array[num] &= (1 << remainder) - 1;
124 }
125 m_array.AsSpan(num + 1, int32ArrayLengthFromBitLength - num - 1).Clear();
126 }
127 m_length = value;
128 _version++;
129 }
130 }
131
132 public int Count => m_length;
133
134 public object SyncRoot => this;
135
136 public bool IsSynchronized => false;
137
138 public bool IsReadOnly => false;
139
140 public BitArray(int length)
141 : this(length, defaultValue: false)
142 {
143 }
144
145 public BitArray(int length, bool defaultValue)
146 {
147 if (length < 0)
148 {
150 }
153 if (defaultValue)
154 {
155 Array.Fill(m_array, -1);
156 Div32Rem(length, out var remainder);
157 if (remainder > 0)
158 {
159 m_array[^1] = (1 << remainder) - 1;
160 }
161 }
162 _version = 0;
163 }
164
165 public BitArray(byte[] bytes)
166 {
167 if (bytes == null)
168 {
169 throw new ArgumentNullException("bytes");
170 }
171 if (bytes.Length > 268435455)
172 {
174 }
176 m_length = bytes.Length * 8;
177 uint num = (uint)bytes.Length / 4u;
179 for (int i = 0; i < num; i++)
180 {
182 source = source.Slice(4);
183 }
184 int num2 = 0;
185 switch (source.Length)
186 {
187 case 3:
188 num2 = source[2] << 16;
189 goto case 2;
190 case 2:
191 num2 |= source[1] << 8;
192 goto case 1;
193 case 1:
194 m_array[num] = num2 | source[0];
195 break;
196 }
197 _version = 0;
198 }
199
200 public unsafe BitArray(bool[] values)
201 {
202 if (values == null)
203 {
204 throw new ArgumentNullException("values");
205 }
207 m_length = values.Length;
208 uint num = 0u;
209 if (values.Length >= Vector256<byte>.Count)
210 {
211 if (Avx2.IsSupported)
212 {
214 fixed (bool* ptr = values)
215 {
216 for (; num + 32 <= (uint)values.Length; num += 32)
217 {
218 Vector256<byte> left = Avx.LoadVector256((byte*)(ptr + num));
220 int num2 = Avx2.MoveMask(value);
221 m_array[num / 32] = ~num2;
222 }
223 }
224 }
225 else if (Sse2.IsSupported)
226 {
228 fixed (bool* ptr2 = values)
229 {
230 for (; num + 32 <= (uint)values.Length; num += 32)
231 {
232 Vector128<byte> left2 = Sse2.LoadVector128((byte*)(ptr2 + num));
233 Vector128<byte> value2 = Sse2.CompareEqual(left2, zero2);
234 int num3 = Sse2.MoveMask(value2);
235 Vector128<byte> left3 = Sse2.LoadVector128((byte*)(ptr2 + num + Vector128<byte>.Count));
236 Vector128<byte> value3 = Sse2.CompareEqual(left3, zero2);
237 int num4 = Sse2.MoveMask(value3);
238 m_array[num / 32] = ~((num4 << 16) | num3);
239 }
240 }
241 }
242 else if (AdvSimd.Arm64.IsSupported)
243 {
245 Vector128<byte> right = (BitConverter.IsLittleEndian ? Vector128.Create(9241421688590303745uL).AsByte() : Vector128.Create(72624976668147840L).AsByte());
246 fixed (bool* ptr3 = values)
247 {
248 for (; num + 32 <= (uint)values.Length; num += 32)
249 {
250 Vector128<byte> left4 = AdvSimd.LoadVector128((byte*)(ptr3 + num));
251 Vector128<byte> left5 = AdvSimd.CompareEqual(left4, zero3);
252 Vector128<byte> vector = AdvSimd.And(left5, right);
253 vector = AdvSimd.Arm64.AddPairwise(vector, vector);
254 vector = AdvSimd.Arm64.AddPairwise(vector, vector);
255 vector = AdvSimd.Arm64.AddPairwise(vector, vector);
256 Vector128<short> left6 = vector.AsInt16();
257 Vector128<byte> left7 = AdvSimd.LoadVector128((byte*)(ptr3 + num + Vector128<byte>.Count));
258 Vector128<byte> left8 = AdvSimd.CompareEqual(left7, zero3);
259 Vector128<byte> vector2 = AdvSimd.And(left8, right);
260 vector2 = AdvSimd.Arm64.AddPairwise(vector2, vector2);
261 vector2 = AdvSimd.Arm64.AddPairwise(vector2, vector2);
262 vector2 = AdvSimd.Arm64.AddPairwise(vector2, vector2);
263 Vector128<short> right2 = vector2.AsInt16();
264 int num5 = AdvSimd.Arm64.ZipLow(left6, right2).AsInt32().ToScalar();
266 {
268 }
269 m_array[num / 32] = ~num5;
270 }
271 }
272 }
273 }
274 for (; num < (uint)values.Length; num++)
275 {
276 if (values[num])
277 {
278 int remainder;
279 int num6 = Div32Rem((int)num, out remainder);
280 m_array[num6] |= 1 << remainder;
281 }
282 }
283 _version = 0;
284 }
285
286 public BitArray(int[] values)
287 {
288 if (values == null)
289 {
290 throw new ArgumentNullException("values");
291 }
292 if (values.Length > 67108863)
293 {
295 }
296 m_array = new int[values.Length];
297 Array.Copy(values, m_array, values.Length);
298 m_length = values.Length * 32;
299 _version = 0;
300 }
301
302 public BitArray(BitArray bits)
303 {
304 if (bits == null)
305 {
306 throw new ArgumentNullException("bits");
307 }
308 int int32ArrayLengthFromBitLength = GetInt32ArrayLengthFromBitLength(bits.m_length);
309 m_array = new int[int32ArrayLengthFromBitLength];
310 Array.Copy(bits.m_array, m_array, int32ArrayLengthFromBitLength);
311 m_length = bits.m_length;
312 _version = bits._version;
313 }
314
315 [MethodImpl(MethodImplOptions.AggressiveInlining)]
316 public bool Get(int index)
317 {
318 if ((uint)index >= (uint)m_length)
319 {
321 }
322 return (m_array[index >> 5] & (1 << index)) != 0;
323 }
324
325 [MethodImpl(MethodImplOptions.AggressiveInlining)]
326 public void Set(int index, bool value)
327 {
328 if ((uint)index >= (uint)m_length)
329 {
331 }
332 int num = 1 << index;
333 ref int reference = ref m_array[index >> 5];
334 if (value)
335 {
336 reference |= num;
337 }
338 else
339 {
340 reference &= ~num;
341 }
342 _version++;
343 }
344
345 public void SetAll(bool value)
346 {
347 int int32ArrayLengthFromBitLength = GetInt32ArrayLengthFromBitLength(Length);
348 Span<int> span = m_array.AsSpan(0, int32ArrayLengthFromBitLength);
349 if (value)
350 {
351 span.Fill(-1);
352 Div32Rem(m_length, out var remainder);
353 if (remainder > 0)
354 {
355 span[span.Length - 1] &= (1 << remainder) - 1;
356 }
357 }
358 else
359 {
360 span.Clear();
361 }
362 _version++;
363 }
364
365 public unsafe BitArray And(BitArray value)
366 {
367 if (value == null)
368 {
369 throw new ArgumentNullException("value");
370 }
371 int[] array = m_array;
372 int[] array2 = value.m_array;
373 int int32ArrayLengthFromBitLength = GetInt32ArrayLengthFromBitLength(Length);
374 if (Length != value.Length || (uint)int32ArrayLengthFromBitLength > (uint)array.Length || (uint)int32ArrayLengthFromBitLength > (uint)array2.Length)
375 {
377 }
378 switch (int32ArrayLengthFromBitLength)
379 {
380 case 7:
381 array[6] &= array2[6];
382 goto case 6;
383 case 6:
384 array[5] &= array2[5];
385 goto case 5;
386 case 5:
387 array[4] &= array2[4];
388 goto case 4;
389 case 4:
390 array[3] &= array2[3];
391 goto case 3;
392 case 3:
393 array[2] &= array2[2];
394 goto case 2;
395 case 2:
396 array[1] &= array2[1];
397 goto case 1;
398 case 1:
399 array[0] &= array2[0];
400 break;
401 default:
402 {
403 uint num = 0u;
404 if (Avx2.IsSupported)
405 {
406 fixed (int* ptr = array)
407 {
408 fixed (int* ptr2 = array2)
409 {
410 for (; num < (uint)(int32ArrayLengthFromBitLength - 7); num += 8)
411 {
412 Vector256<int> left = Avx.LoadVector256(ptr + num);
413 Vector256<int> right = Avx.LoadVector256(ptr2 + num);
414 Avx.Store(ptr + num, Avx2.And(left, right));
415 }
416 }
417 }
418 }
419 else if (Sse2.IsSupported)
420 {
421 fixed (int* ptr3 = array)
422 {
423 fixed (int* ptr4 = array2)
424 {
425 for (; num < (uint)(int32ArrayLengthFromBitLength - 3); num += 4)
426 {
427 Vector128<int> left2 = Sse2.LoadVector128(ptr3 + num);
428 Vector128<int> right2 = Sse2.LoadVector128(ptr4 + num);
429 Sse2.Store(ptr3 + num, Sse2.And(left2, right2));
430 }
431 }
432 }
433 }
434 else if (AdvSimd.IsSupported)
435 {
436 fixed (int* ptr5 = array)
437 {
438 fixed (int* ptr6 = array2)
439 {
440 for (; num < (uint)(int32ArrayLengthFromBitLength - 3); num += 4)
441 {
442 Vector128<int> left3 = AdvSimd.LoadVector128(ptr5 + num);
443 Vector128<int> right3 = AdvSimd.LoadVector128(ptr6 + num);
444 AdvSimd.Store(ptr5 + num, AdvSimd.And(left3, right3));
445 }
446 }
447 }
448 }
449 for (; num < (uint)int32ArrayLengthFromBitLength; num++)
450 {
451 array[num] &= array2[num];
452 }
453 break;
454 }
455 case 0:
456 break;
457 }
458 _version++;
459 return this;
460 }
461
462 public unsafe BitArray Or(BitArray value)
463 {
464 if (value == null)
465 {
466 throw new ArgumentNullException("value");
467 }
468 int[] array = m_array;
469 int[] array2 = value.m_array;
470 int int32ArrayLengthFromBitLength = GetInt32ArrayLengthFromBitLength(Length);
471 if (Length != value.Length || (uint)int32ArrayLengthFromBitLength > (uint)array.Length || (uint)int32ArrayLengthFromBitLength > (uint)array2.Length)
472 {
474 }
475 switch (int32ArrayLengthFromBitLength)
476 {
477 case 7:
478 array[6] |= array2[6];
479 goto case 6;
480 case 6:
481 array[5] |= array2[5];
482 goto case 5;
483 case 5:
484 array[4] |= array2[4];
485 goto case 4;
486 case 4:
487 array[3] |= array2[3];
488 goto case 3;
489 case 3:
490 array[2] |= array2[2];
491 goto case 2;
492 case 2:
493 array[1] |= array2[1];
494 goto case 1;
495 case 1:
496 array[0] |= array2[0];
497 break;
498 default:
499 {
500 uint num = 0u;
501 if (Avx2.IsSupported)
502 {
503 fixed (int* ptr = array)
504 {
505 fixed (int* ptr2 = array2)
506 {
507 for (; num < (uint)(int32ArrayLengthFromBitLength - 7); num += 8)
508 {
509 Vector256<int> left = Avx.LoadVector256(ptr + num);
510 Vector256<int> right = Avx.LoadVector256(ptr2 + num);
511 Avx.Store(ptr + num, Avx2.Or(left, right));
512 }
513 }
514 }
515 }
516 else if (Sse2.IsSupported)
517 {
518 fixed (int* ptr3 = array)
519 {
520 fixed (int* ptr4 = array2)
521 {
522 for (; num < (uint)(int32ArrayLengthFromBitLength - 3); num += 4)
523 {
524 Vector128<int> left2 = Sse2.LoadVector128(ptr3 + num);
525 Vector128<int> right2 = Sse2.LoadVector128(ptr4 + num);
526 Sse2.Store(ptr3 + num, Sse2.Or(left2, right2));
527 }
528 }
529 }
530 }
531 else if (AdvSimd.IsSupported)
532 {
533 fixed (int* ptr5 = array)
534 {
535 fixed (int* ptr6 = array2)
536 {
537 for (; num < (uint)(int32ArrayLengthFromBitLength - 3); num += 4)
538 {
539 Vector128<int> left3 = AdvSimd.LoadVector128(ptr5 + num);
540 Vector128<int> right3 = AdvSimd.LoadVector128(ptr6 + num);
541 AdvSimd.Store(ptr5 + num, AdvSimd.Or(left3, right3));
542 }
543 }
544 }
545 }
546 for (; num < (uint)int32ArrayLengthFromBitLength; num++)
547 {
548 array[num] |= array2[num];
549 }
550 break;
551 }
552 case 0:
553 break;
554 }
555 _version++;
556 return this;
557 }
558
559 public unsafe BitArray Xor(BitArray value)
560 {
561 if (value == null)
562 {
563 throw new ArgumentNullException("value");
564 }
565 int[] array = m_array;
566 int[] array2 = value.m_array;
567 int int32ArrayLengthFromBitLength = GetInt32ArrayLengthFromBitLength(Length);
568 if (Length != value.Length || (uint)int32ArrayLengthFromBitLength > (uint)array.Length || (uint)int32ArrayLengthFromBitLength > (uint)array2.Length)
569 {
571 }
572 switch (int32ArrayLengthFromBitLength)
573 {
574 case 7:
575 array[6] ^= array2[6];
576 goto case 6;
577 case 6:
578 array[5] ^= array2[5];
579 goto case 5;
580 case 5:
581 array[4] ^= array2[4];
582 goto case 4;
583 case 4:
584 array[3] ^= array2[3];
585 goto case 3;
586 case 3:
587 array[2] ^= array2[2];
588 goto case 2;
589 case 2:
590 array[1] ^= array2[1];
591 goto case 1;
592 case 1:
593 array[0] ^= array2[0];
594 break;
595 default:
596 {
597 uint num = 0u;
598 if (Avx2.IsSupported)
599 {
600 fixed (int* ptr = m_array)
601 {
602 fixed (int* ptr2 = value.m_array)
603 {
604 for (; num < (uint)(int32ArrayLengthFromBitLength - 7); num += 8)
605 {
606 Vector256<int> left = Avx.LoadVector256(ptr + num);
607 Vector256<int> right = Avx.LoadVector256(ptr2 + num);
608 Avx.Store(ptr + num, Avx2.Xor(left, right));
609 }
610 }
611 }
612 }
613 else if (Sse2.IsSupported)
614 {
615 fixed (int* ptr3 = array)
616 {
617 fixed (int* ptr4 = array2)
618 {
619 for (; num < (uint)(int32ArrayLengthFromBitLength - 3); num += 4)
620 {
621 Vector128<int> left2 = Sse2.LoadVector128(ptr3 + num);
622 Vector128<int> right2 = Sse2.LoadVector128(ptr4 + num);
623 Sse2.Store(ptr3 + num, Sse2.Xor(left2, right2));
624 }
625 }
626 }
627 }
628 else if (AdvSimd.IsSupported)
629 {
630 fixed (int* ptr5 = array)
631 {
632 fixed (int* ptr6 = array2)
633 {
634 for (; num < (uint)(int32ArrayLengthFromBitLength - 3); num += 4)
635 {
636 Vector128<int> left3 = AdvSimd.LoadVector128(ptr5 + num);
637 Vector128<int> right3 = AdvSimd.LoadVector128(ptr6 + num);
638 AdvSimd.Store(ptr5 + num, AdvSimd.Xor(left3, right3));
639 }
640 }
641 }
642 }
643 for (; num < (uint)int32ArrayLengthFromBitLength; num++)
644 {
645 array[num] ^= array2[num];
646 }
647 break;
648 }
649 case 0:
650 break;
651 }
652 _version++;
653 return this;
654 }
655
656 public unsafe BitArray Not()
657 {
658 int[] array = m_array;
659 int int32ArrayLengthFromBitLength = GetInt32ArrayLengthFromBitLength(Length);
660 switch (int32ArrayLengthFromBitLength)
661 {
662 case 7:
663 array[6] = ~array[6];
664 goto case 6;
665 case 6:
666 array[5] = ~array[5];
667 goto case 5;
668 case 5:
669 array[4] = ~array[4];
670 goto case 4;
671 case 4:
672 array[3] = ~array[3];
673 goto case 3;
674 case 3:
675 array[2] = ~array[2];
676 goto case 2;
677 case 2:
678 array[1] = ~array[1];
679 goto case 1;
680 case 1:
681 array[0] = ~array[0];
682 break;
683 default:
684 {
685 uint num = 0u;
686 if (Avx2.IsSupported)
687 {
688 Vector256<int> right = Vector256.Create(-1);
689 fixed (int* ptr = array)
690 {
691 for (; num < (uint)(int32ArrayLengthFromBitLength - 7); num += 8)
692 {
693 Vector256<int> left = Avx.LoadVector256(ptr + num);
694 Avx.Store(ptr + num, Avx2.Xor(left, right));
695 }
696 }
697 }
698 else if (Sse2.IsSupported)
699 {
700 Vector128<int> right2 = Vector128.Create(-1);
701 fixed (int* ptr2 = array)
702 {
703 for (; num < (uint)(int32ArrayLengthFromBitLength - 3); num += 4)
704 {
705 Vector128<int> left2 = Sse2.LoadVector128(ptr2 + num);
706 Sse2.Store(ptr2 + num, Sse2.Xor(left2, right2));
707 }
708 }
709 }
710 else if (AdvSimd.IsSupported)
711 {
712 fixed (int* ptr3 = array)
713 {
714 for (; num < (uint)(int32ArrayLengthFromBitLength - 3); num += 4)
715 {
717 AdvSimd.Store(ptr3 + num, AdvSimd.Not(value));
718 }
719 }
720 }
721 for (; num < (uint)int32ArrayLengthFromBitLength; num++)
722 {
723 array[num] = ~array[num];
724 }
725 break;
726 }
727 case 0:
728 break;
729 }
730 _version++;
731 return this;
732 }
733
735 {
736 if (count <= 0)
737 {
738 if (count < 0)
739 {
741 }
742 _version++;
743 return this;
744 }
745 int num = 0;
746 int int32ArrayLengthFromBitLength = GetInt32ArrayLengthFromBitLength(m_length);
747 if (count < m_length)
748 {
749 int remainder;
750 int num2 = Div32Rem(count, out remainder);
751 Div32Rem(m_length, out var remainder2);
752 if (remainder == 0)
753 {
754 uint num3 = uint.MaxValue >> 32 - remainder2;
755 m_array[int32ArrayLengthFromBitLength - 1] &= (int)num3;
756 Array.Copy(m_array, num2, m_array, 0, int32ArrayLengthFromBitLength - num2);
757 num = int32ArrayLengthFromBitLength - num2;
758 }
759 else
760 {
761 int num4 = int32ArrayLengthFromBitLength - 1;
762 while (num2 < num4)
763 {
764 uint num5 = (uint)m_array[num2] >> remainder;
765 int num6 = m_array[++num2] << 32 - remainder;
766 m_array[num++] = num6 | (int)num5;
767 }
768 uint num7 = uint.MaxValue >> 32 - remainder2;
769 num7 &= (uint)m_array[num2];
770 m_array[num++] = (int)(num7 >> remainder);
771 }
772 }
773 m_array.AsSpan(num, int32ArrayLengthFromBitLength - num).Clear();
774 _version++;
775 return this;
776 }
777
779 {
780 if (count <= 0)
781 {
782 if (count < 0)
783 {
785 }
786 _version++;
787 return this;
788 }
789 int num2;
790 if (count < m_length)
791 {
792 int num = m_length - 1 >> 5;
793 num2 = Div32Rem(count, out var remainder);
794 if (remainder == 0)
795 {
796 Array.Copy(m_array, 0, m_array, num2, num + 1 - num2);
797 }
798 else
799 {
800 int num3 = num - num2;
801 while (num3 > 0)
802 {
803 int num4 = m_array[num3] << remainder;
804 uint num5 = (uint)m_array[--num3] >> 32 - remainder;
805 m_array[num] = num4 | (int)num5;
806 num--;
807 }
808 m_array[num] = m_array[num3] << remainder;
809 }
810 }
811 else
812 {
814 }
815 m_array.AsSpan(0, num2).Clear();
816 _version++;
817 return this;
818 }
819
820 public unsafe void CopyTo(Array array, int index)
821 {
822 if (array == null)
823 {
824 throw new ArgumentNullException("array");
825 }
826 if (index < 0)
827 {
829 }
830 if (array.Rank != 1)
831 {
833 }
834 if (array is int[] array2)
835 {
836 Div32Rem(m_length, out var remainder);
837 if (remainder == 0)
838 {
839 Array.Copy(m_array, 0, array2, index, m_array.Length);
840 return;
841 }
842 int num = m_length - 1 >> 5;
843 Array.Copy(m_array, 0, array2, index, num);
844 array2[index + num] = m_array[num] & ((1 << remainder) - 1);
845 return;
846 }
847 if (array is byte[] array3)
848 {
850 if (array.Length - index < num2)
851 {
853 }
854 uint num3 = (uint)m_length & 7u;
855 if (num3 != 0)
856 {
857 num2--;
858 }
859 Span<byte> destination = array3.AsSpan(index);
860 int remainder2;
861 int num4 = Div4Rem(num2, out remainder2);
862 for (int i = 0; i < num4; i++)
863 {
865 destination = destination.Slice(4);
866 }
867 if (num3 != 0)
868 {
869 destination[remainder2] = (byte)((m_array[num4] >> remainder2 * 8) & ((1 << (int)num3) - 1));
870 }
871 switch (remainder2)
872 {
873 default:
874 return;
875 case 3:
876 destination[2] = (byte)(m_array[num4] >> 16);
877 goto case 2;
878 case 2:
879 destination[1] = (byte)(m_array[num4] >> 8);
880 break;
881 case 1:
882 break;
883 }
884 destination[0] = (byte)m_array[num4];
885 return;
886 }
887 if (array is bool[] array4)
888 {
889 if (array.Length - index < m_length)
890 {
892 }
893 uint num5 = 0u;
894 if (m_length >= 32)
895 {
896 Vector128<byte> vector = Vector128.Create(0L, 72340172838076673L).AsByte();
897 Vector128<byte> vector2 = Vector128.Create(144680345676153346L, 217020518514230019L).AsByte();
898 if (Avx2.IsSupported)
899 {
900 Vector256<byte> mask = Vector256.Create(vector, vector2);
901 Vector256<byte> right = Vector256.Create(9241421688590303745uL).AsByte();
902 Vector256<byte> right2 = Vector256.Create((byte)1);
903 fixed (bool* ptr = &array4[index])
904 {
905 for (; num5 + 32 <= (uint)m_length; num5 += 32)
906 {
907 int value = m_array[num5 / 32];
909 Vector256<byte> left = Avx2.Shuffle(vector3.AsByte(), mask);
910 Vector256<byte> left2 = Avx2.And(left, right);
911 Vector256<byte> source = Avx2.Min(left2, right2);
912 Avx.Store((byte*)(ptr + num5), source);
913 }
914 }
915 }
916 else if (Ssse3.IsSupported)
917 {
918 Vector128<byte> mask2 = vector;
919 Vector128<byte> mask3 = vector2;
920 Vector128<byte> right3 = Vector128.Create((byte)1);
921 Vector128<byte> right4 = (BitConverter.IsLittleEndian ? Vector128.Create(9241421688590303745uL).AsByte() : Vector128.Create(72624976668147840L).AsByte());
922 fixed (bool* ptr2 = &array4[index])
923 {
924 for (; num5 + 32 <= (uint)m_length; num5 += 32)
925 {
926 int value2 = m_array[num5 / 32];
928 Vector128<byte> left3 = Ssse3.Shuffle(vector4.AsByte(), mask2);
929 Vector128<byte> left4 = Sse2.And(left3, right4);
930 Vector128<byte> source2 = Sse2.Min(left4, right3);
931 Sse2.Store((byte*)(ptr2 + num5), source2);
932 Vector128<byte> left5 = Ssse3.Shuffle(vector4.AsByte(), mask3);
933 Vector128<byte> left6 = Sse2.And(left5, right4);
934 Vector128<byte> source3 = Sse2.Min(left6, right3);
935 Sse2.Store((byte*)(ptr2 + num5 + Vector128<byte>.Count), source3);
936 }
937 }
938 }
939 else if (AdvSimd.IsSupported)
940 {
941 Vector128<byte> right5 = Vector128.Create((byte)1);
942 Vector128<byte> right6 = (BitConverter.IsLittleEndian ? Vector128.Create(9241421688590303745uL).AsByte() : Vector128.Create(72624976668147840L).AsByte());
943 fixed (bool* ptr3 = &array4[index])
944 {
945 for (; num5 + 32 <= (uint)m_length; num5 += 32)
946 {
947 int value3 = m_array[num5 / 32];
949 {
950 value3 = BinaryPrimitives.ReverseEndianness(value3);
951 }
952 Vector128<byte> vector5 = Vector128.Create(value3).AsByte();
953 vector5 = AdvSimd.Arm64.ZipLow(vector5, vector5);
954 vector5 = AdvSimd.Arm64.ZipLow(vector5, vector5);
955 Vector128<byte> left7 = AdvSimd.Arm64.ZipLow(vector5, vector5);
956 Vector128<byte> left8 = AdvSimd.And(left7, right6);
957 Vector128<byte> source4 = AdvSimd.Min(left8, right5);
958 AdvSimd.Store((byte*)(ptr3 + num5), source4);
959 Vector128<byte> left9 = AdvSimd.Arm64.ZipHigh(vector5, vector5);
960 Vector128<byte> left10 = AdvSimd.And(left9, right6);
961 Vector128<byte> source5 = AdvSimd.Min(left10, right5);
962 AdvSimd.Store((byte*)(ptr3 + num5 + Vector128<byte>.Count), source5);
963 }
964 }
965 }
966 }
967 for (; num5 < (uint)m_length; num5++)
968 {
969 int remainder3;
970 int num6 = Div32Rem((int)num5, out remainder3);
971 array4[index + (int)num5] = ((m_array[num6] >> remainder3) & 1) != 0;
972 }
973 return;
974 }
976 }
977
978 public object Clone()
979 {
980 return new BitArray(this);
981 }
982
984 {
985 return new BitArrayEnumeratorSimple(this);
986 }
987
988 private static int GetInt32ArrayLengthFromBitLength(int n)
989 {
990 return n - 1 + 32 >>> 5;
991 }
992
993 private static int GetInt32ArrayLengthFromByteLength(int n)
994 {
995 return n - 1 + 4 >>> 2;
996 }
997
998 private static int GetByteArrayLengthFromBitLength(int n)
999 {
1000 return n - 1 + 8 >>> 3;
1001 }
1002
1003 private static int Div32Rem(int number, out int remainder)
1004 {
1005 uint result = (uint)number / 32u;
1006 remainder = number & 0x1F;
1007 return (int)result;
1008 }
1009
1010 private static int Div4Rem(int number, out int remainder)
1011 {
1012 uint result = (uint)number / 4u;
1013 remainder = number & 3;
1014 return (int)result;
1015 }
1016
1018 {
1020 }
1021}
static unsafe void Copy(Array sourceArray, Array destinationArray, int length)
Definition Array.cs:624
static readonly bool IsLittleEndian
static void WriteInt32LittleEndian(Span< byte > destination, int value)
static sbyte ReverseEndianness(sbyte value)
static int ReadInt32LittleEndian(ReadOnlySpan< byte > source)
InvalidOperationException GetInvalidOperationException(int index)
Definition BitArray.cs:72
unsafe BitArray(bool[] values)
Definition BitArray.cs:200
static void ThrowArgumentOutOfRangeException(int index)
Definition BitArray.cs:1017
BitArray(int length, bool defaultValue)
Definition BitArray.cs:145
static int GetInt32ArrayLengthFromByteLength(int n)
Definition BitArray.cs:993
IEnumerator GetEnumerator()
Definition BitArray.cs:983
static int GetInt32ArrayLengthFromBitLength(int n)
Definition BitArray.cs:988
BitArray(BitArray bits)
Definition BitArray.cs:302
void SetAll(bool value)
Definition BitArray.cs:345
unsafe BitArray Or(BitArray value)
Definition BitArray.cs:462
unsafe BitArray And(BitArray value)
Definition BitArray.cs:365
BitArray LeftShift(int count)
Definition BitArray.cs:778
unsafe BitArray Xor(BitArray value)
Definition BitArray.cs:559
void Set(int index, bool value)
Definition BitArray.cs:326
static int Div4Rem(int number, out int remainder)
Definition BitArray.cs:1010
BitArray RightShift(int count)
Definition BitArray.cs:734
unsafe void CopyTo(Array array, int index)
Definition BitArray.cs:820
static int Div32Rem(int number, out int remainder)
Definition BitArray.cs:1003
unsafe BitArray Not()
Definition BitArray.cs:656
static int GetByteArrayLengthFromBitLength(int n)
Definition BitArray.cs:998
static Vector64< byte > ZipLow(Vector64< byte > left, Vector64< byte > right)
Definition AdvSimd.cs:2879
static Vector64< byte > ZipHigh(Vector64< byte > left, Vector64< byte > right)
Definition AdvSimd.cs:2794
static Vector128< byte > AddPairwise(Vector128< byte > left, Vector128< byte > right)
Definition AdvSimd.cs:239
static Vector64< byte > CompareEqual(Vector64< byte > left, Vector64< byte > right)
Definition AdvSimd.cs:4239
static Vector64< byte > Min(Vector64< byte > left, Vector64< byte > right)
Definition AdvSimd.cs:6209
static unsafe void Store(byte *address, Vector64< byte > source)
Definition AdvSimd.cs:10249
static unsafe Vector128< byte > LoadVector128(byte *address)
Definition AdvSimd.cs:6034
static Vector64< byte > And(Vector64< byte > left, Vector64< byte > right)
Definition AdvSimd.cs:3919
static Vector64< byte > Not(Vector64< byte > value)
Definition AdvSimd.cs:7834
static Vector64< byte > Xor(Vector64< byte > left, Vector64< byte > right)
Definition AdvSimd.cs:10874
static Vector64< byte > Or(Vector64< byte > left, Vector64< byte > right)
Definition AdvSimd.cs:7934
static Vector128< byte > Create(byte value)
Definition Vector128.cs:138
static unsafe Vector128< byte > CreateScalarUnsafe(byte value)
Definition Vector128.cs:829
static Vector256< byte > Create(byte value)
Definition Vector256.cs:105
static int MoveMask(Vector256< sbyte > value)
Definition Avx2.cs:1578
static Vector256< sbyte > And(Vector256< sbyte > left, Vector256< sbyte > right)
Definition Avx2.cs:132
static Vector256< sbyte > CompareEqual(Vector256< sbyte > left, Vector256< sbyte > right)
Definition Avx2.cs:512
static new bool IsSupported
Definition Avx2.cs:15
static Vector256< sbyte > Min(Vector256< sbyte > left, Vector256< sbyte > right)
Definition Avx2.cs:1548
static Vector256< sbyte > Or(Vector256< sbyte > left, Vector256< sbyte > right)
Definition Avx2.cs:1638
static Vector256< sbyte > Shuffle(Vector256< sbyte > value, Vector256< sbyte > mask)
Definition Avx2.cs:2078
static Vector256< sbyte > Xor(Vector256< sbyte > left, Vector256< sbyte > right)
Definition Avx2.cs:2278
static unsafe Vector256< sbyte > LoadVector256(sbyte *address)
Definition Avx.cs:462
static unsafe void Store(sbyte *address, Vector256< sbyte > source)
Definition Avx.cs:962
static unsafe Vector128< sbyte > LoadVector128(sbyte *address)
Definition Sse2.cs:582
static int MoveMask(Vector128< sbyte > value)
Definition Sse2.cs:772
static Vector128< byte > Xor(Vector128< byte > left, Vector128< byte > right)
Definition Sse2.cs:1512
static Vector128< sbyte > CompareEqual(Vector128< sbyte > left, Vector128< sbyte > right)
Definition Sse2.cs:232
static unsafe void Store(sbyte *address, Vector128< sbyte > source)
Definition Sse2.cs:1287
static Vector128< byte > Or(Vector128< byte > left, Vector128< byte > right)
Definition Sse2.cs:837
static Vector128< byte > And(Vector128< byte > left, Vector128< byte > right)
Definition Sse2.cs:132
static Vector128< byte > Min(Vector128< byte > left, Vector128< byte > right)
Definition Sse2.cs:747
static new bool IsSupported
Definition Sse2.cs:60
static Vector128< sbyte > Shuffle(Vector128< sbyte > value, Vector128< sbyte > mask)
Definition Ssse3.cs:112
static string ArgumentOutOfRange_Index
Definition SR.cs:30
static string InvalidOperation_EnumNotStarted
Definition SR.cs:46
static string InvalidOperation_EnumEnded
Definition SR.cs:42
static string Format(string resourceFormat, object p1)
Definition SR.cs:118
static string Arg_BitArrayTypeUnsupported
Definition SR.cs:46
static string InvalidOperation_EnumFailedVersion
Definition SR.cs:44
static string Arg_ArrayLengthsDiffer
Definition SR.cs:44
static string Arg_RankMultiDimNotSupported
Definition SR.cs:18
static string Argument_ArrayTooLarge
Definition SR.cs:52
static string Argument_InvalidOffLen
Definition SR.cs:22
static string ArgumentOutOfRange_NeedNonNegNum
Definition SR.cs:32
Definition SR.cs:7
void Fill(T value)
Definition Span.cs:211
unsafe void Clear()
Definition Span.cs:198