private static int SlowGetSegmentPosition(ref SequenceSegment <T> segment, long index) { if (index < 0) { Throw.IndexOutOfRange(); } if (segment == null) { Throw.ArgumentNull(nameof(segment)); } do { if (index < segment.Length | // inside this segment (segment.Next == null & index == segment.Length)) // EOF in final segment { return((int)index); } index -= segment.Length; segment = segment.Next; } while (segment != null); Throw.IndexOutOfRange(); // not in the sequence at all return(default);
/// <summary> /// Creates a new SequenceSegment, optionally attaching the segment to an existing chain /// </summary> protected SequenceSegment(Memory <T> memory, SequenceSegment <T> previous = null) { if (previous != null) { var oldNext = previous.Next; if (oldNext != null) { Throw.InvalidOperation("The previous segment already has an onwards chain"); } previous.Next = this; RunningIndex = previous.RunningIndex + previous.Length; } Memory = memory; // also sets Length }
internal static int GetSegmentPosition(ref SequenceSegment <T> segment, long index) => (index >= 0 & segment != null) && (index < segment.Length) ? (int)index : SlowGetSegmentPosition(ref segment, index);