Implement missing interfaces on `SortedList<T>`

This commit is contained in:
YoshiRulz 2025-03-21 08:51:49 +10:00
parent 2b587f2061
commit c391c6ff58
No known key found for this signature in database
GPG Key ID: C4DE31C245353FB7
1 changed files with 52 additions and 1 deletions

View File

@ -4,17 +4,28 @@ using System.Linq;
namespace BizHawk.Common
{
public class SortedList<T> : IList<T>
public class SortedList<T> : IList, IList<T>, IReadOnlyList<T>
where T : IComparable<T>
{
private const string ERR_MSG_OUT_OF_ORDER = "setting/inserting elements must preserve ordering";
private const string ERR_MSG_WRONG_TYPE = "wrong type";
protected readonly List<T> _list;
public virtual int Count => _list.Count;
bool IList.IsFixedSize
=> false;
public virtual bool IsReadOnly { get; } = false;
bool ICollection.IsSynchronized
=> false;
object ICollection.SyncRoot
=> this;
protected SortedList(List<T> wrapped)
=> _list = wrapped;
@ -46,20 +57,43 @@ namespace BizHawk.Common
}
}
object? IList.this[int index]
{
get => _list[index];
set
{
if (value is not T value1) throw new ArgumentException(paramName: nameof(value), message: ERR_MSG_WRONG_TYPE);
this[index] = value1;
}
}
public virtual void Add(T item)
{
var i = _list.BinarySearch(item);
_list.Insert(i < 0 ? ~i : i, item);
}
int IList.Add(object? item)
{
if (item is not T item1) throw new ArgumentException(paramName: nameof(item), message: ERR_MSG_WRONG_TYPE);
Add(item1);
return IndexOf(item1);
}
public virtual int BinarySearch(T item) => _list.BinarySearch(item);
public virtual void Clear() => _list.Clear();
public virtual bool Contains(T item) => !(_list.BinarySearch(item) < 0); // can't use `!= -1`, BinarySearch can return multiple negative values
bool IList.Contains(object? item)
=> item is T item1 && Contains(item1);
public virtual void CopyTo(T[] array, int arrayIndex) => _list.CopyTo(array, arrayIndex);
void ICollection.CopyTo(Array array, int arrayIndex)
=> ((ICollection) _list).CopyTo(array, arrayIndex);
public T FirstOrDefault()
=> _list.Count is 0 ? default! : _list[0];
@ -79,6 +113,11 @@ namespace BizHawk.Common
return i < 0 ? -1 : i;
}
int IList.IndexOf(object? item)
=> item is T item1
? IndexOf(item1)
: throw new ArgumentException(paramName: nameof(item), message: ERR_MSG_WRONG_TYPE);
public virtual void Insert(int index, T item)
{
// allowing appends per `IList<T>` docs
@ -94,6 +133,12 @@ namespace BizHawk.Common
else throw new NotSupportedException(ERR_MSG_OUT_OF_ORDER);
}
void IList.Insert(int index, object? item)
{
if (item is not T item1) throw new ArgumentException(paramName: nameof(item), message: ERR_MSG_WRONG_TYPE);
Insert(index, item1);
}
public T LastOrDefault()
=> _list.Count is 0 ? default! : _list[_list.Count - 1];
@ -109,6 +154,12 @@ namespace BizHawk.Common
#endif
}
void IList.Remove(object? item)
{
if (item is not T item1) throw new ArgumentException(paramName: nameof(item), message: ERR_MSG_WRONG_TYPE);
_ = Remove(item1);
}
public virtual int RemoveAll(Predicate<T> match) => _list.RemoveAll(match);