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 @@ -3,7 +3,6 @@

using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;

namespace System.Collections.Immutable
{
Expand Down Expand Up @@ -591,17 +590,10 @@ public void RemoveRange(int index, int length)

if (index + length < this._count)
{

#if NET
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
Comment thread
eiriktsarpalis marked this conversation as resolved.
Resolved
{
Array.Clear(_elements, index, length); // Clear the elements so that the gc can reclaim the references.
}
#endif
Array.Copy(_elements, index + length, _elements, index, this.Count - index - length);
}

this._count -= length;
this.Count -= length;
}

/// <summary>
Expand Down Expand Up @@ -1095,7 +1087,7 @@ private void RemoveAtRange(ICollection<int> indicesToRemove)

Array.Copy(_elements, copied + removed, _elements, copied, _elements.Length - (copied + removed));

_count -= indicesToRemove.Count;
this.Count -= indicesToRemove.Count;
}

/// <summary>Gets a <see cref="Memory{T}"/> for the filled portion of the backing array.</summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,69 @@ public void RemoveAll()
AssertExtensions.Throws<ArgumentNullException>("match", () => builder.RemoveAll(match: null));
}

[Theory]
[InlineData(4, 0, 0)]
[InlineData(4, 4, 0)]
[InlineData(4, 0, 1)]
[InlineData(4, 1, 2)]
[InlineData(4, 3, 1)]
[InlineData(4, 0, 4)]
[InlineData(70, 0, 65)]
[InlineData(70, 1, 65)]
[InlineData(70, 5, 65)]
public void RemoveRange_ClearsElements(int count, int index, int length)
{
Verify(Enumerable.Range(1, count).ToArray());
Verify(Enumerable.Range(1, count).Select(i => i.ToString()).ToArray());
Verify(Enumerable.Range(1, count).Select(i => new KeyValuePair<int, string>(i, i.ToString())).ToArray());

void Verify<T>(T[] items)
{
T[] expected = items.Take(index).Concat(items.Skip(index + length)).ToArray();
AssertRemovedElementsCleared(items, expected, builder => builder.RemoveRange(index, length));
}
}

[Theory]
[InlineData(0)]
[InlineData(1)]
[InlineData(4)]
[InlineData(70)]
public void RemoveAllAndEnumerableRemoveRange_ClearsElements(int count)
{
Verify(Enumerable.Range(1, count).ToArray());
Verify(Enumerable.Range(1, count).Select(i => i.ToString()).ToArray());
Verify(Enumerable.Range(1, count).Select(i => new KeyValuePair<int, string>(i, i.ToString())).ToArray());

void Verify<T>(T[] items)
{
foreach (T[] removed in new[] { Array.Empty<T>(), items, items.Where((_, i) => i % 2 == 0).ToArray() })
{
T[] expected = items.Where(item => !removed.Contains(item)).ToArray();
AssertRemovedElementsCleared(items, expected, builder => builder.RemoveRange(removed));
AssertRemovedElementsCleared(items, expected, builder => builder.RemoveRange(removed, EqualityComparer<T>.Default));
AssertRemovedElementsCleared(items, expected, builder => builder.RemoveAll(item => removed.Contains(item)));
}
}
}

private static void AssertRemovedElementsCleared<T>(T[] items, T[] expected, Action<ImmutableArray<T>.Builder> remove)
{
foreach (int capacity in new[] { items.Length, items.Length + 8 })
{
ImmutableArray<T>.Builder builder = ImmutableArray.CreateBuilder<T>(capacity);
builder.AddRange(items);

remove(builder);
Assert.Equal(expected, builder);

builder.Count = items.Length;
var expanded = new T[items.Length];
Array.Copy(expected, expanded, expected.Length);
Assert.Equal(expanded, builder);
}
}

[Fact]
public void ReverseContents()
{
Expand Down
Loading