Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apiCount.include.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
**API count: 656**
**API count: 661**
9 changes: 9 additions & 0 deletions api_list.include.md
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,15 @@
* `int CommonPrefixLength<T>(ReadOnlySpan<T>, IEqualityComparer<T>?)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.commonprefixlength?view=net-10.0#system-memoryextensions-commonprefixlength-1(system-span((-0))-system-readonlyspan((-0))-system-collections-generic-iequalitycomparer((-0))))
* `int CommonPrefixLength<T>(ReadOnlySpan<T>)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.commonprefixlength?view=net-10.0#system-memoryextensions-commonprefixlength-1(system-span((-0))-system-readonlyspan((-0))))
* `bool Contains<T>(T) where T : IEquatable<T>` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains?view=net-10.0#system-memoryextensions-contains-1(system-span((-0))-0))
* `void Sort<T>(Comparison<T>)`
* `void Sort<T>() where T : IComparable<T>` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sort?view=net-10.0#system-memoryextensions-sort-1(system-span((-0))))


#### Span<TKey>

* `void Sort<TKey, TValue, TComparer>(Span<TValue>, TComparer) where TComparer : IComparer<TKey>` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sort?view=net-10.0#system-memoryextensions-sort-3(system-span((-0))-system-span((-1))-2))
* `void Sort<TKey, TValue>(Span<TValue>, Comparison<TKey>)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sort?view=net-10.0#system-memoryextensions-sort-2(system-span((-0))-system-span((-1))-system-comparison((-0))))
* `void Sort<TKey, TValue>(Span<TValue>)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sort?view=net-10.0#system-memoryextensions-sort-2(system-span((-0))-system-span((-1))))


#### Stack<T>
Expand Down
56 changes: 28 additions & 28 deletions assemblySize.include.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@

| | Empty Assembly | With Polyfill | Diff | Ensure | ArgumentExceptions | StringInterpolation | Nullability |
|----------------|----------------|---------------|-----------|-----------|--------------------|---------------------|-------------|
| netstandard2.0 | 8.0 KB | 191.5 KB | +183.5 KB | +8.5 KB | +5.5 KB | +9.0 KB | +14.0 KB |
| netstandard2.1 | 8.5 KB | 154.5 KB | +146.0 KB | +8.0 KB | +5.0 KB | +9.0 KB | +13.5 KB |
| net461 | 8.5 KB | 198.0 KB | +189.5 KB | +8.5 KB | +5.0 KB | +9.0 KB | +13.5 KB |
| net462 | 7.0 KB | 196.5 KB | +189.5 KB | +8.5 KB | +5.5 KB | +9.0 KB | +14.0 KB |
| net47 | 7.0 KB | 196.5 KB | +189.5 KB | +8.5 KB | +5.0 KB | +9.0 KB | +13.5 KB |
| net471 | 8.5 KB | 196.5 KB | +188.0 KB | +8.5 KB | +5.5 KB | +9.0 KB | +13.5 KB |
| net472 | 8.5 KB | 195.0 KB | +186.5 KB | +8.5 KB | +5.5 KB | +9.0 KB | +14.0 KB |
| net48 | 8.5 KB | 195.0 KB | +186.5 KB | +8.5 KB | +5.5 KB | +9.0 KB | +14.0 KB |
| net481 | 8.5 KB | 195.0 KB | +186.5 KB | +8.5 KB | +5.5 KB | +9.0 KB | +14.0 KB |
| netcoreapp2.0 | 9.0 KB | 172.5 KB | +163.5 KB | +11.5 KB | +8.0 KB | +12.0 KB | +16.5 KB |
| netcoreapp2.1 | 9.0 KB | 164.0 KB | +155.0 KB | +8.0 KB | +5.0 KB | +9.0 KB | +13.5 KB |
| netcoreapp2.2 | 9.0 KB | 164.0 KB | +155.0 KB | +8.5 KB | +5.0 KB | +9.0 KB | +14.0 KB |
| netcoreapp3.0 | 9.5 KB | 160.0 KB | +150.5 KB | +8.5 KB | +5.0 KB | +9.0 KB | +14.0 KB |
| netcoreapp3.1 | 9.5 KB | 158.5 KB | +149.0 KB | +8.5 KB | +5.0 KB | +9.0 KB | +13.5 KB |
| netstandard2.0 | 8.0 KB | 193.5 KB | +185.5 KB | +8.5 KB | +5.0 KB | +9.0 KB | +13.5 KB |
| netstandard2.1 | 8.5 KB | 156.5 KB | +148.0 KB | +8.0 KB | +5.0 KB | +8.5 KB | +13.5 KB |
| net461 | 8.5 KB | 199.5 KB | +191.0 KB | +8.5 KB | +5.5 KB | +9.5 KB | +14.0 KB |
| net462 | 7.0 KB | 198.5 KB | +191.5 KB | +8.5 KB | +5.0 KB | +9.0 KB | +13.5 KB |
| net47 | 7.0 KB | 198.5 KB | +191.5 KB | +8.0 KB | +5.0 KB | +9.0 KB | +13.5 KB |
| net471 | 8.5 KB | 198.5 KB | +190.0 KB | +8.5 KB | +5.5 KB | +9.0 KB | +13.5 KB |
| net472 | 8.5 KB | 197.0 KB | +188.5 KB | +8.5 KB | +5.5 KB | +9.0 KB | +13.5 KB |
| net48 | 8.5 KB | 197.0 KB | +188.5 KB | +8.5 KB | +5.5 KB | +9.0 KB | +13.5 KB |
| net481 | 8.5 KB | 197.0 KB | +188.5 KB | +8.5 KB | +5.5 KB | +9.0 KB | +13.5 KB |
| netcoreapp2.0 | 9.0 KB | 177.0 KB | +168.0 KB | +8.5 KB | +5.5 KB | +9.0 KB | +14.0 KB |
| netcoreapp2.1 | 9.0 KB | 166.0 KB | +157.0 KB | +8.0 KB | +5.0 KB | +8.5 KB | +13.5 KB |
| netcoreapp2.2 | 9.0 KB | 166.0 KB | +157.0 KB | +8.0 KB | +5.0 KB | +9.0 KB | +13.5 KB |
| netcoreapp3.0 | 9.5 KB | 162.0 KB | +152.5 KB | +8.5 KB | +5.0 KB | +9.0 KB | +14.0 KB |
| netcoreapp3.1 | 9.5 KB | 160.5 KB | +151.0 KB | +8.0 KB | +5.0 KB | +9.0 KB | +13.5 KB |
| net5.0 | 9.5 KB | 136.5 KB | +127.0 KB | +8.5 KB | +5.0 KB | +9.0 KB | +14.0 KB |
| net6.0 | 10.0 KB | 105.5 KB | +95.5 KB | +9.0 KB | +5.0 KB | +512 bytes | +3.5 KB |
| net7.0 | 10.0 KB | 84.0 KB | +74.0 KB | +8.5 KB | +4.5 KB | +512 bytes | +3.5 KB |
Expand All @@ -28,20 +28,20 @@

| | Empty Assembly | With Polyfill | Diff | Ensure | ArgumentExceptions | StringInterpolation | Nullability |
|----------------|----------------|---------------|-----------|-----------|--------------------|---------------------|-------------|
| netstandard2.0 | 8.0 KB | 299.1 KB | +291.1 KB | +16.2 KB | +6.9 KB | +14.4 KB | +19.8 KB |
| netstandard2.1 | 8.5 KB | 242.9 KB | +234.4 KB | +15.7 KB | +6.4 KB | +14.4 KB | +19.3 KB |
| net461 | 8.5 KB | 306.1 KB | +297.6 KB | +16.2 KB | +6.4 KB | +14.4 KB | +19.3 KB |
| net462 | 7.0 KB | 304.6 KB | +297.6 KB | +16.2 KB | +6.9 KB | +14.4 KB | +19.8 KB |
| net47 | 7.0 KB | 304.3 KB | +297.3 KB | +16.2 KB | +6.4 KB | +14.4 KB | +19.3 KB |
| net471 | 8.5 KB | 304.3 KB | +295.8 KB | +16.2 KB | +6.9 KB | +14.4 KB | +19.3 KB |
| net472 | 8.5 KB | 301.8 KB | +293.3 KB | +16.2 KB | +6.9 KB | +14.4 KB | +19.8 KB |
| net48 | 8.5 KB | 301.8 KB | +293.3 KB | +16.2 KB | +6.9 KB | +14.4 KB | +19.8 KB |
| net481 | 8.5 KB | 301.8 KB | +293.3 KB | +16.2 KB | +6.9 KB | +14.4 KB | +19.8 KB |
| netcoreapp2.0 | 9.0 KB | 271.0 KB | +262.0 KB | +19.2 KB | +9.4 KB | +17.4 KB | +22.3 KB |
| netcoreapp2.1 | 9.0 KB | 256.0 KB | +247.0 KB | +15.7 KB | +6.4 KB | +14.4 KB | +19.3 KB |
| netcoreapp2.2 | 9.0 KB | 256.0 KB | +247.0 KB | +16.2 KB | +6.4 KB | +14.4 KB | +19.8 KB |
| netcoreapp3.0 | 9.5 KB | 245.0 KB | +235.5 KB | +16.2 KB | +6.4 KB | +14.4 KB | +19.8 KB |
| netcoreapp3.1 | 9.5 KB | 243.5 KB | +234.0 KB | +16.2 KB | +6.4 KB | +14.4 KB | +19.3 KB |
| netstandard2.0 | 8.0 KB | 301.9 KB | +293.9 KB | +16.2 KB | +6.4 KB | +14.4 KB | +19.3 KB |
| netstandard2.1 | 8.5 KB | 245.6 KB | +237.1 KB | +15.7 KB | +6.4 KB | +13.9 KB | +19.3 KB |
| net461 | 8.5 KB | 308.3 KB | +299.8 KB | +16.2 KB | +6.9 KB | +14.9 KB | +19.8 KB |
| net462 | 7.0 KB | 307.3 KB | +300.3 KB | +16.2 KB | +6.4 KB | +14.4 KB | +19.3 KB |
| net47 | 7.0 KB | 307.1 KB | +300.1 KB | +15.7 KB | +6.4 KB | +14.4 KB | +19.3 KB |
| net471 | 8.5 KB | 307.1 KB | +298.6 KB | +16.2 KB | +6.9 KB | +14.4 KB | +19.3 KB |
| net472 | 8.5 KB | 304.5 KB | +296.0 KB | +16.2 KB | +6.9 KB | +14.4 KB | +19.3 KB |
| net48 | 8.5 KB | 304.5 KB | +296.0 KB | +16.2 KB | +6.9 KB | +14.4 KB | +19.3 KB |
| net481 | 8.5 KB | 304.5 KB | +296.0 KB | +16.2 KB | +6.9 KB | +14.4 KB | +19.3 KB |
| netcoreapp2.0 | 9.0 KB | 276.2 KB | +267.2 KB | +16.2 KB | +6.9 KB | +14.4 KB | +19.8 KB |
| netcoreapp2.1 | 9.0 KB | 258.8 KB | +249.8 KB | +15.7 KB | +6.4 KB | +13.9 KB | +19.3 KB |
| netcoreapp2.2 | 9.0 KB | 258.8 KB | +249.8 KB | +15.7 KB | +6.4 KB | +14.4 KB | +19.3 KB |
| netcoreapp3.0 | 9.5 KB | 247.8 KB | +238.3 KB | +16.2 KB | +6.4 KB | +14.4 KB | +19.8 KB |
| netcoreapp3.1 | 9.5 KB | 246.2 KB | +236.7 KB | +15.7 KB | +6.4 KB | +14.4 KB | +19.3 KB |
| net5.0 | 9.5 KB | 218.4 KB | +208.9 KB | +16.2 KB | +6.4 KB | +14.4 KB | +19.8 KB |
| net6.0 | 10.0 KB | 173.9 KB | +163.9 KB | +16.7 KB | +6.4 KB | +1.6 KB | +4.5 KB |
| net7.0 | 10.0 KB | 140.0 KB | +130.0 KB | +16.2 KB | +5.8 KB | +1.6 KB | +4.5 KB |
Expand Down
11 changes: 10 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ The package targets `netstandard2.0` and is designed to support the following ru
* `uap10`


**API count: 656**<!-- singleLineInclude: apiCount. path: /apiCount.include.md -->
**API count: 661**<!-- singleLineInclude: apiCount. path: /apiCount.include.md -->


**See [Milestones](../../milestones?state=closed) for release notes.**
Expand Down Expand Up @@ -1109,6 +1109,15 @@ The class `Polyfill` includes the following extension methods:
* `int CommonPrefixLength<T>(ReadOnlySpan<T>, IEqualityComparer<T>?)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.commonprefixlength?view=net-10.0#system-memoryextensions-commonprefixlength-1(system-span((-0))-system-readonlyspan((-0))-system-collections-generic-iequalitycomparer((-0))))
* `int CommonPrefixLength<T>(ReadOnlySpan<T>)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.commonprefixlength?view=net-10.0#system-memoryextensions-commonprefixlength-1(system-span((-0))-system-readonlyspan((-0))))
* `bool Contains<T>(T) where T : IEquatable<T>` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.contains?view=net-10.0#system-memoryextensions-contains-1(system-span((-0))-0))
* `void Sort<T>(Comparison<T>)`
* `void Sort<T>() where T : IComparable<T>` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sort?view=net-10.0#system-memoryextensions-sort-1(system-span((-0))))


#### Span<TKey>

* `void Sort<TKey, TValue, TComparer>(Span<TValue>, TComparer) where TComparer : IComparer<TKey>` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sort?view=net-10.0#system-memoryextensions-sort-3(system-span((-0))-system-span((-1))-2))
* `void Sort<TKey, TValue>(Span<TValue>, Comparison<TKey>)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sort?view=net-10.0#system-memoryextensions-sort-2(system-span((-0))-system-span((-1))-system-comparison((-0))))
* `void Sort<TKey, TValue>(Span<TValue>)` [reference](https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sort?view=net-10.0#system-memoryextensions-sort-2(system-span((-0))-system-span((-1))))


#### Stack<T>
Expand Down
11 changes: 11 additions & 0 deletions src/Consume/Consume.cs
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,17 @@ void Span_Methods()
var span = new Span<char>(new char[1]);
_ = span.TrimEnd();
_ = span.TrimStart();

var array = Enumerable.Range(0, 5).ToArray();

#if !NET8_0_OR_GREATER
Polyfill.Shuffle(array);
#else
Random.Shared.Shuffle(array);
#endif

var numbers = new Span<int>(array);
numbers.Sort();
}

#endif
Expand Down
112 changes: 112 additions & 0 deletions src/Polyfill/Polyfill_Memory_SpanSort.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#if FeatureMemory && !NET5_0_OR_GREATER

namespace Polyfills;

using System;
using System.Collections.Generic;
using System.Buffers;

static partial class Polyfill
{
/// <summary>
/// Sorts the elements in the entire <see cref="Span{T}"/> using the <see cref="IComparable{T}"/> implementation of each element of the <see cref="Span{T}"/>.
/// </summary>
//Link: https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sort?view=net-10.0#system-memoryextensions-sort-1(system-span((-0)))
public static void Sort<T>(this Span<T> source)
where T : IComparable<T>
=> Sort(source, (x, y) => x.CompareTo(y));

/// <summary>
/// Sorts the elements in the entire <see cref="Span{T}"/> using the specified <see cref="Comparison{T}"/>.
/// </summary>
/// Link: https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sort?view=net-10.0#system-memoryextensions-sort-1(system-span((-0))-system-comparison((-0)))
public static void Sort<T>(this Span<T> source, Comparison<T> comparison)
{
if((Comparison<T>?)comparison is null)
throw new ArgumentNullException(nameof(comparison));

var array = ArrayPool<T>.Shared.Rent(source.Length);

try
{
source.CopyTo(array);
Array.Sort(array, 0, source.Length, Comparer<T>.Create(comparison));

array.AsSpan(0, source.Length).CopyTo(source);
}
finally
{
ArrayPool<T>.Shared.Return(array);
}
}

/// <summary>
/// Sorts a pair of spans (one containing the keys and the other containing the corresponding items) based on the keys in the first <see cref="Span{T}"/> using the <see cref=" IComparable{T}"/> implementation of each key.
/// </summary>
//Link: https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sort?view=net-10.0#system-memoryextensions-sort-2(system-span((-0))-system-span((-1)))
public static void Sort<TKey, TValue>(this Span<TKey> keys, Span<TValue> values)
=> Sort(keys, values, Comparer<TKey>.Default);


/// <summary>
/// Sorts a pair of spans (one containing the keys and the other containing the corresponding items) based on the keys in the first <see cref="Span{T}"/> using the specified comparer.
/// </summary>
//Link: https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sort?view=net-10.0#system-memoryextensions-sort-3(system-span((-0))-system-span((-1))-2)
public static void Sort<TKey, TValue, TComparer>(this Span<TKey> keys, Span<TValue> values, TComparer comparer)
where TComparer : IComparer<TKey>
{
comparer = comparer is not null ? comparer : throw new ArgumentNullException(nameof(comparer));

if(keys.Length != values.Length)
throw new ArgumentException();

var keysArray = ArrayPool<TKey>.Shared.Rent(keys.Length);
var valsArray = ArrayPool<TValue>.Shared.Rent(values.Length);

try
{
keys.CopyTo(keysArray);
values.CopyTo(valsArray);

Array.Sort(keysArray, valsArray, 0, keys.Length, comparer);

keysArray.AsSpan(0, keys.Length).CopyTo(keys);
valsArray.AsSpan(0, values.Length).CopyTo(values);
}
finally
{
ArrayPool<TKey>.Shared.Return(keysArray);
ArrayPool<TValue>.Shared.Return(valsArray);
}
}

/// <summary>
/// Sorts a pair of spans (one containing the keys and the other containing the corresponding items) based on the keys in the first <see cref="Span{T}"/> using the specified comparison.
/// </summary>
//Link: https://learn.microsoft.com/en-us/dotnet/api/system.memoryextensions.sort?view=net-10.0#system-memoryextensions-sort-2(system-span((-0))-system-span((-1))-system-comparison((-0)))
public static void Sort<TKey, TValue>(this Span<TKey> keys, Span<TValue> items, Comparison<TKey> comparison)
=> Sort(keys, items, new ComparerWrapper<TKey>(comparison));

class ComparerWrapper<T> : IComparer<T>
{
readonly Comparison<T> comparison;

internal ComparerWrapper(Comparison<T> comparison)
{
if ((Comparison<T>?)comparison is null)
throw new ArgumentNullException(nameof(comparison));

this.comparison = comparison;
}

public int Compare(T? x, T? y)
{
if (x is null || y is null)
return 0;

return comparison((T)x, (T)y);
}
}
}

#endif
Loading