Last active
August 31, 2020 12:37
-
-
Save IEvangelist/d4fb5ad70652a3d8918816d62217323b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public readonly struct EnumerableRange : IEnumerable<int> | |
{ | |
readonly Range _range; | |
public EnumerableRange(Range range) | |
{ | |
if (range.Start.IsFromEnd || range.End.IsFromEnd) | |
{ | |
throw new ArgumentException(nameof(range)); | |
} | |
_range = range; | |
} | |
public static implicit operator EnumerableRange(Range range) => new EnumerableRange(range); | |
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); | |
IEnumerator<int> IEnumerable<int>.GetEnumerator() => GetEnumerator(); | |
// Important to return RangeEnumerator, not IEnumerable<int> here, or foreach would box the struct | |
public RangeEnumerator GetEnumerator() => new RangeEnumerator(_range); | |
public override string ToString() => _range.ToString(); | |
public struct RangeEnumerator : IEnumerator<int>, IEnumerator | |
{ | |
public int Current => _range.Start.Value + (_isAscending ? _index : -_index); | |
object IEnumerator.Current => Current; | |
int _index; | |
readonly Range _range; | |
readonly bool _isAscending; | |
internal RangeEnumerator(Range range) | |
{ | |
_index = -1; | |
_range = range; | |
_isAscending = _range.Start.Value < _range.End.Value; | |
} | |
public bool MoveNext() | |
{ | |
if (_index + 1 >= Math.Abs(_range.End.Value - _range.Start.Value)) | |
{ | |
return false; | |
} | |
_index++; | |
return true; | |
} | |
public void Reset() => _index = 0; | |
public void Dispose() { } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment