diff options
author | Ahson Khan <ahkha@microsoft.com> | 2017-12-07 21:27:48 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-12-07 21:27:48 +0300 |
commit | d2193783e6b009295f78e122ccf228e533f3f94c (patch) | |
tree | 1a6c5ec396ecdfa599f4389cdf382c25f6624987 | |
parent | 6d57c82817cd58672af8c3b39bf2019247bc78b4 (diff) |
Implement Span LastIndexOf extension method and add tests (#25748)
* Implement Span LastIndexOf and add tests
* Add LastIndexOfSequence tests and fix implementation
* Vectorize LastIndexOf<byte> similar to IndexOf<byte>
* Add LastIndexOf performance tests
* Adding IndexOf and LastIndexOf tests for reference type (string).
* Use abbreviated version of 'default' literal
* Remove unnecessary type specifiers in generic function calls.
* Cleanup and format all files in the solution to follow coding style.
* Cleaning up leftover unused using directives and extra spaces
100 files changed, 3135 insertions, 464 deletions
diff --git a/src/Common/src/System/NotImplemented.cs b/src/Common/src/System/NotImplemented.cs index ffbec64447..fa0fe07fa7 100644 --- a/src/Common/src/System/NotImplemented.cs +++ b/src/Common/src/System/NotImplemented.cs @@ -26,6 +26,6 @@ namespace System /// Temporary NotImplementedException with no message shown to user. /// Example: Exception.ActiveIssue("https://github.com/dotnet/corefx/issues/xxxx") or Exception.ActiveIssue("TFS xxxxxx"). /// </summary> - internal static Exception ActiveIssue(string issue) => new NotImplementedException(); + internal static Exception ActiveIssue(string issue) => new NotImplementedException(); } } diff --git a/src/Common/tests/System/PerfUtils.cs b/src/Common/tests/System/PerfUtils.cs index 532edde051..f205f0bf91 100644 --- a/src/Common/tests/System/PerfUtils.cs +++ b/src/Common/tests/System/PerfUtils.cs @@ -41,7 +41,7 @@ namespace System for (int i = 0; i < str.Length; i++) { // Add path separator so folders aren't too long. - if (i%20 == 0) + if (i % 20 == 0) { str[i] = Path.DirectorySeparatorChar; } diff --git a/src/System.Memory/ref/System.Memory.cs b/src/System.Memory/ref/System.Memory.cs index ddbb5f8004..ee872fc669 100644 --- a/src/System.Memory/ref/System.Memory.cs +++ b/src/System.Memory/ref/System.Memory.cs @@ -15,7 +15,7 @@ namespace System [CLSCompliant(false)] public unsafe ReadOnlySpan(void* pointer, int length) { throw null; } public bool IsEmpty { get { throw null; } } - public T this[int index] { get { throw null; }} + public T this[int index] { get { throw null; } } public int Length { get { throw null; } } public void CopyTo(Span<T> destination) { } [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] @@ -32,8 +32,8 @@ namespace System public override int GetHashCode() { throw null; } #pragma warning restore 0809 public static bool operator ==(ReadOnlySpan<T> left, ReadOnlySpan<T> right) { throw null; } - public static implicit operator ReadOnlySpan<T> (T[] array) { throw null; } - public static implicit operator ReadOnlySpan<T> (ArraySegment<T> arraySegment) { throw null; } + public static implicit operator ReadOnlySpan<T>(T[] array) { throw null; } + public static implicit operator ReadOnlySpan<T>(ArraySegment<T> arraySegment) { throw null; } public static bool operator !=(ReadOnlySpan<T> left, ReadOnlySpan<T> right) { throw null; } public ReadOnlySpan<T> Slice(int start) { throw null; } public ReadOnlySpan<T> Slice(int start, int length) { throw null; } @@ -73,9 +73,9 @@ namespace System public override int GetHashCode() { throw null; } #pragma warning restore 0809 public static bool operator ==(Span<T> left, Span<T> right) { throw null; } - public static implicit operator Span<T> (T[] array) { throw null; } - public static implicit operator Span<T> (ArraySegment<T> arraySegment) { throw null; } - public static implicit operator ReadOnlySpan<T> (Span<T> span) { throw null; } + public static implicit operator Span<T>(T[] array) { throw null; } + public static implicit operator Span<T>(ArraySegment<T> arraySegment) { throw null; } + public static implicit operator ReadOnlySpan<T>(Span<T> span) { throw null; } public static bool operator !=(Span<T> left, Span<T> right) { throw null; } public Span<T> Slice(int start) { throw null; } public Span<T> Slice(int start, int length) { throw null; } @@ -87,7 +87,7 @@ namespace System public ref T Current { get { throw null; } } } } - + public static class MemoryExtensions { public static int IndexOf<T>(this Span<T> span, T value) where T : IEquatable<T> { throw null; } @@ -97,8 +97,11 @@ namespace System public static int IndexOfAny(this Span<byte> span, byte value0, byte value1, byte value2) { throw null; } public static int IndexOfAny(this Span<byte> span, ReadOnlySpan<byte> values) { throw null; } + public static int LastIndexOf<T>(this Span<T> span, T value) where T : IEquatable<T> { throw null; } + public static int LastIndexOf<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T> { throw null; } + public static bool SequenceEqual<T>(this Span<T> first, ReadOnlySpan<T> second) where T : IEquatable<T> { throw null; } - + public static bool StartsWith<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T> { throw null; } public static bool EndsWith<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T> { throw null; } @@ -107,7 +110,7 @@ namespace System public static Span<byte> AsBytes<T>(this Span<T> source) where T : struct { throw null; } public static Span<TTo> NonPortableCast<TFrom, TTo>(this Span<TFrom> source) where TFrom : struct where TTo : struct { throw null; } - + public static ReadOnlySpan<char> AsReadOnlySpan(this string text) { throw null; } public static ReadOnlyMemory<char> AsReadOnlyMemory(this string text) { throw null; } @@ -128,12 +131,15 @@ namespace System public static int IndexOfAny(this ReadOnlySpan<byte> span, byte value0, byte value1, byte value2) { throw null; } public static int IndexOfAny(this ReadOnlySpan<byte> span, ReadOnlySpan<byte> values) { throw null; } + public static int LastIndexOf<T>(this ReadOnlySpan<T> span, T value) where T : IEquatable<T> { throw null; } + public static int LastIndexOf<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T> { throw null; } + public static bool SequenceEqual<T>(this ReadOnlySpan<T> first, ReadOnlySpan<T> second) where T : IEquatable<T> { throw null; } public static bool StartsWith<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T> { throw null; } public static ReadOnlySpan<byte> AsBytes<T>(this ReadOnlySpan<T> source) where T : struct { throw null; } - + public static ReadOnlySpan<TTo> NonPortableCast<TFrom, TTo>(this ReadOnlySpan<TFrom> source) where TFrom : struct where TTo : struct { throw null; } public static bool TryGetString(this ReadOnlyMemory<char> readOnlyMemory, out string text, out int start, out int length) { throw null; } @@ -197,23 +203,23 @@ namespace System namespace System.Buffers { - public unsafe struct MemoryHandle : IDisposable + public unsafe struct MemoryHandle : IDisposable { [CLSCompliant(false)] - public MemoryHandle(IRetainable owner, void* pointer = null, System.Runtime.InteropServices.GCHandle handle = default(System.Runtime.InteropServices.GCHandle)) { throw null; } + public MemoryHandle(IRetainable owner, void* pointer = null, System.Runtime.InteropServices.GCHandle handle = default) { throw null; } [CLSCompliant(false)] public void* Pointer { get { throw null; } } public bool HasPointer { get { throw null; } } public void Dispose() { throw null; } } - public interface IRetainable + public interface IRetainable { bool Release(); void Retain(); } - - public abstract class OwnedMemory<T> : IDisposable, IRetainable + + public abstract class OwnedMemory<T> : IDisposable, IRetainable { public Memory<T> Memory { get { throw null; } } public abstract bool IsDisposed { get; } @@ -353,7 +359,7 @@ namespace System.Buffers public bool IsDefault => throw null; public byte Precision => throw null; public char Symbol => throw null; - public static implicit operator StandardFormat (char symbol) => throw null; + public static implicit operator StandardFormat(char symbol) => throw null; public static StandardFormat Parse(ReadOnlySpan<char> format) => throw null; public static StandardFormat Parse(string format) => throw null; public override bool Equals(object obj) => throw null; diff --git a/src/System.Memory/src/System/Buffers/Binary/ReaderLittleEndian.cs b/src/System.Memory/src/System/Buffers/Binary/ReaderLittleEndian.cs index 05c26fbbc0..17cebf1f27 100644 --- a/src/System.Memory/src/System/Buffers/Binary/ReaderLittleEndian.cs +++ b/src/System.Memory/src/System/Buffers/Binary/ReaderLittleEndian.cs @@ -94,7 +94,7 @@ namespace System.Buffers.Binary } return result; } - + /// <summary> /// Reads an Int16 out of a read-only span of bytes as little endian. /// <returns>If the span is too small to contain an Int16, return false.</returns> diff --git a/src/System.Memory/src/System/Buffers/MemoryHandle.cs b/src/System.Memory/src/System/Buffers/MemoryHandle.cs index 35d0ab6f0c..fb192d1a6b 100644 --- a/src/System.Memory/src/System/Buffers/MemoryHandle.cs +++ b/src/System.Memory/src/System/Buffers/MemoryHandle.cs @@ -63,20 +63,20 @@ namespace System.Buffers /// Frees the pinned handle and releases IRetainable. /// </summary> public void Dispose() - { - if (_handle.IsAllocated) + { + if (_handle.IsAllocated) { _handle.Free(); } - if (_retainable != null) + if (_retainable != null) { _retainable.Release(); _retainable = null; } - _pointer = null; + _pointer = null; } - + } } diff --git a/src/System.Memory/src/System/Buffers/OwnedMemory.cs b/src/System.Memory/src/System/Buffers/OwnedMemory.cs index 3daae843da..0342ed9196 100644 --- a/src/System.Memory/src/System/Buffers/OwnedMemory.cs +++ b/src/System.Memory/src/System/Buffers/OwnedMemory.cs @@ -32,9 +32,9 @@ namespace System.Buffers /// </exception> public Memory<T> Memory { - get + get { - if (IsDisposed) + if (IsDisposed) { ThrowHelper.ThrowObjectDisposedException_MemoryDisposed(nameof(OwnedMemory<T>)); } @@ -60,7 +60,7 @@ namespace System.Buffers /// </exception> public void Dispose() { - if (IsRetained) + if (IsRetained) { ThrowHelper.ThrowInvalidOperationException_OutstandingReferences(); } diff --git a/src/System.Memory/src/System/Buffers/Text/Base64Decoder.cs b/src/System.Memory/src/System/Buffers/Text/Base64Decoder.cs index 1e35373cd6..73d345a695 100644 --- a/src/System.Memory/src/System/Buffers/Text/Base64Decoder.cs +++ b/src/System.Memory/src/System/Buffers/Text/Base64Decoder.cs @@ -36,7 +36,8 @@ namespace System.Buffers.Text int sourceIndex = 0; int destIndex = 0; - if (utf8.Length == 0) goto DoneExit; + if (utf8.Length == 0) + goto DoneExit; ref sbyte decodingMap = ref s_decodingMap[0]; @@ -59,24 +60,27 @@ namespace System.Buffers.Text while (sourceIndex < maxSrcLength) { int result = Decode(ref Unsafe.Add(ref srcBytes, sourceIndex), ref decodingMap); - if (result < 0) goto InvalidExit; + if (result < 0) + goto InvalidExit; WriteThreeLowOrderBytes(ref Unsafe.Add(ref destBytes, destIndex), result); destIndex += 3; sourceIndex += 4; } - if (maxSrcLength != srcLength - skipLastChunk) goto DestinationSmallExit; + if (maxSrcLength != srcLength - skipLastChunk) + goto DestinationSmallExit; // If input is less than 4 bytes, srcLength == sourceIndex == 0 // If input is not a multiple of 4, sourceIndex == srcLength != 0 if (sourceIndex == srcLength) { - if (isFinalBlock) goto InvalidExit; + if (isFinalBlock) + goto InvalidExit; goto NeedMoreExit; } // if isFinalBlock is false, we will never reach this point - + int i0 = Unsafe.Add(ref srcBytes, srcLength - 4); int i1 = Unsafe.Add(ref srcBytes, srcLength - 3); int i2 = Unsafe.Add(ref srcBytes, srcLength - 2); @@ -100,8 +104,10 @@ namespace System.Buffers.Text i0 |= i3; i0 |= i2; - if (i0 < 0) goto InvalidExit; - if (destIndex > destLength - 3) goto DestinationSmallExit; + if (i0 < 0) + goto InvalidExit; + if (destIndex > destLength - 3) + goto DestinationSmallExit; WriteThreeLowOrderBytes(ref Unsafe.Add(ref destBytes, destIndex), i0); destIndex += 3; } @@ -113,41 +119,47 @@ namespace System.Buffers.Text i0 |= i2; - if (i0 < 0) goto InvalidExit; - if (destIndex > destLength - 2) goto DestinationSmallExit; + if (i0 < 0) + goto InvalidExit; + if (destIndex > destLength - 2) + goto DestinationSmallExit; Unsafe.Add(ref destBytes, destIndex) = (byte)(i0 >> 16); Unsafe.Add(ref destBytes, destIndex + 1) = (byte)(i0 >> 8); destIndex += 2; } else { - if (i0 < 0) goto InvalidExit; - if (destIndex > destLength - 1) goto DestinationSmallExit; + if (i0 < 0) + goto InvalidExit; + if (destIndex > destLength - 1) + goto DestinationSmallExit; Unsafe.Add(ref destBytes, destIndex) = (byte)(i0 >> 16); destIndex += 1; } sourceIndex += 4; - if (srcLength != utf8.Length) goto InvalidExit; + if (srcLength != utf8.Length) + goto InvalidExit; - DoneExit: + DoneExit: consumed = sourceIndex; written = destIndex; return OperationStatus.Done; - DestinationSmallExit: - if (srcLength != utf8.Length && isFinalBlock) goto InvalidExit; // if input is not a multiple of 4, and there is no more data, return invalid data instead + DestinationSmallExit: + if (srcLength != utf8.Length && isFinalBlock) + goto InvalidExit; // if input is not a multiple of 4, and there is no more data, return invalid data instead consumed = sourceIndex; written = destIndex; return OperationStatus.DestinationTooSmall; - NeedMoreExit: + NeedMoreExit: consumed = sourceIndex; written = destIndex; return OperationStatus.NeedMoreData; - InvalidExit: + InvalidExit: consumed = sourceIndex; written = destIndex; return OperationStatus.InvalidData; @@ -190,8 +202,10 @@ namespace System.Buffers.Text int destIndex = 0; // only decode input if it is a multiple of 4 - if (bufferLength != ((bufferLength >> 2) * 4)) goto InvalidExit; - if (bufferLength == 0) goto DoneExit; + if (bufferLength != ((bufferLength >> 2) * 4)) + goto InvalidExit; + if (bufferLength == 0) + goto DoneExit; ref byte bufferBytes = ref buffer.DangerousGetPinnableReference(); @@ -200,7 +214,8 @@ namespace System.Buffers.Text while (sourceIndex < bufferLength - 4) { int result = Decode(ref Unsafe.Add(ref bufferBytes, sourceIndex), ref decodingMap); - if (result < 0) goto InvalidExit; + if (result < 0) + goto InvalidExit; WriteThreeLowOrderBytes(ref Unsafe.Add(ref bufferBytes, destIndex), result); destIndex += 3; sourceIndex += 4; @@ -229,7 +244,8 @@ namespace System.Buffers.Text i0 |= i3; i0 |= i2; - if (i0 < 0) goto InvalidExit; + if (i0 < 0) + goto InvalidExit; WriteThreeLowOrderBytes(ref Unsafe.Add(ref bufferBytes, destIndex), i0); destIndex += 3; } @@ -241,23 +257,25 @@ namespace System.Buffers.Text i0 |= i2; - if (i0 < 0) goto InvalidExit; + if (i0 < 0) + goto InvalidExit; Unsafe.Add(ref bufferBytes, destIndex) = (byte)(i0 >> 16); Unsafe.Add(ref bufferBytes, destIndex + 1) = (byte)(i0 >> 8); destIndex += 2; } else { - if (i0 < 0) goto InvalidExit; + if (i0 < 0) + goto InvalidExit; Unsafe.Add(ref bufferBytes, destIndex) = (byte)(i0 >> 16); destIndex += 1; } - DoneExit: + DoneExit: written = destIndex; return OperationStatus.Done; - InvalidExit: + InvalidExit: written = destIndex; return OperationStatus.InvalidData; } diff --git a/src/System.Memory/src/System/Buffers/Text/Base64Encoder.cs b/src/System.Memory/src/System/Buffers/Text/Base64Encoder.cs index 5df073d68f..8dac2ca80c 100644 --- a/src/System.Memory/src/System/Buffers/Text/Base64Encoder.cs +++ b/src/System.Memory/src/System/Buffers/Text/Base64Encoder.cs @@ -58,9 +58,11 @@ namespace System.Buffers.Text sourceIndex += 3; } - if (maxSrcLength != srcLength - 2) goto DestinationSmallExit; - - if (isFinalBlock != true) goto NeedMoreDataExit; + if (maxSrcLength != srcLength - 2) + goto DestinationSmallExit; + + if (isFinalBlock != true) + goto NeedMoreDataExit; if (sourceIndex == srcLength - 1) { @@ -81,12 +83,12 @@ namespace System.Buffers.Text written = destIndex; return OperationStatus.Done; - NeedMoreDataExit: + NeedMoreDataExit: consumed = sourceIndex; written = destIndex; return OperationStatus.NeedMoreData; - DestinationSmallExit: + DestinationSmallExit: consumed = sourceIndex; written = destIndex; return OperationStatus.DestinationTooSmall; @@ -125,7 +127,8 @@ namespace System.Buffers.Text public static OperationStatus EncodeToUtf8InPlace(Span<byte> buffer, int dataLength, out int written) { int encodedLength = GetMaxEncodedToUtf8Length(dataLength); - if (buffer.Length < encodedLength) goto FalseExit; + if (buffer.Length < encodedLength) + goto FalseExit; int leftover = dataLength - dataLength / 3 * 3; // how many bytes after packs of 3 @@ -135,7 +138,7 @@ namespace System.Buffers.Text ref byte encodingMap = ref s_encodingMap[0]; ref byte bufferBytes = ref buffer.DangerousGetPinnableReference(); - + // encode last pack to avoid conditional in the main loop if (leftover != 0) { @@ -165,7 +168,7 @@ namespace System.Buffers.Text written = encodedLength; return OperationStatus.Done; - FalseExit: + FalseExit: written = 0; return OperationStatus.DestinationTooSmall; } diff --git a/src/System.Memory/src/System/Buffers/Text/Utf8Constants.cs b/src/System.Memory/src/System/Buffers/Text/Utf8Constants.cs index ff2ea8b69e..39ea35ce63 100644 --- a/src/System.Memory/src/System/Buffers/Text/Utf8Constants.cs +++ b/src/System.Memory/src/System/Buffers/Text/Utf8Constants.cs @@ -21,12 +21,12 @@ namespace System.Buffers.Text // ex. 1,234,567,890 public const int GroupSize = 3; - public static readonly byte[] s_True = { (byte)'T', (byte)'r', (byte)'u', (byte)'e' }; - public static readonly byte[] s_False = { (byte)'F', (byte)'a', (byte)'l', (byte)'s', (byte)'e' }; + public static readonly byte[] s_capitalizedTrue = { (byte)'T', (byte)'r', (byte)'u', (byte)'e' }; + public static readonly byte[] s_capitalizedFalse = { (byte)'F', (byte)'a', (byte)'l', (byte)'s', (byte)'e' }; public static readonly byte[] s_true = { (byte)'t', (byte)'r', (byte)'u', (byte)'e' }; public static readonly byte[] s_false = { (byte)'f', (byte)'a', (byte)'l', (byte)'s', (byte)'e' }; - public static readonly TimeSpan NullUtcOffset = TimeSpan.MinValue; // Utc offsets must range from -14:00 to 14:00 so this is never a valid offset. + public static readonly TimeSpan s_nullUtcOffset = TimeSpan.MinValue; // Utc offsets must range from -14:00 to 14:00 so this is never a valid offset. public const int DateTimeMaxUtcOffsetHours = 14; // The UTC offset portion of a TimeSpan or DateTime can be no more than 14 hours and no less than -14 hours. diff --git a/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/FormattingHelpers.cs b/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/FormattingHelpers.cs index c80ef2ac3e..96ac29fa39 100644 --- a/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/FormattingHelpers.cs +++ b/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/FormattingHelpers.cs @@ -98,7 +98,7 @@ namespace System.Buffers.Text left = DivMod(left, 10, out ulong num); Unsafe.Add(ref buffer, index + i) = (byte)('0' + num); } - + Debug.Assert(left == 0); } @@ -182,11 +182,11 @@ namespace System.Buffers.Text part = (uint)value; } - if (part < 10) - { + if (part < 10) + { // no-op } - else if (part < 100) + else if (part < 100) { digits += 1; } @@ -194,20 +194,20 @@ namespace System.Buffers.Text { digits += 2; } - else if (part < 10000) + else if (part < 10000) { digits += 3; } - else if (part < 100000) + else if (part < 100000) { digits += 4; } - else if (part < 1000000) + else if (part < 1000000) { digits += 5; } - else - { + else + { Debug.Assert(part < 10000000); digits += 6; } diff --git a/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Boolean.cs b/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Boolean.cs index f0fee509b4..e27c47a680 100644 --- a/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Boolean.cs +++ b/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Boolean.cs @@ -30,7 +30,7 @@ namespace System.Buffers.Text ReadOnlySpan<byte> result; if (format.IsDefault || format.Symbol == 'G') { - result = value ? Utf8Constants.s_True : Utf8Constants.s_False; + result = value ? Utf8Constants.s_capitalizedTrue : Utf8Constants.s_capitalizedFalse; } else if (format.Symbol == 'l') { diff --git a/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.G.cs b/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.G.cs index 44cc38f743..9c52817aa6 100644 --- a/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.G.cs +++ b/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.G.cs @@ -27,7 +27,7 @@ namespace System.Buffers.Text const int MinimumBytesNeeded = 19; bytesWritten = MinimumBytesNeeded; - if (offset != Utf8Constants.NullUtcOffset) + if (offset != Utf8Constants.s_nullUtcOffset) { bytesWritten += 7; // Space['+'|'-']hh:ss } @@ -57,7 +57,7 @@ namespace System.Buffers.Text FormattingHelpers.WriteDigits(value.Second, 2, ref utf8Bytes, 17); - if (offset != Utf8Constants.NullUtcOffset) + if (offset != Utf8Constants.s_nullUtcOffset) { Unsafe.Add(ref utf8Bytes, 19) = Utf8Constants.Space; diff --git a/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.O.cs b/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.O.cs index 8fccceeeed..4c5fefd372 100644 --- a/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.O.cs +++ b/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.O.cs @@ -24,7 +24,7 @@ namespace System.Buffers.Text bytesWritten = MinimumBytesNeeded; DateTimeKind kind = DateTimeKind.Local; - if (offset == Utf8Constants.NullUtcOffset) + if (offset == Utf8Constants.s_nullUtcOffset) { kind = value.Kind; if (kind == DateTimeKind.Local) diff --git a/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.cs b/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.cs index d8f66a3b63..5fb273eb66 100644 --- a/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.cs +++ b/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Date.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. - namespace System.Buffers.Text { public static partial class Utf8Formatter @@ -96,7 +95,7 @@ namespace System.Buffers.Text /// </exceptions> public static bool TryFormat(DateTimeOffset value, Span<byte> buffer, out int bytesWritten, StandardFormat format = default) { - TimeSpan offset = Utf8Constants.NullUtcOffset; + TimeSpan offset = Utf8Constants.s_nullUtcOffset; char symbol = format.Symbol; if (format.IsDefault) { @@ -157,10 +156,10 @@ namespace System.Buffers.Text return TryFormatDateTimeL(value, buffer, out bytesWritten); case 'O': - return TryFormatDateTimeO(value, Utf8Constants.NullUtcOffset, buffer, out bytesWritten); + return TryFormatDateTimeO(value, Utf8Constants.s_nullUtcOffset, buffer, out bytesWritten); case 'G': - return TryFormatDateTimeG(value, Utf8Constants.NullUtcOffset, buffer, out bytesWritten); + return TryFormatDateTimeG(value, Utf8Constants.s_nullUtcOffset, buffer, out bytesWritten); default: return ThrowHelper.TryFormatThrowFormatException(out bytesWritten); diff --git a/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Decimal.E.cs b/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Decimal.E.cs index fc422d386f..840e766d49 100644 --- a/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Decimal.E.cs +++ b/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Decimal.E.cs @@ -22,7 +22,6 @@ namespace System.Buffers.Text + 2 // 'E' or 'e' followed by '+' or '-' + NumExponentDigits; // exponent digits - if (buffer.Length < numBytesNeeded) { bytesWritten = 0; diff --git a/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Guid.cs b/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Guid.cs index 71a851c47e..59ee9f2c23 100644 --- a/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Guid.cs +++ b/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Guid.cs @@ -75,7 +75,6 @@ namespace System.Buffers.Text return ThrowHelper.TryFormatThrowFormatException(out bytesWritten); } - bytesWritten = GuidChars + (dash ? 4 : 0) + (bookEnds ? 2 : 0); if (buffer.Length < bytesWritten) { diff --git a/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Unsigned.D.cs b/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Unsigned.D.cs index f68f25f9ef..8b598934b1 100644 --- a/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Unsigned.D.cs +++ b/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.Unsigned.D.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. - namespace System.Buffers.Text { /// <summary> diff --git a/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.cs b/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.cs index 3b8a538121..a25155cab9 100644 --- a/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.cs +++ b/src/System.Memory/src/System/Buffers/Text/Utf8Formatter/Utf8Formatter.Integer.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. - namespace System.Buffers.Text { /// <summary> diff --git a/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.Default.cs b/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.Default.cs index 9d61b29214..73c21c8535 100644 --- a/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.Default.cs +++ b/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.Default.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. - namespace System.Buffers.Text { public static partial class Utf8Parser @@ -46,7 +45,6 @@ namespace System.Buffers.Text return false; } - int offsetHours; { uint digit1 = text[21] - 48u; // '0' diff --git a/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.R.cs b/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.R.cs index 7307134d00..af70ca62e5 100644 --- a/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.R.cs +++ b/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.R.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. - namespace System.Buffers.Text { public static partial class Utf8Parser diff --git a/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.cs b/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.cs index 1ebedd865b..d69ff7ce13 100644 --- a/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.cs +++ b/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Date.cs @@ -89,7 +89,7 @@ namespace System.Buffers.Text return true; } - case default(char): + case (default): case 'G': return TryParseDateTimeG(text, out value, out _, out bytesConsumed); @@ -132,7 +132,7 @@ namespace System.Buffers.Text case 'O': return TryParseDateTimeOffsetO(text, out value, out bytesConsumed, out _); - case default(char): + case (default): return TryParseDateTimeOffsetDefault(text, out value, out bytesConsumed); case 'G': diff --git a/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Decimal.cs b/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Decimal.cs index dbf3af22ad..59f74bb847 100644 --- a/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Decimal.cs +++ b/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Decimal.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. - namespace System.Buffers.Text { public static partial class Utf8Parser @@ -32,7 +31,7 @@ namespace System.Buffers.Text ParseNumberOptions options; switch (standardFormat) { - case default(char): + case (default): case 'G': case 'g': case 'E': @@ -42,7 +41,7 @@ namespace System.Buffers.Text case 'F': case 'f': - options = default(ParseNumberOptions); + options = default; break; default: diff --git a/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Float.cs b/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Float.cs index 0c2c4bda16..0b0e25e22d 100644 --- a/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Float.cs +++ b/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Float.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. - namespace System.Buffers.Text { public static partial class Utf8Parser @@ -80,7 +79,7 @@ namespace System.Buffers.Text ParseNumberOptions options; switch (standardFormat) { - case default(char): + case (default): case 'G': case 'g': case 'E': @@ -90,7 +89,7 @@ namespace System.Buffers.Text case 'F': case 'f': - options = default(ParseNumberOptions); + options = default; break; default: diff --git a/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Guid.cs b/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Guid.cs index d1a687bb85..2d38e6ec59 100644 --- a/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Guid.cs +++ b/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Guid.cs @@ -31,7 +31,7 @@ namespace System.Buffers.Text { switch (standardFormat) { - case default(char): + case (default): case 'D': return TryParseGuidCore(text, false, ' ', ' ', out value, out bytesConsumed); case 'B': @@ -228,7 +228,6 @@ namespace System.Buffers.Text return false; // 12 digits } - if (ends && text[justConsumed] != end) { value = default; diff --git a/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Signed.D.cs b/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Signed.D.cs index 73946fe2df..b5f7649181 100644 --- a/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Signed.D.cs +++ b/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Signed.D.cs @@ -80,12 +80,12 @@ namespace System.Buffers.Text goto FalseExit; } -FalseExit: + FalseExit: bytesConsumed = default; value = default; return false; -Done: + Done: bytesConsumed = index; value = (sbyte)(answer * sign); return true; @@ -181,12 +181,12 @@ Done: goto FalseExit; } -FalseExit: + FalseExit: bytesConsumed = default; value = default; return false; -Done: + Done: bytesConsumed = index; value = (short)(answer * sign); return true; @@ -324,12 +324,12 @@ Done: goto FalseExit; } -FalseExit: + FalseExit: bytesConsumed = default; value = default; return false; -Done: + Done: bytesConsumed = index; value = answer * sign; return true; diff --git a/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Signed.cs b/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Signed.cs index b8ec994f4a..914ff9e5af 100644 --- a/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Signed.cs +++ b/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Signed.cs @@ -37,7 +37,7 @@ namespace System.Buffers.Text { switch (standardFormat) { - case default(char): + case (default): case 'g': case 'G': case 'd': @@ -83,7 +83,7 @@ namespace System.Buffers.Text { switch (standardFormat) { - case default(char): + case (default): case 'g': case 'G': case 'd': @@ -129,7 +129,7 @@ namespace System.Buffers.Text { switch (standardFormat) { - case default(char): + case (default): case 'g': case 'G': case 'd': @@ -175,7 +175,7 @@ namespace System.Buffers.Text { switch (standardFormat) { - case default(char): + case (default): case 'g': case 'G': case 'd': diff --git a/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.D.cs b/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.D.cs index 3248c7556f..99aeceddd3 100644 --- a/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.D.cs +++ b/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.D.cs @@ -61,12 +61,12 @@ namespace System.Buffers.Text goto FalseExit; } -FalseExit: + FalseExit: bytesConsumed = default; value = default; return false; -Done: + Done: bytesConsumed = index; value = (byte)answer; return true; @@ -143,12 +143,12 @@ Done: goto FalseExit; } -FalseExit: + FalseExit: bytesConsumed = default; value = default; return false; -Done: + Done: bytesConsumed = index; value = (ushort)answer; return true; @@ -265,12 +265,12 @@ Done: goto FalseExit; } -FalseExit: + FalseExit: bytesConsumed = default; value = default; return false; -Done: + Done: bytesConsumed = index; value = (uint)answer; return true; diff --git a/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.N.cs b/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.N.cs index 3ce7e98e1e..0990336af3 100644 --- a/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.N.cs +++ b/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.N.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. - namespace System.Buffers.Text { // diff --git a/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.cs b/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.cs index 6158ee1288..78dfdebcd9 100644 --- a/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.cs +++ b/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.Integer.Unsigned.cs @@ -31,7 +31,7 @@ namespace System.Buffers.Text { switch (standardFormat) { - case default(char): + case (default): case 'g': case 'G': case 'd': @@ -77,7 +77,7 @@ namespace System.Buffers.Text { switch (standardFormat) { - case default(char): + case (default): case 'g': case 'G': case 'd': @@ -123,7 +123,7 @@ namespace System.Buffers.Text { switch (standardFormat) { - case default(char): + case (default): case 'g': case 'G': case 'd': @@ -169,7 +169,7 @@ namespace System.Buffers.Text { switch (standardFormat) { - case default(char): + case (default): case 'g': case 'G': case 'd': diff --git a/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.TimeSpan.LittleG.cs b/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.TimeSpan.LittleG.cs index 8a4c0be6d9..ebf885ce9f 100644 --- a/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.TimeSpan.LittleG.cs +++ b/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.TimeSpan.LittleG.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. - namespace System.Buffers.Text { public static partial class Utf8Parser diff --git a/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.TimeSpan.cs b/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.TimeSpan.cs index e8a47b87cc..e971718fbb 100644 --- a/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.TimeSpan.cs +++ b/src/System.Memory/src/System/Buffers/Text/Utf8Parser/Utf8Parser.TimeSpan.cs @@ -32,7 +32,7 @@ namespace System.Buffers.Text { switch (standardFormat) { - case default(char): + case (default): case 'c': case 't': case 'T': diff --git a/src/System.Memory/src/System/Memory.cs b/src/System.Memory/src/System/Memory.cs index d81caa2828..e998455d2a 100644 --- a/src/System.Memory/src/System/Memory.cs +++ b/src/System.Memory/src/System/Memory.cs @@ -78,7 +78,7 @@ namespace System _index = start; _length = length; } - + // Constructor for internal use only. [MethodImpl(MethodImplOptions.AggressiveInlining)] internal Memory(OwnedMemory<T> owner, int index, int length) @@ -109,7 +109,7 @@ namespace System /// Defines an implicit conversion of an array to a <see cref="Memory{T}"/> /// </summary> public static implicit operator Memory<T>(T[] array) => new Memory<T>(array); - + /// <summary> /// Defines an implicit conversion of a <see cref="ArraySegment{T}"/> to a <see cref="Memory{T}"/> /// </summary> @@ -165,7 +165,7 @@ namespace System { if ((uint)start > (uint)_length || (uint)length > (uint)(_length - start)) ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.start); - + return new Memory<T>(_object, _index + start, length); } diff --git a/src/System.Memory/src/System/MemoryExtensions.Fast.cs b/src/System.Memory/src/System/MemoryExtensions.Fast.cs index 9d5756873f..23445c6afa 100644 --- a/src/System.Memory/src/System/MemoryExtensions.Fast.cs +++ b/src/System.Memory/src/System/MemoryExtensions.Fast.cs @@ -75,7 +75,7 @@ namespace System /// Thrown if the Length property of the new Span would exceed Int32.MaxValue. /// </exception> [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Span<TTo> NonPortableCast<TFrom, TTo>(this Span<TFrom> source) + public static Span<TTo> NonPortableCast<TFrom, TTo>(this Span<TFrom> source) where TFrom : struct where TTo : struct => Span.NonPortableCast<TFrom, TTo>(source); @@ -97,7 +97,7 @@ namespace System [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ReadOnlySpan<TTo> NonPortableCast<TFrom, TTo>(this ReadOnlySpan<TFrom> source) where TFrom : struct - where TTo : struct + where TTo : struct => Span.NonPortableCast<TFrom, TTo>(source); } } diff --git a/src/System.Memory/src/System/MemoryExtensions.Portable.cs b/src/System.Memory/src/System/MemoryExtensions.Portable.cs index 3d1e6e94fb..bc6dc0c0d4 100644 --- a/src/System.Memory/src/System/MemoryExtensions.Portable.cs +++ b/src/System.Memory/src/System/MemoryExtensions.Portable.cs @@ -165,7 +165,6 @@ namespace System return new ReadOnlySpan<TTo>(Unsafe.As<Pinnable<TTo>>(source.Pinnable), source.ByteOffset, newLength); } - internal static readonly IntPtr StringAdjustment = MeasureStringAdjustment(); private static IntPtr MeasureStringAdjustment() diff --git a/src/System.Memory/src/System/MemoryExtensions.cs b/src/System.Memory/src/System/MemoryExtensions.cs index 272eed1bbd..5a3013eec2 100644 --- a/src/System.Memory/src/System/MemoryExtensions.cs +++ b/src/System.Memory/src/System/MemoryExtensions.cs @@ -20,10 +20,10 @@ namespace System public static int IndexOf<T>(this Span<T> span, T value) where T : IEquatable<T> { - if (typeof(T) == typeof(byte)) + if (typeof(T) == typeof(byte)) return SpanHelpers.IndexOf( - ref Unsafe.As<T, byte>(ref span.DangerousGetPinnableReference()), - Unsafe.As<T, byte>(ref value), + ref Unsafe.As<T, byte>(ref span.DangerousGetPinnableReference()), + Unsafe.As<T, byte>(ref value), span.Length); return SpanHelpers.IndexOf<T>(ref span.DangerousGetPinnableReference(), value, span.Length); } @@ -37,16 +37,51 @@ namespace System public static int IndexOf<T>(this Span<T> span, ReadOnlySpan<T> value) where T : IEquatable<T> { - if (typeof(T) == typeof(byte)) + if (typeof(T) == typeof(byte)) return SpanHelpers.IndexOf( - ref Unsafe.As<T, byte>(ref span.DangerousGetPinnableReference()), - span.Length, - ref Unsafe.As<T, byte>(ref value.DangerousGetPinnableReference()), + ref Unsafe.As<T, byte>(ref span.DangerousGetPinnableReference()), + span.Length, + ref Unsafe.As<T, byte>(ref value.DangerousGetPinnableReference()), value.Length); return SpanHelpers.IndexOf<T>(ref span.DangerousGetPinnableReference(), span.Length, ref value.DangerousGetPinnableReference(), value.Length); } /// <summary> + /// Searches for the specified value and returns the index of its last occurrence. If not found, returns -1. Values are compared using IEquatable{T}.Equals(T). + /// </summary> + /// <param name="span">The span to search.</param> + /// <param name="value">The value to search for.</param> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int LastIndexOf<T>(this Span<T> span, T value) + where T : IEquatable<T> + { + if (typeof(T) == typeof(byte)) + return SpanHelpers.LastIndexOf( + ref Unsafe.As<T, byte>(ref span.DangerousGetPinnableReference()), + Unsafe.As<T, byte>(ref value), + span.Length); + return SpanHelpers.LastIndexOf<T>(ref span.DangerousGetPinnableReference(), value, span.Length); + } + + /// <summary> + /// Searches for the specified sequence and returns the index of its last occurrence. If not found, returns -1. Values are compared using IEquatable{T}.Equals(T). + /// </summary> + /// <param name="span">The span to search.</param> + /// <param name="value">The sequence to search for.</param> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int LastIndexOf<T>(this Span<T> span, ReadOnlySpan<T> value) + where T : IEquatable<T> + { + if (typeof(T) == typeof(byte)) + return SpanHelpers.LastIndexOf( + ref Unsafe.As<T, byte>(ref span.DangerousGetPinnableReference()), + span.Length, + ref Unsafe.As<T, byte>(ref value.DangerousGetPinnableReference()), + value.Length); + return SpanHelpers.LastIndexOf<T>(ref span.DangerousGetPinnableReference(), span.Length, ref value.DangerousGetPinnableReference(), value.Length); + } + + /// <summary> /// Determines whether two sequences are equal by comparing the elements using IEquatable{T}.Equals(T). /// </summary> [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -72,10 +107,10 @@ namespace System public static int IndexOf<T>(this ReadOnlySpan<T> span, T value) where T : IEquatable<T> { - if (typeof(T) == typeof(byte)) + if (typeof(T) == typeof(byte)) return SpanHelpers.IndexOf( - ref Unsafe.As<T, byte>(ref span.DangerousGetPinnableReference()), - Unsafe.As<T, byte>(ref value), + ref Unsafe.As<T, byte>(ref span.DangerousGetPinnableReference()), + Unsafe.As<T, byte>(ref value), span.Length); return SpanHelpers.IndexOf<T>(ref span.DangerousGetPinnableReference(), value, span.Length); } @@ -89,16 +124,51 @@ namespace System public static int IndexOf<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) where T : IEquatable<T> { - if (typeof(T) == typeof(byte)) + if (typeof(T) == typeof(byte)) return SpanHelpers.IndexOf( - ref Unsafe.As<T, byte>(ref span.DangerousGetPinnableReference()), - span.Length, - ref Unsafe.As<T, byte>(ref value.DangerousGetPinnableReference()), + ref Unsafe.As<T, byte>(ref span.DangerousGetPinnableReference()), + span.Length, + ref Unsafe.As<T, byte>(ref value.DangerousGetPinnableReference()), value.Length); return SpanHelpers.IndexOf<T>(ref span.DangerousGetPinnableReference(), span.Length, ref value.DangerousGetPinnableReference(), value.Length); } /// <summary> + /// Searches for the specified value and returns the index of its last occurrence. If not found, returns -1. Values are compared using IEquatable{T}.Equals(T). + /// </summary> + /// <param name="span">The span to search.</param> + /// <param name="value">The value to search for.</param> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int LastIndexOf<T>(this ReadOnlySpan<T> span, T value) + where T : IEquatable<T> + { + if (typeof(T) == typeof(byte)) + return SpanHelpers.LastIndexOf( + ref Unsafe.As<T, byte>(ref span.DangerousGetPinnableReference()), + Unsafe.As<T, byte>(ref value), + span.Length); + return SpanHelpers.LastIndexOf<T>(ref span.DangerousGetPinnableReference(), value, span.Length); + } + + /// <summary> + /// Searches for the specified sequence and returns the index of its last occurrence. If not found, returns -1. Values are compared using IEquatable{T}.Equals(T). + /// </summary> + /// <param name="span">The span to search.</param> + /// <param name="value">The sequence to search for.</param> + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int LastIndexOf<T>(this ReadOnlySpan<T> span, ReadOnlySpan<T> value) + where T : IEquatable<T> + { + if (typeof(T) == typeof(byte)) + return SpanHelpers.LastIndexOf( + ref Unsafe.As<T, byte>(ref span.DangerousGetPinnableReference()), + span.Length, + ref Unsafe.As<T, byte>(ref value.DangerousGetPinnableReference()), + value.Length); + return SpanHelpers.LastIndexOf<T>(ref span.DangerousGetPinnableReference(), span.Length, ref value.DangerousGetPinnableReference(), value.Length); + } + + /// <summary> /// Searches for the first index of any of the specified values similar to calling IndexOf several times with the logical OR operator. If not found, returns -1. /// </summary> /// <param name="span">The span to search.</param> @@ -196,7 +266,7 @@ namespace System { int valueLength = value.Length; if (typeof(T) == typeof(byte)) - return valueLength <= span.Length && + return valueLength <= span.Length && SpanHelpers.SequenceEqual( ref Unsafe.As<T, byte>(ref span.DangerousGetPinnableReference()), ref Unsafe.As<T, byte>(ref value.DangerousGetPinnableReference()), @@ -213,7 +283,7 @@ namespace System { int valueLength = value.Length; if (typeof(T) == typeof(byte)) - return valueLength <= span.Length && + return valueLength <= span.Length && SpanHelpers.SequenceEqual( ref Unsafe.As<T, byte>(ref span.DangerousGetPinnableReference()), ref Unsafe.As<T, byte>(ref value.DangerousGetPinnableReference()), @@ -236,10 +306,10 @@ namespace System ref Unsafe.As<T, byte>(ref Unsafe.Add(ref span.DangerousGetPinnableReference(), spanLength - valueLength)), ref Unsafe.As<T, byte>(ref value.DangerousGetPinnableReference()), valueLength); - return valueLength <= spanLength && + return valueLength <= spanLength && SpanHelpers.SequenceEqual( - ref Unsafe.Add(ref span.DangerousGetPinnableReference(), spanLength - valueLength), - ref value.DangerousGetPinnableReference(), + ref Unsafe.Add(ref span.DangerousGetPinnableReference(), spanLength - valueLength), + ref value.DangerousGetPinnableReference(), valueLength); } @@ -261,7 +331,7 @@ namespace System return valueLength <= spanLength && SpanHelpers.SequenceEqual( ref Unsafe.Add(ref span.DangerousGetPinnableReference(), spanLength - valueLength), - ref value.DangerousGetPinnableReference(), + ref value.DangerousGetPinnableReference(), valueLength); } diff --git a/src/System.Memory/src/System/Number/Decimal.DecCalc.cs b/src/System.Memory/src/System/Number/Decimal.DecCalc.cs index e5b51799a1..7592000372 100644 --- a/src/System.Memory/src/System/Number/Decimal.DecCalc.cs +++ b/src/System.Memory/src/System/Number/Decimal.DecCalc.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. - // // This code is copied almost verbatim from the same-named file in CoreRT with mechanical changes to make it build outside of CoreLib. // diff --git a/src/System.Memory/src/System/Number/Number.FormatAndParse.cs b/src/System.Memory/src/System/Number/Number.FormatAndParse.cs index 69263e8c46..d154d401e5 100644 --- a/src/System.Memory/src/System/Number/Number.FormatAndParse.cs +++ b/src/System.Memory/src/System/Number/Number.FormatAndParse.cs @@ -455,7 +455,6 @@ namespace System val = Mul64Lossy(val, multval, ref exp); } - // round & scale down if (((int)val & (1 << 10)) != 0) { diff --git a/src/System.Memory/src/System/Number/Number.cs b/src/System.Memory/src/System/Number/Number.cs index b5bbbe35b0..a30ae75750 100644 --- a/src/System.Memory/src/System/Number/Number.cs +++ b/src/System.Memory/src/System/Number/Number.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. - // // This code is copied almost verbatim from the same-named file in CoreRT with mechanical changes to Span-ify it. // diff --git a/src/System.Memory/src/System/ReadOnlyMemory.cs b/src/System.Memory/src/System/ReadOnlyMemory.cs index 60af54a1be..6a27ecf1e2 100644 --- a/src/System.Memory/src/System/ReadOnlyMemory.cs +++ b/src/System.Memory/src/System/ReadOnlyMemory.cs @@ -95,7 +95,7 @@ namespace System /// Defines an implicit conversion of an array to a <see cref="ReadOnlyMemory{T}"/> /// </summary> public static implicit operator ReadOnlyMemory<T>(T[] array) => new ReadOnlyMemory<T>(array); - + /// <summary> /// Defines an implicit conversion of a <see cref="ArraySegment{T}"/> to a <see cref="ReadOnlyMemory{T}"/> /// </summary> @@ -303,12 +303,12 @@ namespace System /// <summary> /// Serves as the default hash function. /// </summary> - [EditorBrowsable( EditorBrowsableState.Never)] + [EditorBrowsable(EditorBrowsableState.Never)] public override int GetHashCode() { return _object != null ? CombineHashCodes(_object.GetHashCode(), _index.GetHashCode(), _length.GetHashCode()) : 0; } - + private static int CombineHashCodes(int left, int right) { return ((left << 5) + left) ^ right; diff --git a/src/System.Memory/src/System/ReadOnlySpan.cs b/src/System.Memory/src/System/ReadOnlySpan.cs index 8dae95629f..9d74559c3c 100644 --- a/src/System.Memory/src/System/ReadOnlySpan.cs +++ b/src/System.Memory/src/System/ReadOnlySpan.cs @@ -172,7 +172,6 @@ namespace System ThrowHelper.ThrowArgumentException_DestinationTooShort(); } - /// <summary> /// Copies the contents of this read-only span into destination span. If the source /// and destinations overlap, this method behaves as if the original values in diff --git a/src/System.Memory/src/System/SpanHelpers.T.cs b/src/System.Memory/src/System/SpanHelpers.T.cs index 88bb4447f8..db119a8913 100644 --- a/src/System.Memory/src/System/SpanHelpers.T.cs +++ b/src/System.Memory/src/System/SpanHelpers.T.cs @@ -23,7 +23,7 @@ namespace System int valueTailLength = valueLength - 1; int index = 0; - for (;;) + for (; ; ) { Debug.Assert(0 <= index && index <= searchSpaceLength); // Ensures no deceptive underflows in the computation of "remainingSearchSpaceLength". int remainingSearchSpaceLength = searchSpaceLength - index - valueTailLength; @@ -119,6 +119,109 @@ namespace System return (int)(byte*)(index + 7); } + public static int LastIndexOf<T>(ref T searchSpace, int searchSpaceLength, ref T value, int valueLength) + where T : IEquatable<T> + { + Debug.Assert(searchSpaceLength >= 0); + Debug.Assert(valueLength >= 0); + + if (valueLength == 0) + return 0; // A zero-length sequence is always treated as "found" at the start of the search space. + + T valueHead = value; + ref T valueTail = ref Unsafe.Add(ref value, 1); + int valueTailLength = valueLength - 1; + + int index = 0; + for (; ; ) + { + Debug.Assert(0 <= index && index <= searchSpaceLength); // Ensures no deceptive underflows in the computation of "remainingSearchSpaceLength". + int remainingSearchSpaceLength = searchSpaceLength - index - valueTailLength; + if (remainingSearchSpaceLength <= 0) + break; // The unsearched portion is now shorter than the sequence we're looking for. So it can't be there. + + // Do a quick search for the first element of "value". + int relativeIndex = LastIndexOf(ref searchSpace, valueHead, remainingSearchSpaceLength); + if (relativeIndex == -1) + break; + + // Found the first element of "value". See if the tail matches. + if (SequenceEqual(ref Unsafe.Add(ref searchSpace, relativeIndex + 1), ref valueTail, valueTailLength)) + return relativeIndex; // The tail matched. Return a successful find. + + index += remainingSearchSpaceLength - relativeIndex; + } + return -1; + } + + public static unsafe int LastIndexOf<T>(ref T searchSpace, T value, int length) + where T : IEquatable<T> + { + Debug.Assert(length >= 0); + + while (length >= 8) + { + length -= 8; + + if (value.Equals(Unsafe.Add(ref searchSpace, length + 7))) + goto Found7; + if (value.Equals(Unsafe.Add(ref searchSpace, length + 6))) + goto Found6; + if (value.Equals(Unsafe.Add(ref searchSpace, length + 5))) + goto Found5; + if (value.Equals(Unsafe.Add(ref searchSpace, length + 4))) + goto Found4; + if (value.Equals(Unsafe.Add(ref searchSpace, length + 3))) + goto Found3; + if (value.Equals(Unsafe.Add(ref searchSpace, length + 2))) + goto Found2; + if (value.Equals(Unsafe.Add(ref searchSpace, length + 1))) + goto Found1; + if (value.Equals(Unsafe.Add(ref searchSpace, length))) + goto Found; + } + + if (length >= 4) + { + length -= 4; + + if (value.Equals(Unsafe.Add(ref searchSpace, length + 3))) + goto Found3; + if (value.Equals(Unsafe.Add(ref searchSpace, length + 2))) + goto Found2; + if (value.Equals(Unsafe.Add(ref searchSpace, length + 1))) + goto Found1; + if (value.Equals(Unsafe.Add(ref searchSpace, length))) + goto Found; + } + + while (length > 0) + { + length--; + + if (value.Equals(Unsafe.Add(ref searchSpace, length))) + goto Found; + } + return -1; + + Found: // Workaround for https://github.com/dotnet/coreclr/issues/13549 + return length; + Found1: + return length + 1; + Found2: + return length + 2; + Found3: + return length + 3; + Found4: + return length + 4; + Found5: + return length + 5; + Found6: + return length + 6; + Found7: + return length + 7; + } + public static bool SequenceEqual<T>(ref T first, ref T second, int length) where T : IEquatable<T> { diff --git a/src/System.Memory/src/System/SpanHelpers.byte.cs b/src/System.Memory/src/System/SpanHelpers.byte.cs index ba0e8b990d..54a6a34a47 100644 --- a/src/System.Memory/src/System/SpanHelpers.byte.cs +++ b/src/System.Memory/src/System/SpanHelpers.byte.cs @@ -26,7 +26,7 @@ namespace System int valueTailLength = valueLength - 1; int index = 0; - for (;;) + for (; ; ) { Debug.Assert(0 <= index && index <= searchSpaceLength); // Ensures no deceptive underflows in the computation of "remainingSearchSpaceLength". int remainingSearchSpaceLength = searchSpaceLength - index - valueTailLength; @@ -182,6 +182,149 @@ namespace System return (int)(byte*)(index + 7); } + public static int LastIndexOf(ref byte searchSpace, int searchSpaceLength, ref byte value, int valueLength) + { + Debug.Assert(searchSpaceLength >= 0); + Debug.Assert(valueLength >= 0); + + if (valueLength == 0) + return 0; // A zero-length sequence is always treated as "found" at the start of the search space. + + byte valueHead = value; + ref byte valueTail = ref Unsafe.Add(ref value, 1); + int valueTailLength = valueLength - 1; + + int index = 0; + for (; ; ) + { + Debug.Assert(0 <= index && index <= searchSpaceLength); // Ensures no deceptive underflows in the computation of "remainingSearchSpaceLength". + int remainingSearchSpaceLength = searchSpaceLength - index - valueTailLength; + if (remainingSearchSpaceLength <= 0) + break; // The unsearched portion is now shorter than the sequence we're looking for. So it can't be there. + + // Do a quick search for the first element of "value". + int relativeIndex = LastIndexOf(ref searchSpace, valueHead, remainingSearchSpaceLength); + if (relativeIndex == -1) + break; + + // Found the first element of "value". See if the tail matches. + if (SequenceEqual(ref Unsafe.Add(ref searchSpace, relativeIndex + 1), ref valueTail, valueTailLength)) + return relativeIndex; // The tail matched. Return a successful find. + + index += remainingSearchSpaceLength - relativeIndex; + } + return -1; + } + + public static unsafe int LastIndexOf(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)(uint)length; // Use UIntPtr for arithmetic to avoid unnecessary 64->32->64 truncations + IntPtr nLength = (IntPtr)(uint)length; +#if !netstandard11 + if (Vector.IsHardwareAccelerated && length >= Vector<byte>.Count * 2) + { + unchecked + { + int unaligned = (int)(byte*)Unsafe.AsPointer(ref searchSpace) & (Vector<byte>.Count - 1); + nLength = (IntPtr)(((length & (Vector<byte>.Count - 1)) + unaligned) & (Vector<byte>.Count - 1)); + } + } + SequentialScan: +#endif + while ((byte*)nLength >= (byte*)8) + { + nLength -= 8; + index -= 8; + + if (uValue == Unsafe.Add(ref searchSpace, index + 7)) + goto Found7; + if (uValue == Unsafe.Add(ref searchSpace, index + 6)) + goto Found6; + if (uValue == Unsafe.Add(ref searchSpace, index + 5)) + goto Found5; + if (uValue == Unsafe.Add(ref searchSpace, index + 4)) + goto Found4; + if (uValue == Unsafe.Add(ref searchSpace, index + 3)) + goto Found3; + if (uValue == Unsafe.Add(ref searchSpace, index + 2)) + goto Found2; + if (uValue == Unsafe.Add(ref searchSpace, index + 1)) + goto Found1; + if (uValue == Unsafe.Add(ref searchSpace, index)) + goto Found; + } + + if ((byte*)nLength >= (byte*)4) + { + nLength -= 4; + index -= 4; + + if (uValue == Unsafe.Add(ref searchSpace, index + 3)) + goto Found3; + if (uValue == Unsafe.Add(ref searchSpace, index + 2)) + goto Found2; + if (uValue == Unsafe.Add(ref searchSpace, index + 1)) + goto Found1; + if (uValue == Unsafe.Add(ref searchSpace, index)) + goto Found; + } + + while ((byte*)nLength > (byte*)0) + { + nLength -= 1; + index -= 1; + + if (uValue == Unsafe.Add(ref searchSpace, index)) + goto Found; + } +#if !netstandard11 + if (Vector.IsHardwareAccelerated && ((int)(byte*)index > 0)) + { + nLength = (IntPtr)(uint)((uint)index & ~(Vector<byte>.Count - 1)); + + // Get comparison Vector + Vector<byte> vComparison = GetVector(value); + while ((byte*)nLength > (byte*)(Vector<byte>.Count - 1)) + { + var vMatches = Vector.Equals(vComparison, Unsafe.ReadUnaligned<Vector<byte>>(ref Unsafe.AddByteOffset(ref searchSpace, index - Vector<byte>.Count))); + if (Vector<byte>.Zero.Equals(vMatches)) + { + index -= Vector<byte>.Count; + nLength -= Vector<byte>.Count; + continue; + } + // Find offset of first match + return (int)(byte*)(index) - Vector<byte>.Count + LocateLastFoundByte(vMatches); + } + if ((int)(byte*)index > 0) + { + nLength = index; + goto SequentialScan; + } + } +#endif + return -1; + Found: // Workaround for https://github.com/dotnet/coreclr/issues/13549 + return (int)(byte*)index; + Found1: + return (int)(byte*)(index + 1); + Found2: + return (int)(byte*)(index + 2); + Found3: + return (int)(byte*)(index + 3); + Found4: + return (int)(byte*)(index + 4); + Found5: + return (int)(byte*)(index + 5); + Found6: + return (int)(byte*)(index + 6); + Found7: + return (int)(byte*)(index + 7); + } + public static unsafe int IndexOfAny(ref byte searchSpace, byte value0, byte value1, int length) { Debug.Assert(length >= 0); @@ -537,6 +680,29 @@ namespace System #endif #if !netstandard11 + // Vector sub-search adapted from https://github.com/aspnet/KestrelHttpServer/pull/1138 + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static int LocateLastFoundByte(Vector<byte> match) + { + var vector64 = Vector.AsVectorUInt64(match); + ulong candidate = 0; + int i = Vector<ulong>.Count - 1; + // Pattern unrolled by jit https://github.com/dotnet/coreclr/pull/8001 + for (; i >= 0; i--) + { + candidate = vector64[i]; + if (candidate != 0) + { + break; + } + } + + // Single LEA instruction with jitted const (using function result) + return i * 8 + LocateLastFoundByte(candidate); + } +#endif + +#if !netstandard11 [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int LocateFirstFoundByte(ulong match) { @@ -552,6 +718,21 @@ namespace System #if !netstandard11 [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static int LocateLastFoundByte(ulong match) + { + // Find the most significant byte that has its highest bit set + int index = 7; + while ((long)match > 0) + { + match = match << 8; + index--; + } + return index; + } +#endif + +#if !netstandard11 + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static Vector<byte> GetVector(byte vectorByte) { #if !netcoreapp diff --git a/src/System.Memory/tests/AllocationHelper.cs b/src/System.Memory/tests/AllocationHelper.cs index 69311ba0ab..3496465d49 100644 --- a/src/System.Memory/tests/AllocationHelper.cs +++ b/src/System.Memory/tests/AllocationHelper.cs @@ -11,14 +11,14 @@ namespace System.SpanTests /// </summary> static class AllocationHelper { - private static readonly Mutex MemoryLock = new Mutex(); - private static readonly TimeSpan WaitTimeout = TimeSpan.FromSeconds(120); + private static readonly Mutex s_memoryLock = new Mutex(); + private static readonly TimeSpan s_waitTimeout = TimeSpan.FromSeconds(120); public static bool TryAllocNative(IntPtr size, out IntPtr memory) { memory = IntPtr.Zero; - if (!MemoryLock.WaitOne(WaitTimeout)) + if (!s_memoryLock.WaitOne(s_waitTimeout)) return false; try @@ -28,7 +28,7 @@ namespace System.SpanTests catch (OutOfMemoryException) { memory = IntPtr.Zero; - MemoryLock.ReleaseMutex(); + s_memoryLock.ReleaseMutex(); } return memory != IntPtr.Zero; @@ -43,7 +43,7 @@ namespace System.SpanTests } finally { - MemoryLock.ReleaseMutex(); + s_memoryLock.ReleaseMutex(); } } } diff --git a/src/System.Memory/tests/Base64/Base64DecoderUnitTests.cs b/src/System.Memory/tests/Base64/Base64DecoderUnitTests.cs index 4bc0f20063..15a6733060 100644 --- a/src/System.Memory/tests/Base64/Base64DecoderUnitTests.cs +++ b/src/System.Memory/tests/Base64/Base64DecoderUnitTests.cs @@ -24,7 +24,7 @@ namespace System.Buffers.Text.Tests Base64TestHelper.InitalizeDecodableBytes(source, numBytes); Span<byte> decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)]; - Assert.Equal(OperationStatus.Done, + Assert.Equal(OperationStatus.Done, Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount)); Assert.Equal(source.Length, consumed); Assert.Equal(decodedBytes.Length, decodedByteCount); @@ -38,7 +38,7 @@ namespace System.Buffers.Text.Tests Span<byte> source = Span<byte>.Empty; Span<byte> decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)]; - Assert.Equal(OperationStatus.Done, + Assert.Equal(OperationStatus.Done, Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount)); Assert.Equal(source.Length, consumed); Assert.Equal(decodedBytes.Length, decodedByteCount); @@ -62,7 +62,7 @@ namespace System.Buffers.Text.Tests Span<byte> decodedBytes = new byte[Base64.GetMaxDecodedFromUtf8Length(source.Length)]; int expectedConsumed = source.Length / 4 * 4; // only consume closest multiple of four since isFinalBlock is false - Assert.Equal(OperationStatus.NeedMoreData, + Assert.Equal(OperationStatus.NeedMoreData, Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount, isFinalBlock: false)); Assert.Equal(expectedConsumed, consumed); Assert.Equal(decodedBytes.Length, decodedByteCount); @@ -151,7 +151,7 @@ namespace System.Buffers.Text.Tests // 123-255 byte[] invalidBytes = Base64TestHelper.InvalidBytes; Assert.Equal(byte.MaxValue + 1 - 64, invalidBytes.Length); // 192 - + for (int j = 0; j < 8; j++) { Span<byte> source = new byte[8] { 50, 50, 50, 50, 80, 80, 80, 80 }; // valid input - "2222PPPP" @@ -160,14 +160,15 @@ namespace System.Buffers.Text.Tests for (int i = 0; i < invalidBytes.Length; i++) { // Don't test padding (byte 61 i.e. '='), which is tested in DecodingInvalidBytesPadding - if (invalidBytes[i] == Base64TestHelper.s_encodingPad) continue; + if (invalidBytes[i] == Base64TestHelper.s_encodingPad) + continue; // replace one byte with an invalid input source[j] = invalidBytes[i]; Assert.Equal(OperationStatus.InvalidData, Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount)); - + if (j < 4) { Assert.Equal(0, consumed); @@ -302,7 +303,7 @@ namespace System.Buffers.Text.Tests source[11] = Base64TestHelper.s_encodingPad; Span<byte> decodedBytes = new byte[6]; - Assert.Equal(OperationStatus.DestinationTooSmall, + Assert.Equal(OperationStatus.DestinationTooSmall, Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int written)); int expectedConsumed = 8; Assert.Equal(expectedConsumed, consumed); @@ -316,7 +317,7 @@ namespace System.Buffers.Text.Tests source[11] = Base64TestHelper.s_encodingPad; Span<byte> decodedBytes = new byte[7]; - Assert.Equal(OperationStatus.DestinationTooSmall, + Assert.Equal(OperationStatus.DestinationTooSmall, Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int written)); int expectedConsumed = 8; Assert.Equal(expectedConsumed, consumed); @@ -335,10 +336,10 @@ namespace System.Buffers.Text.Tests int requiredSize = Base64.GetMaxDecodedFromUtf8Length(source.Length); Span<byte> decodedBytes = new byte[outputSize]; - Assert.Equal(OperationStatus.DestinationTooSmall, + Assert.Equal(OperationStatus.DestinationTooSmall, Base64.DecodeFromUtf8(source, decodedBytes, out int consumed, out int decodedByteCount)); int expectedConsumed = decodedBytes.Length / 3 * 4; - Assert.Equal(expectedConsumed, consumed); + Assert.Equal(expectedConsumed, consumed); Assert.Equal(decodedBytes.Length, decodedByteCount); Assert.True(Base64TestHelper.VerifyDecodingCorrectness(expectedConsumed, decodedBytes.Length, source, decodedBytes)); @@ -380,7 +381,6 @@ namespace System.Buffers.Text.Tests Assert.Throws<ArgumentOutOfRangeException>(() => Base64.GetMaxDecodedFromUtf8Length(int.MinValue)); } - [Fact] public void DecodeInPlace() { @@ -429,7 +429,7 @@ namespace System.Buffers.Text.Tests public void DecodeInPlaceInvalidBytes() { byte[] invalidBytes = Base64TestHelper.InvalidBytes; - + for (int j = 0; j < 8; j++) { for (int i = 0; i < invalidBytes.Length; i++) @@ -437,14 +437,15 @@ namespace System.Buffers.Text.Tests Span<byte> buffer = new byte[8] { 50, 50, 50, 50, 80, 80, 80, 80 }; // valid input - "2222PPPP" // Don't test padding (byte 61 i.e. '='), which is tested in DecodeInPlaceInvalidBytesPadding - if (invalidBytes[i] == Base64TestHelper.s_encodingPad) continue; + if (invalidBytes[i] == Base64TestHelper.s_encodingPad) + continue; // replace one byte with an invalid input buffer[j] = invalidBytes[i]; string sourceString = Encoding.ASCII.GetString(buffer.Slice(0, 4).ToArray()); Assert.Equal(OperationStatus.InvalidData, Base64.DecodeFromUtf8InPlace(buffer, out int bytesWritten)); - + if (j < 4) { Assert.Equal(0, bytesWritten); @@ -523,7 +524,7 @@ namespace System.Buffers.Text.Tests Span<byte> expectedBytes = Convert.FromBase64String(sourceString); Assert.True(expectedBytes.SequenceEqual(buffer.Slice(0, bytesWritten))); } - + { Span<byte> buffer = new byte[] { 50, 50, 50, 50, 80, 80, 80, 80 }; buffer[7] = Base64TestHelper.s_encodingPad; // valid input - "2222PPP=" diff --git a/src/System.Memory/tests/Base64/Base64EncoderUnitTests.cs b/src/System.Memory/tests/Base64/Base64EncoderUnitTests.cs index d2e25a497a..c3f5335106 100644 --- a/src/System.Memory/tests/Base64/Base64EncoderUnitTests.cs +++ b/src/System.Memory/tests/Base64/Base64EncoderUnitTests.cs @@ -64,7 +64,7 @@ namespace System.Buffers.Text.Tests { Span<byte> source = Span<byte>.Empty; Span<byte> encodedBytes = new byte[Base64.GetMaxEncodedToUtf8Length(source.Length)]; - + Assert.Equal(OperationStatus.Done, Base64.EncodeToUtf8(source, encodedBytes, out int consumed, out int encodedBytesCount)); Assert.Equal(source.Length, consumed); Assert.Equal(encodedBytes.Length, encodedBytesCount); @@ -79,7 +79,7 @@ namespace System.Buffers.Text.Tests // CLR default limit of 2 gigabytes (GB). try { - // 1610612734, larger than MaximumEncodeLength, requires output buffer of size 2147483648 (which is > int.MaxValue) + // 1610612734, larger than MaximumEncodeLength, requires output buffer of size 2147483648 (which is > int.MaxValue) Span<byte> source = new byte[(int.MaxValue >> 2) * 3 + 1]; Span<byte> encodedBytes = new byte[2000000000]; Assert.Equal(OperationStatus.DestinationTooSmall, Base64.EncodeToUtf8(source, encodedBytes, out int consumed, out int encodedBytesCount)); @@ -249,7 +249,7 @@ namespace System.Buffers.Text.Tests [Fact] public void EncodeInPlaceOutputTooSmall() { - byte[] testBytes = {1, 2, 3}; + byte[] testBytes = { 1, 2, 3 }; for (int numberOfBytesToTest = 1; numberOfBytesToTest <= testBytes.Length; numberOfBytesToTest++) { @@ -261,7 +261,7 @@ namespace System.Buffers.Text.Tests [Fact] public void EncodeInPlaceDataLengthTooLarge() { - byte[] testBytes = {1, 2, 3}; + byte[] testBytes = { 1, 2, 3 }; Assert.Equal(OperationStatus.DestinationTooSmall, Base64.EncodeToUtf8InPlace(testBytes, testBytes.Length + 1, out int bytesWritten)); Assert.Equal(0, bytesWritten); } diff --git a/src/System.Memory/tests/Base64/Base64TestHelper.cs b/src/System.Memory/tests/Base64/Base64TestHelper.cs index 1026a97683..1aa8271674 100644 --- a/src/System.Memory/tests/Base64/Base64TestHelper.cs +++ b/src/System.Memory/tests/Base64/Base64TestHelper.cs @@ -57,7 +57,7 @@ namespace System.Buffers.Text.Tests // Workaroudn for indices.Cast<byte>().ToArray() since it throws // InvalidCastException: Unable to cast object of type 'System.Int32' to type 'System.Byte' byte[] bytes = new byte[indices.Length]; - for(int i = 0; i < indices.Length; i++) + for (int i = 0; i < indices.Length; i++) { bytes[i] = (byte)indices[i]; } diff --git a/src/System.Memory/tests/Binary/BinaryReaderUnitTests.cs b/src/System.Memory/tests/Binary/BinaryReaderUnitTests.cs index 7bb001f314..7fc1502fbc 100644 --- a/src/System.Memory/tests/Binary/BinaryReaderUnitTests.cs +++ b/src/System.Memory/tests/Binary/BinaryReaderUnitTests.cs @@ -19,7 +19,8 @@ namespace System.Buffers.Binary.Tests ulong value = 0x8877665544332211; // [11 22 33 44 55 66 77 88] Span<byte> span; - unsafe { + unsafe + { span = new Span<byte>(&value, 8); } @@ -87,7 +88,8 @@ namespace System.Buffers.Binary.Tests ulong value = 0x8877665544332211; // [11 22 33 44 55 66 77 88] ReadOnlySpan<byte> span; - unsafe { + unsafe + { span = new ReadOnlySpan<byte>(&value, 8); } @@ -225,18 +227,18 @@ namespace System.Buffers.Binary.Tests Span<byte> spanBE = new byte[Unsafe.SizeOf<TestStruct>()]; - WriteInt16BigEndian(spanBE, testStruct.S0); - WriteInt32BigEndian(spanBE.Slice(2), testStruct.I0); - WriteInt64BigEndian(spanBE.Slice(6), testStruct.L0); - WriteUInt16BigEndian(spanBE.Slice(14), testStruct.US0); - WriteUInt32BigEndian(spanBE.Slice(16), testStruct.UI0); - WriteUInt64BigEndian(spanBE.Slice(20), testStruct.UL0); - WriteInt16BigEndian(spanBE.Slice(28), testStruct.S1); - WriteInt32BigEndian(spanBE.Slice(30), testStruct.I1); - WriteInt64BigEndian(spanBE.Slice(34), testStruct.L1); - WriteUInt16BigEndian(spanBE.Slice(42), testStruct.US1); - WriteUInt32BigEndian(spanBE.Slice(44), testStruct.UI1); - WriteUInt64BigEndian(spanBE.Slice(48), testStruct.UL1); + WriteInt16BigEndian(spanBE, s_testStruct.S0); + WriteInt32BigEndian(spanBE.Slice(2), s_testStruct.I0); + WriteInt64BigEndian(spanBE.Slice(6), s_testStruct.L0); + WriteUInt16BigEndian(spanBE.Slice(14), s_testStruct.US0); + WriteUInt32BigEndian(spanBE.Slice(16), s_testStruct.UI0); + WriteUInt64BigEndian(spanBE.Slice(20), s_testStruct.UL0); + WriteInt16BigEndian(spanBE.Slice(28), s_testStruct.S1); + WriteInt32BigEndian(spanBE.Slice(30), s_testStruct.I1); + WriteInt64BigEndian(spanBE.Slice(34), s_testStruct.L1); + WriteUInt16BigEndian(spanBE.Slice(42), s_testStruct.US1); + WriteUInt32BigEndian(spanBE.Slice(44), s_testStruct.UI1); + WriteUInt64BigEndian(spanBE.Slice(48), s_testStruct.UL1); ReadOnlySpan<byte> readOnlySpanBE = new ReadOnlySpan<byte>(spanBE.ToArray()); @@ -272,8 +274,8 @@ namespace System.Buffers.Binary.Tests UL1 = ReadUInt64BigEndian(readOnlySpanBE.Slice(48)) }; - Assert.Equal(testStruct, readStruct); - Assert.Equal(testStruct, readStructFromReadOnlySpan); + Assert.Equal(s_testStruct, readStruct); + Assert.Equal(s_testStruct, readStructFromReadOnlySpan); } [Fact] @@ -283,18 +285,18 @@ namespace System.Buffers.Binary.Tests Span<byte> spanLE = new byte[Unsafe.SizeOf<TestStruct>()]; - WriteInt16LittleEndian(spanLE, testStruct.S0); - WriteInt32LittleEndian(spanLE.Slice(2), testStruct.I0); - WriteInt64LittleEndian(spanLE.Slice(6), testStruct.L0); - WriteUInt16LittleEndian(spanLE.Slice(14), testStruct.US0); - WriteUInt32LittleEndian(spanLE.Slice(16), testStruct.UI0); - WriteUInt64LittleEndian(spanLE.Slice(20), testStruct.UL0); - WriteInt16LittleEndian(spanLE.Slice(28), testStruct.S1); - WriteInt32LittleEndian(spanLE.Slice(30), testStruct.I1); - WriteInt64LittleEndian(spanLE.Slice(34), testStruct.L1); - WriteUInt16LittleEndian(spanLE.Slice(42), testStruct.US1); - WriteUInt32LittleEndian(spanLE.Slice(44), testStruct.UI1); - WriteUInt64LittleEndian(spanLE.Slice(48), testStruct.UL1); + WriteInt16LittleEndian(spanLE, s_testStruct.S0); + WriteInt32LittleEndian(spanLE.Slice(2), s_testStruct.I0); + WriteInt64LittleEndian(spanLE.Slice(6), s_testStruct.L0); + WriteUInt16LittleEndian(spanLE.Slice(14), s_testStruct.US0); + WriteUInt32LittleEndian(spanLE.Slice(16), s_testStruct.UI0); + WriteUInt64LittleEndian(spanLE.Slice(20), s_testStruct.UL0); + WriteInt16LittleEndian(spanLE.Slice(28), s_testStruct.S1); + WriteInt32LittleEndian(spanLE.Slice(30), s_testStruct.I1); + WriteInt64LittleEndian(spanLE.Slice(34), s_testStruct.L1); + WriteUInt16LittleEndian(spanLE.Slice(42), s_testStruct.US1); + WriteUInt32LittleEndian(spanLE.Slice(44), s_testStruct.UI1); + WriteUInt64LittleEndian(spanLE.Slice(48), s_testStruct.UL1); ReadOnlySpan<byte> readOnlySpanLE = new ReadOnlySpan<byte>(spanLE.ToArray()); @@ -330,8 +332,8 @@ namespace System.Buffers.Binary.Tests UL1 = ReadUInt64LittleEndian(readOnlySpanLE.Slice(48)) }; - Assert.Equal(testStruct, readStruct); - Assert.Equal(testStruct, readStructFromReadOnlySpan); + Assert.Equal(s_testStruct, readStruct); + Assert.Equal(s_testStruct, readStructFromReadOnlySpan); } [Fact] @@ -446,7 +448,7 @@ namespace System.Buffers.Binary.Tests Assert.Equal(testExplicitStruct, readStructFieldByFieldFromReadOnlySpan); } - private static TestStruct testStruct = new TestStruct + private static TestStruct s_testStruct = new TestStruct { S0 = short.MaxValue, I0 = int.MaxValue, diff --git a/src/System.Memory/tests/Binary/BinaryWriterUnitTests.cs b/src/System.Memory/tests/Binary/BinaryWriterUnitTests.cs index 0b9a8f8768..efd6d2be2f 100644 --- a/src/System.Memory/tests/Binary/BinaryWriterUnitTests.cs +++ b/src/System.Memory/tests/Binary/BinaryWriterUnitTests.cs @@ -267,9 +267,9 @@ namespace System.Buffers.Binary.Tests uint uintValue = 1; long longValue = 1; ulong ulongValue = 1; - + Span<byte> span = new byte[1]; - + WriteMachineEndian<byte>(span, ref byteValue); byte read = ReadMachineEndian<byte>(span); Assert.Equal<byte>(byteValue, read); @@ -302,7 +302,7 @@ namespace System.Buffers.Binary.Tests TestHelpers.AssertThrows<ArgumentOutOfRangeException, byte>(span, (_span) => WriteMachineEndian<ulong>(_span, ref ulongValue)); Assert.False(TryWriteMachineEndian<ulong>(span, ref ulongValue)); - var structValue = new TestHelpers.TestValueTypeWithReference{ I = 1, S = "1" }; + var structValue = new TestHelpers.TestValueTypeWithReference { I = 1, S = "1" }; TestHelpers.AssertThrows<ArgumentException, byte>(span, (_span) => WriteMachineEndian<TestHelpers.TestValueTypeWithReference>(_span, ref structValue)); TestHelpers.AssertThrows<ArgumentException, byte>(span, (_span) => TryWriteMachineEndian<TestHelpers.TestValueTypeWithReference>(_span, ref structValue)); } diff --git a/src/System.Memory/tests/Memory/CopyTo.cs b/src/System.Memory/tests/Memory/CopyTo.cs index b5305a32bf..1cb36761e7 100644 --- a/src/System.Memory/tests/Memory/CopyTo.cs +++ b/src/System.Memory/tests/Memory/CopyTo.cs @@ -91,7 +91,7 @@ namespace System.MemoryTests int[] dst = { 99, 100 }; Memory<int> srcMemory = src; - Assert.Throws<ArgumentException>( () => srcMemory.CopyTo(dst) ); + Assert.Throws<ArgumentException>(() => srcMemory.CopyTo(dst)); int[] expected = { 99, 100 }; Assert.Equal<int>(expected, dst); // CopyTo() checks for sufficient space before doing any copying. } @@ -176,7 +176,7 @@ namespace System.MemoryTests int[] src = { 1, 2, 3 }; Memory<int> dst = new int[2] { 99, 100 }; - Assert.Throws<ArgumentException>( () => src.CopyTo(dst) ); + Assert.Throws<ArgumentException>(() => src.CopyTo(dst)); int[] expected = { 99, 100 }; Assert.Equal<int>(expected, dst.ToArray()); // CopyTo() checks for sufficient space before doing any copying. } diff --git a/src/System.Memory/tests/Memory/CustomMemoryForTest.cs b/src/System.Memory/tests/Memory/CustomMemoryForTest.cs index ae23459eac..04f6c2d30d 100644 --- a/src/System.Memory/tests/Memory/CustomMemoryForTest.cs +++ b/src/System.Memory/tests/Memory/CustomMemoryForTest.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. - using System.Buffers; using System.Runtime.InteropServices; using System.Threading; @@ -68,7 +67,7 @@ namespace System.MemoryTests } _disposed = true; - + } public override void Retain() diff --git a/src/System.Memory/tests/Memory/OwnedMemory.cs b/src/System.Memory/tests/Memory/OwnedMemory.cs index 36d3a15520..42c409fde9 100644 --- a/src/System.Memory/tests/Memory/OwnedMemory.cs +++ b/src/System.Memory/tests/Memory/OwnedMemory.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. - using System.Buffers; using Xunit; @@ -118,6 +117,6 @@ namespace System.MemoryTests Assert.True(owner.IsDisposed); } } - + } diff --git a/src/System.Memory/tests/Memory/ToArray.cs b/src/System.Memory/tests/Memory/ToArray.cs index bac27ed72d..23d70b28c5 100644 --- a/src/System.Memory/tests/Memory/ToArray.cs +++ b/src/System.Memory/tests/Memory/ToArray.cs @@ -24,7 +24,7 @@ namespace System.MemoryTests int[] a = { 91, 92, 93, 94, 95 }; var memory = new Memory<int>(a); int[] copy = memory.Slice(2).ToArray(); - + Assert.Equal<int>(new int[] { 93, 94, 95 }, copy); } diff --git a/src/System.Memory/tests/ParsersAndFormatters/Formatter/FormatterTestData.cs b/src/System.Memory/tests/ParsersAndFormatters/Formatter/FormatterTestData.cs index 99a949f451..1784553b49 100644 --- a/src/System.Memory/tests/ParsersAndFormatters/Formatter/FormatterTestData.cs +++ b/src/System.Memory/tests/ParsersAndFormatters/Formatter/FormatterTestData.cs @@ -33,10 +33,10 @@ namespace System.Buffers.Text.Tests // Take good care of this method: it affects Xunit output and makes a lot of difference in how annoying test investigations are. // - string formatString = (FormatSymbol == default) ? - "default" : - FormatSymbol + ((Precision == StandardFormat.NoPrecision) ? - string.Empty : + string formatString = (FormatSymbol == default) ? + "default" : + FormatSymbol + ((Precision == StandardFormat.NoPrecision) ? + string.Empty : Precision.ToString()); string bufferLengthString; @@ -46,7 +46,7 @@ namespace System.Buffers.Text.Tests } else if (PassedInBufferLength < ExpectedOutput.Length) { - bufferLengthString = $", Buffer Length = {PassedInBufferLength} bytes (too short)"; + bufferLengthString = $", Buffer Length = {PassedInBufferLength} bytes (too short)"; } else { diff --git a/src/System.Memory/tests/ParsersAndFormatters/Formatter/TestData.Formatter.cs b/src/System.Memory/tests/ParsersAndFormatters/Formatter/TestData.Formatter.cs index 48be503c3b..632b12908f 100644 --- a/src/System.Memory/tests/ParsersAndFormatters/Formatter/TestData.Formatter.cs +++ b/src/System.Memory/tests/ParsersAndFormatters/Formatter/TestData.Formatter.cs @@ -40,7 +40,7 @@ namespace System.Buffers.Text.Tests public static IEnumerable<object[]> UInt16FormatterTheoryData => UInt16FormatterTestData.Select(td => new object[] { td }); public static IEnumerable<object[]> Int32FormatterTheoryData => Int32FormatterTestData.Select(td => new object[] { td }); public static IEnumerable<object[]> UInt32FormatterTheoryData => UInt32FormatterTestData.Select(td => new object[] { td }); - public static IEnumerable<object[]> Int64FormatterTheoryData => Int64FormatterTestData.Select(td => new object[] { td }); + public static IEnumerable<object[]> Int64FormatterTheoryData => Int64FormatterTestData.Select(td => new object[] { td }); public static IEnumerable<object[]> UInt64FormatterTheoryData => UInt64FormatterTestData.Select(td => new object[] { td }); public static IEnumerable<object[]> DecimalFormatterTheoryData => DecimalFormatterTestData.Select(td => new object[] { td }); public static IEnumerable<object[]> DoubleFormatterTheoryData => DoubleFormatterTestData.Select(td => new object[] { td }); @@ -79,7 +79,7 @@ namespace System.Buffers.Text.Tests if (format.IsDefault) { string expectedOutput = ComputeExpectedOutput<T>(value, format.Symbol, StandardFormat.NoPrecision); - yield return new FormatterTestData<T>(value, new SupportedFormat(default(char), format.SupportsPrecision), default(byte), expectedOutput); + yield return new FormatterTestData<T>(value, new SupportedFormat(default, format.SupportsPrecision), default, expectedOutput); } if (!format.NoRepresentation) @@ -91,7 +91,7 @@ namespace System.Buffers.Text.Tests } else { - foreach (byte precision in TestData.Precisions) + foreach (byte precision in TestData.s_precisions) { string expectedOutput = ComputeExpectedOutput<T>(value, format.Symbol, precision); yield return new FormatterTestData<T>(value, format, precision, expectedOutput); diff --git a/src/System.Memory/tests/ParsersAndFormatters/Parser/ParserTestData.cs b/src/System.Memory/tests/ParsersAndFormatters/Parser/ParserTestData.cs index 6bc08df1a3..ba80a7bfce 100644 --- a/src/System.Memory/tests/ParsersAndFormatters/Parser/ParserTestData.cs +++ b/src/System.Memory/tests/ParsersAndFormatters/Parser/ParserTestData.cs @@ -29,8 +29,8 @@ namespace System.Buffers.Text.Tests // Take good care of this method: it affects Xunit output and makes a lot of difference in how annoying test investigations are. // - string formatString = (FormatSymbol == default) ? - "default" : + string formatString = (FormatSymbol == default) ? + "default" : FormatSymbol.ToString(); return $"[Parse{typeof(T).Name} '{Text}',{formatString} to {(ExpectedSuccess ? ExpectedValue.DisplayString() : "(should-not-parse)")})]"; diff --git a/src/System.Memory/tests/ParsersAndFormatters/Parser/TestData.Parser.Date.cs b/src/System.Memory/tests/ParsersAndFormatters/Parser/TestData.Parser.Date.cs index 672e7cb547..336952d20f 100644 --- a/src/System.Memory/tests/ParsersAndFormatters/Parser/TestData.Parser.Date.cs +++ b/src/System.Memory/tests/ParsersAndFormatters/Parser/TestData.Parser.Date.cs @@ -54,7 +54,7 @@ namespace System.Buffers.Text.Tests // Wrong day of week. yield return new ParserTestData<DateTimeOffset>("Thu, 13 Jan 2017 03:45:32 GMT", default, 'R', expectedSuccess: false); - foreach (ParserTestData<DateTimeOffset> bad in GenerateCorruptedDateTimeText("05/08/2017 10:30:45 +00:00", default(char))) + foreach (ParserTestData<DateTimeOffset> bad in GenerateCorruptedDateTimeText("05/08/2017 10:30:45 +00:00", default)) { yield return bad; } @@ -117,7 +117,7 @@ namespace System.Buffers.Text.Tests } catch (ArgumentOutOfRangeException) { - throw new Exception($"Failed on converting {expectedDto.DateTime} to local time. This is probably a piece of data that fails only in certain time zones. Time zone on this machine is {TimeZoneInfo.Local}"); + throw new Exception($"Failed on converting {expectedDto.DateTime} to local time. This is probably a piece of data that fails only in certain time zones. Time zone on this machine is {TimeZoneInfo.Local}"); } } else @@ -128,7 +128,7 @@ namespace System.Buffers.Text.Tests string text; if ((text = pseudoDateTime.DefaultString) != null) { - yield return new ParserTestData<DateTimeOffset>(text, expectedDto, default(char), pseudoDateTime.ExpectSuccess); + yield return new ParserTestData<DateTimeOffset>(text, expectedDto, default, pseudoDateTime.ExpectSuccess); } if ((text = pseudoDateTime.GFormatString) != null) diff --git a/src/System.Memory/tests/ParsersAndFormatters/Parser/TestData.Parser.DecimalsAndFloats.cs b/src/System.Memory/tests/ParsersAndFormatters/Parser/TestData.Parser.DecimalsAndFloats.cs index 9ac948a79b..5e7b079251 100644 --- a/src/System.Memory/tests/ParsersAndFormatters/Parser/TestData.Parser.DecimalsAndFloats.cs +++ b/src/System.Memory/tests/ParsersAndFormatters/Parser/TestData.Parser.DecimalsAndFloats.cs @@ -21,7 +21,7 @@ namespace System.Buffers.Text.Tests continue; MutableDecimal d = ftd.Value.ToMutableDecimal(); - if (d.High == 0 && d.Mid == 0 && d.Low == 0 && d.IsNegative) + if (d.High == 0 && d.Mid == 0 && d.Low == 0 && d.IsNegative) continue; // -0 is not roundtrippable foreach (ParserTestData<decimal> testData in new FormatterTestData<decimal>[] { ftd }.ToParserTheoryDataCollection()) diff --git a/src/System.Memory/tests/ParsersAndFormatters/Parser/TestData.Parser.Integer.cs b/src/System.Memory/tests/ParsersAndFormatters/Parser/TestData.Parser.Integer.cs index 900ab39389..8e12d876b3 100644 --- a/src/System.Memory/tests/ParsersAndFormatters/Parser/TestData.Parser.Integer.cs +++ b/src/System.Memory/tests/ParsersAndFormatters/Parser/TestData.Parser.Integer.cs @@ -200,7 +200,7 @@ namespace System.Buffers.Text.Tests { foreach (string integerNegativeInput in GeneralIntegerNegativeInputs) { - yield return new ParserTestData<T>(integerNegativeInput, default(T), format.Symbol, expectedSuccess: false); + yield return new ParserTestData<T>(integerNegativeInput, default, format.Symbol, expectedSuccess: false); } // The hex format always parses as an unsigned number. That violates the assumptions made by this next set of test data. @@ -223,13 +223,13 @@ namespace System.Buffers.Text.Tests { BigInteger bigValue = maxValue + offset; string text = bigValue.ToString(format.Symbol.ToString()); - yield return new ParserTestData<T>(text, default(T), format.Symbol, expectedSuccess: false); + yield return new ParserTestData<T>(text, default, format.Symbol, expectedSuccess: false); } { BigInteger bigValue = maxValue * 10; string text = bigValue.ToString(format.Symbol.ToString()); - yield return new ParserTestData<T>(text, default(T), format.Symbol, expectedSuccess: false); + yield return new ParserTestData<T>(text, default, format.Symbol, expectedSuccess: false); } if (isSigned) // No such thing as an underflow for unsigned integer parsing... @@ -249,13 +249,13 @@ namespace System.Buffers.Text.Tests { BigInteger bigValue = minValue + offset; string text = bigValue.ToString(format.Symbol.ToString()); - yield return new ParserTestData<T>(text, default(T), format.Symbol, expectedSuccess: false); + yield return new ParserTestData<T>(text, default, format.Symbol, expectedSuccess: false); } { BigInteger bigValue = minValue * 10; string text = bigValue.ToString(format.Symbol.ToString()); - yield return new ParserTestData<T>(text, default(T), format.Symbol, expectedSuccess: false); + yield return new ParserTestData<T>(text, default, format.Symbol, expectedSuccess: false); } } } diff --git a/src/System.Memory/tests/ParsersAndFormatters/Parser/TestData.Parser.TimeSpan.cs b/src/System.Memory/tests/ParsersAndFormatters/Parser/TestData.Parser.TimeSpan.cs index d884395eba..74fb809744 100644 --- a/src/System.Memory/tests/ParsersAndFormatters/Parser/TestData.Parser.TimeSpan.cs +++ b/src/System.Memory/tests/ParsersAndFormatters/Parser/TestData.Parser.TimeSpan.cs @@ -178,30 +178,30 @@ namespace System.Buffers.Text.Tests { get { - yield return "1"; - yield return "1.9999999"; - yield return "4294967295"; - yield return "1:2"; - yield return "1:2.9999999"; - yield return "1:4294967295"; + yield return "1"; + yield return "1.9999999"; + yield return "4294967295"; + yield return "1:2"; + yield return "1:2.9999999"; + yield return "1:4294967295"; yield return "1:2:3"; yield return "1.2:3"; yield return "1.2:3:4"; - yield return "1:2:3.9999999"; - yield return "1:2:3.$$$$$$$"; - yield return "1:2:4294967295"; - yield return "1:2:4294967295.9999999"; - yield return "1:2:3:4"; - yield return "1:2:3:4.9999999"; + yield return "1:2:3.9999999"; + yield return "1:2:3.$$$$$$$"; + yield return "1:2:4294967295"; + yield return "1:2:4294967295.9999999"; + yield return "1:2:3:4"; + yield return "1:2:3:4.9999999"; yield return "1:2:3:4.$$$$$$$"; - yield return "1:2:3:4294967295"; + yield return "1:2:3:4294967295"; yield return "1:2:3:4294967295.9999999"; yield return "1.2:3:4.9999999"; yield return "1.2:3:4.$$$$$$$"; yield return "1.2:3:4294967295"; yield return "1.2:3:4294967295.9999999"; - yield return "1.2:3:4:5"; - yield return "1.2:3:4:5.9999999"; + yield return "1.2:3:4:5"; + yield return "1.2:3:4:5.9999999"; yield return "1.2:3:4.9999999:"; yield return "1.2:3:4.9999999."; diff --git a/src/System.Memory/tests/ParsersAndFormatters/PseudoDateTime.cs b/src/System.Memory/tests/ParsersAndFormatters/PseudoDateTime.cs index f190ef6419..e546f3e809 100644 --- a/src/System.Memory/tests/ParsersAndFormatters/PseudoDateTime.cs +++ b/src/System.Memory/tests/ParsersAndFormatters/PseudoDateTime.cs @@ -75,7 +75,7 @@ namespace System.Buffers.Text.Tests if (OffsetNegative) offset = -offset; DateTimeOffset dto = new DateTimeOffset(year: Year, month: Month, day: Day, hour: Hour, minute: Minute, second: Second, offset: offset); - dayAbbreviation = s_DayAbbreviations[(int)(dto.DayOfWeek)]; + dayAbbreviation = s_dayAbbreviations[(int)(dto.DayOfWeek)]; } else { @@ -86,7 +86,7 @@ namespace System.Buffers.Text.Tests string monthAbbrevation; if (Month >= 1 && Month <= 12) { - monthAbbrevation = s_MonthAbbreviations[Month - 1]; + monthAbbrevation = s_monthAbbreviations[Month - 1]; } else { @@ -115,7 +115,7 @@ namespace System.Buffers.Text.Tests } } - public string OFormatStringZ => (OffsetHours != 0 || OffsetMinutes != 0)? null : OFormatStringNoOffset + "Z"; + public string OFormatStringZ => (OffsetHours != 0 || OffsetMinutes != 0) ? null : OFormatStringNoOffset + "Z"; public string OFormatStringOffset { get @@ -139,7 +139,7 @@ namespace System.Buffers.Text.Tests public int OffsetMinutes { get; } public bool ExpectSuccess { get; } - private static readonly string[] s_DayAbbreviations = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; - private static readonly string[] s_MonthAbbreviations = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; + private static readonly string[] s_dayAbbreviations = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; + private static readonly string[] s_monthAbbreviations = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; } } diff --git a/src/System.Memory/tests/ParsersAndFormatters/SupportedFormats.cs b/src/System.Memory/tests/ParsersAndFormatters/SupportedFormats.cs index c1afc44358..929e9e2867 100644 --- a/src/System.Memory/tests/ParsersAndFormatters/SupportedFormats.cs +++ b/src/System.Memory/tests/ParsersAndFormatters/SupportedFormats.cs @@ -116,7 +116,7 @@ namespace System.Buffers.Text.Tests get { // The "default" format for DateTimeOffset is weird - it's like "G" but also suffixes an offset so it doesn't exactly match any of the explicit offsets. - yield return new SupportedFormat(default(char), supportsPrecision: false) { IsDefault = true, NoRepresentation = true }; + yield return new SupportedFormat(default, supportsPrecision: false) { IsDefault = true, NoRepresentation = true }; yield return new SupportedFormat('G', supportsPrecision: false); yield return new SupportedFormat('R', supportsPrecision: false); yield return new SupportedFormat('l', supportsPrecision: false); diff --git a/src/System.Memory/tests/ParsersAndFormatters/TestData.cs b/src/System.Memory/tests/ParsersAndFormatters/TestData.cs index 7fec56e3f5..3e6751e66f 100644 --- a/src/System.Memory/tests/ParsersAndFormatters/TestData.cs +++ b/src/System.Memory/tests/ParsersAndFormatters/TestData.cs @@ -12,7 +12,7 @@ namespace System.Buffers.Text.Tests // internal static partial class TestData { - public static readonly IEnumerable<byte> Precisions = new byte[] { StandardFormat.NoPrecision, 0, 1, 3, 10, StandardFormat.MaxPrecision }; + public static readonly IEnumerable<byte> s_precisions = new byte[] { StandardFormat.NoPrecision, 0, 1, 3, 10, StandardFormat.MaxPrecision }; public static IEnumerable<object[]> IntegerTypesTheoryData => IntegerTypes.Select(t => new object[] { t }); diff --git a/src/System.Memory/tests/ParsersAndFormatters/TestUtils.cs b/src/System.Memory/tests/ParsersAndFormatters/TestUtils.cs index cbf23abd9b..f02f6fefdf 100644 --- a/src/System.Memory/tests/ParsersAndFormatters/TestUtils.cs +++ b/src/System.Memory/tests/ParsersAndFormatters/TestUtils.cs @@ -13,7 +13,7 @@ namespace System.Buffers.Text.Tests public static MutableDecimal ToMutableDecimal(this decimal d) { int[] bits = decimal.GetBits(d); - return new MutableDecimal() { High = (uint)bits[0], Low = (uint)bits[1], Mid = (uint)bits[2], Flags = (uint)bits[3] }; + return new MutableDecimal() { High = (uint)bits[0], Low = (uint)bits[1], Mid = (uint)bits[2], Flags = (uint)bits[3] }; } public static decimal ToDecimal(this MutableDecimal md) diff --git a/src/System.Memory/tests/Performance/Perf.Base64EncodeDecode.cs b/src/System.Memory/tests/Performance/Perf.Base64EncodeDecode.cs index 97c5c73a0b..201bd11942 100644 --- a/src/System.Memory/tests/Performance/Perf.Base64EncodeDecode.cs +++ b/src/System.Memory/tests/Performance/Perf.Base64EncodeDecode.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using Microsoft.Xunit.Performance; -using System.Text; using Xunit; namespace System.Buffers.Text.Tests @@ -23,8 +22,10 @@ namespace System.Buffers.Text.Tests Base64TestHelper.InitalizeBytes(source); Span<byte> destination = new byte[Base64.GetMaxEncodedToUtf8Length(numberOfBytes)]; - foreach (var iteration in Benchmark.Iterations) { - using (iteration.StartMeasurement()) { + foreach (var iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { for (int i = 0; i < Benchmark.InnerIterationCount; i++) Base64.EncodeToUtf8(source, destination, out int consumed, out int written); } @@ -46,8 +47,10 @@ namespace System.Buffers.Text.Tests Base64TestHelper.InitalizeBytes(source); Span<byte> destination = new byte[Base64.GetMaxEncodedToUtf8Length(numberOfBytes) - 1]; - foreach (var iteration in Benchmark.Iterations) { - using (iteration.StartMeasurement()) { + foreach (var iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { for (int i = 0; i < Benchmark.InnerIterationCount; i++) Base64.EncodeToUtf8(source, destination, out int consumed, out int written); } @@ -65,8 +68,10 @@ namespace System.Buffers.Text.Tests Base64TestHelper.InitalizeBytes(source.AsSpan()); var destination = new char[Base64.GetMaxEncodedToUtf8Length(numberOfBytes)]; - foreach (var iteration in Benchmark.Iterations) { - using (iteration.StartMeasurement()) { + foreach (var iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { for (int i = 0; i < Benchmark.InnerIterationCount; i++) Convert.ToBase64CharArray(source, 0, source.Length, destination, 0); } @@ -85,8 +90,10 @@ namespace System.Buffers.Text.Tests Span<byte> encoded = new byte[Base64.GetMaxEncodedToUtf8Length(numberOfBytes)]; Base64.EncodeToUtf8(source, encoded, out _, out _); - foreach (var iteration in Benchmark.Iterations) { - using (iteration.StartMeasurement()) { + foreach (var iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { for (int i = 0; i < Benchmark.InnerIterationCount; i++) Base64.DecodeFromUtf8(encoded, source, out int bytesConsumed, out int bytesWritten); } @@ -111,8 +118,10 @@ namespace System.Buffers.Text.Tests source = source.Slice(0, source.Length - 1); - foreach (var iteration in Benchmark.Iterations) { - using (iteration.StartMeasurement()) { + foreach (var iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { for (int i = 0; i < Benchmark.InnerIterationCount; i++) Base64.DecodeFromUtf8(encoded, source, out int bytesConsumed, out int bytesWritten); } @@ -130,8 +139,10 @@ namespace System.Buffers.Text.Tests Base64TestHelper.InitalizeBytes(source); ReadOnlySpan<char> encoded = Convert.ToBase64String(source.ToArray()).ToCharArray(); - foreach (var iteration in Benchmark.Iterations) { - using (iteration.StartMeasurement()) { + foreach (var iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { for (int i = 0; i < Benchmark.InnerIterationCount; i++) Convert.TryFromBase64Chars(encoded, source, out int bytesWritten); } @@ -208,7 +219,7 @@ namespace System.Buffers.Text.Tests int length = Base64.GetMaxEncodedToUtf8Length(numberOfBytes); Span<byte> encodedSpan = new byte[length]; Base64.EncodeToUtf8(source, encodedSpan, out _, out _); - + Span<byte> backupSpan = encodedSpan.ToArray(); int bytesWritten = 0; diff --git a/src/System.Memory/tests/Performance/Perf.MemorySlice.cs b/src/System.Memory/tests/Performance/Perf.MemorySlice.cs index f8f3aa2f3f..0d28fcb7f1 100644 --- a/src/System.Memory/tests/Performance/Perf.MemorySlice.cs +++ b/src/System.Memory/tests/Performance/Perf.MemorySlice.cs @@ -10,7 +10,7 @@ namespace System.Memory.Tests public class MemorySlice { private const int InnerCount = 1000; - volatile static int volatileInt = 0; + volatile static int s_volatileInt = 0; [Benchmark(InnerIterationCount = InnerCount)] [InlineData(1000)] @@ -34,7 +34,7 @@ namespace System.Memory.Tests } } } - volatileInt = localInt; + s_volatileInt = localInt; } } @@ -60,7 +60,7 @@ namespace System.Memory.Tests } } } - volatileInt = localInt; + s_volatileInt = localInt; } } @@ -87,7 +87,7 @@ namespace System.Memory.Tests } } } - volatileInt = localInt; + s_volatileInt = localInt; } } @@ -114,7 +114,7 @@ namespace System.Memory.Tests } } } - volatileInt = localInt; + s_volatileInt = localInt; } } @@ -136,7 +136,7 @@ namespace System.Memory.Tests } } - volatileInt = result.Count; + s_volatileInt = result.Count; } [Benchmark(InnerIterationCount = InnerCount)] @@ -157,7 +157,7 @@ namespace System.Memory.Tests } } - volatileInt = result.Count; + s_volatileInt = result.Count; } } } diff --git a/src/System.Memory/tests/Performance/Perf.Span.BinaryReadAndWrite.cs b/src/System.Memory/tests/Performance/Perf.Span.BinaryReadAndWrite.cs index dbcdc998fb..8c561f961d 100644 --- a/src/System.Memory/tests/Performance/Perf.Span.BinaryReadAndWrite.cs +++ b/src/System.Memory/tests/Performance/Perf.Span.BinaryReadAndWrite.cs @@ -7,7 +7,6 @@ using Xunit; using System.Net; using static System.Buffers.Binary.BinaryPrimitives; -using static System.TestHelpers; namespace System.Buffers.Binary.Tests { @@ -47,7 +46,7 @@ namespace System.Buffers.Binary.Tests } } - Assert.Equal(TestHelpers.testExplicitStruct, readStruct); + Assert.Equal(TestHelpers.s_testExplicitStruct, readStruct); } [Benchmark(InnerIterationCount = InnerCount)] @@ -82,7 +81,7 @@ namespace System.Buffers.Binary.Tests } } - Assert.Equal(TestHelpers.testExplicitStruct, readStruct); + Assert.Equal(TestHelpers.s_testExplicitStruct, readStruct); } [Benchmark(InnerIterationCount = InnerCount)] @@ -116,7 +115,7 @@ namespace System.Buffers.Binary.Tests } } - Assert.Equal(TestHelpers.testExplicitStruct, readStruct); + Assert.Equal(TestHelpers.s_testExplicitStruct, readStruct); } [Benchmark(InnerIterationCount = InnerCount)] @@ -150,7 +149,7 @@ namespace System.Buffers.Binary.Tests } } - Assert.Equal(TestHelpers.testExplicitStruct, readStruct); + Assert.Equal(TestHelpers.s_testExplicitStruct, readStruct); } [Benchmark(InnerIterationCount = InnerCount)] @@ -185,7 +184,7 @@ namespace System.Buffers.Binary.Tests } } - Assert.Equal(TestHelpers.testExplicitStruct, readStruct); + Assert.Equal(TestHelpers.s_testExplicitStruct, readStruct); } [Benchmark(InnerIterationCount = InnerCount)] @@ -235,14 +234,14 @@ namespace System.Buffers.Binary.Tests } } - Assert.Equal(TestHelpers.testExplicitStruct, readStruct); + Assert.Equal(TestHelpers.s_testExplicitStruct, readStruct); } [Benchmark(InnerIterationCount = InnerCount)] private static void MeasureReverseEndianness() { var myArray = new int[1000]; - + foreach (var iteration in Benchmark.Iterations) { using (iteration.StartMeasurement()) diff --git a/src/System.Memory/tests/Performance/Perf.Span.IndexOf.cs b/src/System.Memory/tests/Performance/Perf.Span.IndexOf.cs index 75575338a6..dd678920f4 100644 --- a/src/System.Memory/tests/Performance/Perf.Span.IndexOf.cs +++ b/src/System.Memory/tests/Performance/Perf.Span.IndexOf.cs @@ -19,7 +19,7 @@ namespace System.Memory.Tests public void SpanIndexOfChar(int size) { Span<char> charSpan = new char[size]; - charSpan[size/2] = '5'; + charSpan[size / 2] = '5'; int index = 0; foreach (BenchmarkIteration iteration in Benchmark.Iterations) @@ -32,9 +32,9 @@ namespace System.Memory.Tests } } } - Assert.Equal(size/2, index); + Assert.Equal(size / 2, index); } - + [Benchmark(InnerIterationCount = InnerCount)] [InlineData(1)] [InlineData(10)] @@ -43,7 +43,7 @@ namespace System.Memory.Tests public void SpanIndexOfCharAsBytes(int size) { Span<char> charSpan = new char[size]; - charSpan[size/2] = '5'; + charSpan[size / 2] = '5'; Span<byte> byteSpan = charSpan.AsBytes(); int index = 0; @@ -59,7 +59,7 @@ namespace System.Memory.Tests } Assert.Equal(size > 1 ? size : 0, index); } - + [Benchmark(InnerIterationCount = InnerCount)] [InlineData(1)] [InlineData(10)] @@ -67,10 +67,10 @@ namespace System.Memory.Tests [InlineData(1000)] public void StringIndexOfChar(int size) { - string str = new string('0', size/2) + "5"; + string str = new string('0', size / 2) + "5"; if (size > 1) { - str += new string('0', size/2 - 1); + str += new string('0', size / 2 - 1); } int index = 0; @@ -84,7 +84,83 @@ namespace System.Memory.Tests } } } - Assert.Equal(size/2, index); + Assert.Equal(size / 2, index); + } + + [Benchmark(InnerIterationCount = InnerCount)] + [InlineData(1)] + [InlineData(10)] + [InlineData(100)] + [InlineData(1000)] + public void SpanLastIndexOfChar(int size) + { + Span<char> charSpan = new char[size]; + charSpan[size / 2] = '5'; + + int index = 0; + foreach (BenchmarkIteration iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { + for (int i = 0; i < Benchmark.InnerIterationCount; i++) + { + index |= charSpan.LastIndexOf('5'); + } + } + } + Assert.Equal(size / 2, index); + } + + [Benchmark(InnerIterationCount = InnerCount)] + [InlineData(1)] + [InlineData(10)] + [InlineData(100)] + [InlineData(1000)] + public void SpanLastIndexOfCharAsBytes(int size) + { + Span<char> charSpan = new char[size]; + charSpan[size / 2] = '5'; + Span<byte> byteSpan = charSpan.AsBytes(); + + int index = 0; + foreach (BenchmarkIteration iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { + for (int i = 0; i < Benchmark.InnerIterationCount; i++) + { + index |= byteSpan.LastIndexOf<byte>(53); // '5' = 53 + } + } + } + Assert.Equal(size > 1 ? size : 0, index); + } + + [Benchmark(InnerIterationCount = InnerCount)] + [InlineData(1)] + [InlineData(10)] + [InlineData(100)] + [InlineData(1000)] + public void StringLastIndexOfChar(int size) + { + string str = new string('0', size / 2) + "5"; + if (size > 1) + { + str += new string('0', size / 2 - 1); + } + + int index = 0; + foreach (BenchmarkIteration iteration in Benchmark.Iterations) + { + using (iteration.StartMeasurement()) + { + for (int i = 0; i < Benchmark.InnerIterationCount; i++) + { + index |= str.LastIndexOf('5'); + } + } + } + Assert.Equal(size / 2, index); } } } diff --git a/src/System.Memory/tests/Performance/Perf.Utf8Parser.cs b/src/System.Memory/tests/Performance/Perf.Utf8Parser.cs index 7794ad752d..7d1294f70d 100644 --- a/src/System.Memory/tests/Performance/Perf.Utf8Parser.cs +++ b/src/System.Memory/tests/Performance/Perf.Utf8Parser.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for more information. using System.Text; -using System.Runtime.CompilerServices; using Microsoft.Xunit.Performance; using Xunit; diff --git a/src/System.Memory/tests/ReadOnlyMemory/CopyTo.cs b/src/System.Memory/tests/ReadOnlyMemory/CopyTo.cs index e9f2f5d65b..319840d52c 100644 --- a/src/System.Memory/tests/ReadOnlyMemory/CopyTo.cs +++ b/src/System.Memory/tests/ReadOnlyMemory/CopyTo.cs @@ -91,7 +91,7 @@ namespace System.MemoryTests int[] dst = { 99, 100 }; ReadOnlyMemory<int> srcMemory = src; - Assert.Throws<ArgumentException>( () => srcMemory.CopyTo(dst) ); + Assert.Throws<ArgumentException>(() => srcMemory.CopyTo(dst)); int[] expected = { 99, 100 }; Assert.Equal<int>(expected, dst); // CopyTo() checks for sufficient space before doing any copying. } diff --git a/src/System.Memory/tests/ReadOnlyMemory/ImplicitConversion.cs b/src/System.Memory/tests/ReadOnlyMemory/ImplicitConversion.cs index 205dfd28c3..c3cc2f902a 100644 --- a/src/System.Memory/tests/ReadOnlyMemory/ImplicitConversion.cs +++ b/src/System.Memory/tests/ReadOnlyMemory/ImplicitConversion.cs @@ -45,7 +45,7 @@ namespace System.MemoryTests long[] b = { 1, -3, 7, -15, 31 }; ArraySegment<long> segmentLong = new ArraySegment<long>(b, 1, 3); CastReadOnly<long>(segmentLong, -3, 7, -15); - + object o1 = new object(); object o2 = new object(); object o3 = new object(); @@ -61,7 +61,7 @@ namespace System.MemoryTests int[] empty = Array.Empty<int>(); ArraySegment<int> emptySegment = new ArraySegment<int>(empty); CastReadOnly<int>(emptySegment); - + int[] a = { 19, -17 }; ArraySegment<int> segmentInt = new ArraySegment<int>(a, 1, 0); CastReadOnly<int>(segmentInt); diff --git a/src/System.Memory/tests/ReadOnlySpan/CopyTo.cs b/src/System.Memory/tests/ReadOnlySpan/CopyTo.cs index a964c32808..077459be1c 100644 --- a/src/System.Memory/tests/ReadOnlySpan/CopyTo.cs +++ b/src/System.Memory/tests/ReadOnlySpan/CopyTo.cs @@ -181,8 +181,10 @@ namespace System.SpanTests } finally { - if (allocatedFirst) AllocationHelper.ReleaseNative(ref memBlockFirst); - if (allocatedSecond) AllocationHelper.ReleaseNative(ref memBlockSecond); + if (allocatedFirst) + AllocationHelper.ReleaseNative(ref memBlockFirst); + if (allocatedSecond) + AllocationHelper.ReleaseNative(ref memBlockSecond); } } } diff --git a/src/System.Memory/tests/ReadOnlySpan/CtorPointerInt.cs b/src/System.Memory/tests/ReadOnlySpan/CtorPointerInt.cs index 3cf399b055..8f2d42f6f9 100644 --- a/src/System.Memory/tests/ReadOnlySpan/CtorPointerInt.cs +++ b/src/System.Memory/tests/ReadOnlySpan/CtorPointerInt.cs @@ -17,7 +17,7 @@ namespace System.SpanTests unsafe { int[] a = { 90, 91, 92 }; - fixed (int *pa = a) + fixed (int* pa = a) { ReadOnlySpan<int> span = new ReadOnlySpan<int>(pa, 3); span.Validate(90, 91, 92); diff --git a/src/System.Memory/tests/ReadOnlySpan/IndexOf.T.cs b/src/System.Memory/tests/ReadOnlySpan/IndexOf.T.cs index 3ace67ee0e..2c80369662 100644 --- a/src/System.Memory/tests/ReadOnlySpan/IndexOf.T.cs +++ b/src/System.Memory/tests/ReadOnlySpan/IndexOf.T.cs @@ -27,7 +27,7 @@ namespace System.SpanTests a[i] = 10 * (i + 1); } ReadOnlySpan<int> span = new ReadOnlySpan<int>(a); - + for (int targetIndex = 0; targetIndex < length; targetIndex++) { int target = a[targetIndex]; @@ -116,5 +116,74 @@ namespace System.SpanTests Assert.Equal(-1, idx); } } + + [Fact] + public static void ZeroLengthIndexOf_String() + { + ReadOnlySpan<string> sp = new ReadOnlySpan<string>(Array.Empty<string>()); + int idx = sp.IndexOf("a"); + Assert.Equal(-1, idx); + } + + [Fact] + public static void TestMatchIndexOf_String() + { + for (int length = 0; length < 32; length++) + { + string[] a = new string[length]; + for (int i = 0; i < length; i++) + { + a[i] = (10 * (i + 1)).ToString(); + } + ReadOnlySpan<string> span = new ReadOnlySpan<string>(a); + + for (int targetIndex = 0; targetIndex < length; targetIndex++) + { + string target = a[targetIndex]; + int idx = span.IndexOf(target); + Assert.Equal(targetIndex, idx); + } + } + } + + [Fact] + public static void TestNoMatchIndexOf_String() + { + var rnd = new Random(42); + for (int length = 0; length <= byte.MaxValue; length++) + { + string[] a = new string[length]; + string target = (rnd.Next(0, 256)).ToString(); + for (int i = 0; i < length; i++) + { + string val = (i + 1).ToString(); + a[i] = val == target ? (target + 1) : val; + } + ReadOnlySpan<string> span = new ReadOnlySpan<string>(a); + + int idx = span.IndexOf(target); + Assert.Equal(-1, idx); + } + } + + [Fact] + public static void TestMultipleMatchIndexOf_String() + { + for (int length = 2; length < 32; length++) + { + string[] a = new string[length]; + for (int i = 0; i < length; i++) + { + a[i] = (10 * (i + 1)).ToString(); + } + + a[length - 1] = "5555"; + a[length - 2] = "5555"; + + ReadOnlySpan<string> span = new ReadOnlySpan<string>(a); + int idx = span.IndexOf("5555"); + Assert.Equal(length - 2, idx); + } + } } } diff --git a/src/System.Memory/tests/ReadOnlySpan/IndexOf.byte.cs b/src/System.Memory/tests/ReadOnlySpan/IndexOf.byte.cs index f37938f941..4f902c7fc8 100644 --- a/src/System.Memory/tests/ReadOnlySpan/IndexOf.byte.cs +++ b/src/System.Memory/tests/ReadOnlySpan/IndexOf.byte.cs @@ -28,7 +28,7 @@ namespace System.SpanTests for (int i = 0; i < length; i++) { - byte target0 = default(byte); + byte target0 = default; int idx = span.IndexOf<byte>(target0); Assert.Equal(0, idx); } @@ -215,7 +215,7 @@ namespace System.SpanTests byte[] a = new byte[length]; ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(a); - byte[] targets = { default(byte), 99 }; + byte[] targets = { default, 99 }; for (int i = 0; i < length; i++) { @@ -346,7 +346,7 @@ namespace System.SpanTests byte[] a = new byte[length]; ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(a); - byte[] targets = { default(byte), 99, 98 }; + byte[] targets = { default, 99, 98 }; for (int i = 0; i < length; i++) { @@ -486,7 +486,7 @@ namespace System.SpanTests byte[] a = new byte[length]; ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(a); - var values = new ReadOnlySpan<byte>(new byte[] { default(byte), 99, 98, 0 }); + var values = new ReadOnlySpan<byte>(new byte[] { default, 99, 98, 0 }); for (int i = 0; i < length; i++) { diff --git a/src/System.Memory/tests/ReadOnlySpan/IndexOf.char.cs b/src/System.Memory/tests/ReadOnlySpan/IndexOf.char.cs index 24ce08b73e..2e71529b10 100644 --- a/src/System.Memory/tests/ReadOnlySpan/IndexOf.char.cs +++ b/src/System.Memory/tests/ReadOnlySpan/IndexOf.char.cs @@ -27,7 +27,7 @@ namespace System.SpanTests a[i] = (char)(i + 1); } ReadOnlySpan<char> span = new ReadOnlySpan<char>(a); - + for (int targetIndex = 0; targetIndex < length; targetIndex++) { char target = a[targetIndex]; diff --git a/src/System.Memory/tests/ReadOnlySpan/IndexOfSequence.T.cs b/src/System.Memory/tests/ReadOnlySpan/IndexOfSequence.T.cs index 49a863acb2..401e7c6aec 100644 --- a/src/System.Memory/tests/ReadOnlySpan/IndexOfSequence.T.cs +++ b/src/System.Memory/tests/ReadOnlySpan/IndexOfSequence.T.cs @@ -119,5 +119,117 @@ namespace System.SpanTests int index = span.IndexOf(value); Assert.Equal(-1, index); } + + [Fact] + public static void IndexOfSequenceMatchAtStart_String() + { + ReadOnlySpan<string> span = new ReadOnlySpan<string>(new string[] { "5", "1", "77", "2", "3", "77", "77", "4", "5", "77", "77", "77", "88", "6", "6", "77", "77", "88", "9" }); + ReadOnlySpan<string> value = new ReadOnlySpan<string>(new string[] { "5", "1", "77" }); + int index = span.IndexOf(value); + Assert.Equal(0, index); + } + + [Fact] + public static void IndexOfSequenceMultipleMatch_String() + { + ReadOnlySpan<string> span = new ReadOnlySpan<string>(new string[] { "1", "2", "3", "1", "2", "3", "1", "2", "3" }); + ReadOnlySpan<string> value = new ReadOnlySpan<string>(new string[] { "2", "3" }); + int index = span.IndexOf(value); + Assert.Equal(1, index); + } + + [Fact] + public static void IndexOfSequenceRestart_String() + { + ReadOnlySpan<string> span = new ReadOnlySpan<string>(new string[] { "0", "1", "77", "2", "3", "77", "77", "4", "5", "77", "77", "77", "88", "6", "6", "77", "77", "88", "9" }); + ReadOnlySpan<string> value = new ReadOnlySpan<string>(new string[] { "77", "77", "88" }); + int index = span.IndexOf(value); + Assert.Equal(10, index); + } + + [Fact] + public static void IndexOfSequenceNoMatch_String() + { + ReadOnlySpan<string> span = new ReadOnlySpan<string>(new string[] { "0", "1", "77", "2", "3", "77", "77", "4", "5", "77", "77", "77", "88", "6", "6", "77", "77", "88", "9" }); + ReadOnlySpan<string> value = new ReadOnlySpan<string>(new string[] { "77", "77", "88", "99" }); + int index = span.IndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void IndexOfSequenceNotEvenAHeadMatch_String() + { + ReadOnlySpan<string> span = new ReadOnlySpan<string>(new string[] { "0", "1", "77", "2", "3", "77", "77", "4", "5", "77", "77", "77", "88", "6", "6", "77", "77", "88", "9" }); + ReadOnlySpan<string> value = new ReadOnlySpan<string>(new string[] { "100", "77", "88", "99" }); + int index = span.IndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void IndexOfSequenceMatchAtVeryEnd_String() + { + ReadOnlySpan<string> span = new ReadOnlySpan<string>(new string[] { "0", "1", "2", "3", "4", "5" }); + ReadOnlySpan<string> value = new ReadOnlySpan<string>(new string[] { "3", "4", "5" }); + int index = span.IndexOf(value); + Assert.Equal(3, index); + } + + [Fact] + public static void IndexOfSequenceJustPastVeryEnd_String() + { + ReadOnlySpan<string> span = new ReadOnlySpan<string>(new string[] { "0", "1", "2", "3", "4", "5" }, 0, 5); + ReadOnlySpan<string> value = new ReadOnlySpan<string>(new string[] { "3", "4", "5" }); + int index = span.IndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void IndexOfSequenceZeroLengthValue_String() + { + // A zero-length value is always "found" at the start of the span. + ReadOnlySpan<string> span = new ReadOnlySpan<string>(new string[] { "0", "1", "77", "2", "3", "77", "77", "4", "5", "77", "77", "77", "88", "6", "6", "77", "77", "88", "9" }); + ReadOnlySpan<string> value = new ReadOnlySpan<string>(Array.Empty<string>()); + int index = span.IndexOf(value); + Assert.Equal(0, index); + } + + [Fact] + public static void IndexOfSequenceZeroLengthSpan_String() + { + ReadOnlySpan<string> span = new ReadOnlySpan<string>(Array.Empty<string>()); + ReadOnlySpan<string> value = new ReadOnlySpan<string>(new string[] { "1", "2", "3" }); + int index = span.IndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void IndexOfSequenceLengthOneValue_String() + { + // A zero-length value is always "found" at the start of the span. + ReadOnlySpan<string> span = new ReadOnlySpan<string>(new string[] { "0", "1", "2", "3", "4", "5" }); + ReadOnlySpan<string> value = new ReadOnlySpan<string>(new string[] { "2" }); + int index = span.IndexOf(value); + Assert.Equal(2, index); + } + + [Fact] + public static void IndexOfSequenceLengthOneValueAtVeryEnd_String() + { + // A zero-length value is always "found" at the start of the span. + ReadOnlySpan<string> span = new ReadOnlySpan<string>(new string[] { "0", "1", "2", "3", "4", "5" }); + ReadOnlySpan<string> value = new ReadOnlySpan<string>(new string[] { "5" }); + int index = span.IndexOf(value); + Assert.Equal(5, index); + } + + [Fact] + public static void IndexOfSequenceLengthOneValueJustPasttVeryEnd_String() + { + // A zero-length value is always "found" at the start of the span. + ReadOnlySpan<string> span = new ReadOnlySpan<string>(new string[] { "0", "1", "2", "3", "4", "5" }, 0, 5); + ReadOnlySpan<string> value = new ReadOnlySpan<string>(new string[] { "5" }); + int index = span.IndexOf(value); + Assert.Equal(-1, index); + } } } diff --git a/src/System.Memory/tests/ReadOnlySpan/LastIndexOf.T.cs b/src/System.Memory/tests/ReadOnlySpan/LastIndexOf.T.cs new file mode 100644 index 0000000000..9738142626 --- /dev/null +++ b/src/System.Memory/tests/ReadOnlySpan/LastIndexOf.T.cs @@ -0,0 +1,189 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Xunit; + +namespace System.SpanTests +{ + public static partial class ReadOnlySpanTests + { + [Fact] + public static void ZeroLengthLastIndexOf() + { + ReadOnlySpan<int> sp = new ReadOnlySpan<int>(Array.Empty<int>()); + int idx = sp.LastIndexOf(0); + Assert.Equal(-1, idx); + } + + [Fact] + public static void TestMatchLastIndexOf() + { + for (int length = 0; length < 32; length++) + { + int[] a = new int[length]; + for (int i = 0; i < length; i++) + { + a[i] = 10 * (i + 1); + } + ReadOnlySpan<int> span = new ReadOnlySpan<int>(a); + + for (int targetIndex = 0; targetIndex < length; targetIndex++) + { + int target = a[targetIndex]; + int idx = span.LastIndexOf(target); + Assert.Equal(targetIndex, idx); + } + } + } + + [Fact] + public static void TestMultipleMatchLastIndexOf() + { + for (int length = 2; length < 32; length++) + { + int[] a = new int[length]; + for (int i = 0; i < length; i++) + { + a[i] = 10 * (i + 1); + } + + a[length - 1] = 5555; + a[length - 2] = 5555; + + ReadOnlySpan<int> span = new ReadOnlySpan<int>(a); + int idx = span.LastIndexOf(5555); + Assert.Equal(length - 1, idx); + } + } + + [Fact] + public static void OnNoMatchMakeSureEveryElementIsComparedLastIndexOf() + { + for (int length = 0; length < 100; length++) + { + TIntLog log = new TIntLog(); + + TInt[] a = new TInt[length]; + for (int i = 0; i < length; i++) + { + a[i] = new TInt(10 * (i + 1), log); + } + ReadOnlySpan<TInt> span = new ReadOnlySpan<TInt>(a); + int idx = span.LastIndexOf(new TInt(9999, log)); + Assert.Equal(-1, idx); + + // Since we asked for a non-existent value, make sure each element of the array was compared once. + // (Strictly speaking, it would not be illegal for IndexOf to compare an element more than once but + // that would be a non-optimal implementation and a red flag. So we'll stick with the stricter test.) + Assert.Equal(a.Length, log.Count); + foreach (TInt elem in a) + { + int numCompares = log.CountCompares(elem.Value, 9999); + Assert.True(numCompares == 1, $"Expected {numCompares} == 1 for element {elem.Value}."); + } + } + } + + [Fact] + public static void MakeSureNoChecksGoOutOfRangeLastIndexOf() + { + const int GuardValue = 77777; + const int GuardLength = 50; + + Action<int, int> checkForOutOfRangeAccess = + delegate (int x, int y) + { + if (x == GuardValue || y == GuardValue) + throw new Exception("Detected out of range access in IndexOf()"); + }; + + for (int length = 0; length < 100; length++) + { + TInt[] a = new TInt[GuardLength + length + GuardLength]; + for (int i = 0; i < a.Length; i++) + { + a[i] = new TInt(GuardValue, checkForOutOfRangeAccess); + } + + for (int i = 0; i < length; i++) + { + a[GuardLength + i] = new TInt(10 * (i + 1), checkForOutOfRangeAccess); + } + + ReadOnlySpan<TInt> span = new ReadOnlySpan<TInt>(a, GuardLength, length); + int idx = span.LastIndexOf(new TInt(9999, checkForOutOfRangeAccess)); + Assert.Equal(-1, idx); + } + } + + [Fact] + public static void ZeroLengthLastIndexOf_String() + { + ReadOnlySpan<string> sp = new ReadOnlySpan<string>(Array.Empty<string>()); + int idx = sp.LastIndexOf("a"); + Assert.Equal(-1, idx); + } + + [Fact] + public static void TestMatchLastIndexOf_String() + { + for (int length = 0; length < 32; length++) + { + string[] a = new string[length]; + for (int i = 0; i < length; i++) + { + a[i] = (10 * (i + 1)).ToString(); + } + ReadOnlySpan<string> span = new ReadOnlySpan<string>(a); + + for (int targetIndex = 0; targetIndex < length; targetIndex++) + { + string target = a[targetIndex]; + int idx = span.LastIndexOf(target); + Assert.Equal(targetIndex, idx); + } + } + } + + [Fact] + public static void TestNoMatchLastIndexOf_String() + { + var rnd = new Random(42); + for (int length = 0; length <= byte.MaxValue; length++) + { + string[] a = new string[length]; + string target = (rnd.Next(0, 256)).ToString(); + for (int i = 0; i < length; i++) + { + string val = (i + 1).ToString(); + a[i] = val == target ? (target + 1) : val; + } + ReadOnlySpan<string> span = new ReadOnlySpan<string>(a); + + int idx = span.LastIndexOf(target); + Assert.Equal(-1, idx); + } + } + + [Fact] + public static void TestMultipleMatchLastIndexOf_String() + { + for (int length = 2; length < 32; length++) + { + string[] a = new string[length]; + for (int i = 0; i < length; i++) + { + a[i] = (10 * (i + 1)).ToString(); + } + + a[length - 1] = "5555"; + a[length - 2] = "5555"; + + ReadOnlySpan<string> span = new ReadOnlySpan<string>(a); + int idx = span.LastIndexOf("5555"); + Assert.Equal(length - 1, idx); + } + } + } +} diff --git a/src/System.Memory/tests/ReadOnlySpan/LastIndexOf.byte.cs b/src/System.Memory/tests/ReadOnlySpan/LastIndexOf.byte.cs new file mode 100644 index 0000000000..37cecc6c8f --- /dev/null +++ b/src/System.Memory/tests/ReadOnlySpan/LastIndexOf.byte.cs @@ -0,0 +1,149 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Numerics; +using Xunit; + +namespace System.SpanTests +{ + public static partial class ReadOnlySpanTests + { + [Fact] + public static void ZeroLengthLastIndexOf_Byte() + { + ReadOnlySpan<byte> sp = new ReadOnlySpan<byte>(Array.Empty<byte>()); + int idx = sp.LastIndexOf<byte>(0); + Assert.Equal(-1, idx); + } + + [Fact] + public static void DefaultFilledLastIndexOf_Byte() + { + for (int length = 0; length <= byte.MaxValue; length++) + { + byte[] a = new byte[length]; + ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(a); + + for (int i = 0; i < length; i++) + { + byte target0 = default; + int idx = span.LastIndexOf(target0); + Assert.Equal(length - 1, idx); + } + } + } + + [Fact] + public static void TestMatchLastIndexOf_Byte() + { + for (int length = 0; length <= byte.MaxValue; length++) + { + byte[] a = new byte[length]; + for (int i = 0; i < length; i++) + { + a[i] = (byte)(i + 1); + } + ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(a); + + for (int targetIndex = 0; targetIndex < length; targetIndex++) + { + byte target = a[targetIndex]; + int idx = span.LastIndexOf(target); + Assert.Equal(targetIndex, idx); + } + } + } + + [Fact] + public static void TestNoMatchLastIndexOf_Byte() + { + var rnd = new Random(42); + for (int length = 0; length <= byte.MaxValue; length++) + { + byte[] a = new byte[length]; + byte target = (byte)rnd.Next(0, 256); + for (int i = 0; i < length; i++) + { + byte val = (byte)(i + 1); + a[i] = val == target ? (byte)(target + 1) : val; + } + ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(a); + + int idx = span.LastIndexOf(target); + Assert.Equal(-1, idx); + } + } + + [Fact] + public static void TestAllignmentNoMatchLastIndexOf_Byte() + { + byte[] array = new byte[4 * Vector<byte>.Count]; + for (var i = 0; i < Vector<byte>.Count; i++) + { + var span = new ReadOnlySpan<byte>(array, i, 3 * Vector<byte>.Count); + int idx = span.LastIndexOf<byte>(5); + Assert.Equal(-1, idx); + + span = new ReadOnlySpan<byte>(array, i, 3 * Vector<byte>.Count - 3); + idx = span.LastIndexOf<byte>(5); + Assert.Equal(-1, idx); + } + } + + [Fact] + public static void TestAllignmentMatchLastIndexOf_Byte() + { + byte[] array = new byte[4 * Vector<byte>.Count]; + for (int i = 0; i < array.Length; i++) + { + array[i] = 5; + } + for (var i = 0; i < Vector<byte>.Count; i++) + { + var span = new ReadOnlySpan<byte>(array, i, 3 * Vector<byte>.Count); + int idx = span.LastIndexOf<byte>(5); + Assert.Equal(span.Length - 1, idx); + + span = new ReadOnlySpan<byte>(array, i, 3 * Vector<byte>.Count - 3); + idx = span.LastIndexOf<byte>(5); + Assert.Equal(span.Length - 1, idx); + } + } + + [Fact] + public static void TestMultipleMatchLastIndexOf_Byte() + { + for (int length = 2; length <= byte.MaxValue; length++) + { + byte[] a = new byte[length]; + for (int i = 0; i < length; i++) + { + byte val = (byte)(i + 1); + a[i] = val == 200 ? (byte)201 : val; + } + + a[length - 1] = 200; + a[length - 2] = 200; + + ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(a); + int idx = span.LastIndexOf<byte>(200); + Assert.Equal(length - 1, idx); + } + } + + [Fact] + public static void MakeSureNoChecksGoOutOfRangeLastIndexOf_Byte() + { + for (int length = 0; length <= byte.MaxValue; length++) + { + byte[] a = new byte[length + 2]; + a[0] = 99; + a[length + 1] = 99; + ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(a, 1, length); + int index = span.LastIndexOf<byte>(99); + Assert.Equal(-1, index); + } + } + } +} diff --git a/src/System.Memory/tests/ReadOnlySpan/LastIndexOf.char.cs b/src/System.Memory/tests/ReadOnlySpan/LastIndexOf.char.cs new file mode 100644 index 0000000000..9a60ea90c9 --- /dev/null +++ b/src/System.Memory/tests/ReadOnlySpan/LastIndexOf.char.cs @@ -0,0 +1,74 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Xunit; + +namespace System.SpanTests +{ + public static partial class ReadOnlySpanTests + { + [Fact] + public static void ZeroLengthLastIndexOf_Char() + { + ReadOnlySpan<char> sp = new ReadOnlySpan<char>(Array.Empty<char>()); + int idx = sp.LastIndexOf((char)0); + Assert.Equal(-1, idx); + } + + [Fact] + public static void TestMatchLastIndexOf_Char() + { + for (int length = 0; length < 32; length++) + { + char[] a = new char[length]; + for (int i = 0; i < length; i++) + { + a[i] = (char)(i + 1); + } + ReadOnlySpan<char> span = new ReadOnlySpan<char>(a); + + for (int targetIndex = 0; targetIndex < length; targetIndex++) + { + char target = a[targetIndex]; + int idx = span.LastIndexOf(target); + Assert.Equal(targetIndex, idx); + } + } + } + + [Fact] + public static void TestMultipleMatchLastIndexOf_Char() + { + for (int length = 2; length < 32; length++) + { + char[] a = new char[length]; + for (int i = 0; i < length; i++) + { + a[i] = (char)(i + 1); + } + + a[length - 1] = (char)200; + a[length - 2] = (char)200; + + ReadOnlySpan<char> span = new ReadOnlySpan<char>(a); + int idx = span.LastIndexOf((char)200); + Assert.Equal(length - 1, idx); + } + } + + [Fact] + public static void MakeSureNoChecksGoOutOfRangeLastIndexOf_Char() + { + for (int length = 0; length < 100; length++) + { + char[] a = new char[length + 2]; + a[0] = '9'; + a[length + 1] = '9'; + ReadOnlySpan<char> span = new ReadOnlySpan<char>(a, 1, length); + int index = span.LastIndexOf('9'); + Assert.Equal(-1, index); + } + } + } +} diff --git a/src/System.Memory/tests/ReadOnlySpan/LastIndexOfSequence.T.cs b/src/System.Memory/tests/ReadOnlySpan/LastIndexOfSequence.T.cs new file mode 100644 index 0000000000..2dde13b322 --- /dev/null +++ b/src/System.Memory/tests/ReadOnlySpan/LastIndexOfSequence.T.cs @@ -0,0 +1,245 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Xunit; + +namespace System.SpanTests +{ + public static partial class ReadOnlySpanTests + { + [Fact] + public static void LastIndexOfSequenceMatchAtStart() + { + ReadOnlySpan<int> span = new ReadOnlySpan<int>(new int[] { 5, 1, 77, 2, 3, 77, 77, 4, 5, 77, 77, 77, 88, 6, 6, 77, 77, 88, 9 }); + ReadOnlySpan<int> value = new ReadOnlySpan<int>(new int[] { 5, 1, 77 }); + int index = span.LastIndexOf(value); + Assert.Equal(0, index); + } + + [Fact] + public static void LastIndexOfSequenceMultipleMatch() + { + ReadOnlySpan<int> span = new ReadOnlySpan<int>(new int[] { 1, 2, 3, 1, 2, 3, 1, 2, 3, 1 }); + ReadOnlySpan<int> value = new ReadOnlySpan<int>(new int[] { 2, 3 }); + int index = span.LastIndexOf(value); + Assert.Equal(7, index); + } + + [Fact] + public static void LastIndexOfSequenceRestart() + { + ReadOnlySpan<int> span = new ReadOnlySpan<int>(new int[] { 0, 1, 77, 2, 3, 77, 77, 4, 5, 77, 77, 77, 88, 6, 6, 77, 77, 8, 9, 77, 0, 1 }); + ReadOnlySpan<int> value = new ReadOnlySpan<int>(new int[] { 77, 77, 88 }); + int index = span.LastIndexOf(value); + Assert.Equal(10, index); + } + + [Fact] + public static void LastIndexOfSequenceNoMatch() + { + ReadOnlySpan<int> span = new ReadOnlySpan<int>(new int[] { 0, 1, 77, 2, 3, 77, 77, 4, 5, 77, 77, 77, 88, 6, 6, 77, 77, 88, 9 }); + ReadOnlySpan<int> value = new ReadOnlySpan<int>(new int[] { 77, 77, 88, 99 }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceNotEvenAHeadMatch() + { + ReadOnlySpan<int> span = new ReadOnlySpan<int>(new int[] { 0, 1, 77, 2, 3, 77, 77, 4, 5, 77, 77, 77, 88, 6, 6, 77, 77, 88, 9 }); + ReadOnlySpan<int> value = new ReadOnlySpan<int>(new int[] { 100, 77, 88, 99 }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceMatchAtVeryEnd() + { + ReadOnlySpan<int> span = new ReadOnlySpan<int>(new int[] { 0, 1, 2, 3, 4, 5 }); + ReadOnlySpan<int> value = new ReadOnlySpan<int>(new int[] { 3, 4, 5 }); + int index = span.LastIndexOf(value); + Assert.Equal(3, index); + } + + [Fact] + public static void LastIndexOfSequenceJustPastVeryEnd() + { + ReadOnlySpan<int> span = new ReadOnlySpan<int>(new int[] { 0, 1, 2, 3, 4, 5 }, 0, 5); + ReadOnlySpan<int> value = new ReadOnlySpan<int>(new int[] { 3, 4, 5 }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceZeroLengthValue() + { + // A zero-length value is always "found" at the start of the span. + ReadOnlySpan<int> span = new ReadOnlySpan<int>(new int[] { 0, 1, 77, 2, 3, 77, 77, 4, 5, 77, 77, 77, 88, 6, 6, 77, 77, 88, 9 }); + ReadOnlySpan<int> value = new ReadOnlySpan<int>(Array.Empty<int>()); + int index = span.LastIndexOf(value); + Assert.Equal(0, index); + } + + [Fact] + public static void LastIndexOfSequenceZeroLengthSpan() + { + ReadOnlySpan<int> span = new ReadOnlySpan<int>(Array.Empty<int>()); + ReadOnlySpan<int> value = new ReadOnlySpan<int>(new int[] { 1, 2, 3 }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValue() + { + // A zero-length value is always "found" at the start of the span. + ReadOnlySpan<int> span = new ReadOnlySpan<int>(new int[] { 0, 1, 2, 3, 4, 5 }); + ReadOnlySpan<int> value = new ReadOnlySpan<int>(new int[] { 2 }); + int index = span.LastIndexOf(value); + Assert.Equal(2, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValueAtVeryEnd() + { + // A zero-length value is always "found" at the start of the span. + ReadOnlySpan<int> span = new ReadOnlySpan<int>(new int[] { 0, 1, 2, 3, 4, 5 }); + ReadOnlySpan<int> value = new ReadOnlySpan<int>(new int[] { 5 }); + int index = span.LastIndexOf(value); + Assert.Equal(5, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValueMultipleTimes() + { + // A zero-length value is always "found" at the start of the span. + ReadOnlySpan<int> span = new ReadOnlySpan<int>(new int[] { 0, 1, 5, 3, 4, 5 }); + ReadOnlySpan<int> value = new ReadOnlySpan<int>(new int[] { 5 }); + int index = span.LastIndexOf(value); + Assert.Equal(5, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValueJustPasttVeryEnd() + { + // A zero-length value is always "found" at the start of the span. + ReadOnlySpan<int> span = new ReadOnlySpan<int>(new int[] { 0, 1, 2, 3, 4, 5 }, 0, 5); + ReadOnlySpan<int> value = new ReadOnlySpan<int>(new int[] { 5 }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceMatchAtStart_String() + { + ReadOnlySpan<string> span = new ReadOnlySpan<string>(new string[] { "5", "1", "77", "2", "3", "77", "77", "4", "5", "77", "77", "77", "88", "6", "6", "77", "77", "88", "9" }); + ReadOnlySpan<string> value = new ReadOnlySpan<string>(new string[] { "5", "1", "77" }); + int index = span.LastIndexOf(value); + Assert.Equal(0, index); + } + + [Fact] + public static void LastIndexOfSequenceMultipleMatch_String() + { + ReadOnlySpan<string> span = new ReadOnlySpan<string>(new string[] { "1", "2", "3", "1", "2", "3", "1", "2", "3" }); + ReadOnlySpan<string> value = new ReadOnlySpan<string>(new string[] { "2", "3" }); + int index = span.LastIndexOf(value); + Assert.Equal(7, index); + } + + [Fact] + public static void LastIndexOfSequenceRestart_String() + { + ReadOnlySpan<string> span = new ReadOnlySpan<string>(new string[] { "0", "1", "77", "2", "3", "77", "77", "4", "5", "77", "77", "77", "88", "6", "6", "77", "77", "8", "9", "77", "0", "1" }); + ReadOnlySpan<string> value = new ReadOnlySpan<string>(new string[] { "77", "77", "88" }); + int index = span.LastIndexOf(value); + Assert.Equal(10, index); + } + + [Fact] + public static void LastIndexOfSequenceNoMatch_String() + { + ReadOnlySpan<string> span = new ReadOnlySpan<string>(new string[] { "0", "1", "77", "2", "3", "77", "77", "4", "5", "77", "77", "77", "88", "6", "6", "77", "77", "88", "9" }); + ReadOnlySpan<string> value = new ReadOnlySpan<string>(new string[] { "77", "77", "88", "99" }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceNotEvenAHeadMatch_String() + { + ReadOnlySpan<string> span = new ReadOnlySpan<string>(new string[] { "0", "1", "77", "2", "3", "77", "77", "4", "5", "77", "77", "77", "88", "6", "6", "77", "77", "88", "9" }); + ReadOnlySpan<string> value = new ReadOnlySpan<string>(new string[] { "100", "77", "88", "99" }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceMatchAtVeryEnd_String() + { + ReadOnlySpan<string> span = new ReadOnlySpan<string>(new string[] { "0", "1", "2", "3", "4", "5" }); + ReadOnlySpan<string> value = new ReadOnlySpan<string>(new string[] { "3", "4", "5" }); + int index = span.LastIndexOf(value); + Assert.Equal(3, index); + } + + [Fact] + public static void LastIndexOfSequenceJustPastVeryEnd_String() + { + ReadOnlySpan<string> span = new ReadOnlySpan<string>(new string[] { "0", "1", "2", "3", "4", "5" }, 0, 5); + ReadOnlySpan<string> value = new ReadOnlySpan<string>(new string[] { "3", "4", "5" }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceZeroLengthValue_String() + { + // A zero-length value is always "found" at the start of the span. + ReadOnlySpan<string> span = new ReadOnlySpan<string>(new string[] { "0", "1", "77", "2", "3", "77", "77", "4", "5", "77", "77", "77", "88", "6", "6", "77", "77", "88", "9" }); + ReadOnlySpan<string> value = new ReadOnlySpan<string>(Array.Empty<string>()); + int index = span.LastIndexOf(value); + Assert.Equal(0, index); + } + + [Fact] + public static void LastIndexOfSequenceZeroLengthSpan_String() + { + ReadOnlySpan<string> span = new ReadOnlySpan<string>(Array.Empty<string>()); + ReadOnlySpan<string> value = new ReadOnlySpan<string>(new string[] { "1", "2", "3" }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValue_String() + { + // A zero-length value is always "found" at the start of the span. + ReadOnlySpan<string> span = new ReadOnlySpan<string>(new string[] { "0", "1", "2", "3", "4", "5" }); + ReadOnlySpan<string> value = new ReadOnlySpan<string>(new string[] { "2" }); + int index = span.LastIndexOf(value); + Assert.Equal(2, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValueAtVeryEnd_String() + { + // A zero-length value is always "found" at the start of the span. + ReadOnlySpan<string> span = new ReadOnlySpan<string>(new string[] { "0", "1", "2", "3", "4", "5" }); + ReadOnlySpan<string> value = new ReadOnlySpan<string>(new string[] { "5" }); + int index = span.LastIndexOf(value); + Assert.Equal(5, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValueJustPasttVeryEnd_String() + { + // A zero-length value is always "found" at the start of the span. + ReadOnlySpan<string> span = new ReadOnlySpan<string>(new string[] { "0", "1", "2", "3", "4", "5" }, 0, 5); + ReadOnlySpan<string> value = new ReadOnlySpan<string>(new string[] { "5" }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + } +} diff --git a/src/System.Memory/tests/ReadOnlySpan/LastIndexOfSequence.byte.cs b/src/System.Memory/tests/ReadOnlySpan/LastIndexOfSequence.byte.cs new file mode 100644 index 0000000000..293920a2f7 --- /dev/null +++ b/src/System.Memory/tests/ReadOnlySpan/LastIndexOfSequence.byte.cs @@ -0,0 +1,133 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Xunit; + +namespace System.SpanTests +{ + public static partial class ReadOnlySpanTests + { + [Fact] + public static void LastIndexOfSequenceMatchAtStart_Byte() + { + ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(new byte[] { 5, 1, 77, 2, 3, 77, 77, 4, 5, 77, 77, 77, 88, 6, 6, 77, 77, 88, 9 }); + ReadOnlySpan<byte> value = new ReadOnlySpan<byte>(new byte[] { 5, 1, 77 }); + int index = span.LastIndexOf(value); + Assert.Equal(0, index); + } + + [Fact] + public static void LastIndexOfSequenceMultipleMatch_Byte() + { + ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(new byte[] { 1, 2, 3, 1, 2, 3, 1, 2, 3, 1 }); + ReadOnlySpan<byte> value = new ReadOnlySpan<byte>(new byte[] { 2, 3 }); + int index = span.LastIndexOf(value); + Assert.Equal(7, index); + } + + [Fact] + public static void LastIndexOfSequenceRestart_Byte() + { + ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(new byte[] { 0, 1, 77, 2, 3, 77, 77, 4, 5, 77, 77, 77, 88, 6, 6, 77, 77, 8, 9, 77, 0, 1 }); + ReadOnlySpan<byte> value = new ReadOnlySpan<byte>(new byte[] { 77, 77, 88 }); + int index = span.LastIndexOf(value); + Assert.Equal(10, index); + } + + [Fact] + public static void LastIndexOfSequenceNoMatch_Byte() + { + ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(new byte[] { 0, 1, 77, 2, 3, 77, 77, 4, 5, 77, 77, 77, 88, 6, 6, 77, 77, 88, 9 }); + ReadOnlySpan<byte> value = new ReadOnlySpan<byte>(new byte[] { 77, 77, 88, 99 }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceNotEvenAHeadMatch_Byte() + { + ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(new byte[] { 0, 1, 77, 2, 3, 77, 77, 4, 5, 77, 77, 77, 88, 6, 6, 77, 77, 88, 9 }); + ReadOnlySpan<byte> value = new ReadOnlySpan<byte>(new byte[] { 100, 77, 88, 99 }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceMatchAtVeryEnd_Byte() + { + ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(new byte[] { 0, 1, 2, 3, 4, 5 }); + ReadOnlySpan<byte> value = new ReadOnlySpan<byte>(new byte[] { 3, 4, 5 }); + int index = span.LastIndexOf(value); + Assert.Equal(3, index); + } + + [Fact] + public static void LastIndexOfSequenceJustPastVeryEnd_Byte() + { + ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(new byte[] { 0, 1, 2, 3, 4, 5 }, 0, 5); + ReadOnlySpan<byte> value = new ReadOnlySpan<byte>(new byte[] { 3, 4, 5 }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceZeroLengthValue_Byte() + { + // A zero-length value is always "found" at the start of the span. + ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(new byte[] { 0, 1, 77, 2, 3, 77, 77, 4, 5, 77, 77, 77, 88, 6, 6, 77, 77, 88, 9 }); + ReadOnlySpan<byte> value = new ReadOnlySpan<byte>(Array.Empty<byte>()); + int index = span.LastIndexOf(value); + Assert.Equal(0, index); + } + + [Fact] + public static void LastIndexOfSequenceZeroLengthSpan_Byte() + { + ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(Array.Empty<byte>()); + ReadOnlySpan<byte> value = new ReadOnlySpan<byte>(new byte[] { 1, 2, 3 }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValue_Byte() + { + // A zero-length value is always "found" at the start of the span. + ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(new byte[] { 0, 1, 2, 3, 4, 5 }); + ReadOnlySpan<byte> value = new ReadOnlySpan<byte>(new byte[] { 2 }); + int index = span.LastIndexOf(value); + Assert.Equal(2, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValueAtVeryEnd_Byte() + { + // A zero-length value is always "found" at the start of the span. + ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(new byte[] { 0, 1, 2, 3, 4, 5 }); + ReadOnlySpan<byte> value = new ReadOnlySpan<byte>(new byte[] { 5 }); + int index = span.LastIndexOf(value); + Assert.Equal(5, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValueMultipleTimes_Byte() + { + // A zero-length value is always "found" at the start of the span. + ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(new byte[] { 0, 1, 5, 3, 4, 5 }); + ReadOnlySpan<byte> value = new ReadOnlySpan<byte>(new byte[] { 5 }); + int index = span.LastIndexOf(value); + Assert.Equal(5, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValueJustPasttVeryEnd_Byte() + { + // A zero-length value is always "found" at the start of the span. + ReadOnlySpan<byte> span = new ReadOnlySpan<byte>(new byte[] { 0, 1, 2, 3, 4, 5 }, 0, 5); + ReadOnlySpan<byte> value = new ReadOnlySpan<byte>(new byte[] { 5 }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + } +} diff --git a/src/System.Memory/tests/ReadOnlySpan/LastIndexOfSequence.char.cs b/src/System.Memory/tests/ReadOnlySpan/LastIndexOfSequence.char.cs new file mode 100644 index 0000000000..63f6635f76 --- /dev/null +++ b/src/System.Memory/tests/ReadOnlySpan/LastIndexOfSequence.char.cs @@ -0,0 +1,133 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Xunit; + +namespace System.SpanTests +{ + public static partial class ReadOnlySpanTests + { + [Fact] + public static void LastIndexOfSequenceMatchAtStart_Char() + { + ReadOnlySpan<char> span = new ReadOnlySpan<char>(new char[] { '5', '1', '7', '2', '3', '7', '7', '4', '5', '7', '7', '7', '8', '6', '6', '7', '7', '8', '9' }); + ReadOnlySpan<char> value = new ReadOnlySpan<char>(new char[] { '5', '1', '7' }); + int index = span.LastIndexOf(value); + Assert.Equal(0, index); + } + + [Fact] + public static void LastIndexOfSequenceMultipleMatch_Char() + { + ReadOnlySpan<char> span = new ReadOnlySpan<char>(new char[] { '1', '2', '3', '1', '2', '3', '1', '2', '3', '1' }); + ReadOnlySpan<char> value = new ReadOnlySpan<char>(new char[] { '2', '3' }); + int index = span.LastIndexOf(value); + Assert.Equal(7, index); + } + + [Fact] + public static void LastIndexOfSequenceRestart_Char() + { + ReadOnlySpan<char> span = new ReadOnlySpan<char>(new char[] { '5', '1', '7', '2', '3', '7', '7', '4', '5', '7', '7', '7', '8', '6', '6', '7', '7', '6', '9', '7', '0', '1' }); + ReadOnlySpan<char> value = new ReadOnlySpan<char>(new char[] { '7', '7', '8' }); + int index = span.LastIndexOf(value); + Assert.Equal(10, index); + } + + [Fact] + public static void LastIndexOfSequenceNoMatch_Char() + { + ReadOnlySpan<char> span = new ReadOnlySpan<char>(new char[] { '0', '1', '7', '2', '3', '7', '7', '4', '5', '7', '7', '7', '8', '6', '6', '7', '7', '8', '9' }); + ReadOnlySpan<char> value = new ReadOnlySpan<char>(new char[] { '7', '7', '8', 'X' }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceNotEvenAHeadMatch_Char() + { + ReadOnlySpan<char> span = new ReadOnlySpan<char>(new char[] { '0', '1', '7', '2', '3', '7', '7', '4', '5', '7', '7', '7', '8', '6', '6', '7', '7', '8', '9' }); + ReadOnlySpan<char> value = new ReadOnlySpan<char>(new char[] { 'X', '7', '8', '9' }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceMatchAtVeryEnd_Char() + { + ReadOnlySpan<char> span = new ReadOnlySpan<char>(new char[] { '0', '1', '2', '3', '4', '5' }); + ReadOnlySpan<char> value = new ReadOnlySpan<char>(new char[] { '3', '4', '5' }); + int index = span.LastIndexOf(value); + Assert.Equal(3, index); + } + + [Fact] + public static void LastIndexOfSequenceJustPastVeryEnd_Char() + { + ReadOnlySpan<char> span = new ReadOnlySpan<char>(new char[] { '0', '1', '2', '3', '4', '5' }, 0, 5); + ReadOnlySpan<char> value = new ReadOnlySpan<char>(new char[] { '3', '4', '5' }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceZeroLengthValue_Char() + { + // A zero-length value is always "found" at the start of the span. + ReadOnlySpan<char> span = new ReadOnlySpan<char>(new char[] { '0', '1', '7', '2', '3', '7', '7', '4', '5', '7', '7', '7', '8', '6', '6', '7', '7', '8', '9' }); + ReadOnlySpan<char> value = new ReadOnlySpan<char>(Array.Empty<char>()); + int index = span.LastIndexOf(value); + Assert.Equal(0, index); + } + + [Fact] + public static void LastIndexOfSequenceZeroLengthSpan_Char() + { + ReadOnlySpan<char> span = new ReadOnlySpan<char>(Array.Empty<char>()); + ReadOnlySpan<char> value = new ReadOnlySpan<char>(new char[] { '1', '2', '3' }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValue_Char() + { + // A zero-length value is always "found" at the start of the span. + ReadOnlySpan<char> span = new ReadOnlySpan<char>(new char[] { '0', '1', '2', '3', '4', '5' }); + ReadOnlySpan<char> value = new ReadOnlySpan<char>(new char[] { '2' }); + int index = span.LastIndexOf(value); + Assert.Equal(2, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValueAtVeryEnd_Char() + { + // A zero-length value is always "found" at the start of the span. + ReadOnlySpan<char> span = new ReadOnlySpan<char>(new char[] { '0', '1', '2', '3', '4', '5' }); + ReadOnlySpan<char> value = new ReadOnlySpan<char>(new char[] { '5' }); + int index = span.LastIndexOf(value); + Assert.Equal(5, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValueMultipleTimes_Char() + { + // A zero-length value is always "found" at the start of the span. + ReadOnlySpan<char> span = new ReadOnlySpan<char>(new char[] { '0', '1', '5', '3', '4', '5' }); + ReadOnlySpan<char> value = new ReadOnlySpan<char>(new char[] { '5' }); + int index = span.LastIndexOf(value); + Assert.Equal(5, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValueJustPasttVeryEnd_Char() + { + // A zero-length value is always "found" at the start of the span. + ReadOnlySpan<char> span = new ReadOnlySpan<char>(new char[] { '0', '1', '2', '3', '4', '5' }, 0, 5); + ReadOnlySpan<char> value = new ReadOnlySpan<char>(new char[] { '5' }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + } +} diff --git a/src/System.Memory/tests/ReadOnlySpan/Overflow.cs b/src/System.Memory/tests/ReadOnlySpan/Overflow.cs index dc9ed088e7..54f9fc7a93 100644 --- a/src/System.Memory/tests/ReadOnlySpan/Overflow.cs +++ b/src/System.Memory/tests/ReadOnlySpan/Overflow.cs @@ -36,9 +36,9 @@ namespace System.SpanTests try { ref Guid memory = ref Unsafe.AsRef<Guid>(memBlock.ToPointer()); - var span = new ReadOnlySpan<Guid>(memBlock.ToPointer(), GuidThreeGiBLimit); + var span = new ReadOnlySpan<Guid>(memBlock.ToPointer(), s_guidThreeGiBLimit); - int bigIndex = checked(GuidTwoGiBLimit + 1); + int bigIndex = checked(s_guidTwoGiBLimit + 1); uint byteOffset = checked((uint)bigIndex * (uint)sizeof(Guid)); Assert.True(byteOffset > int.MaxValue); // Make sure byteOffset actually overflows 2Gb, or this test is pointless. Guid expectedGuid = Guid.NewGuid(); @@ -65,8 +65,7 @@ namespace System.SpanTests private const long TwoGiB = 2L * 1024L * 1024L * 1024L; private const long OneGiB = 1L * 1024L * 1024L * 1024L; - private static readonly int GuidThreeGiBLimit = (int)(ThreeGiB / Unsafe.SizeOf<Guid>()); // sizeof(Guid) requires unsafe keyword and I don't want to mark the entire class unsafe. - private static readonly int GuidTwoGiBLimit = (int)(TwoGiB / Unsafe.SizeOf<Guid>()); - private static readonly int GuidOneGiBLimit = (int)(OneGiB / Unsafe.SizeOf<Guid>()); + private static readonly int s_guidThreeGiBLimit = (int)(ThreeGiB / Unsafe.SizeOf<Guid>()); // sizeof(Guid) requires unsafe keyword and I don't want to mark the entire class unsafe. + private static readonly int s_guidTwoGiBLimit = (int)(TwoGiB / Unsafe.SizeOf<Guid>()); } } diff --git a/src/System.Memory/tests/Span/Clear.cs b/src/System.Memory/tests/Span/Clear.cs index ecd0c4a34f..7fbb5cb697 100644 --- a/src/System.Memory/tests/Span/Clear.cs +++ b/src/System.Memory/tests/Span/Clear.cs @@ -131,7 +131,6 @@ namespace System.SpanTests Assert.Equal<IntPtr>(expected, actual); } - [Fact] public static void ClearValueTypeWithoutReferences() { @@ -202,8 +201,8 @@ namespace System.SpanTests [Fact] public static void ClearEnumType() { - TestEnum[] actual = {TestEnum.e0, TestEnum.e1, TestEnum.e2}; - TestEnum[] expected = {default(TestEnum), default(TestEnum), default(TestEnum) }; + TestEnum[] actual = { TestEnum.e0, TestEnum.e1, TestEnum.e2 }; + TestEnum[] expected = { default, default, default }; var span = new Span<TestEnum>(actual); span.Clear(); @@ -218,9 +217,9 @@ namespace System.SpanTests new TestValueTypeWithReference() { I = 2, S = "b" }, new TestValueTypeWithReference() { I = 3, S = "c" } }; TestValueTypeWithReference[] expected = { - default(TestValueTypeWithReference), - default(TestValueTypeWithReference), - default(TestValueTypeWithReference) }; + default, + default, + default }; var span = new Span<TestValueTypeWithReference>(actual); span.Clear(); diff --git a/src/System.Memory/tests/Span/CopyTo.cs b/src/System.Memory/tests/Span/CopyTo.cs index 22ff1d0150..213354214c 100644 --- a/src/System.Memory/tests/Span/CopyTo.cs +++ b/src/System.Memory/tests/Span/CopyTo.cs @@ -250,8 +250,10 @@ namespace System.SpanTests } finally { - if (allocatedFirst) AllocationHelper.ReleaseNative(ref memBlockFirst); - if (allocatedSecond) AllocationHelper.ReleaseNative(ref memBlockSecond); + if (allocatedFirst) + AllocationHelper.ReleaseNative(ref memBlockFirst); + if (allocatedSecond) + AllocationHelper.ReleaseNative(ref memBlockSecond); } } } diff --git a/src/System.Memory/tests/Span/IndexOf.T.cs b/src/System.Memory/tests/Span/IndexOf.T.cs index 8d9736be83..0da12edee9 100644 --- a/src/System.Memory/tests/Span/IndexOf.T.cs +++ b/src/System.Memory/tests/Span/IndexOf.T.cs @@ -27,7 +27,7 @@ namespace System.SpanTests a[i] = 10 * (i + 1); } Span<int> span = new Span<int>(a); - + for (int targetIndex = 0; targetIndex < length; targetIndex++) { int target = a[targetIndex]; @@ -116,5 +116,74 @@ namespace System.SpanTests Assert.Equal(-1, idx); } } + + [Fact] + public static void ZeroLengthIndexOf_String() + { + Span<string> sp = new Span<string>(Array.Empty<string>()); + int idx = sp.IndexOf("a"); + Assert.Equal(-1, idx); + } + + [Fact] + public static void TestMatchIndexOf_String() + { + for (int length = 0; length < 32; length++) + { + string[] a = new string[length]; + for (int i = 0; i < length; i++) + { + a[i] = (10 * (i + 1)).ToString(); + } + Span<string> span = new Span<string>(a); + + for (int targetIndex = 0; targetIndex < length; targetIndex++) + { + string target = a[targetIndex]; + int idx = span.IndexOf(target); + Assert.Equal(targetIndex, idx); + } + } + } + + [Fact] + public static void TestNoMatchIndexOf_String() + { + var rnd = new Random(42); + for (int length = 0; length <= byte.MaxValue; length++) + { + string[] a = new string[length]; + string target = (rnd.Next(0, 256)).ToString(); + for (int i = 0; i < length; i++) + { + string val = (i + 1).ToString(); + a[i] = val == target ? (target + 1) : val; + } + Span<string> span = new Span<string>(a); + + int idx = span.IndexOf(target); + Assert.Equal(-1, idx); + } + } + + [Fact] + public static void TestMultipleMatchIndexOf_String() + { + for (int length = 2; length < 32; length++) + { + string[] a = new string[length]; + for (int i = 0; i < length; i++) + { + a[i] = (10 * (i + 1)).ToString(); + } + + a[length - 1] = "5555"; + a[length - 2] = "5555"; + + Span<string> span = new Span<string>(a); + int idx = span.IndexOf("5555"); + Assert.Equal(length - 2, idx); + } + } } } diff --git a/src/System.Memory/tests/Span/IndexOf.byte.cs b/src/System.Memory/tests/Span/IndexOf.byte.cs index 71981631b5..e4a535570a 100644 --- a/src/System.Memory/tests/Span/IndexOf.byte.cs +++ b/src/System.Memory/tests/Span/IndexOf.byte.cs @@ -28,7 +28,7 @@ namespace System.SpanTests for (int i = 0; i < length; i++) { - byte target0 = default(byte); + byte target0 = default; int idx = span.IndexOf<byte>(target0); Assert.Equal(0, idx); } @@ -215,7 +215,7 @@ namespace System.SpanTests byte[] a = new byte[length]; Span<byte> span = new Span<byte>(a); - byte[] targets = { default(byte), 99 }; + byte[] targets = { default, 99 }; for (int i = 0; i < length; i++) { @@ -346,7 +346,7 @@ namespace System.SpanTests byte[] a = new byte[length]; Span<byte> span = new Span<byte>(a); - byte[] targets = { default(byte), 99, 98 }; + byte[] targets = { default, 99, 98 }; for (int i = 0; i < length; i++) { @@ -486,7 +486,7 @@ namespace System.SpanTests byte[] a = new byte[length]; Span<byte> span = new Span<byte>(a); - var values = new ReadOnlySpan<byte>(new byte[] { default(byte), 99, 98, 0 }); + var values = new ReadOnlySpan<byte>(new byte[] { default, 99, 98, 0 }); for (int i = 0; i < length; i++) { diff --git a/src/System.Memory/tests/Span/IndexOf.char.cs b/src/System.Memory/tests/Span/IndexOf.char.cs index 51c91ffa0e..b77c3f7d77 100644 --- a/src/System.Memory/tests/Span/IndexOf.char.cs +++ b/src/System.Memory/tests/Span/IndexOf.char.cs @@ -27,7 +27,7 @@ namespace System.SpanTests a[i] = (char)(i + 1); } Span<char> span = new Span<char>(a); - + for (int targetIndex = 0; targetIndex < length; targetIndex++) { char target = a[targetIndex]; diff --git a/src/System.Memory/tests/Span/IndexOfSequence.T.cs b/src/System.Memory/tests/Span/IndexOfSequence.T.cs index 9c2ffc5b91..e8c270c0a2 100644 --- a/src/System.Memory/tests/Span/IndexOfSequence.T.cs +++ b/src/System.Memory/tests/Span/IndexOfSequence.T.cs @@ -119,5 +119,117 @@ namespace System.SpanTests int index = span.IndexOf(value); Assert.Equal(-1, index); } + + [Fact] + public static void IndexOfSequenceMatchAtStart_String() + { + Span<string> span = new Span<string>(new string[] { "5", "1", "77", "2", "3", "77", "77", "4", "5", "77", "77", "77", "88", "6", "6", "77", "77", "88", "9" }); + Span<string> value = new Span<string>(new string[] { "5", "1", "77" }); + int index = span.IndexOf(value); + Assert.Equal(0, index); + } + + [Fact] + public static void IndexOfSequenceMultipleMatch_String() + { + Span<string> span = new Span<string>(new string[] { "1", "2", "3", "1", "2", "3", "1", "2", "3" }); + Span<string> value = new Span<string>(new string[] { "2", "3" }); + int index = span.IndexOf(value); + Assert.Equal(1, index); + } + + [Fact] + public static void IndexOfSequenceRestart_String() + { + Span<string> span = new Span<string>(new string[] { "0", "1", "77", "2", "3", "77", "77", "4", "5", "77", "77", "77", "88", "6", "6", "77", "77", "88", "9" }); + Span<string> value = new Span<string>(new string[] { "77", "77", "88" }); + int index = span.IndexOf(value); + Assert.Equal(10, index); + } + + [Fact] + public static void IndexOfSequenceNoMatch_String() + { + Span<string> span = new Span<string>(new string[] { "0", "1", "77", "2", "3", "77", "77", "4", "5", "77", "77", "77", "88", "6", "6", "77", "77", "88", "9" }); + Span<string> value = new Span<string>(new string[] { "77", "77", "88", "99" }); + int index = span.IndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void IndexOfSequenceNotEvenAHeadMatch_String() + { + Span<string> span = new Span<string>(new string[] { "0", "1", "77", "2", "3", "77", "77", "4", "5", "77", "77", "77", "88", "6", "6", "77", "77", "88", "9" }); + Span<string> value = new Span<string>(new string[] { "100", "77", "88", "99" }); + int index = span.IndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void IndexOfSequenceMatchAtVeryEnd_String() + { + Span<string> span = new Span<string>(new string[] { "0", "1", "2", "3", "4", "5" }); + Span<string> value = new Span<string>(new string[] { "3", "4", "5" }); + int index = span.IndexOf(value); + Assert.Equal(3, index); + } + + [Fact] + public static void IndexOfSequenceJustPastVeryEnd_String() + { + Span<string> span = new Span<string>(new string[] { "0", "1", "2", "3", "4", "5" }, 0, 5); + Span<string> value = new Span<string>(new string[] { "3", "4", "5" }); + int index = span.IndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void IndexOfSequenceZeroLengthValue_String() + { + // A zero-length value is always "found" at the start of the span. + Span<string> span = new Span<string>(new string[] { "0", "1", "77", "2", "3", "77", "77", "4", "5", "77", "77", "77", "88", "6", "6", "77", "77", "88", "9" }); + Span<string> value = new Span<string>(Array.Empty<string>()); + int index = span.IndexOf(value); + Assert.Equal(0, index); + } + + [Fact] + public static void IndexOfSequenceZeroLengthSpan_String() + { + Span<string> span = new Span<string>(Array.Empty<string>()); + Span<string> value = new Span<string>(new string[] { "1", "2", "3" }); + int index = span.IndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void IndexOfSequenceLengthOneValue_String() + { + // A zero-length value is always "found" at the start of the span. + Span<string> span = new Span<string>(new string[] { "0", "1", "2", "3", "4", "5" }); + Span<string> value = new Span<string>(new string[] { "2" }); + int index = span.IndexOf(value); + Assert.Equal(2, index); + } + + [Fact] + public static void IndexOfSequenceLengthOneValueAtVeryEnd_String() + { + // A zero-length value is always "found" at the start of the span. + Span<string> span = new Span<string>(new string[] { "0", "1", "2", "3", "4", "5" }); + Span<string> value = new Span<string>(new string[] { "5" }); + int index = span.IndexOf(value); + Assert.Equal(5, index); + } + + [Fact] + public static void IndexOfSequenceLengthOneValueJustPasttVeryEnd_String() + { + // A zero-length value is always "found" at the start of the span. + Span<string> span = new Span<string>(new string[] { "0", "1", "2", "3", "4", "5" }, 0, 5); + Span<string> value = new Span<string>(new string[] { "5" }); + int index = span.IndexOf(value); + Assert.Equal(-1, index); + } } } diff --git a/src/System.Memory/tests/Span/LastIndexOf.T.cs b/src/System.Memory/tests/Span/LastIndexOf.T.cs new file mode 100644 index 0000000000..e15858eb3f --- /dev/null +++ b/src/System.Memory/tests/Span/LastIndexOf.T.cs @@ -0,0 +1,189 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Xunit; + +namespace System.SpanTests +{ + public static partial class SpanTests + { + [Fact] + public static void ZeroLengthLastIndexOf() + { + Span<int> sp = new Span<int>(Array.Empty<int>()); + int idx = sp.LastIndexOf(0); + Assert.Equal(-1, idx); + } + + [Fact] + public static void TestMatchLastIndexOf() + { + for (int length = 0; length < 32; length++) + { + int[] a = new int[length]; + for (int i = 0; i < length; i++) + { + a[i] = 10 * (i + 1); + } + Span<int> span = new Span<int>(a); + + for (int targetIndex = 0; targetIndex < length; targetIndex++) + { + int target = a[targetIndex]; + int idx = span.LastIndexOf(target); + Assert.Equal(targetIndex, idx); + } + } + } + + [Fact] + public static void TestMultipleMatchLastIndexOf() + { + for (int length = 2; length < 32; length++) + { + int[] a = new int[length]; + for (int i = 0; i < length; i++) + { + a[i] = 10 * (i + 1); + } + + a[length - 1] = 5555; + a[length - 2] = 5555; + + Span<int> span = new Span<int>(a); + int idx = span.LastIndexOf(5555); + Assert.Equal(length - 1, idx); + } + } + + [Fact] + public static void OnNoMatchMakeSureEveryElementIsComparedLastIndexOf() + { + for (int length = 0; length < 100; length++) + { + TIntLog log = new TIntLog(); + + TInt[] a = new TInt[length]; + for (int i = 0; i < length; i++) + { + a[i] = new TInt(10 * (i + 1), log); + } + Span<TInt> span = new Span<TInt>(a); + int idx = span.LastIndexOf(new TInt(9999, log)); + Assert.Equal(-1, idx); + + // Since we asked for a non-existent value, make sure each element of the array was compared once. + // (Strictly speaking, it would not be illegal for IndexOf to compare an element more than once but + // that would be a non-optimal implementation and a red flag. So we'll stick with the stricter test.) + Assert.Equal(a.Length, log.Count); + foreach (TInt elem in a) + { + int numCompares = log.CountCompares(elem.Value, 9999); + Assert.True(numCompares == 1, $"Expected {numCompares} == 1 for element {elem.Value}."); + } + } + } + + [Fact] + public static void MakeSureNoChecksGoOutOfRangeLastIndexOf() + { + const int GuardValue = 77777; + const int GuardLength = 50; + + Action<int, int> checkForOutOfRangeAccess = + delegate (int x, int y) + { + if (x == GuardValue || y == GuardValue) + throw new Exception("Detected out of range access in IndexOf()"); + }; + + for (int length = 0; length < 100; length++) + { + TInt[] a = new TInt[GuardLength + length + GuardLength]; + for (int i = 0; i < a.Length; i++) + { + a[i] = new TInt(GuardValue, checkForOutOfRangeAccess); + } + + for (int i = 0; i < length; i++) + { + a[GuardLength + i] = new TInt(10 * (i + 1), checkForOutOfRangeAccess); + } + + Span<TInt> span = new Span<TInt>(a, GuardLength, length); + int idx = span.LastIndexOf(new TInt(9999, checkForOutOfRangeAccess)); + Assert.Equal(-1, idx); + } + } + + [Fact] + public static void ZeroLengthLastIndexOf_String() + { + Span<string> sp = new Span<string>(Array.Empty<string>()); + int idx = sp.LastIndexOf("a"); + Assert.Equal(-1, idx); + } + + [Fact] + public static void TestMatchLastIndexOf_String() + { + for (int length = 0; length < 32; length++) + { + string[] a = new string[length]; + for (int i = 0; i < length; i++) + { + a[i] = (10 * (i + 1)).ToString(); + } + Span<string> span = new Span<string>(a); + + for (int targetIndex = 0; targetIndex < length; targetIndex++) + { + string target = a[targetIndex]; + int idx = span.LastIndexOf(target); + Assert.Equal(targetIndex, idx); + } + } + } + + [Fact] + public static void TestNoMatchLastIndexOf_String() + { + var rnd = new Random(42); + for (int length = 0; length <= byte.MaxValue; length++) + { + string[] a = new string[length]; + string target = (rnd.Next(0, 256)).ToString(); + for (int i = 0; i < length; i++) + { + string val = (i + 1).ToString(); + a[i] = val == target ? (target + 1) : val; + } + Span<string> span = new Span<string>(a); + + int idx = span.LastIndexOf(target); + Assert.Equal(-1, idx); + } + } + + [Fact] + public static void TestMultipleMatchLastIndexOf_String() + { + for (int length = 2; length < 32; length++) + { + string[] a = new string[length]; + for (int i = 0; i < length; i++) + { + a[i] = (10 * (i + 1)).ToString(); + } + + a[length - 1] = "5555"; + a[length - 2] = "5555"; + + Span<string> span = new Span<string>(a); + int idx = span.LastIndexOf("5555"); + Assert.Equal(length - 1, idx); + } + } + } +} diff --git a/src/System.Memory/tests/Span/LastIndexOf.byte.cs b/src/System.Memory/tests/Span/LastIndexOf.byte.cs new file mode 100644 index 0000000000..93582c6ed0 --- /dev/null +++ b/src/System.Memory/tests/Span/LastIndexOf.byte.cs @@ -0,0 +1,149 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Numerics; +using Xunit; + +namespace System.SpanTests +{ + public static partial class SpanTests + { + [Fact] + public static void ZeroLengthLastIndexOf_Byte() + { + Span<byte> sp = new Span<byte>(Array.Empty<byte>()); + int idx = sp.LastIndexOf<byte>(0); + Assert.Equal(-1, idx); + } + + [Fact] + public static void DefaultFilledLastIndexOf_Byte() + { + for (int length = 0; length <= byte.MaxValue; length++) + { + byte[] a = new byte[length]; + Span<byte> span = new Span<byte>(a); + + for (int i = 0; i < length; i++) + { + byte target0 = default; + int idx = span.LastIndexOf(target0); + Assert.Equal(length - 1, idx); + } + } + } + + [Fact] + public static void TestMatchLastIndexOf_Byte() + { + for (int length = 0; length <= byte.MaxValue; length++) + { + byte[] a = new byte[length]; + for (int i = 0; i < length; i++) + { + a[i] = (byte)(i + 1); + } + Span<byte> span = new Span<byte>(a); + + for (int targetIndex = 0; targetIndex < length; targetIndex++) + { + byte target = a[targetIndex]; + int idx = span.LastIndexOf(target); + Assert.Equal(targetIndex, idx); + } + } + } + + [Fact] + public static void TestNoMatchLastIndexOf_Byte() + { + var rnd = new Random(42); + for (int length = 0; length <= byte.MaxValue; length++) + { + byte[] a = new byte[length]; + byte target = (byte)rnd.Next(0, 256); + for (int i = 0; i < length; i++) + { + byte val = (byte)(i + 1); + a[i] = val == target ? (byte)(target + 1) : val; + } + Span<byte> span = new Span<byte>(a); + + int idx = span.LastIndexOf(target); + Assert.Equal(-1, idx); + } + } + + [Fact] + public static void TestAllignmentNoMatchLastIndexOf_Byte() + { + byte[] array = new byte[4 * Vector<byte>.Count]; + for (var i = 0; i < Vector<byte>.Count; i++) + { + var span = new Span<byte>(array, i, 3 * Vector<byte>.Count); + int idx = span.LastIndexOf<byte>(5); + Assert.Equal(-1, idx); + + span = new Span<byte>(array, i, 3 * Vector<byte>.Count - 3); + idx = span.LastIndexOf<byte>(5); + Assert.Equal(-1, idx); + } + } + + [Fact] + public static void TestAllignmentMatchLastIndexOf_Byte() + { + byte[] array = new byte[4 * Vector<byte>.Count]; + for (int i = 0; i < array.Length; i++) + { + array[i] = 5; + } + for (var i = 0; i < Vector<byte>.Count; i++) + { + var span = new Span<byte>(array, i, 3 * Vector<byte>.Count); + int idx = span.LastIndexOf<byte>(5); + Assert.Equal(span.Length - 1, idx); + + span = new Span<byte>(array, i, 3 * Vector<byte>.Count - 3); + idx = span.LastIndexOf<byte>(5); + Assert.Equal(span.Length - 1, idx); + } + } + + [Fact] + public static void TestMultipleMatchLastIndexOf_Byte() + { + for (int length = 2; length <= byte.MaxValue; length++) + { + byte[] a = new byte[length]; + for (int i = 0; i < length; i++) + { + byte val = (byte)(i + 1); + a[i] = val == 200 ? (byte)201 : val; + } + + a[length - 1] = 200; + a[length - 2] = 200; + + Span<byte> span = new Span<byte>(a); + int idx = span.LastIndexOf<byte>(200); + Assert.Equal(length - 1, idx); + } + } + + [Fact] + public static void MakeSureNoChecksGoOutOfRangeLastIndexOf_Byte() + { + for (int length = 0; length <= byte.MaxValue; length++) + { + byte[] a = new byte[length + 2]; + a[0] = 99; + a[length + 1] = 99; + Span<byte> span = new Span<byte>(a, 1, length); + int index = span.LastIndexOf<byte>(99); + Assert.Equal(-1, index); + } + } + } +} diff --git a/src/System.Memory/tests/Span/LastIndexOf.char.cs b/src/System.Memory/tests/Span/LastIndexOf.char.cs new file mode 100644 index 0000000000..902150a35b --- /dev/null +++ b/src/System.Memory/tests/Span/LastIndexOf.char.cs @@ -0,0 +1,74 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Xunit; + +namespace System.SpanTests +{ + public static partial class SpanTests + { + [Fact] + public static void ZeroLengthLastIndexOf_Char() + { + Span<char> sp = new Span<char>(Array.Empty<char>()); + int idx = sp.LastIndexOf((char)0); + Assert.Equal(-1, idx); + } + + [Fact] + public static void TestMatchLastIndexOf_Char() + { + for (int length = 0; length < 32; length++) + { + char[] a = new char[length]; + for (int i = 0; i < length; i++) + { + a[i] = (char)(i + 1); + } + Span<char> span = new Span<char>(a); + + for (int targetIndex = 0; targetIndex < length; targetIndex++) + { + char target = a[targetIndex]; + int idx = span.LastIndexOf(target); + Assert.Equal(targetIndex, idx); + } + } + } + + [Fact] + public static void TestMultipleMatchLastIndexOf_Char() + { + for (int length = 2; length < 32; length++) + { + char[] a = new char[length]; + for (int i = 0; i < length; i++) + { + a[i] = (char)(i + 1); + } + + a[length - 1] = (char)200; + a[length - 2] = (char)200; + + Span<char> span = new Span<char>(a); + int idx = span.LastIndexOf((char)200); + Assert.Equal(length - 1, idx); + } + } + + [Fact] + public static void MakeSureNoChecksGoOutOfRangeLastIndexOf_Char() + { + for (int length = 0; length < 100; length++) + { + char[] a = new char[length + 2]; + a[0] = '9'; + a[length + 1] = '9'; + Span<char> span = new Span<char>(a, 1, length); + int index = span.LastIndexOf('9'); + Assert.Equal(-1, index); + } + } + } +} diff --git a/src/System.Memory/tests/Span/LastIndexOfSequence.T.cs b/src/System.Memory/tests/Span/LastIndexOfSequence.T.cs new file mode 100644 index 0000000000..833d80c200 --- /dev/null +++ b/src/System.Memory/tests/Span/LastIndexOfSequence.T.cs @@ -0,0 +1,245 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Xunit; + +namespace System.SpanTests +{ + public static partial class SpanTests + { + [Fact] + public static void LastIndexOfSequenceMatchAtStart() + { + Span<int> span = new Span<int>(new int[] { 5, 1, 77, 2, 3, 77, 77, 4, 5, 77, 77, 77, 88, 6, 6, 77, 77, 88, 9 }); + Span<int> value = new Span<int>(new int[] { 5, 1, 77 }); + int index = span.LastIndexOf(value); + Assert.Equal(0, index); + } + + [Fact] + public static void LastIndexOfSequenceMultipleMatch() + { + Span<int> span = new Span<int>(new int[] { 1, 2, 3, 1, 2, 3, 1, 2, 3, 1 }); + Span<int> value = new Span<int>(new int[] { 2, 3 }); + int index = span.LastIndexOf(value); + Assert.Equal(7, index); + } + + [Fact] + public static void LastIndexOfSequenceRestart() + { + Span<int> span = new Span<int>(new int[] { 0, 1, 77, 2, 3, 77, 77, 4, 5, 77, 77, 77, 88, 6, 6, 77, 77, 8, 9, 77, 0, 1 }); + Span<int> value = new Span<int>(new int[] { 77, 77, 88 }); + int index = span.LastIndexOf(value); + Assert.Equal(10, index); + } + + [Fact] + public static void LastIndexOfSequenceNoMatch() + { + Span<int> span = new Span<int>(new int[] { 0, 1, 77, 2, 3, 77, 77, 4, 5, 77, 77, 77, 88, 6, 6, 77, 77, 88, 9 }); + Span<int> value = new Span<int>(new int[] { 77, 77, 88, 99 }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceNotEvenAHeadMatch() + { + Span<int> span = new Span<int>(new int[] { 0, 1, 77, 2, 3, 77, 77, 4, 5, 77, 77, 77, 88, 6, 6, 77, 77, 88, 9 }); + Span<int> value = new Span<int>(new int[] { 100, 77, 88, 99 }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceMatchAtVeryEnd() + { + Span<int> span = new Span<int>(new int[] { 0, 1, 2, 3, 4, 5 }); + Span<int> value = new Span<int>(new int[] { 3, 4, 5 }); + int index = span.LastIndexOf(value); + Assert.Equal(3, index); + } + + [Fact] + public static void LastIndexOfSequenceJustPastVeryEnd() + { + Span<int> span = new Span<int>(new int[] { 0, 1, 2, 3, 4, 5 }, 0, 5); + Span<int> value = new Span<int>(new int[] { 3, 4, 5 }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceZeroLengthValue() + { + // A zero-length value is always "found" at the start of the span. + Span<int> span = new Span<int>(new int[] { 0, 1, 77, 2, 3, 77, 77, 4, 5, 77, 77, 77, 88, 6, 6, 77, 77, 88, 9 }); + Span<int> value = new Span<int>(Array.Empty<int>()); + int index = span.LastIndexOf(value); + Assert.Equal(0, index); + } + + [Fact] + public static void LastIndexOfSequenceZeroLengthSpan() + { + Span<int> span = new Span<int>(Array.Empty<int>()); + Span<int> value = new Span<int>(new int[] { 1, 2, 3 }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValue() + { + // A zero-length value is always "found" at the start of the span. + Span<int> span = new Span<int>(new int[] { 0, 1, 2, 3, 4, 5 }); + Span<int> value = new Span<int>(new int[] { 2 }); + int index = span.LastIndexOf(value); + Assert.Equal(2, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValueAtVeryEnd() + { + // A zero-length value is always "found" at the start of the span. + Span<int> span = new Span<int>(new int[] { 0, 1, 2, 3, 4, 5 }); + Span<int> value = new Span<int>(new int[] { 5 }); + int index = span.LastIndexOf(value); + Assert.Equal(5, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValueMultipleTimes() + { + // A zero-length value is always "found" at the start of the span. + Span<int> span = new Span<int>(new int[] { 0, 1, 5, 3, 4, 5 }); + Span<int> value = new Span<int>(new int[] { 5 }); + int index = span.LastIndexOf(value); + Assert.Equal(5, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValueJustPasttVeryEnd() + { + // A zero-length value is always "found" at the start of the span. + Span<int> span = new Span<int>(new int[] { 0, 1, 2, 3, 4, 5 }, 0, 5); + Span<int> value = new Span<int>(new int[] { 5 }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceMatchAtStart_String() + { + Span<string> span = new Span<string>(new string[] { "5", "1", "77", "2", "3", "77", "77", "4", "5", "77", "77", "77", "88", "6", "6", "77", "77", "88", "9" }); + Span<string> value = new Span<string>(new string[] { "5", "1", "77" }); + int index = span.LastIndexOf(value); + Assert.Equal(0, index); + } + + [Fact] + public static void LastIndexOfSequenceMultipleMatch_String() + { + Span<string> span = new Span<string>(new string[] { "1", "2", "3", "1", "2", "3", "1", "2", "3" }); + Span<string> value = new Span<string>(new string[] { "2", "3" }); + int index = span.LastIndexOf(value); + Assert.Equal(7, index); + } + + [Fact] + public static void LastIndexOfSequenceRestart_String() + { + Span<string> span = new Span<string>(new string[] { "0", "1", "77", "2", "3", "77", "77", "4", "5", "77", "77", "77", "88", "6", "6", "77", "77", "8", "9", "77", "0", "1" }); + Span<string> value = new Span<string>(new string[] { "77", "77", "88" }); + int index = span.LastIndexOf(value); + Assert.Equal(10, index); + } + + [Fact] + public static void LastIndexOfSequenceNoMatch_String() + { + Span<string> span = new Span<string>(new string[] { "0", "1", "77", "2", "3", "77", "77", "4", "5", "77", "77", "77", "88", "6", "6", "77", "77", "88", "9" }); + Span<string> value = new Span<string>(new string[] { "77", "77", "88", "99" }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceNotEvenAHeadMatch_String() + { + Span<string> span = new Span<string>(new string[] { "0", "1", "77", "2", "3", "77", "77", "4", "5", "77", "77", "77", "88", "6", "6", "77", "77", "88", "9" }); + Span<string> value = new Span<string>(new string[] { "100", "77", "88", "99" }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceMatchAtVeryEnd_String() + { + Span<string> span = new Span<string>(new string[] { "0", "1", "2", "3", "4", "5" }); + Span<string> value = new Span<string>(new string[] { "3", "4", "5" }); + int index = span.LastIndexOf(value); + Assert.Equal(3, index); + } + + [Fact] + public static void LastIndexOfSequenceJustPastVeryEnd_String() + { + Span<string> span = new Span<string>(new string[] { "0", "1", "2", "3", "4", "5" }, 0, 5); + Span<string> value = new Span<string>(new string[] { "3", "4", "5" }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceZeroLengthValue_String() + { + // A zero-length value is always "found" at the start of the span. + Span<string> span = new Span<string>(new string[] { "0", "1", "77", "2", "3", "77", "77", "4", "5", "77", "77", "77", "88", "6", "6", "77", "77", "88", "9" }); + Span<string> value = new Span<string>(Array.Empty<string>()); + int index = span.LastIndexOf(value); + Assert.Equal(0, index); + } + + [Fact] + public static void LastIndexOfSequenceZeroLengthSpan_String() + { + Span<string> span = new Span<string>(Array.Empty<string>()); + Span<string> value = new Span<string>(new string[] { "1", "2", "3" }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValue_String() + { + // A zero-length value is always "found" at the start of the span. + Span<string> span = new Span<string>(new string[] { "0", "1", "2", "3", "4", "5" }); + Span<string> value = new Span<string>(new string[] { "2" }); + int index = span.LastIndexOf(value); + Assert.Equal(2, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValueAtVeryEnd_String() + { + // A zero-length value is always "found" at the start of the span. + Span<string> span = new Span<string>(new string[] { "0", "1", "2", "3", "4", "5" }); + Span<string> value = new Span<string>(new string[] { "5" }); + int index = span.LastIndexOf(value); + Assert.Equal(5, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValueJustPasttVeryEnd_String() + { + // A zero-length value is always "found" at the start of the span. + Span<string> span = new Span<string>(new string[] { "0", "1", "2", "3", "4", "5" }, 0, 5); + Span<string> value = new Span<string>(new string[] { "5" }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + } +} diff --git a/src/System.Memory/tests/Span/LastIndexOfSequence.byte.cs b/src/System.Memory/tests/Span/LastIndexOfSequence.byte.cs new file mode 100644 index 0000000000..96b229725e --- /dev/null +++ b/src/System.Memory/tests/Span/LastIndexOfSequence.byte.cs @@ -0,0 +1,133 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Xunit; + +namespace System.SpanTests +{ + public static partial class SpanTests + { + [Fact] + public static void LastIndexOfSequenceMatchAtStart_Byte() + { + Span<byte> span = new Span<byte>(new byte[] { 5, 1, 77, 2, 3, 77, 77, 4, 5, 77, 77, 77, 88, 6, 6, 77, 77, 88, 9 }); + Span<byte> value = new Span<byte>(new byte[] { 5, 1, 77 }); + int index = span.LastIndexOf(value); + Assert.Equal(0, index); + } + + [Fact] + public static void LastIndexOfSequenceMultipleMatch_Byte() + { + Span<byte> span = new Span<byte>(new byte[] { 1, 2, 3, 1, 2, 3, 1, 2, 3, 1 }); + Span<byte> value = new Span<byte>(new byte[] { 2, 3 }); + int index = span.LastIndexOf(value); + Assert.Equal(7, index); + } + + [Fact] + public static void LastIndexOfSequenceRestart_Byte() + { + Span<byte> span = new Span<byte>(new byte[] { 0, 1, 77, 2, 3, 77, 77, 4, 5, 77, 77, 77, 88, 6, 6, 77, 77, 8, 9, 77, 0, 1 }); + Span<byte> value = new Span<byte>(new byte[] { 77, 77, 88 }); + int index = span.LastIndexOf(value); + Assert.Equal(10, index); + } + + [Fact] + public static void LastIndexOfSequenceNoMatch_Byte() + { + Span<byte> span = new Span<byte>(new byte[] { 0, 1, 77, 2, 3, 77, 77, 4, 5, 77, 77, 77, 88, 6, 6, 77, 77, 88, 9 }); + Span<byte> value = new Span<byte>(new byte[] { 77, 77, 88, 99 }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceNotEvenAHeadMatch_Byte() + { + Span<byte> span = new Span<byte>(new byte[] { 0, 1, 77, 2, 3, 77, 77, 4, 5, 77, 77, 77, 88, 6, 6, 77, 77, 88, 9 }); + Span<byte> value = new Span<byte>(new byte[] { 100, 77, 88, 99 }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceMatchAtVeryEnd_Byte() + { + Span<byte> span = new Span<byte>(new byte[] { 0, 1, 2, 3, 4, 5 }); + Span<byte> value = new Span<byte>(new byte[] { 3, 4, 5 }); + int index = span.LastIndexOf(value); + Assert.Equal(3, index); + } + + [Fact] + public static void LastIndexOfSequenceJustPastVeryEnd_Byte() + { + Span<byte> span = new Span<byte>(new byte[] { 0, 1, 2, 3, 4, 5 }, 0, 5); + Span<byte> value = new Span<byte>(new byte[] { 3, 4, 5 }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceZeroLengthValue_Byte() + { + // A zero-length value is always "found" at the start of the span. + Span<byte> span = new Span<byte>(new byte[] { 0, 1, 77, 2, 3, 77, 77, 4, 5, 77, 77, 77, 88, 6, 6, 77, 77, 88, 9 }); + Span<byte> value = new Span<byte>(Array.Empty<byte>()); + int index = span.LastIndexOf(value); + Assert.Equal(0, index); + } + + [Fact] + public static void LastIndexOfSequenceZeroLengthSpan_Byte() + { + Span<byte> span = new Span<byte>(Array.Empty<byte>()); + Span<byte> value = new Span<byte>(new byte[] { 1, 2, 3 }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValue_Byte() + { + // A zero-length value is always "found" at the start of the span. + Span<byte> span = new Span<byte>(new byte[] { 0, 1, 2, 3, 4, 5 }); + Span<byte> value = new Span<byte>(new byte[] { 2 }); + int index = span.LastIndexOf(value); + Assert.Equal(2, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValueAtVeryEnd_Byte() + { + // A zero-length value is always "found" at the start of the span. + Span<byte> span = new Span<byte>(new byte[] { 0, 1, 2, 3, 4, 5 }); + Span<byte> value = new Span<byte>(new byte[] { 5 }); + int index = span.LastIndexOf(value); + Assert.Equal(5, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValueMultipleTimes_Byte() + { + // A zero-length value is always "found" at the start of the span. + Span<byte> span = new Span<byte>(new byte[] { 0, 1, 5, 3, 4, 5 }); + Span<byte> value = new Span<byte>(new byte[] { 5 }); + int index = span.LastIndexOf(value); + Assert.Equal(5, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValueJustPasttVeryEnd_Byte() + { + // A zero-length value is always "found" at the start of the span. + Span<byte> span = new Span<byte>(new byte[] { 0, 1, 2, 3, 4, 5 }, 0, 5); + Span<byte> value = new Span<byte>(new byte[] { 5 }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + } +} diff --git a/src/System.Memory/tests/Span/LastIndexOfSequence.char.cs b/src/System.Memory/tests/Span/LastIndexOfSequence.char.cs new file mode 100644 index 0000000000..af027cb54a --- /dev/null +++ b/src/System.Memory/tests/Span/LastIndexOfSequence.char.cs @@ -0,0 +1,133 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Xunit; + +namespace System.SpanTests +{ + public static partial class SpanTests + { + [Fact] + public static void LastIndexOfSequenceMatchAtStart_Char() + { + Span<char> span = new Span<char>(new char[] { '5', '1', '7', '2', '3', '7', '7', '4', '5', '7', '7', '7', '8', '6', '6', '7', '7', '8', '9' }); + Span<char> value = new Span<char>(new char[] { '5', '1', '7' }); + int index = span.LastIndexOf(value); + Assert.Equal(0, index); + } + + [Fact] + public static void LastIndexOfSequenceMultipleMatch_Char() + { + Span<char> span = new Span<char>(new char[] { '1', '2', '3', '1', '2', '3', '1', '2', '3', '1' }); + Span<char> value = new Span<char>(new char[] { '2', '3' }); + int index = span.LastIndexOf(value); + Assert.Equal(7, index); + } + + [Fact] + public static void LastIndexOfSequenceRestart_Char() + { + Span<char> span = new Span<char>(new char[] { '5', '1', '7', '2', '3', '7', '7', '4', '5', '7', '7', '7', '8', '6', '6', '7', '7', '6', '9', '7', '0', '1' }); + Span<char> value = new Span<char>(new char[] { '7', '7', '8' }); + int index = span.LastIndexOf(value); + Assert.Equal(10, index); + } + + [Fact] + public static void LastIndexOfSequenceNoMatch_Char() + { + Span<char> span = new Span<char>(new char[] { '0', '1', '7', '2', '3', '7', '7', '4', '5', '7', '7', '7', '8', '6', '6', '7', '7', '8', '9' }); + Span<char> value = new Span<char>(new char[] { '7', '7', '8', 'X' }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceNotEvenAHeadMatch_Char() + { + Span<char> span = new Span<char>(new char[] { '0', '1', '7', '2', '3', '7', '7', '4', '5', '7', '7', '7', '8', '6', '6', '7', '7', '8', '9' }); + Span<char> value = new Span<char>(new char[] { 'X', '7', '8', '9' }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceMatchAtVeryEnd_Char() + { + Span<char> span = new Span<char>(new char[] { '0', '1', '2', '3', '4', '5' }); + Span<char> value = new Span<char>(new char[] { '3', '4', '5' }); + int index = span.LastIndexOf(value); + Assert.Equal(3, index); + } + + [Fact] + public static void LastIndexOfSequenceJustPastVeryEnd_Char() + { + Span<char> span = new Span<char>(new char[] { '0', '1', '2', '3', '4', '5' }, 0, 5); + Span<char> value = new Span<char>(new char[] { '3', '4', '5' }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceZeroLengthValue_Char() + { + // A zero-length value is always "found" at the start of the span. + Span<char> span = new Span<char>(new char[] { '0', '1', '7', '2', '3', '7', '7', '4', '5', '7', '7', '7', '8', '6', '6', '7', '7', '8', '9' }); + Span<char> value = new Span<char>(Array.Empty<char>()); + int index = span.LastIndexOf(value); + Assert.Equal(0, index); + } + + [Fact] + public static void LastIndexOfSequenceZeroLengthSpan_Char() + { + Span<char> span = new Span<char>(Array.Empty<char>()); + Span<char> value = new Span<char>(new char[] { '1', '2', '3' }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValue_Char() + { + // A zero-length value is always "found" at the start of the span. + Span<char> span = new Span<char>(new char[] { '0', '1', '2', '3', '4', '5' }); + Span<char> value = new Span<char>(new char[] { '2' }); + int index = span.LastIndexOf(value); + Assert.Equal(2, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValueAtVeryEnd_Char() + { + // A zero-length value is always "found" at the start of the span. + Span<char> span = new Span<char>(new char[] { '0', '1', '2', '3', '4', '5' }); + Span<char> value = new Span<char>(new char[] { '5' }); + int index = span.LastIndexOf(value); + Assert.Equal(5, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValueMultipleTimes_Char() + { + // A zero-length value is always "found" at the start of the span. + Span<char> span = new Span<char>(new char[] { '0', '1', '5', '3', '4', '5' }); + Span<char> value = new Span<char>(new char[] { '5' }); + int index = span.LastIndexOf(value); + Assert.Equal(5, index); + } + + [Fact] + public static void LastIndexOfSequenceLengthOneValueJustPasttVeryEnd_Char() + { + // A zero-length value is always "found" at the start of the span. + Span<char> span = new Span<char>(new char[] { '0', '1', '2', '3', '4', '5' }, 0, 5); + Span<char> value = new Span<char>(new char[] { '5' }); + int index = span.LastIndexOf(value); + Assert.Equal(-1, index); + } + } +} diff --git a/src/System.Memory/tests/Span/Overflow.cs b/src/System.Memory/tests/Span/Overflow.cs index b9f9070f1b..77d036d3ea 100644 --- a/src/System.Memory/tests/Span/Overflow.cs +++ b/src/System.Memory/tests/Span/Overflow.cs @@ -36,9 +36,9 @@ namespace System.SpanTests try { ref Guid memory = ref Unsafe.AsRef<Guid>(memBlock.ToPointer()); - var span = new Span<Guid>(memBlock.ToPointer(), GuidThreeGiBLimit); + var span = new Span<Guid>(memBlock.ToPointer(), s_guidThreeGiBLimit); - int bigIndex = checked(GuidTwoGiBLimit + 1); + int bigIndex = checked(s_guidTwoGiBLimit + 1); uint byteOffset = checked((uint)bigIndex * (uint)sizeof(Guid)); Assert.True(byteOffset > int.MaxValue); // Make sure byteOffset actually overflows 2Gb, or this test is pointless. ref Guid expected = ref Unsafe.Add<Guid>(ref memory, bigIndex); @@ -63,8 +63,7 @@ namespace System.SpanTests private const long TwoGiB = 2L * 1024L * 1024L * 1024L; private const long OneGiB = 1L * 1024L * 1024L * 1024L; - private static readonly int GuidThreeGiBLimit = (int)(ThreeGiB / Unsafe.SizeOf<Guid>()); // sizeof(Guid) requires unsafe keyword and I don't want to mark the entire class unsafe. - private static readonly int GuidTwoGiBLimit = (int)(TwoGiB / Unsafe.SizeOf<Guid>()); - private static readonly int GuidOneGiBLimit = (int)(OneGiB / Unsafe.SizeOf<Guid>()); + private static readonly int s_guidThreeGiBLimit = (int)(ThreeGiB / Unsafe.SizeOf<Guid>()); // sizeof(Guid) requires unsafe keyword and I don't want to mark the entire class unsafe. + private static readonly int s_guidTwoGiBLimit = (int)(TwoGiB / Unsafe.SizeOf<Guid>()); } } diff --git a/src/System.Memory/tests/System.Memory.Tests.csproj b/src/System.Memory/tests/System.Memory.Tests.csproj index f85ef25828..8a9cb59d7d 100644 --- a/src/System.Memory/tests/System.Memory.Tests.csproj +++ b/src/System.Memory/tests/System.Memory.Tests.csproj @@ -38,6 +38,12 @@ <Compile Include="Span\IndexOfSequence.T.cs" /> <Compile Include="Span\IndexOfSequence.byte.cs" /> <Compile Include="Span\IndexOfSequence.char.cs" /> + <Compile Include="Span\LastIndexOf.T.cs" /> + <Compile Include="Span\LastIndexOf.byte.cs" /> + <Compile Include="Span\LastIndexOf.char.cs" /> + <Compile Include="Span\LastIndexOfSequence.T.cs" /> + <Compile Include="Span\LastIndexOfSequence.byte.cs" /> + <Compile Include="Span\LastIndexOfSequence.char.cs" /> <Compile Include="Span\NonPortableCast.cs" /> <Compile Include="Span\Overflow.cs" /> <Compile Include="Span\SequenceEqual.T.cs" /> @@ -70,6 +76,12 @@ <Compile Include="ReadOnlySpan\IndexOfSequence.T.cs" /> <Compile Include="ReadOnlySpan\IndexOfSequence.byte.cs" /> <Compile Include="ReadOnlySpan\IndexOfSequence.char.cs" /> + <Compile Include="ReadOnlySpan\LastIndexOf.T.cs" /> + <Compile Include="ReadOnlySpan\LastIndexOf.byte.cs" /> + <Compile Include="ReadOnlySpan\LastIndexOf.char.cs" /> + <Compile Include="ReadOnlySpan\LastIndexOfSequence.T.cs" /> + <Compile Include="ReadOnlySpan\LastIndexOfSequence.byte.cs" /> + <Compile Include="ReadOnlySpan\LastIndexOfSequence.char.cs" /> <Compile Include="ReadOnlySpan\NonPortableCast.cs" /> <Compile Include="ReadOnlySpan\Overflow.cs" /> <Compile Include="ReadOnlySpan\Overlaps.cs" /> diff --git a/src/System.Memory/tests/TInt.cs b/src/System.Memory/tests/TInt.cs index e6dba18fe8..2bceaa2c80 100644 --- a/src/System.Memory/tests/TInt.cs +++ b/src/System.Memory/tests/TInt.cs @@ -13,7 +13,7 @@ namespace System internal struct TInt : IEquatable<TInt> { public TInt(int value) - : this(value, (Action<int,int>)null) + : this(value, (Action<int, int>)null) { // This constructor does not report comparisons but is still useful for catching uses of the boxing Equals(). } diff --git a/src/System.Memory/tests/TestHelpers.cs b/src/System.Memory/tests/TestHelpers.cs index 29e5291ca2..c5c2fece68 100644 --- a/src/System.Memory/tests/TestHelpers.cs +++ b/src/System.Memory/tests/TestHelpers.cs @@ -33,7 +33,7 @@ namespace System public delegate void AssertThrowsAction<T>(Span<T> span); // Cannot use standard Assert.Throws() when testing Span - Span and closures don't get along. - public static void AssertThrows<E, T>(Span<T> span, AssertThrowsAction<T> action) where E:Exception + public static void AssertThrows<E, T>(Span<T> span, AssertThrowsAction<T> action) where E : Exception { try { @@ -89,7 +89,7 @@ namespace System public delegate void AssertThrowsActionReadOnly<T>(ReadOnlySpan<T> span); // Cannot use standard Assert.Throws() when testing Span - Span and closures don't get along. - public static void AssertThrows<E, T>(ReadOnlySpan<T> span, AssertThrowsActionReadOnly<T> action) where E:Exception + public static void AssertThrows<E, T>(ReadOnlySpan<T> span, AssertThrowsActionReadOnly<T> action) where E : Exception { try { @@ -163,7 +163,7 @@ namespace System span.Clear(); } - public static TestStructExplicit testExplicitStruct = new TestStructExplicit + public static TestStructExplicit s_testExplicitStruct = new TestStructExplicit { S0 = short.MaxValue, I0 = int.MaxValue, @@ -183,18 +183,18 @@ namespace System { Span<byte> spanBE = new byte[Unsafe.SizeOf<TestStructExplicit>()]; - WriteInt16BigEndian(spanBE, testExplicitStruct.S0); - WriteInt32BigEndian(spanBE.Slice(2), testExplicitStruct.I0); - WriteInt64BigEndian(spanBE.Slice(6), testExplicitStruct.L0); - WriteUInt16BigEndian(spanBE.Slice(14), testExplicitStruct.US0); - WriteUInt32BigEndian(spanBE.Slice(16), testExplicitStruct.UI0); - WriteUInt64BigEndian(spanBE.Slice(20), testExplicitStruct.UL0); - WriteInt16BigEndian(spanBE.Slice(28), testExplicitStruct.S1); - WriteInt32BigEndian(spanBE.Slice(30), testExplicitStruct.I1); - WriteInt64BigEndian(spanBE.Slice(34), testExplicitStruct.L1); - WriteUInt16BigEndian(spanBE.Slice(42), testExplicitStruct.US1); - WriteUInt32BigEndian(spanBE.Slice(44), testExplicitStruct.UI1); - WriteUInt64BigEndian(spanBE.Slice(48), testExplicitStruct.UL1); + WriteInt16BigEndian(spanBE, s_testExplicitStruct.S0); + WriteInt32BigEndian(spanBE.Slice(2), s_testExplicitStruct.I0); + WriteInt64BigEndian(spanBE.Slice(6), s_testExplicitStruct.L0); + WriteUInt16BigEndian(spanBE.Slice(14), s_testExplicitStruct.US0); + WriteUInt32BigEndian(spanBE.Slice(16), s_testExplicitStruct.UI0); + WriteUInt64BigEndian(spanBE.Slice(20), s_testExplicitStruct.UL0); + WriteInt16BigEndian(spanBE.Slice(28), s_testExplicitStruct.S1); + WriteInt32BigEndian(spanBE.Slice(30), s_testExplicitStruct.I1); + WriteInt64BigEndian(spanBE.Slice(34), s_testExplicitStruct.L1); + WriteUInt16BigEndian(spanBE.Slice(42), s_testExplicitStruct.US1); + WriteUInt32BigEndian(spanBE.Slice(44), s_testExplicitStruct.UI1); + WriteUInt64BigEndian(spanBE.Slice(48), s_testExplicitStruct.UL1); Assert.Equal(56, spanBE.Length); return spanBE; @@ -204,23 +204,23 @@ namespace System { Span<byte> spanLE = new byte[Unsafe.SizeOf<TestStructExplicit>()]; - WriteInt16LittleEndian(spanLE, testExplicitStruct.S0); - WriteInt32LittleEndian(spanLE.Slice(2), testExplicitStruct.I0); - WriteInt64LittleEndian( spanLE.Slice(6), testExplicitStruct.L0); - WriteUInt16LittleEndian(spanLE.Slice(14), testExplicitStruct.US0); - WriteUInt32LittleEndian(spanLE.Slice(16), testExplicitStruct.UI0); - WriteUInt64LittleEndian(spanLE.Slice(20), testExplicitStruct.UL0); - WriteInt16LittleEndian(spanLE.Slice(28), testExplicitStruct.S1); - WriteInt32LittleEndian(spanLE.Slice(30), testExplicitStruct.I1); - WriteInt64LittleEndian(spanLE.Slice(34), testExplicitStruct.L1); - WriteUInt16LittleEndian(spanLE.Slice(42), testExplicitStruct.US1); - WriteUInt32LittleEndian(spanLE.Slice(44), testExplicitStruct.UI1); - WriteUInt64LittleEndian(spanLE.Slice(48), testExplicitStruct.UL1); + WriteInt16LittleEndian(spanLE, s_testExplicitStruct.S0); + WriteInt32LittleEndian(spanLE.Slice(2), s_testExplicitStruct.I0); + WriteInt64LittleEndian(spanLE.Slice(6), s_testExplicitStruct.L0); + WriteUInt16LittleEndian(spanLE.Slice(14), s_testExplicitStruct.US0); + WriteUInt32LittleEndian(spanLE.Slice(16), s_testExplicitStruct.UI0); + WriteUInt64LittleEndian(spanLE.Slice(20), s_testExplicitStruct.UL0); + WriteInt16LittleEndian(spanLE.Slice(28), s_testExplicitStruct.S1); + WriteInt32LittleEndian(spanLE.Slice(30), s_testExplicitStruct.I1); + WriteInt64LittleEndian(spanLE.Slice(34), s_testExplicitStruct.L1); + WriteUInt16LittleEndian(spanLE.Slice(42), s_testExplicitStruct.US1); + WriteUInt32LittleEndian(spanLE.Slice(44), s_testExplicitStruct.UI1); + WriteUInt64LittleEndian(spanLE.Slice(48), s_testExplicitStruct.UL1); Assert.Equal(56, spanLE.Length); return spanLE; } - + [StructLayout(LayoutKind.Explicit)] public struct TestStructExplicit { diff --git a/src/System.Runtime/ref/System.Runtime.cs b/src/System.Runtime/ref/System.Runtime.cs index 20301c7515..960e91f427 100644 --- a/src/System.Runtime/ref/System.Runtime.cs +++ b/src/System.Runtime/ref/System.Runtime.cs @@ -64,9 +64,9 @@ namespace System public static object CreateInstance(System.Type type) { throw null; } public static object CreateInstance(System.Type type, System.Boolean nonPublic) { throw null; } public static object CreateInstance(System.Type type, params object[] args) { throw null; } - public static object CreateInstance(System.Type type, object[] args, object[] activationAttributes) { throw null; } - public static object CreateInstance(System.Type type, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, object[] args, System.Globalization.CultureInfo culture) { throw null; } - public static object CreateInstance(System.Type type, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, object[] args, System.Globalization.CultureInfo culture, object[] activationAttributes) { throw null; } + public static object CreateInstance(System.Type type, object[] args, object[] activationAttributes) { throw null; } + public static object CreateInstance(System.Type type, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, object[] args, System.Globalization.CultureInfo culture) { throw null; } + public static object CreateInstance(System.Type type, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, object[] args, System.Globalization.CultureInfo culture, object[] activationAttributes) { throw null; } public static T CreateInstance<T>() { throw null; } } @@ -78,7 +78,7 @@ namespace System public static string TargetFrameworkName { get { throw null; } } public static object GetData(string name) { throw null; } } - + public partial class EntryPointNotFoundException : System.TypeLoadException { public EntryPointNotFoundException() { } @@ -402,14 +402,14 @@ namespace System public static System.Attribute[] GetCustomAttributes(System.Reflection.ParameterInfo element, bool inherit) { throw null; } public static System.Attribute[] GetCustomAttributes(System.Reflection.ParameterInfo element, System.Type attributeType) { throw null; } public static System.Attribute[] GetCustomAttributes(System.Reflection.ParameterInfo element, System.Type attributeType, bool inherit) { throw null; } - public static bool IsDefined(System.Reflection.Assembly element, System.Type attributeType) { throw null; } - public static bool IsDefined(System.Reflection.Assembly element, System.Type attributeType, bool inherit) { throw null; } - public static bool IsDefined(System.Reflection.MemberInfo element, System.Type attributeType) { throw null; } - public static bool IsDefined(System.Reflection.MemberInfo element, System.Type attributeType, bool inherit) { throw null; } - public static bool IsDefined(System.Reflection.Module element, System.Type attributeType) { throw null; } - public static bool IsDefined(System.Reflection.Module element, System.Type attributeType, bool inherit) { throw null; } - public static bool IsDefined(System.Reflection.ParameterInfo element, System.Type attributeType) { throw null; } - public static bool IsDefined(System.Reflection.ParameterInfo element, System.Type attributeType, bool inherit) { throw null; } + public static bool IsDefined(System.Reflection.Assembly element, System.Type attributeType) { throw null; } + public static bool IsDefined(System.Reflection.Assembly element, System.Type attributeType, bool inherit) { throw null; } + public static bool IsDefined(System.Reflection.MemberInfo element, System.Type attributeType) { throw null; } + public static bool IsDefined(System.Reflection.MemberInfo element, System.Type attributeType, bool inherit) { throw null; } + public static bool IsDefined(System.Reflection.Module element, System.Type attributeType) { throw null; } + public static bool IsDefined(System.Reflection.Module element, System.Type attributeType, bool inherit) { throw null; } + public static bool IsDefined(System.Reflection.ParameterInfo element, System.Type attributeType) { throw null; } + public static bool IsDefined(System.Reflection.ParameterInfo element, System.Type attributeType, bool inherit) { throw null; } } [System.FlagsAttribute] public enum AttributeTargets @@ -614,7 +614,7 @@ namespace System public static char ToUpperInvariant(char c) { throw null; } public static bool TryParse(string s, out char result) { throw null; } } - public sealed partial class CharEnumerator : System.Collections.Generic.IEnumerator<char>, System.Collections.IEnumerator, System.ICloneable, System.IDisposable + public sealed partial class CharEnumerator : System.Collections.Generic.IEnumerator<char>, System.Collections.IEnumerator, System.ICloneable, System.IDisposable { internal CharEnumerator() { } public char Current { get { throw null; } } @@ -930,38 +930,38 @@ namespace System public static decimal operator --(decimal d) { throw null; } public static decimal operator /(decimal d1, decimal d2) { throw null; } public static bool operator ==(decimal d1, decimal d2) { throw null; } - public static explicit operator byte (decimal value) { throw null; } - public static explicit operator char (decimal value) { throw null; } - public static explicit operator double (decimal value) { throw null; } - public static explicit operator short (decimal value) { throw null; } - public static explicit operator int (decimal value) { throw null; } - public static explicit operator long (decimal value) { throw null; } + public static explicit operator byte(decimal value) { throw null; } + public static explicit operator char(decimal value) { throw null; } + public static explicit operator double(decimal value) { throw null; } + public static explicit operator short(decimal value) { throw null; } + public static explicit operator int(decimal value) { throw null; } + public static explicit operator long(decimal value) { throw null; } [System.CLSCompliantAttribute(false)] - public static explicit operator sbyte (decimal value) { throw null; } - public static explicit operator float (decimal value) { throw null; } + public static explicit operator sbyte(decimal value) { throw null; } + public static explicit operator float(decimal value) { throw null; } [System.CLSCompliantAttribute(false)] - public static explicit operator ushort (decimal value) { throw null; } + public static explicit operator ushort(decimal value) { throw null; } [System.CLSCompliantAttribute(false)] - public static explicit operator uint (decimal value) { throw null; } + public static explicit operator uint(decimal value) { throw null; } [System.CLSCompliantAttribute(false)] - public static explicit operator ulong (decimal value) { throw null; } - public static explicit operator decimal (double value) { throw null; } - public static explicit operator decimal (float value) { throw null; } + public static explicit operator ulong(decimal value) { throw null; } + public static explicit operator decimal(double value) { throw null; } + public static explicit operator decimal(float value) { throw null; } public static bool operator >(decimal d1, decimal d2) { throw null; } public static bool operator >=(decimal d1, decimal d2) { throw null; } - public static implicit operator decimal (byte value) { throw null; } - public static implicit operator decimal (char value) { throw null; } - public static implicit operator decimal (short value) { throw null; } - public static implicit operator decimal (int value) { throw null; } - public static implicit operator decimal (long value) { throw null; } + public static implicit operator decimal(byte value) { throw null; } + public static implicit operator decimal(char value) { throw null; } + public static implicit operator decimal(short value) { throw null; } + public static implicit operator decimal(int value) { throw null; } + public static implicit operator decimal(long value) { throw null; } [System.CLSCompliantAttribute(false)] - public static implicit operator decimal (sbyte value) { throw null; } + public static implicit operator decimal(sbyte value) { throw null; } [System.CLSCompliantAttribute(false)] - public static implicit operator decimal (ushort value) { throw null; } + public static implicit operator decimal(ushort value) { throw null; } [System.CLSCompliantAttribute(false)] - public static implicit operator decimal (uint value) { throw null; } + public static implicit operator decimal(uint value) { throw null; } [System.CLSCompliantAttribute(false)] - public static implicit operator decimal (ulong value) { throw null; } + public static implicit operator decimal(ulong value) { throw null; } public static decimal operator ++(decimal d) { throw null; } public static bool operator !=(decimal d1, decimal d2) { throw null; } public static bool operator <(decimal d1, decimal d2) { throw null; } @@ -1025,7 +1025,7 @@ namespace System public static bool TryParse(System.ReadOnlySpan<char> s, out decimal result) { throw null; } public static bool TryParse(System.ReadOnlySpan<char> s, System.Globalization.NumberStyles style, System.IFormatProvider provider, out decimal result) { throw null; } } - public abstract partial class Delegate: System.ICloneable, System.Runtime.Serialization.ISerializable + public abstract partial class Delegate : System.ICloneable, System.Runtime.Serialization.ISerializable { protected Delegate(object target, string method) { } protected Delegate(System.Type target, string method) { } @@ -1177,7 +1177,7 @@ namespace System public override string ToString() { throw null; } public string ToString(string format) { throw null; } [System.ObsoleteAttribute("The provider argument is not used. Please use ToString().")] - public string ToString(System.IFormatProvider provider) { throw null; } + public string ToString(System.IFormatProvider provider) { throw null; } [System.ObsoleteAttribute("The provider argument is not used. Please use ToString(String).")] public string ToString(string format, System.IFormatProvider provider) { throw null; } public static bool TryParse(System.Type enumType, string value, out object result) { throw null; } @@ -1206,7 +1206,7 @@ namespace System public virtual string Message { get { throw null; } } public virtual string Source { get { throw null; } set { } } public virtual string StackTrace { get { throw null; } } - public System.Reflection.MethodBase TargetSite { get { throw null; } } + public System.Reflection.MethodBase TargetSite { get { throw null; } } protected event System.EventHandler<System.Runtime.Serialization.SafeSerializationEventArgs> SerializeObjectState { add { } remove { } } public virtual System.Exception GetBaseException() { throw null; } public virtual void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } @@ -1558,8 +1558,8 @@ namespace System public static bool operator ==(System.IntPtr value1, System.IntPtr value2) { throw null; } public static explicit operator System.IntPtr(int value) { throw null; } public static explicit operator System.IntPtr(long value) { throw null; } - public static explicit operator int (System.IntPtr value) { throw null; } - public static explicit operator long (System.IntPtr value) { throw null; } + public static explicit operator int(System.IntPtr value) { throw null; } + public static explicit operator long(System.IntPtr value) { throw null; } [System.CLSCompliantAttribute(false)] public static unsafe explicit operator void* (System.IntPtr value) { throw null; } [System.CLSCompliantAttribute(false)] @@ -3180,7 +3180,7 @@ namespace System } [System.CLSCompliantAttribute(false)] [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] - public partial struct UIntPtr : System.Runtime.Serialization.ISerializable, IEquatable<UIntPtr> + public partial struct UIntPtr : System.Runtime.Serialization.ISerializable, IEquatable<UIntPtr> { public static readonly System.UIntPtr Zero; public UIntPtr(uint value) { throw null; } @@ -3197,8 +3197,8 @@ namespace System public static bool operator ==(System.UIntPtr value1, System.UIntPtr value2) { throw null; } public static explicit operator System.UIntPtr(uint value) { throw null; } public static explicit operator System.UIntPtr(ulong value) { throw null; } - public static explicit operator uint (System.UIntPtr value) { throw null; } - public static explicit operator ulong (System.UIntPtr value) { throw null; } + public static explicit operator uint(System.UIntPtr value) { throw null; } + public static explicit operator ulong(System.UIntPtr value) { throw null; } [System.CLSCompliantAttribute(false)] public static unsafe explicit operator void* (System.UIntPtr value) { throw null; } [System.CLSCompliantAttribute(false)] @@ -3462,7 +3462,7 @@ namespace System public static ValueTuple<T1, T2, T3, T4> Create<T1, T2, T3, T4>(T1 item1, T2 item2, T3 item3, T4 item4) { throw null; } public static ValueTuple<T1, T2, T3, T4, T5> Create<T1, T2, T3, T4, T5>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5) { throw null; } public static ValueTuple<T1, T2, T3, T4, T5, T6> Create<T1, T2, T3, T4, T5, T6>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6) { throw null; } - public static ValueTuple<T1, T2, T3, T4, T5, T6, T7> Create<T1, T2, T3, T4, T5, T6, T7>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) { throw null; } + public static ValueTuple<T1, T2, T3, T4, T5, T6, T7> Create<T1, T2, T3, T4, T5, T6, T7>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7) { throw null; } public static ValueTuple<T1, T2, T3, T4, T5, T6, T7, ValueTuple<T8>> Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8) { throw null; } } public struct ValueTuple<T1> @@ -3711,7 +3711,7 @@ namespace System.Runtime.ConstrainedExecution protected CriticalFinalizerObject() { } ~CriticalFinalizerObject() { } } - + public enum Cer { MayFail = 1, @@ -3725,7 +3725,7 @@ namespace System.Runtime.ConstrainedExecution MayCorruptProcess = 0, WillNotCorruptState = 3, } - [System.AttributeUsageAttribute((System.AttributeTargets)(1133), Inherited=false)] + [System.AttributeUsageAttribute((System.AttributeTargets)(1133), Inherited = false)] public sealed partial class ReliabilityContractAttribute : System.Attribute { public ReliabilityContractAttribute(System.Runtime.ConstrainedExecution.Consistency consistencyGuarantee, System.Runtime.ConstrainedExecution.Cer cer) { } @@ -3864,23 +3864,23 @@ namespace System.Runtime.CompilerServices } namespace System.Buffers { - public unsafe struct MemoryHandle : IDisposable + public unsafe struct MemoryHandle : IDisposable { [System.CLSCompliantAttribute(false)] - public MemoryHandle(IRetainable owner, void* pointer = null, System.Runtime.InteropServices.GCHandle handle = default(System.Runtime.InteropServices.GCHandle)) { throw null; } + public MemoryHandle(IRetainable owner, void* pointer = null, System.Runtime.InteropServices.GCHandle handle = default(System.Runtime.InteropServices.GCHandle)) { throw null; } [System.CLSCompliantAttribute(false)] public void* Pointer { get { throw null; } } public bool HasPointer { get { throw null; } } public void Dispose() { throw null; } } - public interface IRetainable + public interface IRetainable { bool Release(); void Retain(); } - - public abstract class OwnedMemory<T> : IDisposable, IRetainable + + public abstract class OwnedMemory<T> : IDisposable, IRetainable { public Memory<T> Memory { get { throw null; } } public abstract bool IsDisposed { get; } @@ -4064,7 +4064,7 @@ namespace System.Collections.Generic } public static class KeyValuePair { - public static KeyValuePair<TKey, TValue> Create<TKey, TValue>(TKey key, TValue value) { throw null; } + public static KeyValuePair<TKey, TValue> Create<TKey, TValue>(TKey key, TValue value) { throw null; } } [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public readonly partial struct KeyValuePair<TKey, TValue> @@ -4204,9 +4204,9 @@ namespace System.Configuration.Assemblies } public enum AssemblyVersionCompatibility { - SameMachine = 1, - SameProcess = 2, - SameDomain = 3, + SameMachine = 1, + SameProcess = 2, + SameDomain = 3, } } namespace System.Diagnostics @@ -4953,7 +4953,7 @@ namespace System.Globalization public string GetUnicode(string ascii) { throw null; } public string GetUnicode(string ascii, int index) { throw null; } public string GetUnicode(string ascii, int index, int count) { throw null; } - } + } public partial class CultureNotFoundException : System.ArgumentException, System.Runtime.Serialization.ISerializable { public CultureNotFoundException() { } @@ -5390,7 +5390,7 @@ namespace System.Reflection public static System.Reflection.Assembly ReflectionOnlyLoadFrom(string assemblyFile) { throw null; } public virtual bool IsDefined(Type attributeType, bool inherit) { throw null; } } - [System.AttributeUsageAttribute((System.AttributeTargets)(1), Inherited=false)] + [System.AttributeUsageAttribute((System.AttributeTargets)(1), Inherited = false)] public sealed partial class AssemblyAlgorithmIdAttribute : System.Attribute { public AssemblyAlgorithmIdAttribute(System.Configuration.Assemblies.AssemblyHashAlgorithm algorithmId) { } @@ -5575,7 +5575,7 @@ namespace System.Reflection CreateInstance = 512, DeclaredOnly = 2, Default = 0, - DoNotWrapExceptions = 33554432, + DoNotWrapExceptions = 33554432, ExactBinding = 65536, FlattenHierarchy = 64, GetField = 1024, @@ -5609,8 +5609,8 @@ namespace System.Reflection public static readonly string TypeConstructorName; protected ConstructorInfo() { } public override bool Equals(object obj) { throw null; } - public static bool operator==(System.Reflection.ConstructorInfo left, System.Reflection.ConstructorInfo right) { throw null; } - public static bool operator!=(System.Reflection.ConstructorInfo left, System.Reflection.ConstructorInfo right) { throw null; } + public static bool operator ==(System.Reflection.ConstructorInfo left, System.Reflection.ConstructorInfo right) { throw null; } + public static bool operator !=(System.Reflection.ConstructorInfo left, System.Reflection.ConstructorInfo right) { throw null; } public override int GetHashCode() { throw null; } public object Invoke(object[] parameters) { throw null; } public abstract object Invoke(System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object[] parameters, System.Globalization.CultureInfo culture); @@ -5758,7 +5758,7 @@ namespace System.Reflection public override string ToString() { throw null; } } [System.FlagsAttribute] - public enum ExceptionHandlingClauseOptions: int + public enum ExceptionHandlingClauseOptions : int { Clause = 0, Filter = 1, @@ -6055,7 +6055,8 @@ namespace System.Reflection public override MemberTypes MemberType { get { throw null; } } public abstract System.Reflection.ICustomAttributeProvider ReturnTypeCustomAttributes { get; } } - public sealed class Missing : System.Runtime.Serialization.ISerializable { + public sealed class Missing : System.Runtime.Serialization.ISerializable + { internal Missing() { } public static readonly System.Reflection.Missing Value; void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } @@ -6187,7 +6188,7 @@ namespace System.Reflection [System.CLSCompliantAttribute(false)] public sealed class Pointer : System.Runtime.Serialization.ISerializable { - private Pointer() { } + private Pointer() { } public static unsafe object Box(void* ptr, System.Type type) { throw null; } public static unsafe void* Unbox(object ptr) { throw null; } unsafe void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } @@ -6196,11 +6197,11 @@ namespace System.Reflection public enum PortableExecutableKinds { NotAPortableExecutableImage = 0, - ILOnly = 1, - Required32Bit = 2, - PE32Plus = 4, - Unmanaged32Bit = 8, - Preferred32Bit = 16, + ILOnly = 1, + Required32Bit = 2, + PE32Plus = 4, + Unmanaged32Bit = 8, + Preferred32Bit = 16, } public enum ProcessorArchitecture { @@ -6244,7 +6245,7 @@ namespace System.Reflection public abstract object GetValue(object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object[] index, System.Globalization.CultureInfo culture); public void SetValue(object obj, object value) { } public virtual void SetValue(object obj, object value, object[] index) { } - public abstract void SetValue(object obj, object value, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object[] index, System.Globalization.CultureInfo culture); + public abstract void SetValue(object obj, object value, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object[] index, System.Globalization.CultureInfo culture); public override MemberTypes MemberType { get { throw null; } } public MethodInfo[] GetAccessors() { throw null; } public abstract MethodInfo[] GetAccessors(bool nonPublic); @@ -6360,7 +6361,7 @@ namespace System.Reflection public TypeDelegator(System.Type delegatingType) { } public override System.Guid GUID { get { throw null; } } public override int MetadataToken { get { throw null; } } - public override object InvokeMember(System.String name,System.Reflection.BindingFlags invokeAttr,System.Reflection.Binder binder,System.Object target, System.Object[] args,System.Reflection.ParameterModifier[] modifiers,System.Globalization.CultureInfo culture,System.String[] namedParameters) { throw null; } + public override object InvokeMember(System.String name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object target, System.Object[] args, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, System.String[] namedParameters) { throw null; } public override System.Reflection.Module Module { get { throw null; } } public override System.Reflection.Assembly Assembly { get { throw null; } } public override System.RuntimeTypeHandle TypeHandle { get { throw null; } } @@ -6369,22 +6370,22 @@ namespace System.Reflection public override System.String Namespace { get { throw null; } } public override System.String AssemblyQualifiedName { get { throw null; } } public override System.Type BaseType { get { throw null; } } - protected override System.Reflection.ConstructorInfo GetConstructorImpl(System.Reflection.BindingFlags bindingAttr,System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) { throw null; } + protected override System.Reflection.ConstructorInfo GetConstructorImpl(System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) { throw null; } public override System.Reflection.ConstructorInfo[] GetConstructors(System.Reflection.BindingFlags bindingAttr) { throw null; } - protected override System.Reflection.MethodInfo GetMethodImpl(System.String name,System.Reflection.BindingFlags bindingAttr,System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, System.Type[] types,System.Reflection.ParameterModifier[] modifiers) { throw null; } + protected override System.Reflection.MethodInfo GetMethodImpl(System.String name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Reflection.CallingConventions callConvention, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) { throw null; } public override System.Reflection.MethodInfo[] GetMethods(System.Reflection.BindingFlags bindingAttr) { throw null; } public override System.Reflection.FieldInfo GetField(System.String name, System.Reflection.BindingFlags bindingAttr) { throw null; } public override System.Reflection.FieldInfo[] GetFields(System.Reflection.BindingFlags bindingAttr) { throw null; } public override System.Type GetInterface(System.String name, bool ignoreCase) { throw null; } public override System.Type[] GetInterfaces() { throw null; } - public override System.Reflection.EventInfo GetEvent(System.String name,System.Reflection.BindingFlags bindingAttr) { throw null; } + public override System.Reflection.EventInfo GetEvent(System.String name, System.Reflection.BindingFlags bindingAttr) { throw null; } public override System.Reflection.EventInfo[] GetEvents() { throw null; } - protected override System.Reflection.PropertyInfo GetPropertyImpl(System.String name,System.Reflection.BindingFlags bindingAttr,System.Reflection.Binder binder, System.Type returnType, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) { throw null; } + protected override System.Reflection.PropertyInfo GetPropertyImpl(System.String name, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Type returnType, System.Type[] types, System.Reflection.ParameterModifier[] modifiers) { throw null; } public override System.Reflection.PropertyInfo[] GetProperties(System.Reflection.BindingFlags bindingAttr) { throw null; } public override System.Reflection.EventInfo[] GetEvents(System.Reflection.BindingFlags bindingAttr) { throw null; } public override System.Type[] GetNestedTypes(System.Reflection.BindingFlags bindingAttr) { throw null; } public override System.Type GetNestedType(System.String name, System.Reflection.BindingFlags bindingAttr) { throw null; } - public override System.Reflection.MemberInfo[] GetMember(System.String name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) { throw null; } + public override System.Reflection.MemberInfo[] GetMember(System.String name, System.Reflection.MemberTypes type, System.Reflection.BindingFlags bindingAttr) { throw null; } public override System.Reflection.MemberInfo[] GetMembers(System.Reflection.BindingFlags bindingAttr) { throw null; } public override bool IsByRefLike { get { throw null; } } protected override System.Reflection.TypeAttributes GetAttributeFlagsImpl() { throw null; } @@ -6466,8 +6467,8 @@ namespace System.Runtime public static partial class GCSettings { public static bool IsServerGC { get { throw null; } } - public static System.Runtime.GCLargeObjectHeapCompactionMode LargeObjectHeapCompactionMode { get { throw null; }set { } } - public static System.Runtime.GCLatencyMode LatencyMode { get { throw null; }set { } } + public static System.Runtime.GCLargeObjectHeapCompactionMode LargeObjectHeapCompactionMode { get { throw null; } set { } } + public static System.Runtime.GCLatencyMode LatencyMode { get { throw null; } set { } } } public sealed partial class MemoryFailPoint : System.Runtime.ConstrainedExecution.CriticalFinalizerObject, System.IDisposable { @@ -6494,14 +6495,14 @@ namespace System.Runtime.CompilerServices IL = System.Reflection.MethodImplAttributes.IL, Native = System.Reflection.MethodImplAttributes.Native, OPTIL = System.Reflection.MethodImplAttributes.OPTIL, - Runtime = System.Reflection.MethodImplAttributes.Runtime + Runtime = System.Reflection.MethodImplAttributes.Runtime } [Flags] public enum CompilationRelaxations : int - { - NoStringInterning = 0x0008, // Start in 0x0008, we had other non public flags in this enum before, - // so we'll start here just in case somebody used them. This flag is only - // valid when set for Assemblies. + { + NoStringInterning = 0x0008, // Start in 0x0008, we had other non public flags in this enum before, + // so we'll start here just in case somebody used them. This flag is only + // valid when set for Assemblies. }; [System.AttributeUsageAttribute((System.AttributeTargets)(256))] public sealed partial class AccessedThroughPropertyAttribute : System.Attribute @@ -6551,14 +6552,14 @@ namespace System.Runtime.CompilerServices { public CompilationRelaxationsAttribute(int relaxations) { } public int CompilationRelaxations { get { throw null; } } - public CompilationRelaxationsAttribute (System.Runtime.CompilerServices.CompilationRelaxations relaxations) { } + public CompilationRelaxationsAttribute(System.Runtime.CompilerServices.CompilationRelaxations relaxations) { } } [System.AttributeUsageAttribute((System.AttributeTargets)(32767), Inherited = true)] public sealed partial class CompilerGeneratedAttribute : System.Attribute { public CompilerGeneratedAttribute() { } } - public sealed partial class ConditionalWeakTable<TKey, TValue> : System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<TKey,TValue>> where TKey : class where TValue : class + public sealed partial class ConditionalWeakTable<TKey, TValue> : System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<TKey, TValue>> where TKey : class where TValue : class { public ConditionalWeakTable() { } public void Add(TKey key, TValue value) { } @@ -6693,7 +6694,7 @@ namespace System.Runtime.CompilerServices } public static partial class RuntimeHelpers { - public static new bool Equals(object o1, object o2) { throw null; } + public static new bool Equals(object o1, object o2) { throw null; } public static int OffsetToStringData { get { throw null; } } public static void EnsureSufficientExecutionStack() { } public static int GetHashCode(object o) { throw null; } @@ -6771,7 +6772,7 @@ namespace System.Runtime.CompilerServices public DefaultDependencyAttribute(System.Runtime.CompilerServices.LoadHint loadHintArgument) { } public System.Runtime.CompilerServices.LoadHint LoadHint { get { throw null; } } } - [System.AttributeUsageAttribute((System.AttributeTargets)(1), AllowMultiple=true)] + [System.AttributeUsageAttribute((System.AttributeTargets)(1), AllowMultiple = true)] public sealed partial class DependencyAttribute : System.Attribute { public DependencyAttribute(string dependentAssemblyArgument, System.Runtime.CompilerServices.LoadHint loadHintArgument) { } @@ -6782,7 +6783,7 @@ namespace System.Runtime.CompilerServices { public DiscardableAttribute() { } } - public enum LoadHint + public enum LoadHint { Always = 1, Default = 0, @@ -6811,7 +6812,7 @@ namespace System.Runtime.CompilerServices public object WrappedException { get { throw null; } } public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } } - [System.AttributeUsageAttribute((System.AttributeTargets)(1), Inherited=false)] + [System.AttributeUsageAttribute((System.AttributeTargets)(1), Inherited = false)] public sealed partial class StringFreezingAttribute : System.Attribute { public StringFreezingAttribute() { } @@ -6832,7 +6833,7 @@ namespace System.Runtime.ExceptionServices public void Throw() { } public static void Throw(Exception source) { } } - [System.AttributeUsageAttribute((System.AttributeTargets)(64), AllowMultiple=false, Inherited=false)] + [System.AttributeUsageAttribute((System.AttributeTargets)(64), AllowMultiple = false, Inherited = false)] public sealed partial class HandleProcessCorruptedStateExceptionsAttribute : System.Attribute { public HandleProcessCorruptedStateExceptionsAttribute() { } @@ -6868,7 +6869,7 @@ namespace System.Runtime.InteropServices public partial struct GCHandle { public bool IsAllocated { get { throw null; } } - public object Target {get { throw null; } set { } } + public object Target { get { throw null; } set { } } public System.IntPtr AddrOfPinnedObject() { throw null; } public static System.Runtime.InteropServices.GCHandle Alloc(object value) { throw null; } public static System.Runtime.InteropServices.GCHandle Alloc(object value, System.Runtime.InteropServices.GCHandleType type) { throw null; } @@ -7120,7 +7121,7 @@ namespace System.Security.Cryptography namespace System.Security { - [System.AttributeUsageAttribute((System.AttributeTargets)(1), AllowMultiple=false, Inherited=false)] + [System.AttributeUsageAttribute((System.AttributeTargets)(1), AllowMultiple = false, Inherited = false)] public sealed partial class AllowPartiallyTrustedCallersAttribute : System.Attribute { public AllowPartiallyTrustedCallersAttribute() { } @@ -7131,7 +7132,7 @@ namespace System.Security NotVisibleByDefault = 1, VisibleToAllHosts = 0, } - [System.AttributeUsageAttribute((System.AttributeTargets)(5501), AllowMultiple=false, Inherited=false)] + [System.AttributeUsageAttribute((System.AttributeTargets)(5501), AllowMultiple = false, Inherited = false)] public sealed partial class SecurityCriticalAttribute : System.Attribute { public SecurityCriticalAttribute() { } @@ -7168,7 +7169,7 @@ namespace System.Security public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } public override string ToString() { throw null; } } - [System.AttributeUsageAttribute((System.AttributeTargets)(1), AllowMultiple=false)] + [System.AttributeUsageAttribute((System.AttributeTargets)(1), AllowMultiple = false)] public sealed partial class SecurityRulesAttribute : System.Attribute { public SecurityRulesAttribute(System.Security.SecurityRuleSet ruleSet) { } @@ -7181,28 +7182,28 @@ namespace System.Security Level2 = (byte)2, None = (byte)0, } - [System.AttributeUsageAttribute((System.AttributeTargets)(5500), AllowMultiple=false, Inherited=false)] + [System.AttributeUsageAttribute((System.AttributeTargets)(5500), AllowMultiple = false, Inherited = false)] public sealed partial class SecuritySafeCriticalAttribute : System.Attribute { public SecuritySafeCriticalAttribute() { } } - [System.AttributeUsageAttribute((System.AttributeTargets)(1), AllowMultiple=false, Inherited=false)] + [System.AttributeUsageAttribute((System.AttributeTargets)(1), AllowMultiple = false, Inherited = false)] public sealed partial class SecurityTransparentAttribute : System.Attribute { public SecurityTransparentAttribute() { } } - [System.AttributeUsageAttribute((System.AttributeTargets)(5501), AllowMultiple=false, Inherited=false)] + [System.AttributeUsageAttribute((System.AttributeTargets)(5501), AllowMultiple = false, Inherited = false)] [System.ObsoleteAttribute("SecurityTreatAsSafe is only used for .NET 2.0 transparency compatibility. Please use the SecuritySafeCriticalAttribute instead.")] public sealed partial class SecurityTreatAsSafeAttribute : System.Attribute { public SecurityTreatAsSafeAttribute() { } } - [System.AttributeUsageAttribute((System.AttributeTargets)(5188), AllowMultiple=true, Inherited=false)] + [System.AttributeUsageAttribute((System.AttributeTargets)(5188), AllowMultiple = true, Inherited = false)] public sealed partial class SuppressUnmanagedCodeSecurityAttribute : System.Attribute { public SuppressUnmanagedCodeSecurityAttribute() { } } - [System.AttributeUsageAttribute((System.AttributeTargets)(2), AllowMultiple=true, Inherited=false)] + [System.AttributeUsageAttribute((System.AttributeTargets)(2), AllowMultiple = true, Inherited = false)] public sealed partial class UnverifiableCodeAttribute : System.Attribute { public UnverifiableCodeAttribute() { } |