using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; namespace Avalonia.Utilities { /// /// Stores either a single key value pair or constructs a dictionary when more than one value is stored. /// /// The type of the key. /// The type of the value. internal class SingleOrDictionary : IEnumerable> where TKey : notnull { private KeyValuePair? _singleValue; private Dictionary? dictionary; public void Add(TKey key, TValue value) { if (_singleValue != null) { dictionary = new Dictionary(); ((ICollection>)dictionary).Add(_singleValue.Value); _singleValue = null; } if (dictionary != null) { dictionary.Add(key, value); } else { _singleValue = new KeyValuePair(key, value); } } public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value) { if (dictionary == null) { if (!_singleValue.HasValue || !EqualityComparer.Default.Equals(_singleValue.Value.Key, key)) { value = default; return false; } else { value = _singleValue.Value.Value; return true; } } else { return dictionary.TryGetValue(key, out value); } } public IEnumerator> GetEnumerator() { if (dictionary == null) { if (_singleValue.HasValue) { return new SingleEnumerator>(_singleValue.Value); } } else { return dictionary.GetEnumerator(); } return Enumerable.Empty>().GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public IEnumerable Values { get { if(dictionary == null) { if (_singleValue.HasValue) { return new[] { _singleValue.Value.Value }; } } else { return dictionary.Values; } return Enumerable.Empty(); } } private class SingleEnumerator : IEnumerator { private readonly T value; private int index = -1; public SingleEnumerator(T value) { this.value = value; } public T Current { get { if (index == 0) { return value; } else { throw new InvalidOperationException(); } } } object? IEnumerator.Current => Current; public void Dispose() { } public bool MoveNext() { index++; return index < 1; } public void Reset() { index = -1; } } } }