Added more constructors to collections

hashcode getters, equality comparers, also a Span property for IndexedFishSet
This commit is contained in:
bbradson
2024-04-28 20:09:11 +02:00
parent b5cda73ecd
commit 91975828e4
12 changed files with 82 additions and 4 deletions
+24
View File
@@ -149,6 +149,21 @@ public class FishSet<T> : ISet<T>, IReadOnlyCollection<T>, ICollection
Initialize(minimumCapacity);
}
public unsafe FishSet(int minimumCapacity, delegate*<T?, int> hashCodeGetter = default,
delegate*<T?, T?, bool> equalityComparer = default)
{
InitializeDelegates(hashCodeGetter, equalityComparer);
Initialize(minimumCapacity);
}
public unsafe FishSet(int minimumCapacity, T defaultValue, delegate*<T?, int> hashCodeGetter = default,
delegate*<T?, T?, bool> equalityComparer = default)
{
_defaultValue = defaultValue;
InitializeDelegates(hashCodeGetter, equalityComparer);
Initialize(minimumCapacity);
}
[MemberNotNull(nameof(_buckets))]
[MemberNotNull(nameof(_tails))]
private void Initialize(int minimumCapacity = 0)
@@ -163,6 +178,15 @@ public class FishSet<T> : ISet<T>, IReadOnlyCollection<T>, ICollection
_wrapAroundMask = _buckets.Length - 1;
}
private unsafe void InitializeDelegates(delegate*<T?, int> hashCodeGetter, delegate*<T?, T?, bool> equalityComparer)
{
if (hashCodeGetter != default)
_hashCodeGetter = hashCodeGetter;
if (equalityComparer != default)
_equalityComparer = equalityComparer;
}
public FishSet(IEnumerable<T> entries) : this(0)
{
foreach (var entry in entries)
@@ -258,6 +258,25 @@ public class FishTable<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary, I
Initialize(minimumCapacity);
}
public unsafe FishTable(int minimumCapacity, delegate*<ref TKey, int> keyHashCodeByRefGetter = default,
delegate*<TKey?, int> keyHashCodeGetter = default,
delegate*<ref TKey, ref TKey, bool> keyEqualityByRefComparer = default,
delegate*<TKey?, TKey?, bool> keyEqualityComparer = default)
{
InitializeDelegates(keyHashCodeByRefGetter, keyHashCodeGetter, keyEqualityByRefComparer, keyEqualityComparer);
Initialize(minimumCapacity);
}
public unsafe FishTable(int minimumCapacity, TKey defaultKey,
delegate*<ref TKey, int> keyHashCodeByRefGetter = default, delegate*<TKey?, int> keyHashCodeGetter = default,
delegate*<ref TKey, ref TKey, bool> keyEqualityByRefComparer = default,
delegate*<TKey?, TKey?, bool> keyEqualityComparer = default)
{
_defaultEntry.Key = defaultKey;
InitializeDelegates(keyHashCodeByRefGetter, keyHashCodeGetter, keyEqualityByRefComparer, keyEqualityComparer);
Initialize(minimumCapacity);
}
[MemberNotNull(nameof(_buckets))]
[MemberNotNull(nameof(_tails))]
private void Initialize(int minimumCapacity = 0)
@@ -272,6 +291,23 @@ public class FishTable<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary, I
_wrapAroundMask = _buckets.Length - 1;
}
private unsafe void InitializeDelegates(delegate*<ref TKey, int> keyHashCodeByRefGetter,
delegate*<TKey?, int> keyHashCodeGetter, delegate*<ref TKey, ref TKey, bool> keyEqualityByRefComparer,
delegate*<TKey?, TKey?, bool> keyEqualityComparer)
{
if (keyHashCodeByRefGetter != default)
_keyHashCodeByRefGetter = keyHashCodeByRefGetter;
if (keyHashCodeGetter != default)
_keyHashCodeGetter = keyHashCodeGetter;
if (keyEqualityByRefComparer != default)
_keyEqualityByRefComparer = keyEqualityByRefComparer;
if (keyEqualityComparer != default)
_keyEqualityComparer = keyEqualityComparer;
}
public FishTable(IEnumerable<KeyValuePair<TKey, TValue>> entries) : this(0)
=> AddRange(entries);
@@ -5,6 +5,7 @@
using System.Collections;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
namespace FisheryLib.Collections;
@@ -17,10 +18,11 @@ namespace FisheryLib.Collections;
public class IndexedFishSet<T> : IList<T>, IList, IReadOnlyList<T>
{
private readonly List<T> _items = [];
private readonly FishTable<T, int> _indices = new();
private readonly FishTable<T, int> _indices;
public T this[int index]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _items[index];
set
{
@@ -31,7 +33,23 @@ public class IndexedFishSet<T> : IList<T>, IList, IReadOnlyList<T>
}
}
public List<T> ReadOnlyList => _items;
public List<T> ReadOnlyList
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _items;
}
public ReadOnlySpan<T> Span
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _items.AsReadOnlySpan();
}
public IndexedFishSet() : this(static () => [])
{
}
public IndexedFishSet(Func<FishTable<T, int>> indicesInitializer) => _indices = indicesInitializer();
public List<T>.Enumerator GetEnumerator() => _items.GetEnumerator();