Skip to content

Commit

Permalink
SortedList<TKey, TValue> added GetKeyAtIndex, GetValueAtIndex, and Se…
Browse files Browse the repository at this point in the history
…tValueAtIndex (#60520)

* SortedList<TKey, TValue> added GetKeyAtIndex, GetValueAtIndex, and SetValueAtIndex

* Update src/libraries/System.Collections/src/System/Collections/Generic/SortedList.cs

Co-authored-by: Eirik Tsarpalis <eirik.tsarpalis@gmail.com>
  • Loading branch information
rhaokiel and eiriktsarpalis committed Nov 15, 2021
1 parent 21f9b73 commit 4cf86c2
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 5 deletions.
3 changes: 3 additions & 0 deletions src/libraries/System.Collections/ref/System.Collections.cs
Original file line number Diff line number Diff line change
Expand Up @@ -606,10 +606,13 @@ public void Clear() { }
public bool ContainsKey(TKey key) { throw null; }
public bool ContainsValue(TValue value) { throw null; }
public System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<TKey, TValue>> GetEnumerator() { throw null; }
public TKey GetKeyAtIndex(int index) { throw null; }
public TValue GetValueAtIndex(int index) { throw null; }
public int IndexOfKey(TKey key) { throw null; }
public int IndexOfValue(TValue value) { throw null; }
public bool Remove(TKey key) { throw null; }
public void RemoveAt(int index) { }
public void SetValueAtIndex(int index, TValue value) { }
void System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey, TValue>>.Add(System.Collections.Generic.KeyValuePair<TKey, TValue> keyValuePair) { }
bool System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey, TValue>>.Contains(System.Collections.Generic.KeyValuePair<TKey, TValue> keyValuePair) { throw null; }
void System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<TKey, TValue>>.CopyTo(System.Collections.Generic.KeyValuePair<TKey, TValue>[] array, int arrayIndex) { }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics;
Expand Down Expand Up @@ -536,13 +536,22 @@ private void EnsureCapacity(int min)
}

// Returns the value of the entry at the given index.
private TValue GetByIndex(int index)
public TValue GetValueAtIndex(int index)
{
if (index < 0 || index >= _size)
throw new ArgumentOutOfRangeException(nameof(index), index, SR.ArgumentOutOfRange_Index);
return values[index];
}

// Sets the value of the entry at the given index.
public void SetValueAtIndex(int index, TValue value)
{
if (index < 0 || index >= _size)
throw new ArgumentOutOfRangeException(nameof(index), index, SR.ArgumentOutOfRange_Index);
values[index] = value;
version++;
}

public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
return new Enumerator(this, Enumerator.KeyValuePair);
Expand All @@ -564,7 +573,7 @@ IEnumerator IEnumerable.GetEnumerator()
}

// Returns the key of the entry at the given index.
private TKey GetKey(int index)
public TKey GetKeyAtIndex(int index)
{
if (index < 0 || index >= _size)
throw new ArgumentOutOfRangeException(nameof(index), index, SR.ArgumentOutOfRange_Index);
Expand Down Expand Up @@ -1082,7 +1091,7 @@ public TKey this[int index]
{
get
{
return _dict.GetKey(index);
return _dict.GetKeyAtIndex(index);
}
set
{
Expand Down Expand Up @@ -1201,7 +1210,7 @@ public TValue this[int index]
{
get
{
return _dict.GetByIndex(index);
return _dict.GetValueAtIndex(index);
}
set
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,59 @@ public void SortedList_Generic_ContainsValue_DefaultValuePresent(int count)

#endregion

#region GetKeyAtIndex

[Theory]
[MemberData(nameof(ValidCollectionSizes))]
public void SortedList_Generic_GetKeyAtIndex_EveryIndex(int count)
{
SortedList<TKey, TValue> dictionary = (SortedList<TKey, TValue>)GenericIDictionaryFactory(count);
Assert.All(Enumerable.Range(0, count), index =>
{
Assert.Equal(index, dictionary.IndexOfKey(dictionary.GetKeyAtIndex(index)));
});
}

[Theory]
[MemberData(nameof(ValidCollectionSizes))]
public void SortedList_Generic_GetKeyAtIndex_OutOfRangeIndicies(int count)
{
SortedList<TKey, TValue> dictionary = (SortedList<TKey, TValue>)GenericIDictionaryFactory(count);
Assert.Throws<ArgumentOutOfRangeException>(() => dictionary.GetKeyAtIndex(-1));
Assert.Throws<ArgumentOutOfRangeException>(() => dictionary.GetKeyAtIndex(int.MinValue));
Assert.Throws<ArgumentOutOfRangeException>(() => dictionary.GetKeyAtIndex(count));
Assert.Throws<ArgumentOutOfRangeException>(() => dictionary.GetKeyAtIndex(count + 1));
}

#endregion

#region GetValueAtIndex

[Theory]
[MemberData(nameof(ValidCollectionSizes))]
public void SortedList_Generic_GetValueAtIndex_EveryIndex(int count)
{
// Assumes no duplicate elements contained in the dictionary returned by GenericIDictionaryFactory
SortedList<TKey, TValue> dictionary = (SortedList<TKey, TValue>)GenericIDictionaryFactory(count);
Assert.All(Enumerable.Range(0, count), index =>
{
Assert.Equal(index, dictionary.IndexOfValue(dictionary.GetValueAtIndex(index)));
});
}

[Theory]
[MemberData(nameof(ValidCollectionSizes))]
public void SortedList_Generic_GetValueAtIndex_OutOfRangeIndicies(int count)
{
SortedList<TKey, TValue> dictionary = (SortedList<TKey, TValue>)GenericIDictionaryFactory(count);
Assert.Throws<ArgumentOutOfRangeException>(() => dictionary.GetValueAtIndex(-1));
Assert.Throws<ArgumentOutOfRangeException>(() => dictionary.GetValueAtIndex(int.MinValue));
Assert.Throws<ArgumentOutOfRangeException>(() => dictionary.GetValueAtIndex(count));
Assert.Throws<ArgumentOutOfRangeException>(() => dictionary.GetValueAtIndex(count + 1));
}

#endregion

#region IndexOfKey

[Theory]
Expand Down Expand Up @@ -377,6 +430,73 @@ public void SortedList_Generic_IndexOfValue_EachValue(int count)

#endregion

#region SetValueAtIndex

[Theory]
[MemberData(nameof(ValidCollectionSizes))]
public void SortedList_Generic_SetValueAtIndex_OnReadOnlySortedList_ThrowsNotSupportedException(int count)
{
if (IsReadOnly)
{
SortedList<TKey, TValue> dictionary = (SortedList<TKey, TValue>)GenericIDictionaryFactory(count);
Assert.Throws<NotSupportedException>(() => dictionary.SetValueAtIndex(0, CreateTValue(34543)));
}
}

[Theory]
[MemberData(nameof(ValidCollectionSizes))]
public void SortedList_Generic_SetValueAtIndex_NonDefaultValueContainedInCollection(int count)
{
if (!IsReadOnly)
{
int seed = count * 251;
SortedList<TKey, TValue> dictionary = (SortedList<TKey, TValue>)GenericIDictionaryFactory(count);
KeyValuePair<TKey, TValue> pair = CreateT(seed++);
if (!dictionary.ContainsKey(pair.Key))
{
dictionary.Add(pair.Key, pair.Value);
count++;
}
TValue newValue = CreateTValue(seed++);
dictionary.SetValueAtIndex(dictionary.IndexOfKey(pair.Key), newValue);
Assert.Equal(newValue, dictionary[pair.Key]);
}
}

[Theory]
[MemberData(nameof(ValidCollectionSizes))]
public void SortedList_Generic_SetValueAtIndex_EveryIndex(int count)
{
if (!IsReadOnly)
{
int seed = count * 193;
SortedList<TKey, TValue> dictionary = (SortedList<TKey, TValue>)GenericIDictionaryFactory(count);
TValue newValue = CreateTValue(seed++);
Assert.All(Enumerable.Range(0, count), index =>
{
Assert.NotEqual(newValue, dictionary.GetValueAtIndex(index));
dictionary.SetValueAtIndex(index, newValue);
Assert.Equal(newValue, dictionary.GetValueAtIndex(index));
});
}
}

[Theory]
[MemberData(nameof(ValidCollectionSizes))]
public void SortedList_Generic_SetValueAtIndex_OutOfRangeIndicies(int count)
{
if (!IsReadOnly)
{
SortedList<TKey, TValue> dictionary = (SortedList<TKey, TValue>)GenericIDictionaryFactory(count);
Assert.Throws<ArgumentOutOfRangeException>(() => dictionary.SetValueAtIndex(-1, default));
Assert.Throws<ArgumentOutOfRangeException>(() => dictionary.SetValueAtIndex(int.MinValue, default));
Assert.Throws<ArgumentOutOfRangeException>(() => dictionary.SetValueAtIndex(count, default));
Assert.Throws<ArgumentOutOfRangeException>(() => dictionary.SetValueAtIndex(count + 1, default));
}
}

#endregion

#region RemoveAt

private void RemoveAt(SortedList<TKey, TValue> dictionary, KeyValuePair<TKey, TValue> element)
Expand Down

0 comments on commit 4cf86c2

Please sign in to comment.