SpanHelpers
using System.Collections.Generic;
using System.Numerics;
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]);
}
}
private const ulong XorPowerOfTwoToHighByte = 283686952306184;
private const ulong XorPowerOfTwoToHighChar = 4295098372;
[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;
if (Vector.IsHardwareAccelerated && length >= Vector<byte>.Count * 2) {
int num = (int)Unsafe.AsPointer(ref searchSpace) & (Vector<byte>.Count - 1);
intPtr2 = (IntPtr)((Vector<byte>.Count - num) & (Vector<byte>.Count - 1));
}
while (true) {
if ((ulong)(void*)intPtr2 < 8) {
if ((ulong)(void*)intPtr2 >= 4) {
intPtr2 -= 4;
if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr))
goto IL_0242;
if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 1))
goto IL_024a;
if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 2))
goto IL_0258;
if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 3))
goto IL_0266;
intPtr += 4;
}
while ((void*)intPtr2 != null) {
intPtr2 -= 1;
if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr)) {
intPtr += 1;
continue;
}
goto IL_0242;
}
if (Vector.IsHardwareAccelerated && (int)(void*)intPtr < length) {
intPtr2 = (IntPtr)((length - (int)(void*)intPtr) & ~(Vector<byte>.Count - 1));
Vector<byte> vector = GetVector(value);
while ((void*)intPtr2 > (void*)intPtr) {
Vector<byte> vector2 = Vector.Equals(vector, Unsafe.ReadUnaligned<Vector<byte>>(ref Unsafe.AddByteOffset(ref searchSpace, intPtr)));
if (!Vector<byte>.Zero.Equals(vector2))
return (int)(void*)intPtr + LocateFirstFoundByte(vector2);
intPtr += Vector<byte>.Count;
}
if ((int)(void*)intPtr < length) {
intPtr2 = (IntPtr)(length - (int)(void*)intPtr);
continue;
}
}
return -1;
}
intPtr2 -= 8;
if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr))
goto IL_0242;
if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 1))
goto IL_024a;
if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 2))
goto IL_0258;
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_0266;
IL_0266:
return (int)(void*)(intPtr + 3);
IL_0242:
return (int)(void*)intPtr;
IL_0258:
return (int)(void*)(intPtr + 2);
IL_024a:
return (int)(void*)(intPtr + 1);
}
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;
if (Vector.IsHardwareAccelerated && length >= Vector<byte>.Count * 2) {
int num = (int)Unsafe.AsPointer(ref searchSpace) & (Vector<byte>.Count - 1);
intPtr2 = (IntPtr)(((length & (Vector<byte>.Count - 1)) + num) & (Vector<byte>.Count - 1));
}
while (true) {
if ((ulong)(void*)intPtr2 < 8) {
if ((ulong)(void*)intPtr2 >= 4) {
intPtr2 -= 4;
intPtr -= 4;
if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 3))
goto IL_0278;
if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 2))
goto IL_026a;
if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr + 1))
goto IL_025c;
if (value == Unsafe.AddByteOffset(ref searchSpace, intPtr))
goto IL_0254;
}
while ((void*)intPtr2 != null) {
intPtr2 -= 1;
intPtr -= 1;
if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr))
continue;
goto IL_0254;
}
if (Vector.IsHardwareAccelerated && (void*)intPtr != null) {
intPtr2 = (IntPtr)((int)(void*)intPtr & ~(Vector<byte>.Count - 1));
Vector<byte> vector = GetVector(value);
while ((ulong)(void*)intPtr2 > (ulong)(Vector<byte>.Count - 1)) {
Vector<byte> vector2 = Vector.Equals(vector, Unsafe.ReadUnaligned<Vector<byte>>(ref Unsafe.AddByteOffset(ref searchSpace, intPtr - Vector<byte>.Count)));
if (!Vector<byte>.Zero.Equals(vector2))
return (int)intPtr - Vector<byte>.Count + LocateLastFoundByte(vector2);
intPtr -= Vector<byte>.Count;
intPtr2 -= Vector<byte>.Count;
}
if ((void*)intPtr != null) {
intPtr2 = intPtr;
continue;
}
}
return -1;
}
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)) {
if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 2)) {
if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr + 1)) {
if (value != Unsafe.AddByteOffset(ref searchSpace, intPtr))
continue;
goto IL_0254;
}
goto IL_025c;
}
goto IL_026a;
}
goto IL_0278;
IL_0254:
return (int)(void*)intPtr;
IL_026a:
return (int)(void*)(intPtr + 2);
IL_0278:
return (int)(void*)(intPtr + 3);
IL_025c:
return (int)(void*)(intPtr + 1);
}
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;
if (Vector.IsHardwareAccelerated && length >= Vector<byte>.Count * 2) {
int num = (int)Unsafe.AsPointer(ref searchSpace) & (Vector<byte>.Count - 1);
intPtr2 = (IntPtr)((Vector<byte>.Count - num) & (Vector<byte>.Count - 1));
}
while (true) {
uint num2;
if ((ulong)(void*)intPtr2 < 8) {
if ((ulong)(void*)intPtr2 >= 4) {
intPtr2 -= 4;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr);
if (value0 == num2 || value1 == num2)
goto IL_02ff;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1);
if (value0 == num2 || value1 == num2)
goto IL_0307;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2);
if (value0 == num2 || value1 == num2)
goto IL_0315;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3);
if (value0 == num2 || value1 == num2)
goto IL_0323;
intPtr += 4;
}
while ((void*)intPtr2 != null) {
intPtr2 -= 1;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr);
if (value0 != num2 && value1 != num2) {
intPtr += 1;
continue;
}
goto IL_02ff;
}
if (Vector.IsHardwareAccelerated && (int)(void*)intPtr < length) {
intPtr2 = (IntPtr)((length - (int)(void*)intPtr) & ~(Vector<byte>.Count - 1));
Vector<byte> vector = GetVector(value0);
Vector<byte> vector2 = GetVector(value1);
while ((void*)intPtr2 > (void*)intPtr) {
Vector<byte> left = Unsafe.ReadUnaligned<Vector<byte>>(ref Unsafe.AddByteOffset(ref searchSpace, intPtr));
Vector<byte> vector3 = Vector.BitwiseOr(Vector.Equals(left, vector), Vector.Equals(left, vector2));
if (!Vector<byte>.Zero.Equals(vector3))
return (int)(void*)intPtr + LocateFirstFoundByte(vector3);
intPtr += Vector<byte>.Count;
}
if ((int)(void*)intPtr < length) {
intPtr2 = (IntPtr)(length - (int)(void*)intPtr);
continue;
}
}
return -1;
}
intPtr2 -= 8;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr);
if (value0 == num2 || value1 == num2)
goto IL_02ff;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1);
if (value0 == num2 || value1 == num2)
goto IL_0307;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2);
if (value0 == num2 || value1 == num2)
goto IL_0315;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3);
if (value0 != num2 && value1 != num2) {
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 4);
if (value0 == num2 || value1 == num2)
return (int)(void*)(intPtr + 4);
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 5);
if (value0 == num2 || value1 == num2)
return (int)(void*)(intPtr + 5);
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 6);
if (value0 == num2 || value1 == num2)
return (int)(void*)(intPtr + 6);
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 7);
if (value0 == num2 || value1 == num2)
break;
intPtr += 8;
continue;
}
goto IL_0323;
IL_02ff:
return (int)(void*)intPtr;
IL_0315:
return (int)(void*)(intPtr + 2);
IL_0307:
return (int)(void*)(intPtr + 1);
IL_0323:
return (int)(void*)(intPtr + 3);
}
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;
if (Vector.IsHardwareAccelerated && length >= Vector<byte>.Count * 2) {
int num = (int)Unsafe.AsPointer(ref searchSpace) & (Vector<byte>.Count - 1);
intPtr2 = (IntPtr)((Vector<byte>.Count - num) & (Vector<byte>.Count - 1));
}
while (true) {
uint num2;
if ((ulong)(void*)intPtr2 < 8) {
if ((ulong)(void*)intPtr2 >= 4) {
intPtr2 -= 4;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr);
if (value0 == num2 || value1 == num2 || value2 == num2)
goto IL_0393;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1);
if (value0 == num2 || value1 == num2 || value2 == num2)
goto IL_039b;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2);
if (value0 == num2 || value1 == num2 || value2 == num2)
goto IL_03a9;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3);
if (value0 == num2 || value1 == num2 || value2 == num2)
goto IL_03b7;
intPtr += 4;
}
while ((void*)intPtr2 != null) {
intPtr2 -= 1;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr);
if (value0 != num2 && value1 != num2 && value2 != num2) {
intPtr += 1;
continue;
}
goto IL_0393;
}
if (Vector.IsHardwareAccelerated && (int)(void*)intPtr < length) {
intPtr2 = (IntPtr)((length - (int)(void*)intPtr) & ~(Vector<byte>.Count - 1));
Vector<byte> vector = GetVector(value0);
Vector<byte> vector2 = GetVector(value1);
Vector<byte> vector3 = GetVector(value2);
while ((void*)intPtr2 > (void*)intPtr) {
Vector<byte> left = Unsafe.ReadUnaligned<Vector<byte>>(ref Unsafe.AddByteOffset(ref searchSpace, intPtr));
Vector<byte> vector4 = Vector.BitwiseOr(Vector.BitwiseOr(Vector.Equals(left, vector), Vector.Equals(left, vector2)), Vector.Equals(left, vector3));
if (!Vector<byte>.Zero.Equals(vector4))
return (int)(void*)intPtr + LocateFirstFoundByte(vector4);
intPtr += Vector<byte>.Count;
}
if ((int)(void*)intPtr < length) {
intPtr2 = (IntPtr)(length - (int)(void*)intPtr);
continue;
}
}
return -1;
}
intPtr2 -= 8;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr);
if (value0 == num2 || value1 == num2 || value2 == num2)
goto IL_0393;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1);
if (value0 == num2 || value1 == num2 || value2 == num2)
goto IL_039b;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2);
if (value0 == num2 || value1 == num2 || value2 == num2)
goto IL_03a9;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3);
if (value0 != num2 && value1 != num2 && value2 != num2) {
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 4);
if (value0 == num2 || value1 == num2 || value2 == num2)
return (int)(void*)(intPtr + 4);
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 5);
if (value0 == num2 || value1 == num2 || value2 == num2)
return (int)(void*)(intPtr + 5);
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 6);
if (value0 == num2 || value1 == num2 || value2 == num2)
return (int)(void*)(intPtr + 6);
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 7);
if (value0 == num2 || value1 == num2 || value2 == num2)
break;
intPtr += 8;
continue;
}
goto IL_03b7;
IL_0393:
return (int)(void*)intPtr;
IL_039b:
return (int)(void*)(intPtr + 1);
IL_03b7:
return (int)(void*)(intPtr + 3);
IL_03a9:
return (int)(void*)(intPtr + 2);
}
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;
if (Vector.IsHardwareAccelerated && length >= Vector<byte>.Count * 2) {
int num = (int)Unsafe.AsPointer(ref searchSpace) & (Vector<byte>.Count - 1);
intPtr2 = (IntPtr)(((length & (Vector<byte>.Count - 1)) + num) & (Vector<byte>.Count - 1));
}
while (true) {
uint num2;
if ((ulong)(void*)intPtr2 < 8) {
if ((ulong)(void*)intPtr2 >= 4) {
intPtr2 -= 4;
intPtr -= 4;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3);
if (value0 == num2 || value1 == num2)
goto IL_0338;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2);
if (value0 == num2 || value1 == num2)
goto IL_032a;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1);
if (value0 == num2 || value1 == num2)
goto IL_031c;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr);
if (value0 == num2 || value1 == num2)
goto IL_0314;
}
while ((void*)intPtr2 != null) {
intPtr2 -= 1;
intPtr -= 1;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr);
if (value0 != num2 && value1 != num2)
continue;
goto IL_0314;
}
if (Vector.IsHardwareAccelerated && (void*)intPtr != null) {
intPtr2 = (IntPtr)((int)(void*)intPtr & ~(Vector<byte>.Count - 1));
Vector<byte> vector = GetVector(value0);
Vector<byte> vector2 = GetVector(value1);
while ((ulong)(void*)intPtr2 > (ulong)(Vector<byte>.Count - 1)) {
Vector<byte> left = Unsafe.ReadUnaligned<Vector<byte>>(ref Unsafe.AddByteOffset(ref searchSpace, intPtr - Vector<byte>.Count));
Vector<byte> vector3 = Vector.BitwiseOr(Vector.Equals(left, vector), Vector.Equals(left, vector2));
if (!Vector<byte>.Zero.Equals(vector3))
return (int)intPtr - Vector<byte>.Count + LocateLastFoundByte(vector3);
intPtr -= Vector<byte>.Count;
intPtr2 -= Vector<byte>.Count;
}
if ((void*)intPtr != null) {
intPtr2 = intPtr;
continue;
}
}
return -1;
}
intPtr2 -= 8;
intPtr -= 8;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 7);
if (value0 == num2 || value1 == num2)
break;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 6);
if (value0 == num2 || value1 == num2)
return (int)(void*)(intPtr + 6);
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 5);
if (value0 == num2 || value1 == num2)
return (int)(void*)(intPtr + 5);
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 4);
if (value0 == num2 || value1 == num2)
return (int)(void*)(intPtr + 4);
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3);
if (value0 != num2 && value1 != num2) {
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2);
if (value0 != num2 && value1 != num2) {
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1);
if (value0 != num2 && value1 != num2) {
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr);
if (value0 != num2 && value1 != num2)
continue;
goto IL_0314;
}
goto IL_031c;
}
goto IL_032a;
}
goto IL_0338;
IL_0314:
return (int)(void*)intPtr;
IL_0338:
return (int)(void*)(intPtr + 3);
IL_031c:
return (int)(void*)(intPtr + 1);
IL_032a:
return (int)(void*)(intPtr + 2);
}
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;
if (Vector.IsHardwareAccelerated && length >= Vector<byte>.Count * 2) {
int num = (int)Unsafe.AsPointer(ref searchSpace) & (Vector<byte>.Count - 1);
intPtr2 = (IntPtr)(((length & (Vector<byte>.Count - 1)) + num) & (Vector<byte>.Count - 1));
}
while (true) {
uint num2;
if ((ulong)(void*)intPtr2 < 8) {
if ((ulong)(void*)intPtr2 >= 4) {
intPtr2 -= 4;
intPtr -= 4;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3);
if (value0 == num2 || value1 == num2 || value2 == num2)
goto IL_03cf;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2);
if (value0 == num2 || value1 == num2 || value2 == num2)
goto IL_03c1;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1);
if (value0 == num2 || value1 == num2 || value2 == num2)
goto IL_03b3;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr);
if (value0 == num2 || value1 == num2 || value2 == num2)
goto IL_03ab;
}
while ((void*)intPtr2 != null) {
intPtr2 -= 1;
intPtr -= 1;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr);
if (value0 != num2 && value1 != num2 && value2 != num2)
continue;
goto IL_03ab;
}
if (Vector.IsHardwareAccelerated && (void*)intPtr != null) {
intPtr2 = (IntPtr)((int)(void*)intPtr & ~(Vector<byte>.Count - 1));
Vector<byte> vector = GetVector(value0);
Vector<byte> vector2 = GetVector(value1);
Vector<byte> vector3 = GetVector(value2);
while ((ulong)(void*)intPtr2 > (ulong)(Vector<byte>.Count - 1)) {
Vector<byte> left = Unsafe.ReadUnaligned<Vector<byte>>(ref Unsafe.AddByteOffset(ref searchSpace, intPtr - Vector<byte>.Count));
Vector<byte> vector4 = Vector.BitwiseOr(Vector.BitwiseOr(Vector.Equals(left, vector), Vector.Equals(left, vector2)), Vector.Equals(left, vector3));
if (!Vector<byte>.Zero.Equals(vector4))
return (int)intPtr - Vector<byte>.Count + LocateLastFoundByte(vector4);
intPtr -= Vector<byte>.Count;
intPtr2 -= Vector<byte>.Count;
}
if ((void*)intPtr != null) {
intPtr2 = intPtr;
continue;
}
}
return -1;
}
intPtr2 -= 8;
intPtr -= 8;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 7);
if (value0 == num2 || value1 == num2 || value2 == num2)
break;
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 6);
if (value0 == num2 || value1 == num2 || value2 == num2)
return (int)(void*)(intPtr + 6);
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 5);
if (value0 == num2 || value1 == num2 || value2 == num2)
return (int)(void*)(intPtr + 5);
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 4);
if (value0 == num2 || value1 == num2 || value2 == num2)
return (int)(void*)(intPtr + 4);
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 3);
if (value0 != num2 && value1 != num2 && value2 != num2) {
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 2);
if (value0 != num2 && value1 != num2 && value2 != num2) {
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr + 1);
if (value0 != num2 && value1 != num2 && value2 != num2) {
num2 = Unsafe.AddByteOffset(ref searchSpace, intPtr);
if (value0 != num2 && value1 != num2 && value2 != num2)
continue;
goto IL_03ab;
}
goto IL_03b3;
}
goto IL_03c1;
}
goto IL_03cf;
IL_03ab:
return (int)(void*)intPtr;
IL_03cf:
return (int)(void*)(intPtr + 3);
IL_03c1:
return (int)(void*)(intPtr + 2);
IL_03b3:
return (int)(void*)(intPtr + 1);
}
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))
goto IL_013d;
IntPtr intPtr = (IntPtr)0;
IntPtr intPtr2 = (IntPtr)(void*)length;
if (Vector.IsHardwareAccelerated && (ulong)(void*)intPtr2 >= (ulong)Vector<byte>.Count) {
intPtr2 -= Vector<byte>.Count;
while (true) {
if ((void*)intPtr2 <= (void*)intPtr)
return Unsafe.ReadUnaligned<Vector<byte>>(ref Unsafe.AddByteOffset(ref first, intPtr2)) == Unsafe.ReadUnaligned<Vector<byte>>(ref Unsafe.AddByteOffset(ref second, intPtr2));
if (Unsafe.ReadUnaligned<Vector<byte>>(ref Unsafe.AddByteOffset(ref first, intPtr)) != Unsafe.ReadUnaligned<Vector<byte>>(ref Unsafe.AddByteOffset(ref second, intPtr)))
break;
intPtr += Vector<byte>.Count;
}
} else {
if ((ulong)(void*)intPtr2 < (ulong)sizeof(UIntPtr)) {
while ((void*)intPtr2 > (void*)intPtr) {
if (Unsafe.AddByteOffset(ref first, intPtr) == Unsafe.AddByteOffset(ref second, intPtr)) {
intPtr += 1;
continue;
}
goto IL_013f;
}
goto IL_013d;
}
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_013f;
IL_013d:
return true;
IL_013f:
return false;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int LocateFirstFoundByte(Vector<byte> match)
{
Vector<ulong> vector = Vector.AsVectorUInt64(match);
ulong num = 0;
int i;
for (i = 0; i < Vector<ulong>.Count; i++) {
num = vector[i];
if (num != 0)
break;
}
return i * 8 + LocateFirstFoundByte(num);
}
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 (Vector.IsHardwareAccelerated && (ulong)(void*)intPtr2 > (ulong)Vector<byte>.Count) {
intPtr2 -= Vector<byte>.Count;
while ((void*)intPtr2 > (void*)intPtr && !(Unsafe.ReadUnaligned<Vector<byte>>(ref Unsafe.AddByteOffset(ref first, intPtr)) != Unsafe.ReadUnaligned<Vector<byte>>(ref Unsafe.AddByteOffset(ref second, intPtr)))) {
intPtr += Vector<byte>.Count;
}
} else 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;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int LocateLastFoundByte(Vector<byte> match)
{
Vector<ulong> vector = Vector.AsVectorUInt64(match);
ulong num = 0;
int num2;
for (num2 = Vector<ulong>.Count - 1; num2 >= 0; num2--) {
num = vector[num2];
if (num != 0)
break;
}
return num2 * 8 + LocateLastFoundByte(num);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int LocateFirstFoundByte(ulong match)
{
ulong num = match ^ (match - 1);
return (int)(num * 283686952306184 >> 57);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int LocateLastFoundByte(ulong match)
{
int num = 7;
while ((long)match > 0) {
match <<= 8;
num--;
}
return num;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector<byte> GetVector(byte vectorByte)
{
return Vector.AsVectorByte(new Vector<uint>((uint)(vectorByte * 16843009)));
}
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 intPtr = (IntPtr)((firstLength < secondLength) ? firstLength : secondLength);
IntPtr intPtr2 = (IntPtr)0;
if ((ulong)(void*)intPtr >= (ulong)(sizeof(UIntPtr) / 2)) {
if (Vector.IsHardwareAccelerated && (ulong)(void*)intPtr >= (ulong)Vector<ushort>.Count) {
IntPtr value = intPtr - Vector<ushort>.Count;
while (!(Unsafe.ReadUnaligned<Vector<ushort>>(ref Unsafe.As<char, byte>(ref Unsafe.Add(ref first, intPtr2))) != Unsafe.ReadUnaligned<Vector<ushort>>(ref Unsafe.As<char, byte>(ref Unsafe.Add(ref second, intPtr2))))) {
intPtr2 += Vector<ushort>.Count;
if ((void*)value < (void*)intPtr2)
break;
}
}
while ((void*)intPtr >= (void*)(intPtr2 + sizeof(UIntPtr) / 2) && !(Unsafe.ReadUnaligned<UIntPtr>(ref Unsafe.As<char, byte>(ref Unsafe.Add(ref first, intPtr2))) != Unsafe.ReadUnaligned<UIntPtr>(ref Unsafe.As<char, byte>(ref Unsafe.Add(ref second, intPtr2))))) {
intPtr2 += sizeof(UIntPtr) / 2;
}
}
if (sizeof(UIntPtr) > 4 && (void*)intPtr >= (void*)(intPtr2 + 2) && Unsafe.ReadUnaligned<int>(ref Unsafe.As<char, byte>(ref Unsafe.Add(ref first, intPtr2))) == Unsafe.ReadUnaligned<int>(ref Unsafe.As<char, byte>(ref Unsafe.Add(ref second, intPtr2))))
intPtr2 += 2;
while ((void*)intPtr2 < (void*)intPtr) {
int num = Unsafe.Add(ref first, intPtr2).CompareTo(Unsafe.Add(ref second, intPtr2));
if (num != 0)
return num;
intPtr2 += 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;
if (Vector.IsHardwareAccelerated && length >= Vector<ushort>.Count * 2) {
int num = ((int)ptr2 & (Unsafe.SizeOf<Vector<ushort>>() - 1)) / 2;
length = ((Vector<ushort>.Count - num) & (Vector<ushort>.Count - 1));
}
while (true) {
if (length >= 4) {
length -= 4;
if (*ptr2 != value) {
if (ptr2[1] != value) {
if (ptr2[2] != value) {
if (ptr2[3] != value) {
ptr2 += 4;
continue;
}
ptr2++;
}
ptr2++;
}
ptr2++;
}
break;
}
while (length > 0) {
length--;
if (*ptr2 == value)
goto end_IL_0079;
ptr2++;
}
if (Vector.IsHardwareAccelerated && ptr2 < ptr3) {
length = (int)((ptr3 - ptr2) & ~(Vector<ushort>.Count - 1));
Vector<ushort> left = new Vector<ushort>(value);
while (length > 0) {
Vector<ushort> vector = Vector.Equals(left, Unsafe.Read<Vector<ushort>>(ptr2));
if (!Vector<ushort>.Zero.Equals(vector))
return (int)(ptr2 - ptr) + LocateFirstFoundChar(vector);
ptr2 += Vector<ushort>.Count;
length -= Vector<ushort>.Count;
}
if (ptr2 < ptr3) {
length = (int)(ptr3 - ptr2);
continue;
}
}
return -1;
continue;
end_IL_0079:
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;
if (Vector.IsHardwareAccelerated && length >= Vector<ushort>.Count * 2)
length = ((int)ptr2 & (Unsafe.SizeOf<Vector<ushort>>() - 1)) / 2;
while (true) {
if (length < 4) {
while (length > 0) {
length--;
ptr2--;
if (*ptr2 != value)
continue;
goto IL_011d;
}
if (Vector.IsHardwareAccelerated && ptr2 > ptr3) {
length = (int)((ptr2 - ptr3) & ~(Vector<ushort>.Count - 1));
Vector<ushort> left = new Vector<ushort>(value);
while (length > 0) {
char* ptr4 = ptr2 - Vector<ushort>.Count;
Vector<ushort> vector = Vector.Equals(left, Unsafe.Read<Vector<ushort>>(ptr4));
if (!Vector<ushort>.Zero.Equals(vector))
return (int)(ptr4 - ptr3) + LocateLastFoundChar(vector);
ptr2 -= Vector<ushort>.Count;
length -= Vector<ushort>.Count;
}
if (ptr2 > ptr3) {
length = (int)(ptr2 - ptr3);
continue;
}
}
return -1;
}
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;
goto IL_011d;
IL_011d:
return (int)(ptr2 - ptr3);
}
return (int)(ptr2 - ptr3) + 3;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int LocateFirstFoundChar(Vector<ushort> match)
{
Vector<ulong> vector = Vector.AsVectorUInt64(match);
ulong num = 0;
int i;
for (i = 0; i < Vector<ulong>.Count; i++) {
num = vector[i];
if (num != 0)
break;
}
return i * 4 + LocateFirstFoundChar(num);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int LocateFirstFoundChar(ulong match)
{
ulong num = match ^ (match - 1);
return (int)(num * 4295098372 >> 49);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int LocateLastFoundChar(Vector<ushort> match)
{
Vector<ulong> vector = Vector.AsVectorUInt64(match);
ulong num = 0;
int num2;
for (num2 = Vector<ulong>.Count - 1; num2 >= 0; num2--) {
num = vector[num2];
if (num != 0)
break;
}
return num2 * 4 + LocateLastFoundChar(num);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int LocateLastFoundChar(ulong match)
{
int num = 3;
while ((long)match > 0) {
match <<= 16;
num--;
}
return num;
}
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().IsPrimitive)
return false;
if (!type.GetTypeInfo().IsValueType)
return true;
Type underlyingType = Nullable.GetUnderlyingType(type);
if (underlyingType != (Type)null)
type = underlyingType;
if (type.GetTypeInfo().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;
}
}
}