diff --git a/.editorconfig b/.editorconfig index 36629f6b744..d10fc7eea1f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -327,4 +327,4 @@ dotnet_diagnostic.SA1413.severity = none # UseTrailingCommasInMultiLineInitializ dotnet_diagnostic.SA1314.severity = none # TypeParameterNamesMustBeginWithT: We do have a few templates that don't start with T. We need to double check that changing this is not a breaking change. If not, we can re-enable this. dotnet_diagnostic.SA1000.severity = none # Hide warnings when using the new() expression from C# 9. dotnet_diagnostic.SA1313.severity = none # Hide warnings for record parameters. -dotnet_diagnostic.SA1101.severity = none # Hide warnings when accessing properties without "this". \ No newline at end of file +dotnet_diagnostic.SA1101.severity = none # Hide warnings when accessing properties without "this". diff --git a/Microsoft.Toolkit.HighPerformance/Buffers/MemoryOwner{T}.cs b/Microsoft.Toolkit.HighPerformance/Buffers/MemoryOwner{T}.cs index da8234dc070..174f3a4b613 100644 --- a/Microsoft.Toolkit.HighPerformance/Buffers/MemoryOwner{T}.cs +++ b/Microsoft.Toolkit.HighPerformance/Buffers/MemoryOwner{T}.cs @@ -91,7 +91,7 @@ private MemoryOwner(int start, int length, ArrayPool pool, T[] array) public static MemoryOwner Empty { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => new MemoryOwner(0, ArrayPool.Shared, AllocationMode.Default); + get => new(0, ArrayPool.Shared, AllocationMode.Default); } /// @@ -103,7 +103,7 @@ public static MemoryOwner Empty /// This method is just a proxy for the constructor, for clarity. [Pure] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static MemoryOwner Allocate(int size) => new MemoryOwner(size, ArrayPool.Shared, AllocationMode.Default); + public static MemoryOwner Allocate(int size) => new(size, ArrayPool.Shared, AllocationMode.Default); /// /// Creates a new instance with the specified parameters. @@ -115,7 +115,7 @@ public static MemoryOwner Empty /// This method is just a proxy for the constructor, for clarity. [Pure] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static MemoryOwner Allocate(int size, ArrayPool pool) => new MemoryOwner(size, pool, AllocationMode.Default); + public static MemoryOwner Allocate(int size, ArrayPool pool) => new(size, pool, AllocationMode.Default); /// /// Creates a new instance with the specified parameters. @@ -127,7 +127,7 @@ public static MemoryOwner Empty /// This method is just a proxy for the constructor, for clarity. [Pure] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static MemoryOwner Allocate(int size, AllocationMode mode) => new MemoryOwner(size, ArrayPool.Shared, mode); + public static MemoryOwner Allocate(int size, AllocationMode mode) => new(size, ArrayPool.Shared, mode); /// /// Creates a new instance with the specified parameters. @@ -140,7 +140,7 @@ public static MemoryOwner Empty /// This method is just a proxy for the constructor, for clarity. [Pure] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static MemoryOwner Allocate(int size, ArrayPool pool, AllocationMode mode) => new MemoryOwner(size, pool, mode); + public static MemoryOwner Allocate(int size, ArrayPool pool, AllocationMode mode) => new(size, pool, mode); /// /// Gets the number of items in the current instance diff --git a/Microsoft.Toolkit.HighPerformance/Buffers/SpanOwner{T}.cs b/Microsoft.Toolkit.HighPerformance/Buffers/SpanOwner{T}.cs index 456d4401831..f7c3863eb5c 100644 --- a/Microsoft.Toolkit.HighPerformance/Buffers/SpanOwner{T}.cs +++ b/Microsoft.Toolkit.HighPerformance/Buffers/SpanOwner{T}.cs @@ -80,7 +80,7 @@ private SpanOwner(int length, ArrayPool pool, AllocationMode mode) public static SpanOwner Empty { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => new SpanOwner(0, ArrayPool.Shared, AllocationMode.Default); + get => new(0, ArrayPool.Shared, AllocationMode.Default); } /// @@ -92,7 +92,7 @@ public static SpanOwner Empty /// This method is just a proxy for the constructor, for clarity. [Pure] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static SpanOwner Allocate(int size) => new SpanOwner(size, ArrayPool.Shared, AllocationMode.Default); + public static SpanOwner Allocate(int size) => new(size, ArrayPool.Shared, AllocationMode.Default); /// /// Creates a new instance with the specified parameters. @@ -104,7 +104,7 @@ public static SpanOwner Empty /// This method is just a proxy for the constructor, for clarity. [Pure] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static SpanOwner Allocate(int size, ArrayPool pool) => new SpanOwner(size, pool, AllocationMode.Default); + public static SpanOwner Allocate(int size, ArrayPool pool) => new(size, pool, AllocationMode.Default); /// /// Creates a new instance with the specified parameters. @@ -116,7 +116,7 @@ public static SpanOwner Empty /// This method is just a proxy for the constructor, for clarity. [Pure] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static SpanOwner Allocate(int size, AllocationMode mode) => new SpanOwner(size, ArrayPool.Shared, mode); + public static SpanOwner Allocate(int size, AllocationMode mode) => new(size, ArrayPool.Shared, mode); /// /// Creates a new instance with the specified parameters. @@ -129,7 +129,7 @@ public static SpanOwner Empty /// This method is just a proxy for the constructor, for clarity. [Pure] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static SpanOwner Allocate(int size, ArrayPool pool, AllocationMode mode) => new SpanOwner(size, pool, mode); + public static SpanOwner Allocate(int size, ArrayPool pool, AllocationMode mode) => new(size, pool, mode); /// /// Gets the number of items in the current instance @@ -183,7 +183,7 @@ public Span Span [MethodImpl(MethodImplOptions.AggressiveInlining)] public ArraySegment DangerousGetArray() { - return new ArraySegment(array!, 0, this.length); + return new(array!, 0, this.length); } /// diff --git a/Microsoft.Toolkit.HighPerformance/Buffers/StringPool.cs b/Microsoft.Toolkit.HighPerformance/Buffers/StringPool.cs index bbd8f5f18fc..492cca7f1bc 100644 --- a/Microsoft.Toolkit.HighPerformance/Buffers/StringPool.cs +++ b/Microsoft.Toolkit.HighPerformance/Buffers/StringPool.cs @@ -137,7 +137,7 @@ static void FindFactors(int size, int factor, out int x, out int y) /// process. Since is thread-safe, the shared instance can be used /// concurrently by multiple threads without the need for manual synchronization. /// - public static StringPool Shared { get; } = new StringPool(); + public static StringPool Shared { get; } = new(); /// /// Gets the total number of that can be stored in the current instance. diff --git a/Microsoft.Toolkit.HighPerformance/Enumerables/ReadOnlyRefEnumerable{T}.cs b/Microsoft.Toolkit.HighPerformance/Enumerables/ReadOnlyRefEnumerable{T}.cs index 2eff0897662..d58dc41b622 100644 --- a/Microsoft.Toolkit.HighPerformance/Enumerables/ReadOnlyRefEnumerable{T}.cs +++ b/Microsoft.Toolkit.HighPerformance/Enumerables/ReadOnlyRefEnumerable{T}.cs @@ -10,6 +10,8 @@ #endif using Microsoft.Toolkit.HighPerformance.Extensions; using Microsoft.Toolkit.HighPerformance.Helpers.Internals; +using Microsoft.Toolkit.HighPerformance.Memory.Internals; + #if !SPAN_RUNTIME_SUPPORT using RuntimeHelpers = Microsoft.Toolkit.HighPerformance.Helpers.Internals.RuntimeHelpers; #endif @@ -76,6 +78,32 @@ internal ReadOnlyRefEnumerable(in T reference, int length, int step) this.span = MemoryMarshal.CreateReadOnlySpan(ref Unsafe.AsRef(reference), length); this.step = step; } + + /// + /// Creates a new instance of the struct with the specified parameters. + /// + /// The reference to the first item to map. + /// The number of items in the sequence. + /// The distance between items in the sequence to enumerate. + /// A instance with the specified parameters. + /// Thrown when one of the parameters are negative. + [Pure] + public static ReadOnlyRefEnumerable DangerousCreate(in T value, int length, int step) + { + if (length < 0) + { + ThrowArgumentOutOfRangeExceptionForLength(); + } + + if (step < 0) + { + ThrowArgumentOutOfRangeExceptionForStep(); + } + + OverflowHelper.EnsureIsInNativeIntRange(length, 1, step); + + return new ReadOnlyRefEnumerable(in value, length, step); + } #else /// /// Initializes a new instance of the struct. @@ -360,6 +388,22 @@ public bool MoveNext() } } + /// + /// Throws an when the "length" parameter is invalid. + /// + private static void ThrowArgumentOutOfRangeExceptionForLength() + { + throw new ArgumentOutOfRangeException("length"); + } + + /// + /// Throws an when the "step" parameter is invalid. + /// + private static void ThrowArgumentOutOfRangeExceptionForStep() + { + throw new ArgumentOutOfRangeException("step"); + } + /// /// Throws an when the target span is too short. /// diff --git a/Microsoft.Toolkit.HighPerformance/Enumerables/RefEnumerable{T}.cs b/Microsoft.Toolkit.HighPerformance/Enumerables/RefEnumerable{T}.cs index fae37dc76fc..656bfe96210 100644 --- a/Microsoft.Toolkit.HighPerformance/Enumerables/RefEnumerable{T}.cs +++ b/Microsoft.Toolkit.HighPerformance/Enumerables/RefEnumerable{T}.cs @@ -10,7 +10,9 @@ #endif using Microsoft.Toolkit.HighPerformance.Extensions; using Microsoft.Toolkit.HighPerformance.Helpers.Internals; -#if !SPAN_RUNTIME_SUPPORT +#if SPAN_RUNTIME_SUPPORT +using Microsoft.Toolkit.HighPerformance.Memory.Internals; +#else using RuntimeHelpers = Microsoft.Toolkit.HighPerformance.Helpers.Internals.RuntimeHelpers; #endif @@ -64,6 +66,32 @@ internal RefEnumerable(ref T reference, int length, int step) Span = MemoryMarshal.CreateSpan(ref reference, length); Step = step; } + + /// + /// Creates a new instance of the struct with the specified parameters. + /// + /// The reference to the first item to map. + /// The number of items in the sequence. + /// The distance between items in the sequence to enumerate. + /// A instance with the specified parameters. + /// Thrown when one of the parameters are negative. + [Pure] + public static RefEnumerable DangerousCreate(ref T value, int length, int step) + { + if (length < 0) + { + ThrowArgumentOutOfRangeExceptionForLength(); + } + + if (step < 0) + { + ThrowArgumentOutOfRangeExceptionForStep(); + } + + OverflowHelper.EnsureIsInNativeIntRange(length, 1, step); + + return new RefEnumerable(ref value, length, step); + } #else /// /// Initializes a new instance of the struct. @@ -453,6 +481,22 @@ public bool MoveNext() } } + /// + /// Throws an when the "length" parameter is invalid. + /// + private static void ThrowArgumentOutOfRangeExceptionForLength() + { + throw new ArgumentOutOfRangeException("length"); + } + + /// + /// Throws an when the "step" parameter is invalid. + /// + private static void ThrowArgumentOutOfRangeExceptionForStep() + { + throw new ArgumentOutOfRangeException("step"); + } + /// /// Throws an when the target span is too short. /// diff --git a/Microsoft.Toolkit.HighPerformance/Extensions/ArrayExtensions.1D.cs b/Microsoft.Toolkit.HighPerformance/Extensions/ArrayExtensions.1D.cs index 6ca8302ed52..75b292d4208 100644 --- a/Microsoft.Toolkit.HighPerformance/Extensions/ArrayExtensions.1D.cs +++ b/Microsoft.Toolkit.HighPerformance/Extensions/ArrayExtensions.1D.cs @@ -146,7 +146,7 @@ public static int Count(this T[] array, T value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static SpanEnumerable Enumerate(this T[] array) { - return new SpanEnumerable(array); + return new(array); } /// @@ -172,7 +172,7 @@ public static SpanEnumerable Enumerate(this T[] array) public static SpanTokenizer Tokenize(this T[] array, T separator) where T : IEquatable { - return new SpanTokenizer(array, separator); + return new(array, separator); } /// diff --git a/Microsoft.Toolkit.HighPerformance/Extensions/ArrayExtensions.2D.cs b/Microsoft.Toolkit.HighPerformance/Extensions/ArrayExtensions.2D.cs index 89781377df8..6b571a68ef1 100644 --- a/Microsoft.Toolkit.HighPerformance/Extensions/ArrayExtensions.2D.cs +++ b/Microsoft.Toolkit.HighPerformance/Extensions/ArrayExtensions.2D.cs @@ -207,7 +207,7 @@ public static RefEnumerable GetColumn(this T[,] array, int column) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Span2D AsSpan2D(this T[,]? array) { - return new Span2D(array); + return new(array); } /// @@ -231,7 +231,7 @@ public static Span2D AsSpan2D(this T[,]? array) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Span2D AsSpan2D(this T[,]? array, int row, int column, int height, int width) { - return new Span2D(array, row, column, height, width); + return new(array, row, column, height, width); } /// @@ -244,7 +244,7 @@ public static Span2D AsSpan2D(this T[,]? array, int row, int column, int h [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Memory2D AsMemory2D(this T[,]? array) { - return new Memory2D(array); + return new(array); } /// @@ -268,7 +268,7 @@ public static Memory2D AsMemory2D(this T[,]? array) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Memory2D AsMemory2D(this T[,]? array, int row, int column, int height, int width) { - return new Memory2D(array, row, column, height, width); + return new(array, row, column, height, width); } #if SPAN_RUNTIME_SUPPORT diff --git a/Microsoft.Toolkit.HighPerformance/Extensions/ArrayExtensions.3D.cs b/Microsoft.Toolkit.HighPerformance/Extensions/ArrayExtensions.3D.cs index 77ad9983a6e..ba4f0bd498d 100644 --- a/Microsoft.Toolkit.HighPerformance/Extensions/ArrayExtensions.3D.cs +++ b/Microsoft.Toolkit.HighPerformance/Extensions/ArrayExtensions.3D.cs @@ -234,7 +234,7 @@ public static Memory AsMemory(this T[,,] array, int depth) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Span2D AsSpan2D(this T[,,] array, int depth) { - return new Span2D(array, depth); + return new(array, depth); } /// @@ -252,7 +252,7 @@ public static Span2D AsSpan2D(this T[,,] array, int depth) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Memory2D AsMemory2D(this T[,,] array, int depth) { - return new Memory2D(array, depth); + return new(array, depth); } /// diff --git a/Microsoft.Toolkit.HighPerformance/Extensions/MemoryExtensions.cs b/Microsoft.Toolkit.HighPerformance/Extensions/MemoryExtensions.cs index 411fb5f390b..1feeb36c966 100644 --- a/Microsoft.Toolkit.HighPerformance/Extensions/MemoryExtensions.cs +++ b/Microsoft.Toolkit.HighPerformance/Extensions/MemoryExtensions.cs @@ -35,7 +35,7 @@ public static class MemoryExtensions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Memory2D AsMemory2D(this Memory memory, int height, int width) { - return new Memory2D(memory, height, width); + return new(memory, height, width); } /// @@ -58,7 +58,7 @@ public static Memory2D AsMemory2D(this Memory memory, int height, int w [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Memory2D AsMemory2D(this Memory memory, int offset, int height, int width, int pitch) { - return new Memory2D(memory, offset, height, width, pitch); + return new(memory, offset, height, width, pitch); } #endif diff --git a/Microsoft.Toolkit.HighPerformance/Extensions/ReadOnlyMemoryExtensions.cs b/Microsoft.Toolkit.HighPerformance/Extensions/ReadOnlyMemoryExtensions.cs index 5e4a07df9ea..ad046a1c68f 100644 --- a/Microsoft.Toolkit.HighPerformance/Extensions/ReadOnlyMemoryExtensions.cs +++ b/Microsoft.Toolkit.HighPerformance/Extensions/ReadOnlyMemoryExtensions.cs @@ -38,7 +38,7 @@ public static class ReadOnlyMemoryExtensions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ReadOnlyMemory2D AsMemory2D(this ReadOnlyMemory memory, int height, int width) { - return new ReadOnlyMemory2D(memory, height, width); + return new(memory, height, width); } /// @@ -61,7 +61,7 @@ public static ReadOnlyMemory2D AsMemory2D(this ReadOnlyMemory memory, i [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ReadOnlyMemory2D AsMemory2D(this ReadOnlyMemory memory, int offset, int height, int width, int pitch) { - return new ReadOnlyMemory2D(memory, offset, height, width, pitch); + return new(memory, offset, height, width, pitch); } #endif diff --git a/Microsoft.Toolkit.HighPerformance/Extensions/ReadOnlySpanExtensions.cs b/Microsoft.Toolkit.HighPerformance/Extensions/ReadOnlySpanExtensions.cs index 2f81a359ff4..cb793eada03 100644 --- a/Microsoft.Toolkit.HighPerformance/Extensions/ReadOnlySpanExtensions.cs +++ b/Microsoft.Toolkit.HighPerformance/Extensions/ReadOnlySpanExtensions.cs @@ -183,7 +183,7 @@ public static class ReadOnlySpanExtensions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ReadOnlySpan2D AsSpan2D(this ReadOnlySpan span, int height, int width) { - return new ReadOnlySpan2D(span, height, width); + return new(span, height, width); } /// @@ -206,7 +206,7 @@ public static ReadOnlySpan2D AsSpan2D(this ReadOnlySpan span, int heigh [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ReadOnlySpan2D AsSpan2D(this ReadOnlySpan span, int offset, int height, int width, int pitch) { - return new ReadOnlySpan2D(span, offset, height, width, pitch); + return new(span, offset, height, width, pitch); } #endif @@ -313,7 +313,7 @@ public static ReadOnlySpan AsBytes(this ReadOnlySpan span) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ReadOnlySpanEnumerable Enumerate(this ReadOnlySpan span) { - return new ReadOnlySpanEnumerable(span); + return new(span); } /// @@ -339,7 +339,7 @@ public static ReadOnlySpanEnumerable Enumerate(this ReadOnlySpan span) public static ReadOnlySpanTokenizer Tokenize(this ReadOnlySpan span, T separator) where T : IEquatable { - return new ReadOnlySpanTokenizer(span, separator); + return new(span, separator); } /// diff --git a/Microsoft.Toolkit.HighPerformance/Extensions/SpanExtensions.cs b/Microsoft.Toolkit.HighPerformance/Extensions/SpanExtensions.cs index 8ad885e0168..d82bad3d4db 100644 --- a/Microsoft.Toolkit.HighPerformance/Extensions/SpanExtensions.cs +++ b/Microsoft.Toolkit.HighPerformance/Extensions/SpanExtensions.cs @@ -85,7 +85,7 @@ public static class SpanExtensions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Span2D AsSpan2D(this Span span, int height, int width) { - return new Span2D(span, height, width); + return new(span, height, width); } /// @@ -108,7 +108,7 @@ public static Span2D AsSpan2D(this Span span, int height, int width) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Span2D AsSpan2D(this Span span, int offset, int height, int width, int pitch) { - return new Span2D(span, offset, height, width, pitch); + return new(span, offset, height, width, pitch); } #endif @@ -214,7 +214,7 @@ public static int Count(this Span span, T value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static SpanEnumerable Enumerate(this Span span) { - return new SpanEnumerable(span); + return new(span); } /// @@ -240,7 +240,7 @@ public static SpanEnumerable Enumerate(this Span span) public static SpanTokenizer Tokenize(this Span span, T separator) where T : IEquatable { - return new SpanTokenizer(span, separator); + return new(span, separator); } /// diff --git a/Microsoft.Toolkit.HighPerformance/Extensions/SpinLockExtensions.cs b/Microsoft.Toolkit.HighPerformance/Extensions/SpinLockExtensions.cs index f1e826bd2f7..d17eab8fae4 100644 --- a/Microsoft.Toolkit.HighPerformance/Extensions/SpinLockExtensions.cs +++ b/Microsoft.Toolkit.HighPerformance/Extensions/SpinLockExtensions.cs @@ -32,7 +32,7 @@ public static class SpinLockExtensions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe UnsafeLock Enter(SpinLock* spinLock) { - return new UnsafeLock(spinLock); + return new(spinLock); } /// @@ -97,7 +97,7 @@ public void Dispose() [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Lock Enter(ref this SpinLock spinLock) { - return new Lock(ref spinLock); + return new(ref spinLock); } #else /// @@ -123,7 +123,7 @@ public static Lock Enter(ref this SpinLock spinLock) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Lock Enter(object owner, ref SpinLock spinLock) { - return new Lock(owner, ref spinLock); + return new(owner, ref spinLock); } #endif diff --git a/Microsoft.Toolkit.HighPerformance/Extensions/StringExtensions.cs b/Microsoft.Toolkit.HighPerformance/Extensions/StringExtensions.cs index 9ea1def2243..9690ad1729e 100644 --- a/Microsoft.Toolkit.HighPerformance/Extensions/StringExtensions.cs +++ b/Microsoft.Toolkit.HighPerformance/Extensions/StringExtensions.cs @@ -121,7 +121,7 @@ public static int Count(this string text, char c) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ReadOnlySpanEnumerable Enumerate(this string text) { - return new ReadOnlySpanEnumerable(text.AsSpan()); + return new(text.AsSpan()); } /// @@ -145,7 +145,7 @@ public static ReadOnlySpanEnumerable Enumerate(this string text) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ReadOnlySpanTokenizer Tokenize(this string text, char separator) { - return new ReadOnlySpanTokenizer(text.AsSpan(), separator); + return new(text.AsSpan(), separator); } /// diff --git a/Microsoft.Toolkit.HighPerformance/Memory/Memory2D{T}.cs b/Microsoft.Toolkit.HighPerformance/Memory/Memory2D{T}.cs index bdd425a99e9..6f6a7262222 100644 --- a/Microsoft.Toolkit.HighPerformance/Memory/Memory2D{T}.cs +++ b/Microsoft.Toolkit.HighPerformance/Memory/Memory2D{T}.cs @@ -900,6 +900,6 @@ public override string ToString() /// /// Defines an implicit conversion of an array to a /// - public static implicit operator Memory2D(T[,]? array) => new Memory2D(array); + public static implicit operator Memory2D(T[,]? array) => new(array); } } diff --git a/Microsoft.Toolkit.HighPerformance/Memory/ReadOnlyMemory2D{T}.cs b/Microsoft.Toolkit.HighPerformance/Memory/ReadOnlyMemory2D{T}.cs index 9f3ea970b86..80e8839cb85 100644 --- a/Microsoft.Toolkit.HighPerformance/Memory/ReadOnlyMemory2D{T}.cs +++ b/Microsoft.Toolkit.HighPerformance/Memory/ReadOnlyMemory2D{T}.cs @@ -625,14 +625,14 @@ public ReadOnlySpan2D Span ref T r0 = ref memoryManager.GetSpan().DangerousGetReference(); ref T r1 = ref Unsafe.Add(ref r0, this.offset); - return new ReadOnlySpan2D(r1, this.height, this.width, this.pitch); + return new ReadOnlySpan2D(in r1, this.height, this.width, this.pitch); } else { // This handles both arrays and strings ref T r0 = ref this.instance.DangerousGetObjectDataReferenceAt(this.offset); - return new ReadOnlySpan2D(r0, this.height, this.width, this.pitch); + return new ReadOnlySpan2D(in r0, this.height, this.width, this.pitch); } #else return new ReadOnlySpan2D(this.instance, this.offset, this.height, this.width, this.pitch); @@ -913,7 +913,7 @@ public override string ToString() /// /// Defines an implicit conversion of an array to a /// - public static implicit operator ReadOnlyMemory2D(T[,]? array) => new ReadOnlyMemory2D(array); + public static implicit operator ReadOnlyMemory2D(T[,]? array) => new(array); /// /// Defines an implicit conversion of a to a diff --git a/Microsoft.Toolkit.HighPerformance/Memory/ReadOnlySpan2D{T}.Enumerator.cs b/Microsoft.Toolkit.HighPerformance/Memory/ReadOnlySpan2D{T}.Enumerator.cs index 24f6e504462..4f1ddedc4de 100644 --- a/Microsoft.Toolkit.HighPerformance/Memory/ReadOnlySpan2D{T}.Enumerator.cs +++ b/Microsoft.Toolkit.HighPerformance/Memory/ReadOnlySpan2D{T}.Enumerator.cs @@ -38,7 +38,7 @@ public ReadOnlyRefEnumerable GetRow(int row) ref T r1 = ref Unsafe.Add(ref r0, startIndex); #if SPAN_RUNTIME_SUPPORT - return new ReadOnlyRefEnumerable(r1, Width, 1); + return new ReadOnlyRefEnumerable(in r1, Width, 1); #else IntPtr offset = RuntimeHelpers.GetObjectDataOrReferenceByteOffset(this.instance, ref r1); @@ -65,7 +65,7 @@ public ReadOnlyRefEnumerable GetColumn(int column) ref T r1 = ref Unsafe.Add(ref r0, (nint)(uint)column); #if SPAN_RUNTIME_SUPPORT - return new ReadOnlyRefEnumerable(r1, Height, this.stride); + return new ReadOnlyRefEnumerable(in r1, Height, this.stride); #else IntPtr offset = RuntimeHelpers.GetObjectDataOrReferenceByteOffset(this.instance, ref r1); @@ -81,7 +81,7 @@ public ReadOnlyRefEnumerable GetColumn(int column) /// [Pure] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Enumerator GetEnumerator() => new Enumerator(this); + public Enumerator GetEnumerator() => new(this); /// /// Provides an enumerator for the elements of a instance. diff --git a/Microsoft.Toolkit.HighPerformance/Memory/ReadOnlySpan2D{T}.cs b/Microsoft.Toolkit.HighPerformance/Memory/ReadOnlySpan2D{T}.cs index 46564207512..17c9f5df51b 100644 --- a/Microsoft.Toolkit.HighPerformance/Memory/ReadOnlySpan2D{T}.cs +++ b/Microsoft.Toolkit.HighPerformance/Memory/ReadOnlySpan2D{T}.cs @@ -478,7 +478,7 @@ public static ReadOnlySpan2D DangerousCreate(in T value, int height, int widt OverflowHelper.EnsureIsInNativeIntRange(height, width, pitch); - return new ReadOnlySpan2D(value, height, width, pitch); + return new ReadOnlySpan2D(in value, height, width, pitch); } #endif @@ -837,7 +837,7 @@ public ReadOnlySpan2D Slice(int row, int column, int width, int height) #if SPAN_RUNTIME_SUPPORT ref T r0 = ref this.span.DangerousGetReferenceAt(shift); - return new ReadOnlySpan2D(r0, height, width, pitch); + return new ReadOnlySpan2D(in r0, height, width, pitch); #else IntPtr offset = this.offset + (shift * (nint)(uint)Unsafe.SizeOf()); @@ -1012,7 +1012,7 @@ public override string ToString() /// Implicily converts a given 2D array into a instance. /// /// The input 2D array to convert. - public static implicit operator ReadOnlySpan2D(T[,]? array) => new ReadOnlySpan2D(array); + public static implicit operator ReadOnlySpan2D(T[,]? array) => new(array); /// /// Implicily converts a given into a instance. @@ -1021,7 +1021,7 @@ public override string ToString() public static implicit operator ReadOnlySpan2D(Span2D span) { #if SPAN_RUNTIME_SUPPORT - return new ReadOnlySpan2D(span.DangerousGetReference(), span.Height, span.Width, span.Stride - span.Width); + return new ReadOnlySpan2D(in span.DangerousGetReference(), span.Height, span.Width, span.Stride - span.Width); #else return new ReadOnlySpan2D(span.Instance!, span.Offset, span.Height, span.Width, span.Stride - span.Width); #endif diff --git a/Microsoft.Toolkit.HighPerformance/Memory/Span2D{T}.Enumerator.cs b/Microsoft.Toolkit.HighPerformance/Memory/Span2D{T}.Enumerator.cs index 99e796d7a79..add6e255d24 100644 --- a/Microsoft.Toolkit.HighPerformance/Memory/Span2D{T}.Enumerator.cs +++ b/Microsoft.Toolkit.HighPerformance/Memory/Span2D{T}.Enumerator.cs @@ -81,7 +81,7 @@ public RefEnumerable GetColumn(int column) /// [Pure] [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Enumerator GetEnumerator() => new Enumerator(this); + public Enumerator GetEnumerator() => new(this); /// /// Provides an enumerator for the elements of a instance. diff --git a/Microsoft.Toolkit.HighPerformance/Memory/Span2D{T}.cs b/Microsoft.Toolkit.HighPerformance/Memory/Span2D{T}.cs index 7f9009ad947..ecdeeccfb58 100644 --- a/Microsoft.Toolkit.HighPerformance/Memory/Span2D{T}.cs +++ b/Microsoft.Toolkit.HighPerformance/Memory/Span2D{T}.cs @@ -1168,6 +1168,6 @@ public override string ToString() /// Implicily converts a given 2D array into a instance. /// /// The input 2D array to convert. - public static implicit operator Span2D(T[,]? array) => new Span2D(array); + public static implicit operator Span2D(T[,]? array) => new(array); } } diff --git a/Microsoft.Toolkit.HighPerformance/NullableReadOnlyRef{T}.cs b/Microsoft.Toolkit.HighPerformance/NullableReadOnlyRef{T}.cs index 9cf22c0a1aa..9d364b4bc07 100644 --- a/Microsoft.Toolkit.HighPerformance/NullableReadOnlyRef{T}.cs +++ b/Microsoft.Toolkit.HighPerformance/NullableReadOnlyRef{T}.cs @@ -92,7 +92,7 @@ public unsafe bool HasValue [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator NullableReadOnlyRef(Ref reference) { - return new NullableReadOnlyRef(reference.Span); + return new(reference.Span); } /// @@ -102,7 +102,7 @@ public unsafe bool HasValue [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator NullableReadOnlyRef(ReadOnlyRef reference) { - return new NullableReadOnlyRef(reference.Span); + return new(reference.Span); } /// @@ -112,7 +112,7 @@ public unsafe bool HasValue [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator NullableReadOnlyRef(NullableRef reference) { - return new NullableReadOnlyRef(reference.Span); + return new(reference.Span); } /// diff --git a/Microsoft.Toolkit.HighPerformance/NullableRef{T}.cs b/Microsoft.Toolkit.HighPerformance/NullableRef{T}.cs index c7c61b96745..2f694537aa9 100644 --- a/Microsoft.Toolkit.HighPerformance/NullableRef{T}.cs +++ b/Microsoft.Toolkit.HighPerformance/NullableRef{T}.cs @@ -96,7 +96,7 @@ public unsafe bool HasValue [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator NullableRef(Ref reference) { - return new NullableRef(reference.Span); + return new(reference.Span); } /// diff --git a/Microsoft.Toolkit.HighPerformance/ReadOnlyRef{T}.cs b/Microsoft.Toolkit.HighPerformance/ReadOnlyRef{T}.cs index 1945e1dffde..37401184821 100644 --- a/Microsoft.Toolkit.HighPerformance/ReadOnlyRef{T}.cs +++ b/Microsoft.Toolkit.HighPerformance/ReadOnlyRef{T}.cs @@ -42,7 +42,7 @@ public ReadOnlyRef(in T value) /// The pointer to the target value. [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe ReadOnlyRef(void* pointer) - : this(Unsafe.AsRef(pointer)) + : this(in Unsafe.AsRef(pointer)) { } @@ -62,7 +62,7 @@ public unsafe ReadOnlyRef(void* pointer) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator ReadOnlyRef(Ref reference) { - return new ReadOnlyRef(reference.Value); + return new(in reference.Value); } #else /// @@ -117,7 +117,7 @@ public ReadOnlyRef(object owner, in T value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator ReadOnlyRef(Ref reference) { - return new ReadOnlyRef(reference.Owner, reference.Offset); + return new(reference.Owner, reference.Offset); } #endif diff --git a/Microsoft.Toolkit.HighPerformance/Streams/Sources/ArrayOwner.cs b/Microsoft.Toolkit.HighPerformance/Streams/Sources/ArrayOwner.cs index 8749ab7682e..5018354e74f 100644 --- a/Microsoft.Toolkit.HighPerformance/Streams/Sources/ArrayOwner.cs +++ b/Microsoft.Toolkit.HighPerformance/Streams/Sources/ArrayOwner.cs @@ -50,7 +50,7 @@ public ArrayOwner(byte[] array, int offset, int length) public static ArrayOwner Empty { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => new ArrayOwner(Array.Empty(), 0, 0); + get => new(Array.Empty(), 0, 0); } /// diff --git a/UnitTests/UnitTests.HighPerformance.Shared/Enumerables/Test_ReadOnlyRefEnumerable{T}.cs b/UnitTests/UnitTests.HighPerformance.Shared/Enumerables/Test_ReadOnlyRefEnumerable{T}.cs new file mode 100644 index 00000000000..f1a8871fdde --- /dev/null +++ b/UnitTests/UnitTests.HighPerformance.Shared/Enumerables/Test_ReadOnlyRefEnumerable{T}.cs @@ -0,0 +1,53 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if !WINDOWS_UWP + +using System; +using System.Runtime.CompilerServices; +using Microsoft.Toolkit.HighPerformance.Enumerables; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace UnitTests.HighPerformance.Enumerables +{ + [TestClass] + public class Test_ReadOnlyRefEnumerable + { + [TestCategory("ReadOnlyRefEnumerable")] + [TestMethod] + [DataRow(1, 1, new[] { 1 })] + [DataRow(4, 1, new[] { 1, 2, 3, 4 })] + [DataRow(4, 4, new[] { 1, 5, 9, 13 })] + [DataRow(4, 5, new[] { 1, 6, 11, 16 })] + public void Test_ReadOnlyRefEnumerable_DangerousCreate_Ok(int length, int step, int[] values) + { + Span data = new[] + { + 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12, + 13, 14, 15, 16 + }; + + ReadOnlyRefEnumerable enumerable = ReadOnlyRefEnumerable.DangerousCreate(in data[0], length, step); + + int[] result = enumerable.ToArray(); + + CollectionAssert.AreEqual(result, values); + } + + [TestCategory("ReadOnlyRefEnumerable")] + [TestMethod] + [DataRow(-44, 10)] + [DataRow(10, -14)] + [DataRow(-32, -1)] + [ExpectedException(typeof(ArgumentOutOfRangeException))] + public void Test_ReadOnlyRefEnumerable_DangerousCreate_BelowZero(int length, int step) + { + _ = ReadOnlyRefEnumerable.DangerousCreate(in Unsafe.NullRef(), length, step); + } + } +} + +#endif diff --git a/UnitTests/UnitTests.HighPerformance.Shared/Enumerables/Test_RefEnumerable{T}.cs b/UnitTests/UnitTests.HighPerformance.Shared/Enumerables/Test_RefEnumerable{T}.cs new file mode 100644 index 00000000000..f82bff8bb28 --- /dev/null +++ b/UnitTests/UnitTests.HighPerformance.Shared/Enumerables/Test_RefEnumerable{T}.cs @@ -0,0 +1,53 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +#if !WINDOWS_UWP + +using System; +using System.Runtime.CompilerServices; +using Microsoft.Toolkit.HighPerformance.Enumerables; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace UnitTests.HighPerformance.Enumerables +{ + [TestClass] + public class Test_RefEnumerable + { + [TestCategory("RefEnumerable")] + [TestMethod] + [DataRow(1, 1, new[] { 1 })] + [DataRow(4, 1, new[] { 1, 2, 3, 4 })] + [DataRow(4, 4, new[] { 1, 5, 9, 13 })] + [DataRow(4, 5, new[] { 1, 6, 11, 16 })] + public void Test_RefEnumerable_DangerousCreate_Ok(int length, int step, int[] values) + { + Span data = new[] + { + 1, 2, 3, 4, + 5, 6, 7, 8, + 9, 10, 11, 12, + 13, 14, 15, 16 + }; + + RefEnumerable enumerable = RefEnumerable.DangerousCreate(ref data[0], length, step); + + int[] result = enumerable.ToArray(); + + CollectionAssert.AreEqual(result, values); + } + + [TestCategory("RefEnumerable")] + [TestMethod] + [DataRow(-44, 10)] + [DataRow(10, -14)] + [DataRow(-32, -1)] + [ExpectedException(typeof(ArgumentOutOfRangeException))] + public void Test_RefEnumerable_DangerousCreate_BelowZero(int length, int step) + { + _ = RefEnumerable.DangerousCreate(ref Unsafe.NullRef(), length, step); + } + } +} + +#endif diff --git a/UnitTests/UnitTests.HighPerformance.Shared/UnitTests.HighPerformance.Shared.projitems b/UnitTests/UnitTests.HighPerformance.Shared/UnitTests.HighPerformance.Shared.projitems index a114963de54..7efff4b2ef4 100644 --- a/UnitTests/UnitTests.HighPerformance.Shared/UnitTests.HighPerformance.Shared.projitems +++ b/UnitTests/UnitTests.HighPerformance.Shared/UnitTests.HighPerformance.Shared.projitems @@ -16,6 +16,8 @@ + +