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;
}
}
}