Range.cs 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. using Cysharp.Threading.Tasks.Internal;
  2. using System.Threading;
  3. namespace Cysharp.Threading.Tasks.Linq
  4. {
  5. public static partial class UniTaskAsyncEnumerable
  6. {
  7. public static IUniTaskAsyncEnumerable<int> Range(int start, int count)
  8. {
  9. if (count < 0) throw Error.ArgumentOutOfRange(nameof(count));
  10. var end = (long)start + count - 1L;
  11. if (end > int.MaxValue) throw Error.ArgumentOutOfRange(nameof(count));
  12. if (count == 0) UniTaskAsyncEnumerable.Empty<int>();
  13. return new Cysharp.Threading.Tasks.Linq.Range(start, count);
  14. }
  15. }
  16. internal class Range : IUniTaskAsyncEnumerable<int>
  17. {
  18. readonly int start;
  19. readonly int end;
  20. public Range(int start, int count)
  21. {
  22. this.start = start;
  23. this.end = start + count;
  24. }
  25. public IUniTaskAsyncEnumerator<int> GetAsyncEnumerator(CancellationToken cancellationToken = default)
  26. {
  27. return new _Range(start, end, cancellationToken);
  28. }
  29. class _Range : IUniTaskAsyncEnumerator<int>
  30. {
  31. readonly int start;
  32. readonly int end;
  33. int current;
  34. CancellationToken cancellationToken;
  35. public _Range(int start, int end, CancellationToken cancellationToken)
  36. {
  37. this.start = start;
  38. this.end = end;
  39. this.cancellationToken = cancellationToken;
  40. this.current = start - 1;
  41. }
  42. public int Current => current;
  43. public UniTask<bool> MoveNextAsync()
  44. {
  45. cancellationToken.ThrowIfCancellationRequested();
  46. current++;
  47. if (current != end)
  48. {
  49. return CompletedTasks.True;
  50. }
  51. return CompletedTasks.False;
  52. }
  53. public UniTask DisposeAsync()
  54. {
  55. return default;
  56. }
  57. }
  58. }
  59. }