Skip to content

Commit

Permalink
Add Contains and IndexOfValue(3 chars)
Browse files Browse the repository at this point in the history
  • Loading branch information
MihaZupan committed Dec 29, 2022
1 parent b2d5f0f commit 178b1f8
Show file tree
Hide file tree
Showing 11 changed files with 453 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -425,20 +425,21 @@
<Compile Include="$(MSBuildThisFileDirectory)System\IndexOfAnyValues\IndexOfAny1ByteValue.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IndexOfAnyValues\IndexOfAny2ByteValues.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IndexOfAnyValues\IndexOfAny2CharValues.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IndexOfAnyValues\IndexOfAny3Values.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IndexOfAnyValues\IndexOfAny3ByteValues.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IndexOfAnyValues\IndexOfAny3CharValues.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IndexOfAnyValues\IndexOfAny4Values.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IndexOfAnyValues\IndexOfAny5Values.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IndexOfAnyValues\IndexOfAnyAsciiByteValues.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IndexOfAnyValues\IndexOfAnyAsciiCharValues.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IndexOfAnyValues\IndexOfAnyAsciiSearcher.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IndexOfAnyValues\IndexOfAnyByteValues.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IndexOfAnyValues\IndexOfAnyByteValuesInRange.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IndexOfAnyValues\IndexOfAnyCharValuesInRange.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IndexOfAnyValues\IndexOfAnyCharValuesProbabilistic.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IndexOfAnyValues\IndexOfAnyLatin1CharValues.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IndexOfAnyValues\IndexOfAnyValues.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IndexOfAnyValues\IndexOfAnyValues.T.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IndexOfAnyValues\IndexOfAnyValuesDebugView.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IndexOfAnyValues\IndexOfAnyByteValuesInRange.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IndexOfAnyValues\IndexOfEmptyValues.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IndexOfAnyValues\ProbabilisticMap.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IndexOutOfRangeException.cs" />
Expand Down Expand Up @@ -1031,8 +1032,8 @@
<Compile Include="$(MSBuildThisFileDirectory)System\SpanHelpers.BinarySearch.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\SpanHelpers.Byte.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\SpanHelpers.Char.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\SpanHelpers.Char.Packed.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\SpanHelpers.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\SpanHelpers.Packed.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\SpanHelpers.T.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\SR.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\StackOverflowException.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -339,8 +339,8 @@ internal static int IndexOfOrdinalIgnoreCase(ReadOnlySpan<char> source, ReadOnly
{
// Do a quick search for the first element of "value".
int relativeIndex = isLetter ?
SpanHelpers.PackedIndexOfIsSupported
? SpanHelpers.PackedIndexOfAny(ref Unsafe.Add(ref searchSpace, offset), valueCharU, valueCharL, searchSpaceLength)
PackedSpanHelpers.PackedIndexOfIsSupported
? PackedSpanHelpers.PackedIndexOfAny(ref Unsafe.Add(ref searchSpace, offset), valueCharU, valueCharL, searchSpaceLength)
: SpanHelpers.IndexOfAnyChar(ref Unsafe.Add(ref searchSpace, offset), valueCharU, valueCharL, searchSpaceLength) :
SpanHelpers.IndexOfChar(ref Unsafe.Add(ref searchSpace, offset), valueChar, searchSpaceLength);
if (relativeIndex < 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ internal sealed class IndexOfAny1CharValue<TShouldUsePacked> : IndexOfAnyValues<
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal override int IndexOfAny(ReadOnlySpan<char> span) =>
TShouldUsePacked.Value
? SpanHelpers.PackedIndexOf(ref MemoryMarshal.GetReference(span), _e0, span.Length)
? PackedSpanHelpers.PackedIndexOf(ref MemoryMarshal.GetReference(span), _e0, span.Length)
: SpanHelpers.NonPackedIndexOfValueType<short, SpanHelpers.DontNegate<short>>(
ref Unsafe.As<char, short>(ref MemoryMarshal.GetReference(span)),
Unsafe.As<char, short>(ref _e0),
Expand All @@ -32,7 +32,7 @@ internal sealed class IndexOfAny1CharValue<TShouldUsePacked> : IndexOfAnyValues<
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal override int IndexOfAnyExcept(ReadOnlySpan<char> span) =>
TShouldUsePacked.Value
? SpanHelpers.PackedIndexOfAnyExcept(ref MemoryMarshal.GetReference(span), _e0, span.Length)
? PackedSpanHelpers.PackedIndexOfAnyExcept(ref MemoryMarshal.GetReference(span), _e0, span.Length)
: SpanHelpers.NonPackedIndexOfValueType<short, SpanHelpers.Negate<short>>(
ref Unsafe.As<char, short>(ref MemoryMarshal.GetReference(span)),
Unsafe.As<char, short>(ref _e0),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ internal sealed class IndexOfAny2CharValue<TShouldUsePacked> : IndexOfAnyValues<
public IndexOfAny2CharValue(char value0, char value1) =>
(_e0, _e1) = (value0, value1);

internal override char[] GetValues() => new[] { _e0 };
internal override char[] GetValues() => new[] { _e0, _e1 };

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal override bool ContainsCore(char value) =>
Expand All @@ -23,7 +23,7 @@ internal sealed class IndexOfAny2CharValue<TShouldUsePacked> : IndexOfAnyValues<
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal override int IndexOfAny(ReadOnlySpan<char> span) =>
TShouldUsePacked.Value
? SpanHelpers.PackedIndexOfAny(ref MemoryMarshal.GetReference(span), _e0, _e1, span.Length)
? PackedSpanHelpers.PackedIndexOfAny(ref MemoryMarshal.GetReference(span), _e0, _e1, span.Length)
: SpanHelpers.NonPackedIndexOfAnyValueType<short, SpanHelpers.DontNegate<short>>(
ref Unsafe.As<char, short>(ref MemoryMarshal.GetReference(span)),
Unsafe.As<char, short>(ref _e0),
Expand All @@ -33,7 +33,7 @@ internal sealed class IndexOfAny2CharValue<TShouldUsePacked> : IndexOfAnyValues<
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal override int IndexOfAnyExcept(ReadOnlySpan<char> span) =>
TShouldUsePacked.Value
? SpanHelpers.PackedIndexOfAnyExcept(ref MemoryMarshal.GetReference(span), _e0, _e1, span.Length)
? PackedSpanHelpers.PackedIndexOfAnyExcept(ref MemoryMarshal.GetReference(span), _e0, _e1, span.Length)
: SpanHelpers.NonPackedIndexOfAnyValueType<short, SpanHelpers.Negate<short>>(
ref Unsafe.As<char, short>(ref MemoryMarshal.GetReference(span)),
Unsafe.As<char, short>(ref _e0),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,40 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics;
using System.Numerics;
using System.Runtime.CompilerServices;

namespace System.Buffers
{
internal sealed class IndexOfAny3Values<T> : IndexOfAnyValues<T>
where T : struct, INumber<T>
internal sealed class IndexOfAny3ByteValues : IndexOfAnyValues<byte>
{
private readonly T _e0, _e1, _e2;
private readonly byte _e0, _e1, _e2;

public IndexOfAny3Values(ReadOnlySpan<T> values)
public IndexOfAny3ByteValues(ReadOnlySpan<byte> values)
{
Debug.Assert(values.Length == 3);
(_e0, _e1, _e2) = (values[0], values[1], values[2]);
}

internal override T[] GetValues() => new[] { _e0, _e1, _e2 };
internal override byte[] GetValues() => new[] { _e0, _e1, _e2 };

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal override bool ContainsCore(T value) =>
internal override bool ContainsCore(byte value) =>
value == _e0 || value == _e1 || value == _e2;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal override int IndexOfAny(ReadOnlySpan<T> span) =>
internal override int IndexOfAny(ReadOnlySpan<byte> span) =>
span.IndexOfAny(_e0, _e1, _e2);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal override int IndexOfAnyExcept(ReadOnlySpan<T> span) =>
internal override int IndexOfAnyExcept(ReadOnlySpan<byte> span) =>
span.IndexOfAnyExcept(_e0, _e1, _e2);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal override int LastIndexOfAny(ReadOnlySpan<T> span) =>
internal override int LastIndexOfAny(ReadOnlySpan<byte> span) =>
span.LastIndexOfAny(_e0, _e1, _e2);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal override int LastIndexOfAnyExcept(ReadOnlySpan<T> span) =>
internal override int LastIndexOfAnyExcept(ReadOnlySpan<byte> span) =>
span.LastIndexOfAnyExcept(_e0, _e1, _e2);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

namespace System.Buffers
{
internal sealed class IndexOfAny3CharValue<TShouldUsePacked> : IndexOfAnyValues<char>
where TShouldUsePacked : struct, IndexOfAnyValues.IRuntimeConst
{
private char _e0, _e1, _e2;

public IndexOfAny3CharValue(char value0, char value1, char value2) =>
(_e0, _e1, _e2) = (value0, value1, value2);

internal override char[] GetValues() => new[] { _e0, _e1, _e2 };

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal override bool ContainsCore(char value) =>
value == _e0 || value == _e1 || value == _e2;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal override int IndexOfAny(ReadOnlySpan<char> span) =>
TShouldUsePacked.Value
? PackedSpanHelpers.PackedIndexOfAny(ref MemoryMarshal.GetReference(span), _e0, _e1, _e2, span.Length)
: SpanHelpers.NonPackedIndexOfAnyValueType<short, SpanHelpers.DontNegate<short>>(
ref Unsafe.As<char, short>(ref MemoryMarshal.GetReference(span)),
Unsafe.As<char, short>(ref _e0),
Unsafe.As<char, short>(ref _e1),
Unsafe.As<char, short>(ref _e2),
span.Length);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal override int IndexOfAnyExcept(ReadOnlySpan<char> span) =>
TShouldUsePacked.Value
? PackedSpanHelpers.PackedIndexOfAnyExcept(ref MemoryMarshal.GetReference(span), _e0, _e1, _e2, span.Length)
: SpanHelpers.NonPackedIndexOfAnyValueType<short, SpanHelpers.Negate<short>>(
ref Unsafe.As<char, short>(ref MemoryMarshal.GetReference(span)),
Unsafe.As<char, short>(ref _e0),
Unsafe.As<char, short>(ref _e1),
Unsafe.As<char, short>(ref _e2),
span.Length);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal override int LastIndexOfAny(ReadOnlySpan<char> span) =>
span.LastIndexOfAny(_e0, _e1, _e2);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal override int LastIndexOfAnyExcept(ReadOnlySpan<char> span) =>
span.LastIndexOfAnyExcept(_e0, _e1, _e2);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ internal override char[] GetValues()
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal override int IndexOfAny(ReadOnlySpan<char> span) =>
TShouldUsePacked.Value
? SpanHelpers.PackedIndexOfAnyInRange(ref MemoryMarshal.GetReference(span), _lowInclusive, _rangeInclusive, span.Length)
? PackedSpanHelpers.PackedIndexOfAnyInRange(ref MemoryMarshal.GetReference(span), _lowInclusive, _rangeInclusive, span.Length)
: SpanHelpers.NonPackedIndexOfAnyInRangeUnsignedNumber<ushort, SpanHelpers.DontNegate<ushort>>(
ref Unsafe.As<char, ushort>(ref MemoryMarshal.GetReference(span)),
Unsafe.As<char, ushort>(ref _lowInclusive),
Expand All @@ -49,7 +49,7 @@ internal override char[] GetValues()
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal override int IndexOfAnyExcept(ReadOnlySpan<char> span) =>
TShouldUsePacked.Value
? SpanHelpers.PackedIndexOfAnyExceptInRange(ref MemoryMarshal.GetReference(span), _lowInclusive, _rangeInclusive, span.Length)
? PackedSpanHelpers.PackedIndexOfAnyExceptInRange(ref MemoryMarshal.GetReference(span), _lowInclusive, _rangeInclusive, span.Length)
: SpanHelpers.NonPackedIndexOfAnyInRangeUnsignedNumber<ushort, SpanHelpers.Negate<ushort>>(
ref Unsafe.As<char, ushort>(ref MemoryMarshal.GetReference(span)),
Unsafe.As<char, ushort>(ref _lowInclusive),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public static IndexOfAnyValues<byte> Create(ReadOnlySpan<byte> values)
return values.Length switch
{
2 => new IndexOfAny2ByteValues(values),
3 => new IndexOfAny3Values<byte>(values),
3 => new IndexOfAny3ByteValues(values),
4 => new IndexOfAny4Values<byte, byte>(values),
_ => new IndexOfAny5Values<byte, byte>(values),
};
Expand Down Expand Up @@ -80,7 +80,7 @@ public static IndexOfAnyValues<char> Create(ReadOnlySpan<char> values)
if (values.Length == 1)
{
char value = values[0];
return SpanHelpers.CanUsePackedIndexOf(value)
return PackedSpanHelpers.CanUsePackedIndexOf(value)
? new IndexOfAny1CharValue<TrueConst>(value)
: new IndexOfAny1CharValue<FalseConst>(value);
}
Expand All @@ -95,14 +95,19 @@ public static IndexOfAnyValues<char> Create(ReadOnlySpan<char> values)
{
char value0 = values[0];
char value1 = values[1];
return SpanHelpers.CanUsePackedIndexOf(value0) && SpanHelpers.CanUsePackedIndexOf(value1)
return PackedSpanHelpers.CanUsePackedIndexOf(value0) && PackedSpanHelpers.CanUsePackedIndexOf(value1)
? new IndexOfAny2CharValue<TrueConst>(value0, value1)
: new IndexOfAny2CharValue<FalseConst>(value0, value1);
}

if (values.Length == 3)
{
return new IndexOfAny3Values<char>(values);
char value0 = values[0];
char value1 = values[1];
char value2 = values[2];
return PackedSpanHelpers.CanUsePackedIndexOf(value0) && PackedSpanHelpers.CanUsePackedIndexOf(value1) && PackedSpanHelpers.CanUsePackedIndexOf(value2)
? new IndexOfAny3CharValue<TrueConst>(value0, value1, value2)
: new IndexOfAny3CharValue<FalseConst>(value0, value1, value2);
}

// IndexOfAnyAsciiSearcher for chars is slower than IndexOfAny3Values, but faster than IndexOfAny4Values
Expand Down Expand Up @@ -180,7 +185,7 @@ public static IndexOfAnyValues<char> Create(ReadOnlySpan<char> values)
}

Debug.Assert(typeof(T) == typeof(char));
return (IndexOfAnyValues<T>)(object)(SpanHelpers.CanUsePackedIndexOf(min) && SpanHelpers.CanUsePackedIndexOf(max)
return (IndexOfAnyValues<T>)(object)(PackedSpanHelpers.CanUsePackedIndexOf(min) && PackedSpanHelpers.CanUsePackedIndexOf(max)
? new IndexOfAnyCharValuesInRange<TrueConst>(*(char*)&min, *(char*)&max)
: new IndexOfAnyCharValuesInRange<FalseConst>(*(char*)&min, *(char*)&max));
}
Expand Down

0 comments on commit 178b1f8

Please sign in to comment.