public IEnumerator <(T[] _arr, int _fromIdx, int _toIdx, int _itIdx, int _absIdx)> Get2DEnumerator(int fromIdx, int toIdx) { if (toIdx < fromIdx) { throw new ArgumentException("To cannot be lower or equal to From"); } if (fromIdx < Lower) { throw new ArgumentException("From cannot be lower than Lower bound"); } if (fromIdx > Upper) { throw new ArgumentException("From cannot be greater or equal to Upper bound"); } if (toIdx < Lower) { throw new ArgumentException("To cannot be lower or equal to Upper bound"); } if (toIdx > Upper) { throw new ArgumentException("To cannot be greater than Upper bound"); } int remaining = toIdx - fromIdx + 1; // Fast-forward to first matching array int arrIdx = Segments.BinarySearch( new SubSegment(null, fromIdx), new PositionalBoundsComparer() ); fromIdx -= Segments[arrIdx].Lower; do { SubSegment sSeg = Segments[arrIdx]; T[] arr = sSeg.Array; toIdx = Math.Min(arr.Length, remaining + fromIdx) - 1; yield return(arr, fromIdx, toIdx, sSeg.Lower - Lower + fromIdx, sSeg.Lower + fromIdx); int lastLength = toIdx - fromIdx + 1; remaining -= lastLength; arrIdx++; fromIdx = 0; } while (remaining > 0); }