-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Add whitespace handling methods to MemoryExtensions #111439
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
b35693b
ad80463
e4069c1
b495165
3f77a0f
866b91d
bb9f9f4
5b45997
955d795
8b8e577
3e4f067
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,261 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
|
|
||
| using System.Collections.Generic; | ||
| using System.Runtime.InteropServices; | ||
| using Xunit; | ||
|
|
||
| namespace System.SpanTests | ||
| { | ||
| public static partial class ReadOnlySpanTests | ||
| { | ||
| [Fact] | ||
| public static void IsWhiteSpace_True() | ||
| { | ||
| Assert.True(Span<char>.Empty.IsWhiteSpace()); | ||
|
|
||
| List<char> chars = []; | ||
| for (int i = 0; i <= char.MaxValue; i++) | ||
| { | ||
| if (char.IsWhiteSpace((char)i)) | ||
| chars.Add((char)i); | ||
| } | ||
|
|
||
| Assert.True(CollectionsMarshal.AsSpan(chars).IsWhiteSpace()); | ||
| } | ||
|
|
||
| [Fact] | ||
| public static void IsWhiteSpace_False() | ||
| { | ||
| List<char> chars = []; | ||
| for (int i = 0; i <= char.MaxValue; i++) | ||
| { | ||
| if (char.IsWhiteSpace((char)i)) | ||
| chars.Add((char)i); | ||
| } | ||
|
|
||
| var index = chars.Count; | ||
| chars.AddRange(chars.ToArray()); | ||
| chars.Insert(index, ' '); | ||
| var span = CollectionsMarshal.AsSpan(chars); | ||
|
|
||
| for (int i = 0; i <= char.MaxValue; i++) | ||
| { | ||
| if (!char.IsWhiteSpace((char)i)) | ||
| { | ||
| chars[index] = (char)i; | ||
| Assert.False(span.IsWhiteSpace()); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| [Fact] | ||
| public static void ContainsAnyWhiteSpace_Found() | ||
| { | ||
| List<char> chars = []; | ||
| for (int i = 0; i <= char.MaxValue; i++) | ||
| { | ||
| if (!char.IsWhiteSpace((char)i)) | ||
| chars.Add((char)i); | ||
| } | ||
|
|
||
| var index = chars.Count; | ||
| chars.AddRange(chars.ToArray()); | ||
| chars.Insert(index, ' '); | ||
| var span = CollectionsMarshal.AsSpan(chars); | ||
|
|
||
| for (int i = 0; i <= char.MaxValue; i++) | ||
| { | ||
| if (char.IsWhiteSpace((char)i)) | ||
| { | ||
| chars[index] = (char)i; | ||
| Assert.True(span.ContainsAnyWhiteSpace()); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| [Fact] | ||
| public static void ContainsAnyWhiteSpace_NotFound() | ||
| { | ||
| Assert.False(Span<char>.Empty.ContainsAnyWhiteSpace()); | ||
|
|
||
| List<char> chars = []; | ||
| for (int i = 0; i <= char.MaxValue; i++) | ||
| { | ||
| if (!char.IsWhiteSpace((char)i)) | ||
| chars.Add((char)i); | ||
| } | ||
|
|
||
| Assert.False(CollectionsMarshal.AsSpan(chars).ContainsAnyWhiteSpace()); | ||
| } | ||
|
|
||
| [Fact] | ||
| public static void IndexOfAnyWhiteSpace_Found() | ||
| { | ||
| List<char> chars = []; | ||
| for (int i = 0; i <= char.MaxValue; i++) | ||
| { | ||
| if (!char.IsWhiteSpace((char)i)) | ||
| chars.Add((char)i); | ||
| } | ||
|
|
||
| var index = chars.Count; | ||
| chars.AddRange(chars.ToArray()); | ||
| chars.Insert(index, ' '); | ||
| chars.Insert(index, ' '); | ||
| var span = CollectionsMarshal.AsSpan(chars); | ||
|
|
||
| for (int i = 0; i <= char.MaxValue; i++) | ||
| { | ||
| if (char.IsWhiteSpace((char)i)) | ||
| { | ||
| chars[index] = (char)i; | ||
| chars[index + 1] = (char)i; | ||
| Assert.Equal(index, span.IndexOfAnyWhiteSpace()); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| [Fact] | ||
| public static void IndexOfAnyWhiteSpace_NotFound() | ||
| { | ||
| Assert.Equal(-1, Span<char>.Empty.IndexOfAnyWhiteSpace()); | ||
|
|
||
| List<char> chars = []; | ||
| for (int i = 0; i <= char.MaxValue; i++) | ||
| { | ||
| if (!char.IsWhiteSpace((char)i)) | ||
| chars.Add((char)i); | ||
| } | ||
|
|
||
| Assert.Equal(-1, CollectionsMarshal.AsSpan(chars).IndexOfAnyWhiteSpace()); | ||
| } | ||
|
|
||
| [Fact] | ||
| public static void IndexOfAnyExceptWhiteSpace_Found() | ||
| { | ||
| List<char> chars = []; | ||
| for (int i = 0; i <= char.MaxValue; i++) | ||
| { | ||
| if (char.IsWhiteSpace((char)i)) | ||
| chars.Add((char)i); | ||
| } | ||
|
|
||
| var index = chars.Count; | ||
| chars.AddRange(chars.ToArray()); | ||
| chars.Insert(index, ' '); | ||
| chars.Insert(index, ' '); | ||
| var span = CollectionsMarshal.AsSpan(chars); | ||
|
|
||
| for (int i = 0; i <= char.MaxValue; i++) | ||
| { | ||
| if (!char.IsWhiteSpace((char)i)) | ||
| { | ||
| chars[index] = (char)i; | ||
| chars[index + 1] = (char)i; | ||
| Assert.Equal(index, span.IndexOfAnyExceptWhiteSpace()); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| [Fact] | ||
| public static void IndexOfAnyExceptWhiteSpace_NotFound() | ||
| { | ||
| Assert.Equal(-1, Span<char>.Empty.IndexOfAnyExceptWhiteSpace()); | ||
|
|
||
| List<char> chars = []; | ||
| for (int i = 0; i <= char.MaxValue; i++) | ||
| { | ||
| if (char.IsWhiteSpace((char)i)) | ||
| chars.Add((char)i); | ||
| } | ||
|
|
||
| Assert.Equal(-1, CollectionsMarshal.AsSpan(chars).IndexOfAnyExceptWhiteSpace()); | ||
| } | ||
|
|
||
| [Fact] | ||
| public static void LastIndexOfAnyWhiteSpace_Found() | ||
| { | ||
| List<char> chars = []; | ||
| for (int i = 0; i <= char.MaxValue; i++) | ||
| { | ||
| if (!char.IsWhiteSpace((char)i)) | ||
| chars.Add((char)i); | ||
| } | ||
|
|
||
| var index = chars.Count; | ||
| chars.AddRange(chars.ToArray()); | ||
| chars.Insert(index, ' '); | ||
| chars.Insert(index, ' '); | ||
| var span = CollectionsMarshal.AsSpan(chars); | ||
|
|
||
| for (int i = 0; i <= char.MaxValue; i++) | ||
| { | ||
| if (char.IsWhiteSpace((char)i)) | ||
| { | ||
| chars[index] = (char)i; | ||
| chars[index + 1] = (char)i; | ||
| Assert.Equal(index + 1, span.LastIndexOfAnyWhiteSpace()); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| [Fact] | ||
| public static void LastIndexOfAnyWhiteSpace_NotFound() | ||
| { | ||
| Assert.Equal(-1, Span<char>.Empty.LastIndexOfAnyWhiteSpace()); | ||
|
|
||
| List<char> chars = []; | ||
| for (int i = 0; i <= char.MaxValue; i++) | ||
| { | ||
| if (!char.IsWhiteSpace((char)i)) | ||
| chars.Add((char)i); | ||
| } | ||
|
|
||
| Assert.Equal(-1, CollectionsMarshal.AsSpan(chars).LastIndexOfAnyWhiteSpace()); | ||
| } | ||
|
|
||
| [Fact] | ||
| public static void LastIndexOfAnyExceptWhiteSpace_Found() | ||
| { | ||
| List<char> chars = []; | ||
| for (int i = 0; i <= char.MaxValue; i++) | ||
| { | ||
| if (char.IsWhiteSpace((char)i)) | ||
| chars.Add((char)i); | ||
| } | ||
|
|
||
| var index = chars.Count; | ||
| chars.AddRange(chars.ToArray()); | ||
| chars.Insert(index, ' '); | ||
| chars.Insert(index, ' '); | ||
| var span = CollectionsMarshal.AsSpan(chars); | ||
|
|
||
| for (int i = 0; i <= char.MaxValue; i++) | ||
| { | ||
| if (!char.IsWhiteSpace((char)i)) | ||
| { | ||
| chars[index] = (char)i; | ||
| chars[index + 1] = (char)i; | ||
| Assert.Equal(index + 1, span.LastIndexOfAnyExceptWhiteSpace()); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| [Fact] | ||
| public static void LastIndexOfAnyExceptWhiteSpace_NotFound() | ||
| { | ||
| Assert.Equal(-1, Span<char>.Empty.LastIndexOfAnyExceptWhiteSpace()); | ||
|
|
||
| List<char> chars = []; | ||
| for (int i = 0; i <= char.MaxValue; i++) | ||
| { | ||
| if (char.IsWhiteSpace((char)i)) | ||
| chars.Add((char)i); | ||
| } | ||
|
|
||
| Assert.Equal(-1, CollectionsMarshal.AsSpan(chars).LastIndexOfAnyExceptWhiteSpace()); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,15 +14,9 @@ public static partial class MemoryExtensions | |
| /// <summary> | ||
| /// Indicates whether the specified span contains only white-space characters. | ||
| /// </summary> | ||
| public static bool IsWhiteSpace(this ReadOnlySpan<char> span) | ||
| { | ||
| for (int i = 0; i < span.Length; i++) | ||
| { | ||
| if (!char.IsWhiteSpace(span[i])) | ||
| return false; | ||
| } | ||
| return true; | ||
| } | ||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In don't think these trivial methods require
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @AlexRadch Did you do analysis to see if the |
||
| public static bool IsWhiteSpace(this ReadOnlySpan<char> span) => | ||
| !string.SearchValuesStorage.WhiteSpaceChars.ContainsAnyExcept(span); | ||
|
|
||
| /// <summary> | ||
| /// Returns a value indicating whether the specified <paramref name="value"/> occurs within the <paramref name="span"/>. | ||
|
|
@@ -35,6 +29,16 @@ public static bool Contains(this ReadOnlySpan<char> span, ReadOnlySpan<char> val | |
| return IndexOf(span, value, comparisonType) >= 0; | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Indicates whether the specified span contains <see cref="char.IsWhiteSpace(char)">any | ||
| /// white-space characters</see>. | ||
| /// </summary> | ||
| /// <param name="span">The source span.</param> | ||
AlexRadch marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| /// <returns><see langword="true"/> if the span contains any whitespace characters, <see langword="false"/> otherwise.</returns> | ||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
AlexRadch marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| public static bool ContainsAnyWhiteSpace(this ReadOnlySpan<char> span) => | ||
| string.SearchValuesStorage.WhiteSpaceChars.ContainsAny(span); | ||
|
|
||
| /// <summary> | ||
| /// Determines whether this <paramref name="span"/> and the specified <paramref name="other"/> span have the same characters | ||
| /// when compared using the specified <paramref name="comparisonType"/> option. | ||
|
|
@@ -149,6 +153,24 @@ public static int IndexOf(this ReadOnlySpan<char> span, ReadOnlySpan<char> value | |
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Reports the zero-based index of the first occurrence of <see cref="char.IsWhiteSpace(char)">any white-space | ||
| /// characters</see> in the current <paramref name="span"/>, or -1 if not founded. | ||
| /// </summary> | ||
| /// <param name="span">The source span.</param> | ||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public static int IndexOfAnyWhiteSpace(this ReadOnlySpan<char> span) => | ||
| string.SearchValuesStorage.WhiteSpaceChars.IndexOfAny(span); | ||
|
|
||
| /// <summary> | ||
| /// Reports the zero-based index of the first occurrence of <see cref="char.IsWhiteSpace(char)">any | ||
| /// non-white-space characters</see> in the current <paramref name="span"/>, or -1 if not founded. | ||
| /// </summary> | ||
| /// <param name="span">The source span.</param> | ||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public static int IndexOfAnyExceptWhiteSpace(this ReadOnlySpan<char> span) => | ||
| string.SearchValuesStorage.WhiteSpaceChars.IndexOfAnyExcept(span); | ||
|
|
||
| /// <summary> | ||
| /// Reports the zero-based index of the last occurrence of the specified <paramref name="value"/> in the current <paramref name="span"/>. | ||
| /// </summary> | ||
|
|
@@ -184,6 +206,24 @@ ref MemoryMarshal.GetReference(value), | |
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Reports the zero-based index of the last occurrence of <see cref="char.IsWhiteSpace(char)">any white-space | ||
| /// characters</see> in the current <paramref name="span"/>, or -1 if not founded. | ||
| /// </summary> | ||
| /// <param name="span">The source span.</param> | ||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public static int LastIndexOfAnyWhiteSpace(this ReadOnlySpan<char> span) => | ||
| string.SearchValuesStorage.WhiteSpaceChars.LastIndexOfAny(span); | ||
|
|
||
| /// <summary> | ||
| /// Reports the zero-based index of the last occurrence of <see cref="char.IsWhiteSpace(char)">any | ||
| /// non-white-space characters</see> in the current <paramref name="span"/>, or -1 if not founded. | ||
| /// </summary> | ||
| /// <param name="span">The source span.</param> | ||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public static int LastIndexOfAnyExceptWhiteSpace(this ReadOnlySpan<char> span) => | ||
| string.SearchValuesStorage.WhiteSpaceChars.LastIndexOfAnyExcept(span); | ||
|
|
||
| /// <summary> | ||
| /// Copies the characters from the source span into the destination, converting each character to lowercase, | ||
| /// using the casing rules of the specified culture. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.