Implement type dictionaries, with hierarchical sets and unsets.

This commit is contained in:
H. Utku Maden 2025-07-25 23:51:14 +03:00
parent 1dcf167022
commit c538dbd56b

View File

@ -0,0 +1,157 @@
using System.Collections;
using System.Diagnostics.CodeAnalysis;
namespace Dashboard.Collections
{
public class TypeDictionary<T>(bool hierarchical = false) : IEnumerable<T>
{
private readonly Dictionary<int, T> _objects = new Dictionary<int, T>();
public bool Contains<T2>() where T2 : T => _objects.ContainsKey(TypeAtom<T2>.Id);
public bool Add<T2>(T2 value) where T2 : T
{
TypeAtom atom = TypeAtom<T2>.Atom;
if (!_objects.TryAdd(atom.Id, value))
return false;
if (!hierarchical)
return true;
foreach (TypeAtom ancestor in atom.Ancestors)
{
_objects[ancestor.Id] = value;
}
return true;
}
public T2 Get<T2>() where T2 : T => TryGet(out T2? value) ? value : throw new KeyNotFoundException();
public void Set<T2>(T2 value) where T2 : T
{
TypeAtom atom = TypeAtom<T2>.Atom;
_objects[atom.Id] = value;
if (!hierarchical)
return;
foreach (TypeAtom ancestor in atom.Ancestors)
{
_objects[ancestor.Id] = value;
}
}
public bool Remove<T2>() where T2 : T => Remove<T>(out _);
public bool Remove<T2>([NotNullWhen(true)] out T2? value) where T2 : T
{
TypeAtom atom = TypeAtom<T2>.Atom;
if (!_objects.Remove(atom.Id, out T? subValue))
{
value = default;
return false;
}
value = (T2?)subValue;
if (hierarchical)
{
foreach (TypeAtom ancestor in atom.Ancestors)
{
_objects.Remove(ancestor.Id);
}
}
return value != null;
}
public bool TryGet<T2>([NotNullWhen(true)] out T2? value) where T2 : T
{
if (!_objects.TryGetValue(TypeAtom<T2>.Id, out T? subValue))
{
value = default;
return false;
}
value = (T2?)subValue;
return value != null;
}
public void Clear() => _objects.Clear();
public IEnumerator<T> GetEnumerator() => _objects.Values.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
public class TypeDictionary<TKey, TValue>(bool hierarchical = false) : IEnumerable<KeyValuePair<TypeAtom, TValue>>
{
private readonly Dictionary<int, TValue> _objects = new Dictionary<int, TValue>();
public bool Contains<TKey2>() where TKey2 : TKey => _objects.ContainsKey(TypeAtom<TKey2>.Id);
public bool Add<TKey2>(TValue value) where TKey2 : TKey
{
TypeAtom atom = TypeAtom<TKey2>.Atom;
if (!_objects.TryAdd(atom.Id, value))
return false;
if (!hierarchical)
return true;
foreach (TypeAtom ancestor in atom.Ancestors)
{
_objects[ancestor.Id] = value;
}
return true;
}
public TValue Get<TKey2>() where TKey2 : TKey => (TValue)_objects[TypeAtom<TKey2>.Id]!;
public void Set<TKey2>(TValue value) where TKey2 : TKey
{
TypeAtom atom = TypeAtom<TKey2>.Atom;
_objects[atom.Id] = value;
if (!hierarchical)
return;
foreach (TypeAtom ancestor in atom.Ancestors)
{
_objects[ancestor.Id] = value;
}
}
public bool Remove<TKey2>() where TKey2 : TKey => Remove<TKey2>(out _);
public bool Remove<TKey2>([MaybeNullWhen(false)] out TValue? value) where TKey2 : TKey
{
TypeAtom atom = TypeAtom<TKey2>.Atom;
if (!_objects.Remove(atom.Id, out value))
{
return false;
}
if (hierarchical)
{
foreach (TypeAtom ancestor in atom.Ancestors)
{
_objects.Remove(ancestor.Id);
}
}
return true;
}
public bool TryGet<TKey2>([NotNullWhen(true)] out TValue? value) where TKey2 : TKey => _objects.TryGetValue(TypeAtom<TKey2>.Id, out value);
public void Clear() => _objects.Clear();
public IEnumerator<KeyValuePair<TypeAtom, TValue>> GetEnumerator() => _objects.Select(x => new KeyValuePair<TypeAtom, TValue>(TypeAtom.Get(x.Key)!, x.Value)).GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
}