<PackageReference Include="System.Memory" Version="4.5.5" />

SpanHelpers

static class SpanHelpers
using System.Collections.Generic; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace System { internal static class SpanHelpers { internal struct ComparerComparable<T, TComparer> : IComparable<T> where TComparer : IComparer<T> { private readonly T _value; private readonly TComparer _comparer; public ComparerComparable(T value, TComparer comparer) { _value = value; _comparer = comparer; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int CompareTo(T other) { return _comparer.Compare(_value, other); } } [StructLayout(LayoutKind.Sequential, Size = 64)] private struct Reg64 { } [StructLayout(LayoutKind.Sequential, Size = 32)] private struct Reg32 { } [StructLayout(LayoutKind.Sequential, Size = 16)] private struct Reg16 { } public static class PerTypeValues<T> { public static readonly bool IsReferenceOrContainsReferences = IsReferenceOrContainsReferencesCore(typeof(T)); public static readonly T[] EmptyArray = new T[0]; public static readonly IntPtr ArrayAdjustment = MeasureArrayAdjustment(); private static IntPtr MeasureArrayAdjustment() { T[] array = new T[1]; return Unsafe.ByteOffset<T>(ref Unsafe.As<Pinnable<T>>((object)array).Data, ref array[0]); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int BinarySearch<T, TComparable>(this ReadOnlySpan<T> span, TComparable comparable) where TComparable : IComparable<T> { if (comparable == null) System.ThrowHelper.ThrowArgumentNullException(System.ExceptionArgument.comparable); return BinarySearch(ref MemoryMarshal.GetReference(span), span.Length, comparable); } public static int BinarySearch<T, TComparable>(ref T spanStart, int length, TComparable comparable) where TComparable : IComparable<T> { int num = 0; int num2 = length - 1; while (num <= num2) { int num3 = (int)((uint)(num2 + num) >> 1); int num4 = ((IComparable<T>)comparable).CompareTo(Unsafe.Add(ref spanStart, num3)); if (num4 == 0) return num3; if (num4 > 0) num = num3 + 1; else num2 = num3 - 1; } return ~num; } public static int IndexOf(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength) { if (valueLength == 0) return 0; byte value2 = value; ref byte second = ref Unsafe.Add(ref value, 1); int num = valueLength - 1; int num2 = 0; while (true) { int num3 = searchSpaceLength - num2 - num; if (num3 <= 0) break; int num4 = IndexOf(ref Unsafe.Add(ref searchSpace, num2), value2, num3); if (num4 == -1) break; num2 += num4; if (SequenceEqual(ref Unsafe.Add(ref searchSpace, num2 + 1), ref second, num)) return num2; num2++; } return -1; } public static int IndexOfAny(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength) { if (valueLength == 0) return 0; int num = -1; for (int i = 0; i < valueLength; i++) { int num2 = IndexOf(ref searchSpace, Unsafe.Add(ref value, i), searchSpaceLength); if ((uint)num2 < (uint)num) { num = num2; searchSpaceLength = num2; if (num == 0) break; } } return num; } public static int LastIndexOfAny(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength) { if (valueLength == 0) return 0; int num = -1; for (int i = 0; i < valueLength; i++) { int num2 = LastIndexOf(ref searchSpace, Unsafe.Add(ref value, i), searchSpaceLength); if (num2 > num) num = num2; } return num; } public unsafe static int IndexOf(ref byte searchSpace, byte value, int length) { IntPtr intPtr = (IntPtr)0; IntPtr intPtr2 = (IntPtr)length; while (true) { if ((ulong)(void*)intPtr2 >= 8) { intPtr2 -= 8; if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr)) { if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 1)) goto IL_0155; if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 2)) goto IL_0163; if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 3)) { if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 4)) return (int)(void*)(intPtr + 4); if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 5)) return (int)(void*)(intPtr + 5); if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 6)) return (int)(void*)(intPtr + 6); if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 7)) break; intPtr += 8; continue; } goto IL_0171; } } else { if ((ulong)(void*)intPtr2 >= 4) { intPtr2 -= 4; if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr)) goto IL_014d; if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 1)) goto IL_0155; if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 2)) goto IL_0163; if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 3)) goto IL_0171; intPtr += 4; } while (true) { if ((void*)intPtr2 == null) return -1; intPtr2 -= 1; if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr)) break; intPtr += 1; } } goto IL_014d; IL_0163: return (int)(void*)(intPtr + 2); IL_014d: return (int)(void*)intPtr; IL_0155: return (int)(void*)(intPtr + 1); IL_0171: return (int)(void*)(intPtr + 3); } return (int)(void*)(intPtr + 7); } public static int LastIndexOf(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength) { if (valueLength == 0) return 0; byte value2 = value; ref byte second = ref Unsafe.Add(ref value, 1); int num = valueLength - 1; int num2 = 0; while (true) { int num3 = searchSpaceLength - num2 - num; if (num3 <= 0) break; int num4 = LastIndexOf(ref searchSpace, value2, num3); if (num4 == -1) break; if (SequenceEqual(ref Unsafe.Add(ref searchSpace, num4 + 1), ref second, num)) return num4; num2 += num3 - num4; } return -1; } public unsafe static int LastIndexOf(ref byte searchSpace, byte value, int length) { IntPtr intPtr = (IntPtr)length; IntPtr intPtr2 = (IntPtr)length; while (true) { if ((ulong)(void*)intPtr2 >= 8) { intPtr2 -= 8; intPtr -= 8; if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 7)) break; if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 6)) return (int)(void*)(intPtr + 6); if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 5)) return (int)(void*)(intPtr + 5); if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 4)) return (int)(void*)(intPtr + 4); if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 3)) goto IL_0171; if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 2)) goto IL_0163; if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 1)) goto IL_0155; if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr)) continue; } else { if ((ulong)(void*)intPtr2 >= 4) { intPtr2 -= 4; intPtr -= 4; if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 3)) goto IL_0171; if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 2)) goto IL_0163; if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 1)) goto IL_0155; if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr)) goto IL_014d; } do { if ((void*)intPtr2 == null) return -1; intPtr2 -= 1; intPtr -= 1; } while (value != Unsafe.AddByteOffset(ref searchSpace, intPtr)); } goto IL_014d; IL_0163: return (int)(void*)(intPtr + 2); IL_0171: return (int)(void*)(intPtr + 3); IL_0155: return (int)(void*)(intPtr + 1); IL_014d: return (int)(void*)intPtr; } return (int)(void*)(intPtr + 7); } public unsafe static int IndexOfAny(ref byte searchSpace, byte value0, byte value1, int length) { IntPtr intPtr = (IntPtr)0; IntPtr intPtr2 = (IntPtr)length; while (true) { if ((ulong)(void*)intPtr2 >= 8) { intPtr2 -= 8; uint num = Unsafe.AddByteOffset(ref searchSpace, intPtr); if (value0 != num && value1 != num) { num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1); if (value0 == num || value1 == num) goto IL_01ed; num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2); if (value0 == num || value1 == num) goto IL_01fb; num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3); if (value0 != num && value1 != num) { num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 4); if (value0 == num || value1 == num) return (int)(void*)(intPtr + 4); num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 5); if (value0 == num || value1 == num) return (int)(void*)(intPtr + 5); num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 6); if (value0 == num || value1 == num) return (int)(void*)(intPtr + 6); num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 7); if (value0 == num || value1 == num) break; intPtr += 8; continue; } goto IL_0209; } } else { if ((ulong)(void*)intPtr2 >= 4) { intPtr2 -= 4; uint num = Unsafe.AddByteOffset(ref searchSpace, intPtr); if (value0 == num || value1 == num) goto IL_01e5; num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1); if (value0 == num || value1 == num) goto IL_01ed; num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2); if (value0 == num || value1 == num) goto IL_01fb; num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3); if (value0 == num || value1 == num) goto IL_0209; intPtr += 4; } while (true) { if ((void*)intPtr2 == null) return -1; intPtr2 -= 1; uint num = Unsafe.AddByteOffset(ref searchSpace, intPtr); if (value0 == num || value1 == num) break; intPtr += 1; } } goto IL_01e5; IL_01fb: return (int)(void*)(intPtr + 2); IL_01ed: return (int)(void*)(intPtr + 1); IL_0209: return (int)(void*)(intPtr + 3); IL_01e5: return (int)(void*)intPtr; } return (int)(void*)(intPtr + 7); } public unsafe static int IndexOfAny(ref byte searchSpace, byte value0, byte value1, byte value2, int length) { IntPtr intPtr = (IntPtr)0; IntPtr intPtr2 = (IntPtr)length; while (true) { if ((ulong)(void*)intPtr2 >= 8) { intPtr2 -= 8; uint num = Unsafe.AddByteOffset(ref searchSpace, intPtr); if (value0 != num && value1 != num && value2 != num) { num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1); if (value0 == num || value1 == num || value2 == num) goto IL_0262; num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2); if (value0 == num || value1 == num || value2 == num) goto IL_0270; num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3); if (value0 != num && value1 != num && value2 != num) { num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 4); if (value0 == num || value1 == num || value2 == num) return (int)(void*)(intPtr + 4); num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 5); if (value0 == num || value1 == num || value2 == num) return (int)(void*)(intPtr + 5); num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 6); if (value0 == num || value1 == num || value2 == num) return (int)(void*)(intPtr + 6); num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 7); if (value0 == num || value1 == num || value2 == num) break; intPtr += 8; continue; } goto IL_027e; } } else { if ((ulong)(void*)intPtr2 >= 4) { intPtr2 -= 4; uint num = Unsafe.AddByteOffset(ref searchSpace, intPtr); if (value0 == num || value1 == num || value2 == num) goto IL_025a; num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1); if (value0 == num || value1 == num || value2 == num) goto IL_0262; num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2); if (value0 == num || value1 == num || value2 == num) goto IL_0270; num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3); if (value0 == num || value1 == num || value2 == num) goto IL_027e; intPtr += 4; } while (true) { if ((void*)intPtr2 == null) return -1; intPtr2 -= 1; uint num = Unsafe.AddByteOffset(ref searchSpace, intPtr); if (value0 == num || value1 == num || value2 == num) break; intPtr += 1; } } goto IL_025a; IL_025a: return (int)(void*)intPtr; IL_0270: return (int)(void*)(intPtr + 2); IL_0262: return (int)(void*)(intPtr + 1); IL_027e: return (int)(void*)(intPtr + 3); } return (int)(void*)(intPtr + 7); } public unsafe static int LastIndexOfAny(ref byte searchSpace, byte value0, byte value1, int length) { IntPtr intPtr = (IntPtr)length; IntPtr intPtr2 = (IntPtr)length; while (true) { if ((ulong)(void*)intPtr2 >= 8) { intPtr2 -= 8; intPtr -= 8; uint num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 7); if (value0 == num || value1 == num) break; num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 6); if (value0 == num || value1 == num) return (int)(void*)(intPtr + 6); num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 5); if (value0 == num || value1 == num) return (int)(void*)(intPtr + 5); num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 4); if (value0 == num || value1 == num) return (int)(void*)(intPtr + 4); num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3); if (value0 == num || value1 == num) goto IL_0209; num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2); if (value0 == num || value1 == num) goto IL_01fb; num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1); if (value0 == num || value1 == num) goto IL_01ed; num = Unsafe.AddByteOffset(ref searchSpace, intPtr); if (value0 != num && value1 != num) continue; } else { uint num; if ((ulong)(void*)intPtr2 >= 4) { intPtr2 -= 4; intPtr -= 4; num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3); if (value0 == num || value1 == num) goto IL_0209; num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2); if (value0 == num || value1 == num) goto IL_01fb; num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1); if (value0 == num || value1 == num) goto IL_01ed; num = Unsafe.AddByteOffset(ref searchSpace, intPtr); if (value0 == num || value1 == num) goto IL_01e5; } do { if ((void*)intPtr2 == null) return -1; intPtr2 -= 1; intPtr -= 1; num = Unsafe.AddByteOffset(ref searchSpace, intPtr); } while (value0 != num && value1 != num); } goto IL_01e5; IL_01fb: return (int)(void*)(intPtr + 2); IL_01ed: return (int)(void*)(intPtr + 1); IL_01e5: return (int)(void*)intPtr; IL_0209: return (int)(void*)(intPtr + 3); } return (int)(void*)(intPtr + 7); } public unsafe static int LastIndexOfAny(ref byte searchSpace, byte value0, byte value1, byte value2, int length) { IntPtr intPtr = (IntPtr)length; IntPtr intPtr2 = (IntPtr)length; while (true) { if ((ulong)(void*)intPtr2 >= 8) { intPtr2 -= 8; intPtr -= 8; uint num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 7); if (value0 == num || value1 == num || value2 == num) break; num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 6); if (value0 == num || value1 == num || value2 == num) return (int)(void*)(intPtr + 6); num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 5); if (value0 == num || value1 == num || value2 == num) return (int)(void*)(intPtr + 5); num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 4); if (value0 == num || value1 == num || value2 == num) return (int)(void*)(intPtr + 4); num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3); if (value0 == num || value1 == num || value2 == num) goto IL_027c; num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2); if (value0 == num || value1 == num || value2 == num) goto IL_026e; num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1); if (value0 == num || value1 == num || value2 == num) goto IL_0260; num = Unsafe.AddByteOffset(ref searchSpace, intPtr); if (value0 != num && value1 != num && value2 != num) continue; } else { uint num; if ((ulong)(void*)intPtr2 >= 4) { intPtr2 -= 4; intPtr -= 4; num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3); if (value0 == num || value1 == num || value2 == num) goto IL_027c; num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2); if (value0 == num || value1 == num || value2 == num) goto IL_026e; num = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1); if (value0 == num || value1 == num || value2 == num) goto IL_0260; num = Unsafe.AddByteOffset(ref searchSpace, intPtr); if (value0 == num || value1 == num || value2 == num) goto IL_0258; } do { if ((void*)intPtr2 == null) return -1; intPtr2 -= 1; intPtr -= 1; num = Unsafe.AddByteOffset(ref searchSpace, intPtr); } while (value0 != num && value1 != num && value2 != num); } goto IL_0258; IL_0260: return (int)(void*)(intPtr + 1); IL_026e: return (int)(void*)(intPtr + 2); IL_027c: return (int)(void*)(intPtr + 3); IL_0258: return (int)(void*)intPtr; } return (int)(void*)(intPtr + 7); } public unsafe static bool SequenceEqual(ref byte first, ref byte second, NUInt length) { if (!Unsafe.AreSame(ref first, ref second)) { IntPtr intPtr = (IntPtr)0; IntPtr intPtr2 = (IntPtr)(void*)length; if ((ulong)(void*)intPtr2 >= (ulong)sizeof(UIntPtr)) { intPtr2 -= sizeof(UIntPtr); while (true) { if ((void*)intPtr2 <= (void*)intPtr) return Unsafe.ReadUnaligned<UIntPtr>(ref Unsafe.AddByteOffset(ref first, intPtr2)) == Unsafe.ReadUnaligned<UIntPtr>(ref Unsafe.AddByteOffset(ref second, intPtr2)); if (Unsafe.ReadUnaligned<UIntPtr>(ref Unsafe.AddByteOffset(ref first, intPtr)) != Unsafe.ReadUnaligned<UIntPtr>(ref Unsafe.AddByteOffset(ref second, intPtr))) break; intPtr += sizeof(UIntPtr); } goto IL_00c2; } while ((void*)intPtr2 > (void*)intPtr) { if (Unsafe.AddByteOffset(ref first, intPtr) == Unsafe.AddByteOffset(ref second, intPtr)) { intPtr += 1; continue; } goto IL_00c2; } } return true; IL_00c2: return false; } public unsafe static int SequenceCompareTo(ref byte first, int firstLength, ref byte second, int secondLength) { if (!Unsafe.AreSame(ref first, ref second)) { IntPtr value = (IntPtr)((firstLength < secondLength) ? firstLength : secondLength); IntPtr intPtr = (IntPtr)0; IntPtr intPtr2 = (IntPtr)(void*)value; if ((ulong)(void*)intPtr2 > (ulong)sizeof(UIntPtr)) { intPtr2 -= sizeof(UIntPtr); while ((void*)intPtr2 > (void*)intPtr && !(Unsafe.ReadUnaligned<UIntPtr>(ref Unsafe.AddByteOffset(ref first, intPtr)) != Unsafe.ReadUnaligned<UIntPtr>(ref Unsafe.AddByteOffset(ref second, intPtr)))) { intPtr += sizeof(UIntPtr); } } while ((void*)value > (void*)intPtr) { int num = Unsafe.AddByteOffset(ref first, intPtr).CompareTo(Unsafe.AddByteOffset(ref second, intPtr)); if (num != 0) return num; intPtr += 1; } } return firstLength - secondLength; } public unsafe static int SequenceCompareTo(ref char first, int firstLength, ref char second, int secondLength) { int result = firstLength - secondLength; if (!Unsafe.AreSame(ref first, ref second)) { IntPtr value = (IntPtr)((firstLength < secondLength) ? firstLength : secondLength); IntPtr intPtr = (IntPtr)0; if ((ulong)(void*)value >= (ulong)(sizeof(UIntPtr) / 2)) { while ((void*)value >= (void*)(intPtr + sizeof(UIntPtr) / 2) && !(Unsafe.ReadUnaligned<UIntPtr>(ref Unsafe.As<char, byte>(ref Unsafe.Add(ref first, intPtr))) != Unsafe.ReadUnaligned<UIntPtr>(ref Unsafe.As<char, byte>(ref Unsafe.Add(ref second, intPtr))))) { intPtr += sizeof(UIntPtr) / 2; } } if (sizeof(UIntPtr) > 4 && (void*)value >= (void*)(intPtr + 2) && Unsafe.ReadUnaligned<int>(ref Unsafe.As<char, byte>(ref Unsafe.Add(ref first, intPtr))) == Unsafe.ReadUnaligned<int>(ref Unsafe.As<char, byte>(ref Unsafe.Add(ref second, intPtr)))) intPtr += 2; while ((void*)intPtr < (void*)value) { int num = Unsafe.Add(ref first, intPtr).CompareTo(Unsafe.Add(ref second, intPtr)); if (num != 0) return num; intPtr += 1; } } return result; } public unsafe static int IndexOf(ref char searchSpace, char value, int length) { fixed (char* ptr = &searchSpace) { char* ptr2 = ptr; char* ptr3 = ptr2 + length; while (true) { if (length < 4) { while (true) { if (length <= 0) return -1; length--; if (*ptr2 == value) break; ptr2++; } } else { length -= 4; if (*ptr2 != value) { if (ptr2[1] != value) { if (ptr2[2] != value) { if (ptr2[3] != value) { ptr2 += 4; continue; } ptr2++; } ptr2++; } ptr2++; } } break; } return (int)(ptr2 - ptr); } } public unsafe static int LastIndexOf(ref char searchSpace, char value, int length) { fixed (char* ptr = &searchSpace) { char* ptr2 = ptr + length; char* ptr3 = ptr; while (true) { if (length >= 4) { length -= 4; ptr2 -= 4; if (ptr2[3] == value) break; if (ptr2[2] == value) return (int)(ptr2 - ptr3) + 2; if (ptr2[1] == value) return (int)(ptr2 - ptr3) + 1; if (*ptr2 != value) continue; } else { do { if (length <= 0) return -1; length--; ptr2--; } while (*ptr2 != value); } return (int)(ptr2 - ptr3); } return (int)(ptr2 - ptr3) + 3; } } public static int IndexOf<T>(ref T searchSpace, int searchSpaceLength, ref T value, int valueLength) where T : IEquatable<T> { if (valueLength == 0) return 0; T value2 = value; ref T second = ref Unsafe.Add(ref value, 1); int num = valueLength - 1; int num2 = 0; while (true) { int num3 = searchSpaceLength - num2 - num; if (num3 <= 0) break; int num4 = IndexOf(ref Unsafe.Add(ref searchSpace, num2), value2, num3); if (num4 == -1) break; num2 += num4; if (SequenceEqual(ref Unsafe.Add(ref searchSpace, num2 + 1), ref second, num)) return num2; num2++; } return -1; } public unsafe static int IndexOf<T>(ref T searchSpace, T value, int length) where T : IEquatable<T> { IntPtr intPtr = (IntPtr)0; while (true) { if (length >= 8) { length -= 8; if (!((IEquatable<T>)value).Equals(Unsafe.Add(ref searchSpace, intPtr))) { if (((IEquatable<T>)value).Equals(Unsafe.Add(ref searchSpace, intPtr + 1))) goto IL_020a; if (((IEquatable<T>)value).Equals(Unsafe.Add(ref searchSpace, intPtr + 2))) goto IL_0218; if (!((IEquatable<T>)value).Equals(Unsafe.Add(ref searchSpace, intPtr + 3))) { if (((IEquatable<T>)value).Equals(Unsafe.Add(ref searchSpace, intPtr + 4))) return (int)(void*)(intPtr + 4); if (((IEquatable<T>)value).Equals(Unsafe.Add(ref searchSpace, intPtr + 5))) return (int)(void*)(intPtr + 5); if (((IEquatable<T>)value).Equals(Unsafe.Add(ref searchSpace, intPtr + 6))) return (int)(void*)(intPtr + 6); if (((IEquatable<T>)value).Equals(Unsafe.Add(ref searchSpace, intPtr + 7))) break; intPtr += 8; continue; } goto IL_0226; } } else { if (length >= 4) { length -= 4; if (((IEquatable<T>)value).Equals(Unsafe.Add(ref searchSpace, intPtr))) goto IL_0202; if (((IEquatable<T>)value).Equals(Unsafe.Add(ref searchSpace, intPtr + 1))) goto IL_020a; if (((IEquatable<T>)value).Equals(Unsafe.Add(ref searchSpace, intPtr + 2))) goto IL_0218; if (((IEquatable<T>)value).Equals(Unsafe.Add(ref searchSpace, intPtr + 3))) goto IL_0226; intPtr += 4; } while (true) { if (length <= 0) return -1; if (((IEquatable<T>)value).Equals(Unsafe.Add(ref searchSpace, intPtr))) break; intPtr += 1; length--; } } goto IL_0202; IL_0218: return (int)(void*)(intPtr + 2); IL_0202: return (int)(void*)intPtr; IL_020a: return (int)(void*)(intPtr + 1); IL_0226: return (int)(void*)(intPtr + 3); } return (int)(void*)(intPtr + 7); } public static int IndexOfAny<T>(ref T searchSpace, T value0, T value1, int length) where T : IEquatable<T> { int num = 0; while (true) { if (length - num >= 8) { T other = Unsafe.Add(ref searchSpace, num); if (!((IEquatable<T>)value0).Equals(other) && !((IEquatable<T>)value1).Equals(other)) { other = Unsafe.Add(ref searchSpace, num + 1); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other)) goto IL_02cb; other = Unsafe.Add(ref searchSpace, num + 2); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other)) goto IL_02cf; other = Unsafe.Add(ref searchSpace, num + 3); if (!((IEquatable<T>)value0).Equals(other) && !((IEquatable<T>)value1).Equals(other)) { other = Unsafe.Add(ref searchSpace, num + 4); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other)) return num + 4; other = Unsafe.Add(ref searchSpace, num + 5); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other)) return num + 5; other = Unsafe.Add(ref searchSpace, num + 6); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other)) return num + 6; other = Unsafe.Add(ref searchSpace, num + 7); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other)) break; num += 8; continue; } goto IL_02d3; } } else { if (length - num >= 4) { T other = Unsafe.Add(ref searchSpace, num); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other)) goto IL_02c9; other = Unsafe.Add(ref searchSpace, num + 1); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other)) goto IL_02cb; other = Unsafe.Add(ref searchSpace, num + 2); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other)) goto IL_02cf; other = Unsafe.Add(ref searchSpace, num + 3); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other)) goto IL_02d3; num += 4; } while (true) { if (num >= length) return -1; T other = Unsafe.Add(ref searchSpace, num); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other)) break; num++; } } goto IL_02c9; IL_02cf: return num + 2; IL_02cb: return num + 1; IL_02d3: return num + 3; IL_02c9: return num; } return num + 7; } public static int IndexOfAny<T>(ref T searchSpace, T value0, T value1, T value2, int length) where T : IEquatable<T> { int num = 0; while (true) { if (length - num >= 8) { T other = Unsafe.Add(ref searchSpace, num); if (!((IEquatable<T>)value0).Equals(other) && !((IEquatable<T>)value1).Equals(other) && !((IEquatable<T>)value2).Equals(other)) { other = Unsafe.Add(ref searchSpace, num + 1); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other) || ((IEquatable<T>)value2).Equals(other)) goto IL_03c2; other = Unsafe.Add(ref searchSpace, num + 2); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other) || ((IEquatable<T>)value2).Equals(other)) goto IL_03c6; other = Unsafe.Add(ref searchSpace, num + 3); if (!((IEquatable<T>)value0).Equals(other) && !((IEquatable<T>)value1).Equals(other) && !((IEquatable<T>)value2).Equals(other)) { other = Unsafe.Add(ref searchSpace, num + 4); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other) || ((IEquatable<T>)value2).Equals(other)) return num + 4; other = Unsafe.Add(ref searchSpace, num + 5); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other) || ((IEquatable<T>)value2).Equals(other)) return num + 5; other = Unsafe.Add(ref searchSpace, num + 6); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other) || ((IEquatable<T>)value2).Equals(other)) return num + 6; other = Unsafe.Add(ref searchSpace, num + 7); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other) || ((IEquatable<T>)value2).Equals(other)) break; num += 8; continue; } goto IL_03ca; } } else { if (length - num >= 4) { T other = Unsafe.Add(ref searchSpace, num); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other) || ((IEquatable<T>)value2).Equals(other)) goto IL_03c0; other = Unsafe.Add(ref searchSpace, num + 1); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other) || ((IEquatable<T>)value2).Equals(other)) goto IL_03c2; other = Unsafe.Add(ref searchSpace, num + 2); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other) || ((IEquatable<T>)value2).Equals(other)) goto IL_03c6; other = Unsafe.Add(ref searchSpace, num + 3); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other) || ((IEquatable<T>)value2).Equals(other)) goto IL_03ca; num += 4; } while (true) { if (num >= length) return -1; T other = Unsafe.Add(ref searchSpace, num); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other) || ((IEquatable<T>)value2).Equals(other)) break; num++; } } goto IL_03c0; IL_03c0: return num; IL_03c6: return num + 2; IL_03c2: return num + 1; IL_03ca: return num + 3; } return num + 7; } public static int IndexOfAny<T>(ref T searchSpace, int searchSpaceLength, ref T value, int valueLength) where T : IEquatable<T> { if (valueLength == 0) return 0; int num = -1; for (int i = 0; i < valueLength; i++) { int num2 = IndexOf(ref searchSpace, Unsafe.Add(ref value, i), searchSpaceLength); if ((uint)num2 < (uint)num) { num = num2; searchSpaceLength = num2; if (num == 0) break; } } return num; } public static int LastIndexOf<T>(ref T searchSpace, int searchSpaceLength, ref T value, int valueLength) where T : IEquatable<T> { if (valueLength == 0) return 0; T value2 = value; ref T second = ref Unsafe.Add(ref value, 1); int num = valueLength - 1; int num2 = 0; while (true) { int num3 = searchSpaceLength - num2 - num; if (num3 <= 0) break; int num4 = LastIndexOf(ref searchSpace, value2, num3); if (num4 == -1) break; if (SequenceEqual(ref Unsafe.Add(ref searchSpace, num4 + 1), ref second, num)) return num4; num2 += num3 - num4; } return -1; } public static int LastIndexOf<T>(ref T searchSpace, T value, int length) where T : IEquatable<T> { while (true) { if (length >= 8) { length -= 8; if (((IEquatable<T>)value).Equals(Unsafe.Add(ref searchSpace, length + 7))) break; if (((IEquatable<T>)value).Equals(Unsafe.Add(ref searchSpace, length + 6))) return length + 6; if (((IEquatable<T>)value).Equals(Unsafe.Add(ref searchSpace, length + 5))) return length + 5; if (((IEquatable<T>)value).Equals(Unsafe.Add(ref searchSpace, length + 4))) return length + 4; if (((IEquatable<T>)value).Equals(Unsafe.Add(ref searchSpace, length + 3))) goto IL_01c2; if (((IEquatable<T>)value).Equals(Unsafe.Add(ref searchSpace, length + 2))) goto IL_01be; if (((IEquatable<T>)value).Equals(Unsafe.Add(ref searchSpace, length + 1))) goto IL_01ba; if (!((IEquatable<T>)value).Equals(Unsafe.Add(ref searchSpace, length))) continue; } else { if (length >= 4) { length -= 4; if (((IEquatable<T>)value).Equals(Unsafe.Add(ref searchSpace, length + 3))) goto IL_01c2; if (((IEquatable<T>)value).Equals(Unsafe.Add(ref searchSpace, length + 2))) goto IL_01be; if (((IEquatable<T>)value).Equals(Unsafe.Add(ref searchSpace, length + 1))) goto IL_01ba; if (((IEquatable<T>)value).Equals(Unsafe.Add(ref searchSpace, length))) goto IL_01b8; } do { if (length <= 0) return -1; length--; } while (!((IEquatable<T>)value).Equals(Unsafe.Add(ref searchSpace, length))); } goto IL_01b8; IL_01be: return length + 2; IL_01c2: return length + 3; IL_01ba: return length + 1; IL_01b8: return length; } return length + 7; } public static int LastIndexOfAny<T>(ref T searchSpace, T value0, T value1, int length) where T : IEquatable<T> { while (true) { if (length >= 8) { length -= 8; T other = Unsafe.Add(ref searchSpace, length + 7); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other)) break; other = Unsafe.Add(ref searchSpace, length + 6); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other)) return length + 6; other = Unsafe.Add(ref searchSpace, length + 5); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other)) return length + 5; other = Unsafe.Add(ref searchSpace, length + 4); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other)) return length + 4; other = Unsafe.Add(ref searchSpace, length + 3); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other)) goto IL_02cd; other = Unsafe.Add(ref searchSpace, length + 2); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other)) goto IL_02c9; other = Unsafe.Add(ref searchSpace, length + 1); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other)) goto IL_02c5; other = Unsafe.Add(ref searchSpace, length); if (!((IEquatable<T>)value0).Equals(other) && !((IEquatable<T>)value1).Equals(other)) continue; } else { T other; if (length >= 4) { length -= 4; other = Unsafe.Add(ref searchSpace, length + 3); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other)) goto IL_02cd; other = Unsafe.Add(ref searchSpace, length + 2); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other)) goto IL_02c9; other = Unsafe.Add(ref searchSpace, length + 1); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other)) goto IL_02c5; other = Unsafe.Add(ref searchSpace, length); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other)) goto IL_02c3; } do { if (length <= 0) return -1; length--; other = Unsafe.Add(ref searchSpace, length); } while (!((IEquatable<T>)value0).Equals(other) && !((IEquatable<T>)value1).Equals(other)); } goto IL_02c3; IL_02c9: return length + 2; IL_02c5: return length + 1; IL_02c3: return length; IL_02cd: return length + 3; } return length + 7; } public static int LastIndexOfAny<T>(ref T searchSpace, T value0, T value1, T value2, int length) where T : IEquatable<T> { while (true) { if (length >= 8) { length -= 8; T other = Unsafe.Add(ref searchSpace, length + 7); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other) || ((IEquatable<T>)value2).Equals(other)) break; other = Unsafe.Add(ref searchSpace, length + 6); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other) || ((IEquatable<T>)value2).Equals(other)) return length + 6; other = Unsafe.Add(ref searchSpace, length + 5); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other) || ((IEquatable<T>)value2).Equals(other)) return length + 5; other = Unsafe.Add(ref searchSpace, length + 4); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other) || ((IEquatable<T>)value2).Equals(other)) return length + 4; other = Unsafe.Add(ref searchSpace, length + 3); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other) || ((IEquatable<T>)value2).Equals(other)) goto IL_03da; other = Unsafe.Add(ref searchSpace, length + 2); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other) || ((IEquatable<T>)value2).Equals(other)) goto IL_03d5; other = Unsafe.Add(ref searchSpace, length + 1); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other) || ((IEquatable<T>)value2).Equals(other)) goto IL_03d0; other = Unsafe.Add(ref searchSpace, length); if (!((IEquatable<T>)value0).Equals(other) && !((IEquatable<T>)value1).Equals(other) && !((IEquatable<T>)value2).Equals(other)) continue; } else { T other; if (length >= 4) { length -= 4; other = Unsafe.Add(ref searchSpace, length + 3); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other) || ((IEquatable<T>)value2).Equals(other)) goto IL_03da; other = Unsafe.Add(ref searchSpace, length + 2); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other) || ((IEquatable<T>)value2).Equals(other)) goto IL_03d5; other = Unsafe.Add(ref searchSpace, length + 1); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other) || ((IEquatable<T>)value2).Equals(other)) goto IL_03d0; other = Unsafe.Add(ref searchSpace, length); if (((IEquatable<T>)value0).Equals(other) || ((IEquatable<T>)value1).Equals(other) || ((IEquatable<T>)value2).Equals(other)) goto IL_03cd; } do { if (length <= 0) return -1; length--; other = Unsafe.Add(ref searchSpace, length); } while (!((IEquatable<T>)value0).Equals(other) && !((IEquatable<T>)value1).Equals(other) && !((IEquatable<T>)value2).Equals(other)); } goto IL_03cd; IL_03d0: return length + 1; IL_03d5: return length + 2; IL_03da: return length + 3; IL_03cd: return length; } return length + 7; } public static int LastIndexOfAny<T>(ref T searchSpace, int searchSpaceLength, ref T value, int valueLength) where T : IEquatable<T> { if (valueLength == 0) return 0; int num = -1; for (int i = 0; i < valueLength; i++) { int num2 = LastIndexOf(ref searchSpace, Unsafe.Add(ref value, i), searchSpaceLength); if (num2 > num) num = num2; } return num; } public static bool SequenceEqual<T>(ref T first, ref T second, int length) where T : IEquatable<T> { if (!Unsafe.AreSame(ref first, ref second)) { IntPtr intPtr = (IntPtr)0; while (true) { if (length < 8) { if (length >= 4) { length -= 4; if (!((IEquatable<T>)Unsafe.Add(ref first, intPtr)).Equals(Unsafe.Add(ref second, intPtr)) || !((IEquatable<T>)Unsafe.Add(ref first, intPtr + 1)).Equals(Unsafe.Add(ref second, intPtr + 1)) || !((IEquatable<T>)Unsafe.Add(ref first, intPtr + 2)).Equals(Unsafe.Add(ref second, intPtr + 2)) || !((IEquatable<T>)Unsafe.Add(ref first, intPtr + 3)).Equals(Unsafe.Add(ref second, intPtr + 3))) goto IL_028b; intPtr += 4; } while (length > 0) { if (((IEquatable<T>)Unsafe.Add(ref first, intPtr)).Equals(Unsafe.Add(ref second, intPtr))) { intPtr += 1; length--; continue; } goto IL_028b; } break; } length -= 8; if (((IEquatable<T>)Unsafe.Add(ref first, intPtr)).Equals(Unsafe.Add(ref second, intPtr)) && ((IEquatable<T>)Unsafe.Add(ref first, intPtr + 1)).Equals(Unsafe.Add(ref second, intPtr + 1)) && ((IEquatable<T>)Unsafe.Add(ref first, intPtr + 2)).Equals(Unsafe.Add(ref second, intPtr + 2)) && ((IEquatable<T>)Unsafe.Add(ref first, intPtr + 3)).Equals(Unsafe.Add(ref second, intPtr + 3)) && ((IEquatable<T>)Unsafe.Add(ref first, intPtr + 4)).Equals(Unsafe.Add(ref second, intPtr + 4)) && ((IEquatable<T>)Unsafe.Add(ref first, intPtr + 5)).Equals(Unsafe.Add(ref second, intPtr + 5)) && ((IEquatable<T>)Unsafe.Add(ref first, intPtr + 6)).Equals(Unsafe.Add(ref second, intPtr + 6)) && ((IEquatable<T>)Unsafe.Add(ref first, intPtr + 7)).Equals(Unsafe.Add(ref second, intPtr + 7))) { intPtr += 8; continue; } goto IL_028b; IL_028b: return false; } } return true; } public static int SequenceCompareTo<T>(ref T first, int firstLength, ref T second, int secondLength) where T : IComparable<T> { int num = firstLength; if (num > secondLength) num = secondLength; for (int i = 0; i < num; i++) { int num2 = ((IComparable<T>)Unsafe.Add(ref first, i)).CompareTo(Unsafe.Add(ref second, i)); if (num2 != 0) return num2; } return firstLength.CompareTo(secondLength); } public unsafe static void CopyTo<T>(ref T dst, int dstLength, ref T src, int srcLength) { IntPtr value = Unsafe.ByteOffset(ref src, ref Unsafe.Add(ref src, srcLength)); IntPtr value2 = Unsafe.ByteOffset(ref dst, ref Unsafe.Add(ref dst, dstLength)); IntPtr value3 = Unsafe.ByteOffset(ref src, ref dst); if (!((sizeof(IntPtr) != 4) ? ((ulong)(long)value3 < (ulong)(long)value || (ulong)(long)value3 > (ulong)(-(long)value2)) : ((uint)(int)value3 < (uint)(int)value || (uint)(int)value3 > (uint)(-(int)value2))) && !IsReferenceOrContainsReferences<T>()) { ref byte source = ref Unsafe.As<T, byte>(ref dst); ref byte source2 = ref Unsafe.As<T, byte>(ref src); ulong num = (ulong)(long)value; uint num3; for (ulong num2 = 0; num2 < num; num2 += num3) { num3 = (uint)((num - num2 > uint.MaxValue) ? (-1) : ((int)(num - num2))); Unsafe.CopyBlock(ref Unsafe.Add(ref source, (IntPtr)(long)num2), ref Unsafe.Add(ref source2, (IntPtr)(long)num2), num3); } } else { bool flag = (sizeof(IntPtr) == 4) ? ((uint)(int)value3 > (uint)(-(int)value2)) : ((ulong)(long)value3 > (ulong)(-(long)value2)); int num4 = flag ? 1 : (-1); int num5 = (!flag) ? (srcLength - 1) : 0; int i; for (i = 0; i < (srcLength & -8); i += 8) { Unsafe.Add(ref dst, num5) = Unsafe.Add(ref src, num5); Unsafe.Add(ref dst, num5 + num4) = Unsafe.Add(ref src, num5 + num4); Unsafe.Add(ref dst, num5 + num4 * 2) = Unsafe.Add(ref src, num5 + num4 * 2); Unsafe.Add(ref dst, num5 + num4 * 3) = Unsafe.Add(ref src, num5 + num4 * 3); Unsafe.Add(ref dst, num5 + num4 * 4) = Unsafe.Add(ref src, num5 + num4 * 4); Unsafe.Add(ref dst, num5 + num4 * 5) = Unsafe.Add(ref src, num5 + num4 * 5); Unsafe.Add(ref dst, num5 + num4 * 6) = Unsafe.Add(ref src, num5 + num4 * 6); Unsafe.Add(ref dst, num5 + num4 * 7) = Unsafe.Add(ref src, num5 + num4 * 7); num5 += num4 * 8; } if (i < (srcLength & -4)) { Unsafe.Add(ref dst, num5) = Unsafe.Add(ref src, num5); Unsafe.Add(ref dst, num5 + num4) = Unsafe.Add(ref src, num5 + num4); Unsafe.Add(ref dst, num5 + num4 * 2) = Unsafe.Add(ref src, num5 + num4 * 2); Unsafe.Add(ref dst, num5 + num4 * 3) = Unsafe.Add(ref src, num5 + num4 * 3); num5 += num4 * 4; i += 4; } for (; i < srcLength; i++) { Unsafe.Add(ref dst, num5) = Unsafe.Add(ref src, num5); num5 += num4; } } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe static IntPtr Add<T>(this IntPtr start, int index) { if (sizeof(IntPtr) == 4) { uint num = (uint)(index * Unsafe.SizeOf<T>()); return (IntPtr)(void*)((byte*)(void*)start + num); } ulong num2 = (ulong)((long)index * (long)Unsafe.SizeOf<T>()); return (IntPtr)(void*)((byte*)(void*)start + num2); } public static bool IsReferenceOrContainsReferences<T>() { return PerTypeValues<T>.IsReferenceOrContainsReferences; } private static bool IsReferenceOrContainsReferencesCore(Type type) { if (type.GetTypeInfo().get_IsPrimitive()) return false; if (!type.GetTypeInfo().get_IsValueType()) return true; Type underlyingType = Nullable.GetUnderlyingType(type); if ((object)underlyingType != null) type = underlyingType; if (type.GetTypeInfo().get_IsEnum()) return false; foreach (FieldInfo declaredField in type.GetTypeInfo().DeclaredFields) { if (!declaredField.IsStatic && IsReferenceOrContainsReferencesCore(declaredField.FieldType)) return true; } return false; } public unsafe static void ClearLessThanPointerSized(byte* ptr, UIntPtr byteLength) { if (sizeof(UIntPtr) == 4) Unsafe.InitBlockUnaligned(ptr, 0, (uint)byteLength); else { ulong num = (ulong)byteLength; uint num2 = (uint)(num & uint.MaxValue); Unsafe.InitBlockUnaligned(ptr, 0, num2); num -= num2; ptr += num2; while (num != 0) { num2 = (uint)((num >= uint.MaxValue) ? (-1) : ((int)num)); Unsafe.InitBlockUnaligned(ptr, 0, num2); ptr += num2; num -= num2; } } } public unsafe static void ClearLessThanPointerSized(ref byte b, UIntPtr byteLength) { if (sizeof(UIntPtr) == 4) Unsafe.InitBlockUnaligned(ref b, 0, (uint)byteLength); else { ulong num = (ulong)byteLength; uint num2 = (uint)(num & uint.MaxValue); Unsafe.InitBlockUnaligned(ref b, 0, num2); num -= num2; long num3 = num2; while (num != 0) { num2 = (uint)((num >= uint.MaxValue) ? (-1) : ((int)num)); ref byte startAddress = ref Unsafe.Add(ref b, (IntPtr)num3); Unsafe.InitBlockUnaligned(ref startAddress, 0, num2); num3 += num2; num -= num2; } } } public unsafe static void ClearPointerSizedWithoutReferences(ref byte b, UIntPtr byteLength) { IntPtr intPtr = IntPtr.Zero; while (intPtr.LessThanEqual(byteLength - sizeof(Reg64))) { Unsafe.As<byte, Reg64>(ref Unsafe.Add(ref b, intPtr)) = default(Reg64); intPtr += sizeof(Reg64); } if (intPtr.LessThanEqual(byteLength - sizeof(Reg32))) { Unsafe.As<byte, Reg32>(ref Unsafe.Add(ref b, intPtr)) = default(Reg32); intPtr += sizeof(Reg32); } if (intPtr.LessThanEqual(byteLength - sizeof(Reg16))) { Unsafe.As<byte, Reg16>(ref Unsafe.Add(ref b, intPtr)) = default(Reg16); intPtr += sizeof(Reg16); } if (intPtr.LessThanEqual(byteLength - 8)) { Unsafe.As<byte, long>(ref Unsafe.Add(ref b, intPtr)) = 0; intPtr += 8; } if (sizeof(IntPtr) == 4 && intPtr.LessThanEqual(byteLength - 4)) { Unsafe.As<byte, int>(ref Unsafe.Add(ref b, intPtr)) = 0; intPtr += 4; } } public static void ClearPointerSizedWithReferences(ref IntPtr ip, UIntPtr pointerSizeLength) { IntPtr intPtr = IntPtr.Zero; IntPtr zero = IntPtr.Zero; while ((zero = intPtr + 8).LessThanEqual(pointerSizeLength)) { Unsafe.Add(ref ip, intPtr + 0) = default(IntPtr); Unsafe.Add(ref ip, intPtr + 1) = default(IntPtr); Unsafe.Add(ref ip, intPtr + 2) = default(IntPtr); Unsafe.Add(ref ip, intPtr + 3) = default(IntPtr); Unsafe.Add(ref ip, intPtr + 4) = default(IntPtr); Unsafe.Add(ref ip, intPtr + 5) = default(IntPtr); Unsafe.Add(ref ip, intPtr + 6) = default(IntPtr); Unsafe.Add(ref ip, intPtr + 7) = default(IntPtr); intPtr = zero; } if ((zero = intPtr + 4).LessThanEqual(pointerSizeLength)) { Unsafe.Add(ref ip, intPtr + 0) = default(IntPtr); Unsafe.Add(ref ip, intPtr + 1) = default(IntPtr); Unsafe.Add(ref ip, intPtr + 2) = default(IntPtr); Unsafe.Add(ref ip, intPtr + 3) = default(IntPtr); intPtr = zero; } if ((zero = intPtr + 2).LessThanEqual(pointerSizeLength)) { Unsafe.Add(ref ip, intPtr + 0) = default(IntPtr); Unsafe.Add(ref ip, intPtr + 1) = default(IntPtr); intPtr = zero; } if ((intPtr + 1).LessThanEqual(pointerSizeLength)) Unsafe.Add(ref ip, intPtr) = default(IntPtr); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private unsafe static bool LessThanEqual(this IntPtr index, UIntPtr length) { if (sizeof(UIntPtr) != 4) return (long)index <= (long)(ulong)length; return (int)index <= (int)(uint)length; } } }