// dnlib: See LICENSE.txt for more info using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; namespace dnlib.DotNet.MD { /// /// Stores a list of rids /// [DebuggerDisplay("Count = {Count}")] public readonly struct RidList : IEnumerable { readonly uint startRid; readonly uint length; readonly IList rids; /// /// Gets the empty instance /// public static readonly RidList Empty = Create(0, 0); /// /// Creates a new instance /// /// /// /// public static RidList Create(uint startRid, uint length) => new RidList(startRid, length); /// /// Creates a new instance /// /// List of valid rids /// public static RidList Create(IList rids) => new RidList(rids); RidList(uint startRid, uint length) { this.startRid = startRid; this.length = length; rids = null; } RidList(IList rids) { this.rids = rids ?? throw new ArgumentNullException(nameof(rids)); startRid = 0; length = (uint)rids.Count; } /// /// Gets the 'th rid /// /// Index. Must be < /// A rid or 0 if is invalid public uint this[int index] { get { if (rids is not null) { if ((uint)index >= (uint)rids.Count) return 0; return rids[index]; } else { if ((uint)index >= length) return 0; return startRid + (uint)index; } } } /// /// Gets the number of rids it will iterate over /// public int Count => (int)length; /// /// Enumerator /// public struct Enumerator : IEnumerator { readonly uint startRid; readonly uint length; readonly IList rids; uint index; uint current; internal Enumerator(in RidList list) { startRid = list.startRid; length = list.length; rids = list.rids; index = 0; current = 0; } /// /// Gets the current rid /// public uint Current => current; object IEnumerator.Current => current; /// /// Disposes this instance /// public void Dispose() { } /// /// Moves to the next rid /// /// public bool MoveNext() { if (rids is null && index < length) { current = startRid + index; index++; return true; } return MoveNextOther(); } bool MoveNextOther() { if (index >= length) { current = 0; return false; } if (rids is not null) current = rids[(int)index]; else current = startRid + index; index++; return true; } void IEnumerator.Reset() => throw new NotSupportedException(); } /// /// Gets the enumerator /// /// public Enumerator GetEnumerator() => new Enumerator(this); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } }