Skip to content

Commit

Permalink
Merge pull request #3645 from Sergio0694/feature/dangerous-ref-enumer…
Browse files Browse the repository at this point in the history
…able

[ReadOnly]RefEnumerable<T>.DangerousCreate static constructors
  • Loading branch information
Sergio0694 committed Feb 12, 2021
2 parents 99f4581 + d57b5d0 commit d437373
Show file tree
Hide file tree
Showing 28 changed files with 256 additions and 60 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Expand Up @@ -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".
dotnet_diagnostic.SA1101.severity = none # Hide warnings when accessing properties without "this".
10 changes: 5 additions & 5 deletions Microsoft.Toolkit.HighPerformance/Buffers/MemoryOwner{T}.cs
Expand Up @@ -91,7 +91,7 @@ private MemoryOwner(int start, int length, ArrayPool<T> pool, T[] array)
public static MemoryOwner<T> Empty
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new MemoryOwner<T>(0, ArrayPool<T>.Shared, AllocationMode.Default);
get => new(0, ArrayPool<T>.Shared, AllocationMode.Default);
}

/// <summary>
Expand All @@ -103,7 +103,7 @@ public static MemoryOwner<T> Empty
/// <remarks>This method is just a proxy for the <see langword="private"/> constructor, for clarity.</remarks>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static MemoryOwner<T> Allocate(int size) => new MemoryOwner<T>(size, ArrayPool<T>.Shared, AllocationMode.Default);
public static MemoryOwner<T> Allocate(int size) => new(size, ArrayPool<T>.Shared, AllocationMode.Default);

/// <summary>
/// Creates a new <see cref="MemoryOwner{T}"/> instance with the specified parameters.
Expand All @@ -115,7 +115,7 @@ public static MemoryOwner<T> Empty
/// <remarks>This method is just a proxy for the <see langword="private"/> constructor, for clarity.</remarks>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static MemoryOwner<T> Allocate(int size, ArrayPool<T> pool) => new MemoryOwner<T>(size, pool, AllocationMode.Default);
public static MemoryOwner<T> Allocate(int size, ArrayPool<T> pool) => new(size, pool, AllocationMode.Default);

/// <summary>
/// Creates a new <see cref="MemoryOwner{T}"/> instance with the specified parameters.
Expand All @@ -127,7 +127,7 @@ public static MemoryOwner<T> Empty
/// <remarks>This method is just a proxy for the <see langword="private"/> constructor, for clarity.</remarks>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static MemoryOwner<T> Allocate(int size, AllocationMode mode) => new MemoryOwner<T>(size, ArrayPool<T>.Shared, mode);
public static MemoryOwner<T> Allocate(int size, AllocationMode mode) => new(size, ArrayPool<T>.Shared, mode);

/// <summary>
/// Creates a new <see cref="MemoryOwner{T}"/> instance with the specified parameters.
Expand All @@ -140,7 +140,7 @@ public static MemoryOwner<T> Empty
/// <remarks>This method is just a proxy for the <see langword="private"/> constructor, for clarity.</remarks>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static MemoryOwner<T> Allocate(int size, ArrayPool<T> pool, AllocationMode mode) => new MemoryOwner<T>(size, pool, mode);
public static MemoryOwner<T> Allocate(int size, ArrayPool<T> pool, AllocationMode mode) => new(size, pool, mode);

/// <summary>
/// Gets the number of items in the current instance
Expand Down
12 changes: 6 additions & 6 deletions Microsoft.Toolkit.HighPerformance/Buffers/SpanOwner{T}.cs
Expand Up @@ -80,7 +80,7 @@ private SpanOwner(int length, ArrayPool<T> pool, AllocationMode mode)
public static SpanOwner<T> Empty
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new SpanOwner<T>(0, ArrayPool<T>.Shared, AllocationMode.Default);
get => new(0, ArrayPool<T>.Shared, AllocationMode.Default);
}

/// <summary>
Expand All @@ -92,7 +92,7 @@ public static SpanOwner<T> Empty
/// <remarks>This method is just a proxy for the <see langword="private"/> constructor, for clarity.</remarks>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static SpanOwner<T> Allocate(int size) => new SpanOwner<T>(size, ArrayPool<T>.Shared, AllocationMode.Default);
public static SpanOwner<T> Allocate(int size) => new(size, ArrayPool<T>.Shared, AllocationMode.Default);

/// <summary>
/// Creates a new <see cref="SpanOwner{T}"/> instance with the specified parameters.
Expand All @@ -104,7 +104,7 @@ public static SpanOwner<T> Empty
/// <remarks>This method is just a proxy for the <see langword="private"/> constructor, for clarity.</remarks>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static SpanOwner<T> Allocate(int size, ArrayPool<T> pool) => new SpanOwner<T>(size, pool, AllocationMode.Default);
public static SpanOwner<T> Allocate(int size, ArrayPool<T> pool) => new(size, pool, AllocationMode.Default);

/// <summary>
/// Creates a new <see cref="SpanOwner{T}"/> instance with the specified parameters.
Expand All @@ -116,7 +116,7 @@ public static SpanOwner<T> Empty
/// <remarks>This method is just a proxy for the <see langword="private"/> constructor, for clarity.</remarks>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static SpanOwner<T> Allocate(int size, AllocationMode mode) => new SpanOwner<T>(size, ArrayPool<T>.Shared, mode);
public static SpanOwner<T> Allocate(int size, AllocationMode mode) => new(size, ArrayPool<T>.Shared, mode);

/// <summary>
/// Creates a new <see cref="SpanOwner{T}"/> instance with the specified parameters.
Expand All @@ -129,7 +129,7 @@ public static SpanOwner<T> Empty
/// <remarks>This method is just a proxy for the <see langword="private"/> constructor, for clarity.</remarks>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static SpanOwner<T> Allocate(int size, ArrayPool<T> pool, AllocationMode mode) => new SpanOwner<T>(size, pool, mode);
public static SpanOwner<T> Allocate(int size, ArrayPool<T> pool, AllocationMode mode) => new(size, pool, mode);

/// <summary>
/// Gets the number of items in the current instance
Expand Down Expand Up @@ -183,7 +183,7 @@ public Span<T> Span
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ArraySegment<T> DangerousGetArray()
{
return new ArraySegment<T>(array!, 0, this.length);
return new(array!, 0, this.length);
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion Microsoft.Toolkit.HighPerformance/Buffers/StringPool.cs
Expand Up @@ -137,7 +137,7 @@ static void FindFactors(int size, int factor, out int x, out int y)
/// process. Since <see cref="StringPool"/> is thread-safe, the shared instance can be used
/// concurrently by multiple threads without the need for manual synchronization.
/// </remarks>
public static StringPool Shared { get; } = new StringPool();
public static StringPool Shared { get; } = new();

/// <summary>
/// Gets the total number of <see cref="string"/> that can be stored in the current instance.
Expand Down
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}

/// <summary>
/// Creates a new instance of the <see cref="ReadOnlyRefEnumerable{T}"/> struct with the specified parameters.
/// </summary>
/// <param name="value">The reference to the first <typeparamref name="T"/> item to map.</param>
/// <param name="length">The number of items in the sequence.</param>
/// <param name="step">The distance between items in the sequence to enumerate.</param>
/// <returns>A <see cref="ReadOnlyRefEnumerable{T}"/> instance with the specified parameters.</returns>
/// <exception cref="ArgumentOutOfRangeException">Thrown when one of the parameters are negative.</exception>
[Pure]
public static ReadOnlyRefEnumerable<T> DangerousCreate(in T value, int length, int step)
{
if (length < 0)
{
ThrowArgumentOutOfRangeExceptionForLength();
}

if (step < 0)
{
ThrowArgumentOutOfRangeExceptionForStep();
}

OverflowHelper.EnsureIsInNativeIntRange(length, 1, step);

return new ReadOnlyRefEnumerable<T>(in value, length, step);
}
#else
/// <summary>
/// Initializes a new instance of the <see cref="ReadOnlyRefEnumerable{T}"/> struct.
Expand Down Expand Up @@ -360,6 +388,22 @@ public bool MoveNext()
}
}

/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when the "length" parameter is invalid.
/// </summary>
private static void ThrowArgumentOutOfRangeExceptionForLength()
{
throw new ArgumentOutOfRangeException("length");
}

/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when the "step" parameter is invalid.
/// </summary>
private static void ThrowArgumentOutOfRangeExceptionForStep()
{
throw new ArgumentOutOfRangeException("step");
}

/// <summary>
/// Throws an <see cref="ArgumentException"/> when the target span is too short.
/// </summary>
Expand Down
Expand Up @@ -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

Expand Down Expand Up @@ -64,6 +66,32 @@ internal RefEnumerable(ref T reference, int length, int step)
Span = MemoryMarshal.CreateSpan(ref reference, length);
Step = step;
}

/// <summary>
/// Creates a new instance of the <see cref="RefEnumerable{T}"/> struct with the specified parameters.
/// </summary>
/// <param name="value">The reference to the first <typeparamref name="T"/> item to map.</param>
/// <param name="length">The number of items in the sequence.</param>
/// <param name="step">The distance between items in the sequence to enumerate.</param>
/// <returns>A <see cref="RefEnumerable{T}"/> instance with the specified parameters.</returns>
/// <exception cref="ArgumentOutOfRangeException">Thrown when one of the parameters are negative.</exception>
[Pure]
public static RefEnumerable<T> DangerousCreate(ref T value, int length, int step)
{
if (length < 0)
{
ThrowArgumentOutOfRangeExceptionForLength();
}

if (step < 0)
{
ThrowArgumentOutOfRangeExceptionForStep();
}

OverflowHelper.EnsureIsInNativeIntRange(length, 1, step);

return new RefEnumerable<T>(ref value, length, step);
}
#else
/// <summary>
/// Initializes a new instance of the <see cref="RefEnumerable{T}"/> struct.
Expand Down Expand Up @@ -453,6 +481,22 @@ public bool MoveNext()
}
}

/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when the "length" parameter is invalid.
/// </summary>
private static void ThrowArgumentOutOfRangeExceptionForLength()
{
throw new ArgumentOutOfRangeException("length");
}

/// <summary>
/// Throws an <see cref="ArgumentOutOfRangeException"/> when the "step" parameter is invalid.
/// </summary>
private static void ThrowArgumentOutOfRangeExceptionForStep()
{
throw new ArgumentOutOfRangeException("step");
}

/// <summary>
/// Throws an <see cref="ArgumentException"/> when the target span is too short.
/// </summary>
Expand Down
Expand Up @@ -146,7 +146,7 @@ public static int Count<T>(this T[] array, T value)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static SpanEnumerable<T> Enumerate<T>(this T[] array)
{
return new SpanEnumerable<T>(array);
return new(array);
}

/// <summary>
Expand All @@ -172,7 +172,7 @@ public static SpanEnumerable<T> Enumerate<T>(this T[] array)
public static SpanTokenizer<T> Tokenize<T>(this T[] array, T separator)
where T : IEquatable<T>
{
return new SpanTokenizer<T>(array, separator);
return new(array, separator);
}

/// <summary>
Expand Down
Expand Up @@ -207,7 +207,7 @@ public static RefEnumerable<T> GetColumn<T>(this T[,] array, int column)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Span2D<T> AsSpan2D<T>(this T[,]? array)
{
return new Span2D<T>(array);
return new(array);
}

/// <summary>
Expand All @@ -231,7 +231,7 @@ public static Span2D<T> AsSpan2D<T>(this T[,]? array)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Span2D<T> AsSpan2D<T>(this T[,]? array, int row, int column, int height, int width)
{
return new Span2D<T>(array, row, column, height, width);
return new(array, row, column, height, width);
}

/// <summary>
Expand All @@ -244,7 +244,7 @@ public static Span2D<T> AsSpan2D<T>(this T[,]? array, int row, int column, int h
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Memory2D<T> AsMemory2D<T>(this T[,]? array)
{
return new Memory2D<T>(array);
return new(array);
}

/// <summary>
Expand All @@ -268,7 +268,7 @@ public static Memory2D<T> AsMemory2D<T>(this T[,]? array)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Memory2D<T> AsMemory2D<T>(this T[,]? array, int row, int column, int height, int width)
{
return new Memory2D<T>(array, row, column, height, width);
return new(array, row, column, height, width);
}

#if SPAN_RUNTIME_SUPPORT
Expand Down
Expand Up @@ -234,7 +234,7 @@ public static Memory<T> AsMemory<T>(this T[,,] array, int depth)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Span2D<T> AsSpan2D<T>(this T[,,] array, int depth)
{
return new Span2D<T>(array, depth);
return new(array, depth);
}

/// <summary>
Expand All @@ -252,7 +252,7 @@ public static Span2D<T> AsSpan2D<T>(this T[,,] array, int depth)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Memory2D<T> AsMemory2D<T>(this T[,,] array, int depth)
{
return new Memory2D<T>(array, depth);
return new(array, depth);
}

/// <summary>
Expand Down
Expand Up @@ -35,7 +35,7 @@ public static class MemoryExtensions
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Memory2D<T> AsMemory2D<T>(this Memory<T> memory, int height, int width)
{
return new Memory2D<T>(memory, height, width);
return new(memory, height, width);
}

/// <summary>
Expand All @@ -58,7 +58,7 @@ public static Memory2D<T> AsMemory2D<T>(this Memory<T> memory, int height, int w
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Memory2D<T> AsMemory2D<T>(this Memory<T> memory, int offset, int height, int width, int pitch)
{
return new Memory2D<T>(memory, offset, height, width, pitch);
return new(memory, offset, height, width, pitch);
}
#endif

Expand Down
Expand Up @@ -38,7 +38,7 @@ public static class ReadOnlyMemoryExtensions
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ReadOnlyMemory2D<T> AsMemory2D<T>(this ReadOnlyMemory<T> memory, int height, int width)
{
return new ReadOnlyMemory2D<T>(memory, height, width);
return new(memory, height, width);
}

/// <summary>
Expand All @@ -61,7 +61,7 @@ public static ReadOnlyMemory2D<T> AsMemory2D<T>(this ReadOnlyMemory<T> memory, i
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ReadOnlyMemory2D<T> AsMemory2D<T>(this ReadOnlyMemory<T> memory, int offset, int height, int width, int pitch)
{
return new ReadOnlyMemory2D<T>(memory, offset, height, width, pitch);
return new(memory, offset, height, width, pitch);
}
#endif

Expand Down
Expand Up @@ -183,7 +183,7 @@ public static class ReadOnlySpanExtensions
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ReadOnlySpan2D<T> AsSpan2D<T>(this ReadOnlySpan<T> span, int height, int width)
{
return new ReadOnlySpan2D<T>(span, height, width);
return new(span, height, width);
}

/// <summary>
Expand All @@ -206,7 +206,7 @@ public static ReadOnlySpan2D<T> AsSpan2D<T>(this ReadOnlySpan<T> span, int heigh
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ReadOnlySpan2D<T> AsSpan2D<T>(this ReadOnlySpan<T> span, int offset, int height, int width, int pitch)
{
return new ReadOnlySpan2D<T>(span, offset, height, width, pitch);
return new(span, offset, height, width, pitch);
}
#endif

Expand Down Expand Up @@ -313,7 +313,7 @@ public static ReadOnlySpan<byte> AsBytes<T>(this ReadOnlySpan<T> span)
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ReadOnlySpanEnumerable<T> Enumerate<T>(this ReadOnlySpan<T> span)
{
return new ReadOnlySpanEnumerable<T>(span);
return new(span);
}

/// <summary>
Expand All @@ -339,7 +339,7 @@ public static ReadOnlySpanEnumerable<T> Enumerate<T>(this ReadOnlySpan<T> span)
public static ReadOnlySpanTokenizer<T> Tokenize<T>(this ReadOnlySpan<T> span, T separator)
where T : IEquatable<T>
{
return new ReadOnlySpanTokenizer<T>(span, separator);
return new(span, separator);
}

/// <summary>
Expand Down

0 comments on commit d437373

Please sign in to comment.