using System; using System.Collections; using System.Collections.Generic; using System.Runtime.CompilerServices; namespace PkmnLibSharp.Utils { public sealed class DisposableCachedExternArray : IReadOnlyList, IDisposable where T: class, IDisposable { private readonly T?[] _array; private readonly Func _getItem; public DisposableCachedExternArray(ulong size, Func getItem) { _array = new T?[(int)size]; _getItem = getItem; } public IEnumerator GetEnumerator() { for (var i = 0; i < Count; i++) { yield return this[i]; } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public int Count => _array.Length; public T this[int index] { get { if (index >= _array.Length) throw new ArgumentOutOfRangeException( $"Index {index} was outside of the bounds of the external array with length {Count}"); return _array[index] ??= _getItem((ulong)index); } } internal T? GetCachedValue(int i) { return _array[i]; } public void Dispose() { foreach (var item in _array) { item?.Dispose(); } } } public sealed class CachedExternArray : IReadOnlyList where T: class { private readonly T?[] _array; private readonly Func _getItem; public CachedExternArray(ulong size, Func getItem) { _array = new T?[(int)size]; _getItem = getItem; } public IEnumerator GetEnumerator() { for (var i = 0; i < Count; i++) { yield return this[i]; } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public int Count => _array.Length; public T this[int index] { get { if (index >= _array.Length) throw new ArgumentOutOfRangeException( $"Index {index} was outside of the bounds of the external array with length {Count}"); return _array[index] ??= _getItem((ulong)index); } } internal T? GetCachedValue(int i) { return _array[i]; } } public class CachedExternValueArray : IReadOnlyList where T: struct { private readonly T?[] _array; private readonly Func _getItem; public CachedExternValueArray(ulong size, Func getItem) { _array = new T?[(int)size]; _getItem = getItem; } public IEnumerator GetEnumerator() { for (var i = 0; i < Count; i++) { yield return this[i]; } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public int Count => _array.Length; public T this[int index] => _array[index] ??= _getItem((ulong)index); } }