Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

issue-22928 Add ImmutableArray Span-based APIs #61196

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
f0c9ca8
issue-22928 Initial commit: AddRange, InsertRange, ToImmutableArray, …
lateapexearlyspeed Nov 4, 2021
4ce2f25
issue-22928 CopyTo, RemoveRange, Slice. Skip old tests.
lateapexearlyspeed Nov 12, 2021
10ed570
Eliminate range based method compilation for .netstandard2.0 and net461.
lateapexearlyspeed Nov 18, 2021
89810ad
issue-22928 Refine to use common code.
lateapexearlyspeed Nov 30, 2021
4f1ef20
Try to use <framework>_OR_GREATER pre-compilation symbol.
lateapexearlyspeed Nov 30, 2021
6691eda
issue-22928 Test cases of ImmutableArray.Create() overloads.
lateapexearlyspeed Dec 2, 2021
b46c0af
issue-22928 Add test cases for ImmutableArray.ToImmutableArray(), Imm…
lateapexearlyspeed Dec 2, 2021
3144366
Test cases for AsSpan(start, length).
lateapexearlyspeed Dec 3, 2021
d0571c4
Test cases of AsSpan(Range).
lateapexearlyspeed Dec 3, 2021
1516ed0
Test cases of ImmutableArray.CopyTo().
lateapexearlyspeed Dec 3, 2021
c8e2b68
Test cases of InsertRange().
lateapexearlyspeed Dec 6, 2021
7fd7041
Test cases of RemoveRange().
lateapexearlyspeed Dec 8, 2021
1f67b98
Add test cases of .Slice().
lateapexearlyspeed Dec 13, 2021
f10ae91
Add test cases of Builder.CopyTo() and Builder.AddRange().
lateapexearlyspeed Dec 16, 2021
4078a17
Add xml doc for AsSpan(Range) method.
lateapexearlyspeed Dec 17, 2021
932e731
Fix comment: refine test cases; adjust method list order; add Debug.A…
lateapexearlyspeed Jan 12, 2022
c4384df
Fix comment: move tfm specific code into separate tfm files.
lateapexearlyspeed Jan 14, 2022
c470255
Fix ValidateDefaultThisBehavior() logic issue.
lateapexearlyspeed Jan 18, 2022
b29f105
Fix comment: use compile condition: $(TargetFrameworkIdentifier)' == …
lateapexearlyspeed Jan 20, 2022
d98e0d9
Fix comment: specify actual data length when construct span.
lateapexearlyspeed Jan 20, 2022
50e278d
Change RemoveRange(ReadOnlySpan) to be O(M+N) implementation.
lateapexearlyspeed Jan 21, 2022
ba0fa13
Fix comment: refine xml doc.
lateapexearlyspeed Jan 21, 2022
fb1dd63
Fix comment: Use new CollectionsMarshal methods to get and update val…
lateapexearlyspeed Jan 24, 2022
7441ab9
Fix comment: refine RemoveRange() to use 'continue'.
lateapexearlyspeed Jan 26, 2022
f1d1d34
Fix comment: merge 2 tfm version RemoveRange() back to ImmutableArray…
lateapexearlyspeed Jan 26, 2022
5366414
Add some demo-used test cases to indicate (null & custom equalityComp…
lateapexearlyspeed Jan 29, 2022
1460a51
Revert "Change RemoveRange(ReadOnlySpan) to be O(M+N) implementation."
lateapexearlyspeed Feb 9, 2022
85ebef4
Fix comment: use explicit type name; enhance RemoveRange test cases t…
lateapexearlyspeed Feb 10, 2022
1bb557c
Use explicit type names.
lateapexearlyspeed Feb 10, 2022
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
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,12 @@ public static partial class ImmutableArray
public static System.Collections.Immutable.ImmutableArray<T> Create<T>(T item1, T item2, T item3, T item4) { throw null; }
public static System.Collections.Immutable.ImmutableArray<T> Create<T>(params T[]? items) { throw null; }
public static System.Collections.Immutable.ImmutableArray<T> Create<T>(T[] items, int start, int length) { throw null; }
public static System.Collections.Immutable.ImmutableArray<T> Create<T>(System.ReadOnlySpan<T> items) { throw null; }
public static System.Collections.Immutable.ImmutableArray<T> Create<T>(System.Span<T> items) { throw null; }
public static System.Collections.Immutable.ImmutableArray<TSource> ToImmutableArray<TSource>(this System.Collections.Generic.IEnumerable<TSource> items) { throw null; }
public static System.Collections.Immutable.ImmutableArray<TSource> ToImmutableArray<TSource>(this System.Collections.Immutable.ImmutableArray<TSource>.Builder builder) { throw null; }
public static System.Collections.Immutable.ImmutableArray<T> ToImmutableArray<T>(this System.ReadOnlySpan<T> items) { throw null; }
public static System.Collections.Immutable.ImmutableArray<T> ToImmutableArray<T>(this System.Span<T> items) { throw null; }
}
public readonly partial struct ImmutableArray<T> : System.Collections.Generic.ICollection<T>, System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.Generic.IReadOnlyList<T>, System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.IList, System.Collections.Immutable.IImmutableList<T>, System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.IEquatable<System.Collections.Immutable.ImmutableArray<T>>
{
Expand All @@ -118,8 +122,11 @@ public static partial class ImmutableArray
public System.Collections.Immutable.ImmutableArray<T> Add(T item) { throw null; }
public System.Collections.Immutable.ImmutableArray<T> AddRange(System.Collections.Generic.IEnumerable<T> items) { throw null; }
public System.Collections.Immutable.ImmutableArray<T> AddRange(System.Collections.Immutable.ImmutableArray<T> items) { throw null; }
public System.Collections.Immutable.ImmutableArray<T> AddRange(System.ReadOnlySpan<T> items) { throw null; }
public System.Collections.Immutable.ImmutableArray<T> AddRange(params T[] items) { throw null; }
public System.ReadOnlyMemory<T> AsMemory() { throw null; }
public System.ReadOnlySpan<T> AsSpan() { throw null; }
public System.ReadOnlySpan<T> AsSpan(int start, int length) { throw null; }
public System.Collections.Immutable.ImmutableArray<
#nullable disable
TOther
Expand All @@ -140,6 +147,7 @@ public static System.Collections.Immutable.ImmutableArray<
public void CopyTo(int sourceIndex, T[] destination, int destinationIndex, int length) { }
public void CopyTo(T[] destination) { }
public void CopyTo(T[] destination, int destinationIndex) { }
public void CopyTo(System.Span<T> destination) { }
public bool Equals(System.Collections.Immutable.ImmutableArray<T> other) { throw null; }
public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; }
public System.Collections.Immutable.ImmutableArray<T>.Enumerator GetEnumerator() { throw null; }
Expand All @@ -152,6 +160,8 @@ public void CopyTo(T[] destination, int destinationIndex) { }
public System.Collections.Immutable.ImmutableArray<T> Insert(int index, T item) { throw null; }
public System.Collections.Immutable.ImmutableArray<T> InsertRange(int index, System.Collections.Generic.IEnumerable<T> items) { throw null; }
public System.Collections.Immutable.ImmutableArray<T> InsertRange(int index, System.Collections.Immutable.ImmutableArray<T> items) { throw null; }
public System.Collections.Immutable.ImmutableArray<T> InsertRange(int index, T[] items) { throw null; }
public System.Collections.Immutable.ImmutableArray<T> InsertRange(int index, System.ReadOnlySpan<T> items) { throw null; }
public ref readonly T ItemRef(int index) { throw null; }
public int LastIndexOf(T item) { throw null; }
public int LastIndexOf(T item, int startIndex) { throw null; }
Expand All @@ -171,9 +181,12 @@ public void CopyTo(T[] destination, int destinationIndex) { }
public System.Collections.Immutable.ImmutableArray<T> RemoveRange(System.Collections.Immutable.ImmutableArray<T> items) { throw null; }
public System.Collections.Immutable.ImmutableArray<T> RemoveRange(System.Collections.Immutable.ImmutableArray<T> items, System.Collections.Generic.IEqualityComparer<T>? equalityComparer) { throw null; }
public System.Collections.Immutable.ImmutableArray<T> RemoveRange(int index, int length) { throw null; }
public System.Collections.Immutable.ImmutableArray<T> RemoveRange(System.ReadOnlySpan<T> items, System.Collections.Generic.IEqualityComparer<T>? equalityComparer = null) { throw null; }
public System.Collections.Immutable.ImmutableArray<T> RemoveRange(T[] items, System.Collections.Generic.IEqualityComparer<T>? equalityComparer = null) { throw null; }
public System.Collections.Immutable.ImmutableArray<T> Replace(T oldValue, T newValue) { throw null; }
public System.Collections.Immutable.ImmutableArray<T> Replace(T oldValue, T newValue, System.Collections.Generic.IEqualityComparer<T>? equalityComparer) { throw null; }
public System.Collections.Immutable.ImmutableArray<T> SetItem(int index, T item) { throw null; }
public System.Collections.Immutable.ImmutableArray<T> Slice(int start, int length) { throw null; }
public System.Collections.Immutable.ImmutableArray<T> Sort() { throw null; }
public System.Collections.Immutable.ImmutableArray<T> Sort(System.Collections.Generic.IComparer<T>? comparer) { throw null; }
public System.Collections.Immutable.ImmutableArray<T> Sort(System.Comparison<T> comparison) { throw null; }
Expand Down Expand Up @@ -226,9 +239,12 @@ public void AddRange(T[] items, int length) { }
public void AddRange<TDerived>(System.Collections.Immutable.ImmutableArray<TDerived> items) where TDerived : T { }
public void AddRange<TDerived>(System.Collections.Immutable.ImmutableArray<TDerived>.Builder items) where TDerived : T { }
public void AddRange<TDerived>(TDerived[] items) where TDerived : T { }
public void AddRange(System.ReadOnlySpan<T> items) { }
public void AddRange<TDerived>(System.ReadOnlySpan<TDerived> items) where TDerived : T { }
public void Clear() { }
public bool Contains(T item) { throw null; }
public void CopyTo(T[] array, int index) { }
public void CopyTo(System.Span<T> destination) { }
public System.Collections.Generic.IEnumerator<T> GetEnumerator() { throw null; }
public int IndexOf(T item) { throw null; }
public int IndexOf(T item, int startIndex) { throw null; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="System.Collections.Immutable.cs" />
<Compile Include="System.Collections.Immutable.netcoreapp.cs" Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp'" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == '$(NetCoreAppCurrent)'">
<ProjectReference Include="$(LibrariesProjectRoot)System.Collections\ref\System.Collections.csproj" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// ------------------------------------------------------------------------------
// Changes to this file must follow the https://aka.ms/api-review process.
// ------------------------------------------------------------------------------

namespace System.Collections.Immutable
{
public readonly partial struct ImmutableArray<T> : System.Collections.Generic.ICollection<T>, System.Collections.Generic.IEnumerable<T>, System.Collections.Generic.IList<T>, System.Collections.Generic.IReadOnlyCollection<T>, System.Collections.Generic.IReadOnlyList<T>, System.Collections.ICollection, System.Collections.IEnumerable, System.Collections.IList, System.Collections.Immutable.IImmutableList<T>, System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.IEquatable<System.Collections.Immutable.ImmutableArray<T>>
{
public System.ReadOnlySpan<T> AsSpan(System.Range range) { throw null; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ System.Collections.Immutable.ImmutableStack&lt;T&gt;</PackageDescription>
<Compile Include="System\Collections\Immutable\ImmutableArray_1.Builder.DebuggerProxy.cs" />
<Compile Include="System\Collections\Immutable\ImmutableArray_1.Enumerator.cs" />
<Compile Include="System\Collections\Immutable\ImmutableArray_1.cs" />
<Compile Include="System\Collections\Immutable\ImmutableArray_1.netcoreapp.cs" Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp'" />
<Compile Include="System\Collections\Immutable\ImmutableArray_1.Minimal.cs" />
<Compile Include="System\Collections\Immutable\ImmutableDictionary.cs" />
<Compile Include="System\Collections\Immutable\ImmutableDictionary_2.Builder.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public static ImmutableArray<T> Create<T>()
/// </summary>
/// <typeparam name="T">The type of element stored in the array.</typeparam>
/// <param name="item">The element to store in the array.</param>
/// <returns>A 1-element array.</returns>
/// <returns>A 1-element immutable array containing the specified item.</returns>
public static ImmutableArray<T> Create<T>(T item)
{
T[] array = new[] { item };
Expand All @@ -45,7 +45,7 @@ public static ImmutableArray<T> Create<T>(T item)
/// <typeparam name="T">The type of element stored in the array.</typeparam>
/// <param name="item1">The first element to store in the array.</param>
/// <param name="item2">The second element to store in the array.</param>
/// <returns>A 2-element array.</returns>
/// <returns>A 2-element immutable array containing the specified items.</returns>
public static ImmutableArray<T> Create<T>(T item1, T item2)
{
T[] array = new[] { item1, item2 };
Expand All @@ -59,7 +59,7 @@ public static ImmutableArray<T> Create<T>(T item1, T item2)
/// <param name="item1">The first element to store in the array.</param>
/// <param name="item2">The second element to store in the array.</param>
/// <param name="item3">The third element to store in the array.</param>
/// <returns>A 3-element array.</returns>
/// <returns>A 3-element immutable array containing the specified items.</returns>
public static ImmutableArray<T> Create<T>(T item1, T item2, T item3)
{
T[] array = new[] { item1, item2, item3 };
Expand All @@ -74,13 +74,63 @@ public static ImmutableArray<T> Create<T>(T item1, T item2, T item3)
/// <param name="item2">The second element to store in the array.</param>
/// <param name="item3">The third element to store in the array.</param>
/// <param name="item4">The fourth element to store in the array.</param>
/// <returns>A 4-element array.</returns>
/// <returns>A 4-element immutable array containing the specified items.</returns>
public static ImmutableArray<T> Create<T>(T item1, T item2, T item3, T item4)
{
T[] array = new[] { item1, item2, item3, item4 };
return new ImmutableArray<T>(array);
}

/// <summary>
/// Creates an <see cref="ImmutableArray{T}"/> with the specified elements.
/// </summary>
/// <typeparam name="T">The type of element stored in the array.</typeparam>
/// <param name="items">The elements to store in the array.</param>
/// <returns>An immutable array containing the specified items.</returns>
public static ImmutableArray<T> Create<T>(ReadOnlySpan<T> items)
{
if (items.IsEmpty)
{
return ImmutableArray<T>.Empty;
}

T[] array = items.ToArray();
return new ImmutableArray<T>(array);
}

/// <summary>
/// Creates an <see cref="ImmutableArray{T}"/> with the specified elements.
/// </summary>
/// <typeparam name="T">The type of element stored in the array.</typeparam>
/// <param name="items">The elements to store in the array.</param>
/// <returns>An immutable array containing the specified items.</returns>
public static ImmutableArray<T> Create<T>(Span<T> items)
{
return Create((ReadOnlySpan<T>)items);
}

/// <summary>
/// Produce an immutable array of contents from specified elements.
/// </summary>
/// <typeparam name="T">The type of element in the list.</typeparam>
/// <param name="items">The elements to store in the array.</param>
/// <returns>An immutable array containing the specified items.</returns>
public static ImmutableArray<T> ToImmutableArray<T>(this ReadOnlySpan<T> items)
{
eiriktsarpalis marked this conversation as resolved.
Show resolved Hide resolved
return Create(items);
}

/// <summary>
/// Produce an immutable array of contents from specified elements.
/// </summary>
/// <typeparam name="T">The type of element in the list.</typeparam>
/// <param name="items">The elements to store in the array.</param>
/// <returns>An immutable array containing the specified items.</returns>
public static ImmutableArray<T> ToImmutableArray<T>(this Span<T> items)
{
return Create((ReadOnlySpan<T>)items);
}

/// <summary>
/// Creates an <see cref="ImmutableArray{T}"/> populated with the contents of the specified sequence.
/// </summary>
Expand Down Expand Up @@ -133,7 +183,7 @@ public static ImmutableArray<T> CreateRange<T>(IEnumerable<T> items)
/// </summary>
/// <typeparam name="T">The type of element stored in the array.</typeparam>
/// <param name="items">The elements to store in the array.</param>
/// <returns>An immutable array.</returns>
/// <returns>An immutable array containing the specified items.</returns>
public static ImmutableArray<T> Create<T>(params T[]? items)
{
if (items == null || items.Length == 0)
Expand Down Expand Up @@ -368,7 +418,7 @@ public static ImmutableArray<T>.Builder CreateBuilder<T>(int initialCapacity)
/// </summary>
/// <typeparam name="TSource">The type of element in the sequence.</typeparam>
/// <param name="items">The sequence to enumerate.</param>
/// <returns>An immutable array.</returns>
/// <returns>An immutable array containing the specified items.</returns>
public static ImmutableArray<TSource> ToImmutableArray<TSource>(this IEnumerable<TSource> items)
{
if (items is ImmutableArray<TSource>)
Expand All @@ -383,7 +433,7 @@ public static ImmutableArray<TSource> ToImmutableArray<TSource>(this IEnumerable
/// Returns an immutable copy of the current contents of the builder's collection.
/// </summary>
/// <param name="builder">The builder to create the immutable array from.</param>
/// <returns>An immutable array.</returns>
/// <returns>An immutable array containing the specified items from <paramref name="builder"/>.</returns>
public static ImmutableArray<TSource> ToImmutableArray<TSource>(this ImmutableArray<TSource>.Builder builder)
{
Requires.NotNull(builder, nameof(builder));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,35 @@ public void AddRange(ImmutableArray<T> items, int length)
/// <summary>
/// Adds the specified items to the end of the array.
/// </summary>
/// <param name="items">The items.</param>
/// <param name="items">The items to add at the end of the array.</param>
public void AddRange(ReadOnlySpan<T> items)
{
int offset = this.Count;
this.Count += items.Length;

items.CopyTo(new Span<T>(_elements, offset, items.Length));
}

/// <summary>
/// Adds the specified items to the end of the array.
/// </summary>
/// <param name="items">The items to add at the end of the array.</param>
public void AddRange<TDerived>(ReadOnlySpan<TDerived> items) where TDerived : T
{
int offset = this.Count;
this.Count += items.Length;

var elements = new Span<T>(_elements, offset, items.Length);
for (int i = 0; i < items.Length; i++)
{
elements[i] = items[i];
}
}

/// <summary>
/// Adds the specified items to the end of the array.
/// </summary>
/// <param name="items">The items to add at the end of the array.</param>
public void AddRange<TDerived>(ImmutableArray<TDerived> items) where TDerived : T
{
if (items.array != null)
Expand All @@ -360,7 +388,7 @@ public void AddRange<TDerived>(ImmutableArray<TDerived> items) where TDerived :
/// <summary>
/// Adds the specified items to the end of the array.
/// </summary>
/// <param name="items">The items.</param>
/// <param name="items">The items to add at the end of the array.</param>
public void AddRange(Builder items)
{
Requires.NotNull(items, nameof(items));
Expand All @@ -370,7 +398,7 @@ public void AddRange(Builder items)
/// <summary>
/// Adds the specified items to the end of the array.
/// </summary>
/// <param name="items">The items.</param>
/// <param name="items">The items to add at the end of the array.</param>
public void AddRange<TDerived>(ImmutableArray<TDerived>.Builder items) where TDerived : T
{
Requires.NotNull(items, nameof(items));
Expand Down Expand Up @@ -705,6 +733,16 @@ public void Sort(int index, int count, IComparer<T>? comparer)
}
}

/// <summary>
/// Copies the current contents to the specified <see cref="Span{T}"/>.
/// </summary>
/// <param name="destination">The <see cref="Span{T}"/> to copy to.</param>
public void CopyTo(Span<T> destination)
{
Requires.Range(this.Count <= destination.Length, nameof(destination));
new ReadOnlySpan<T>(_elements, 0, this.Count).CopyTo(destination);
}

/// <summary>
/// Returns an enumerator for the contents of the array.
/// </summary>
Expand Down
Loading