using System; using System.Collections; using System.Collections.Generic; namespace UnityEngine.InputSystem.Utilities { /// /// Helper when having either a single element or a list of elements. Avoids /// having to allocate GC heap garbage or having to alternatively split code paths. /// /// internal struct OneOrMore : IReadOnlyList where TList : IReadOnlyList { private readonly bool m_IsSingle; private readonly TValue m_Single; private readonly TList m_Multiple; public int Count => m_IsSingle ? 1 : m_Multiple.Count; public TValue this[int index] { get { if (!m_IsSingle) return m_Multiple[index]; if (index < 0 || index > 1) throw new ArgumentOutOfRangeException(nameof(index)); return m_Single; } } public OneOrMore(TValue single) { m_IsSingle = true; m_Single = single; m_Multiple = default; } public OneOrMore(TList multiple) { m_IsSingle = false; m_Single = default; m_Multiple = multiple; } public static implicit operator OneOrMore(TValue single) { return new OneOrMore(single); } public static implicit operator OneOrMore(TList multiple) { return new OneOrMore(multiple); } public IEnumerator GetEnumerator() { return new Enumerator { m_List = this }; } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } private class Enumerator : IEnumerator { internal int m_Index = -1; internal OneOrMore m_List; public bool MoveNext() { ++m_Index; if (m_Index >= m_List.Count) return false; return true; } public void Reset() { m_Index = -1; } public TValue Current => m_List[m_Index]; object IEnumerator.Current => Current; public void Dispose() { } } } }