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
Original file line number Diff line number Diff line change
Expand Up @@ -1302,5 +1302,6 @@ public static partial class ImmutableCollectionsMarshal
{
public static System.Collections.Immutable.ImmutableArray<T> AsImmutableArray<T>(T[]? array) { throw null; }
public static T[]? AsArray<T>(System.Collections.Immutable.ImmutableArray<T> array) { throw null; }
public static System.Memory<T> AsMemory<T>(System.Collections.Immutable.ImmutableArray<T>.Builder? builder) { throw null; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1095,6 +1095,9 @@ private void RemoveAtRange(ICollection<int> indicesToRemove)

_count -= indicesToRemove.Count;
}

/// <summary>Gets a <see cref="Memory{T}"/> for the filled portion of the backing array.</summary>
internal Memory<T> AsMemory() => new(_elements, 0, _count);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Collections;
using System.Collections.Immutable;

namespace System.Runtime.InteropServices
Expand Down Expand Up @@ -54,5 +55,19 @@ public static ImmutableArray<T> AsImmutableArray<T>(T[]? array)
{
return array.array;
}

/// <summary>
/// Gets a <see cref="Memory{T}"/> for the <typeparamref name="T"/> array underlying an input <see cref="ImmutableArray{T}.Builder"/>.
/// </summary>
/// <typeparam name="T">The type of elements in the input <see cref="ImmutableArray{T}.Builder"/> value.</typeparam>
/// <param name="builder">The builder.</param>
/// <returns>
/// A <see cref="Memory{T}"/> for the filled portion of <typeparamref name="T"/> array underlying
/// the input <see cref="ImmutableArray{T}.Builder"/>.
/// </returns>
public static Memory<T> AsMemory<T>(ImmutableArray<T>.Builder? builder)
{
return builder?.AsMemory() ?? default;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,59 @@ static void Test<T>()
Test<UnmanagedCustomStruct?>();
}

[Fact]
public void AsMemoryFromNullBuilder()
{
Memory<Guid> m = ImmutableCollectionsMarshal.AsMemory<Guid>(null);
Assert.True(m.IsEmpty);
Assert.True(MemoryMarshal.TryGetArray(m, out ArraySegment<Guid> segment));
Assert.NotNull(segment.Array);
Assert.Equal(0, segment.Array.Length);
Assert.Equal(0, segment.Offset);
Assert.Equal(0, segment.Count);
}

[Fact]
public void AsMemoryFromEmptyBuilder()
{
Memory<string> m = ImmutableCollectionsMarshal.AsMemory(ImmutableArray.CreateBuilder<string>());
Assert.True(m.IsEmpty);
Assert.True(MemoryMarshal.TryGetArray(m, out ArraySegment<string> segment));
Assert.NotNull(segment.Array);
Assert.Equal(0, segment.Offset);
Assert.Equal(0, segment.Count);
}

[Fact]
public void AsMemoryFromNonEmptyBuilder()
{
ImmutableArray<int>.Builder builder = ImmutableArray.CreateBuilder<int>(1);
builder.Add(42);
builder.Add(43);
builder.Add(44);

Memory<int> m1 = ImmutableCollectionsMarshal.AsMemory(builder);
Assert.Equal(3, m1.Length);

Assert.True(MemoryMarshal.TryGetArray(m1, out ArraySegment<int> segment1));
Assert.NotNull(segment1.Array);
Assert.Equal(0, segment1.Offset);
Assert.Equal(3, segment1.Count);

Span<int> span = m1.Span;
Assert.Equal(42, span[0]);
Assert.Equal(43, span[1]);
Assert.Equal(44, span[2]);

Memory<int> m2 = ImmutableCollectionsMarshal.AsMemory(builder);
Assert.Equal(3, m2.Length);
Assert.True(MemoryMarshal.TryGetArray(m2, out ArraySegment<int> segment2));

Assert.Same(segment1.Array, segment2.Array);
Assert.Equal(segment1.Offset, segment2.Offset);
Assert.Equal(segment1.Count, segment2.Count);
}

public class CustomClass
{
public object Foo;
Expand Down
Loading