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;
}
}
}
}