Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/System.Private.CoreLib/shared/System/SpanHelpers.Byte.cs')
-rw-r--r--src/System.Private.CoreLib/shared/System/SpanHelpers.Byte.cs94
1 files changed, 93 insertions, 1 deletions
diff --git a/src/System.Private.CoreLib/shared/System/SpanHelpers.Byte.cs b/src/System.Private.CoreLib/shared/System/SpanHelpers.Byte.cs
index 2890adb56..373065363 100644
--- a/src/System.Private.CoreLib/shared/System/SpanHelpers.Byte.cs
+++ b/src/System.Private.CoreLib/shared/System/SpanHelpers.Byte.cs
@@ -16,7 +16,7 @@ using nuint = System.UInt32;
namespace System
{
- internal static partial class SpanHelpers
+ internal static partial class SpanHelpers // .Byte
{
public static int IndexOf(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength)
{
@@ -96,6 +96,98 @@ namespace System
return index;
}
+ // Adapted from IndexOf(...)
+ public static unsafe bool Contains(ref byte searchSpace, byte value, int length)
+ {
+ Debug.Assert(length >= 0);
+
+ uint uValue = value; // Use uint for comparisons to avoid unnecessary 8->32 extensions
+ IntPtr index = (IntPtr)0; // Use IntPtr for arithmetic to avoid unnecessary 64->32->64 truncations
+ IntPtr nLength = (IntPtr)length;
+
+ if (Vector.IsHardwareAccelerated && length >= Vector<byte>.Count * 2)
+ {
+ int unaligned = (int)Unsafe.AsPointer(ref searchSpace) & (Vector<byte>.Count - 1);
+ nLength = (IntPtr)((Vector<byte>.Count - unaligned) & (Vector<byte>.Count - 1));
+ }
+
+ SequentialScan:
+ while ((byte*)nLength >= (byte*)8)
+ {
+ nLength -= 8;
+
+ if (uValue == Unsafe.AddByteOffset(ref searchSpace, index + 0) ||
+ uValue == Unsafe.AddByteOffset(ref searchSpace, index + 1) ||
+ uValue == Unsafe.AddByteOffset(ref searchSpace, index + 2) ||
+ uValue == Unsafe.AddByteOffset(ref searchSpace, index + 3) ||
+ uValue == Unsafe.AddByteOffset(ref searchSpace, index + 4) ||
+ uValue == Unsafe.AddByteOffset(ref searchSpace, index + 5) ||
+ uValue == Unsafe.AddByteOffset(ref searchSpace, index + 6) ||
+ uValue == Unsafe.AddByteOffset(ref searchSpace, index + 7))
+ {
+ goto Found;
+ }
+
+ index += 8;
+ }
+
+ if ((byte*)nLength >= (byte*)4)
+ {
+ nLength -= 4;
+
+ if (uValue == Unsafe.AddByteOffset(ref searchSpace, index + 0) ||
+ uValue == Unsafe.AddByteOffset(ref searchSpace, index + 1) ||
+ uValue == Unsafe.AddByteOffset(ref searchSpace, index + 2) ||
+ uValue == Unsafe.AddByteOffset(ref searchSpace, index + 3))
+ {
+ goto Found;
+ }
+
+ index += 4;
+ }
+
+ while ((byte*)nLength > (byte*)0)
+ {
+ nLength -= 1;
+
+ if (uValue == Unsafe.AddByteOffset(ref searchSpace, index))
+ goto Found;
+
+ index += 1;
+ }
+
+ if (Vector.IsHardwareAccelerated && ((int)(byte*)index < length))
+ {
+ nLength = (IntPtr)((length - (int)(byte*)index) & ~(Vector<byte>.Count - 1));
+
+ // Get comparison Vector
+ Vector<byte> vComparison = new Vector<byte>(value);
+
+ while ((byte*)nLength > (byte*)index)
+ {
+ var vMatches = Vector.Equals(vComparison, Unsafe.ReadUnaligned<Vector<byte>>(ref Unsafe.AddByteOffset(ref searchSpace, index)));
+ if (Vector<byte>.Zero.Equals(vMatches))
+ {
+ index += Vector<byte>.Count;
+ continue;
+ }
+
+ goto Found;
+ }
+
+ if ((int)(byte*)index < length)
+ {
+ nLength = (IntPtr)(length - (int)(byte*)index);
+ goto SequentialScan;
+ }
+ }
+
+ return false;
+
+ Found:
+ return true;
+ }
+
public static unsafe int IndexOf(ref byte searchSpace, byte value, int length)
{
Debug.Assert(length >= 0);