SkipWhile.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the Apache 2.0 License.
  3. // See the LICENSE file in the project root for more information.
  4. using System.Collections.Generic;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7. namespace System.Linq
  8. {
  9. public static partial class AsyncEnumerable
  10. {
  11. public static IAsyncEnumerable<TSource> SkipWhile<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, bool> predicate)
  12. {
  13. if (source == null)
  14. throw Error.ArgumentNull(nameof(source));
  15. if (predicate == null)
  16. throw Error.ArgumentNull(nameof(predicate));
  17. return Create(Core);
  18. async IAsyncEnumerator<TSource> Core(CancellationToken cancellationToken)
  19. {
  20. await using var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false);
  21. while (await e.MoveNextAsync())
  22. {
  23. var element = e.Current;
  24. if (!predicate(element))
  25. {
  26. yield return element;
  27. while (await e.MoveNextAsync())
  28. {
  29. yield return e.Current;
  30. }
  31. yield break;
  32. }
  33. }
  34. }
  35. }
  36. public static IAsyncEnumerable<TSource> SkipWhile<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, int, bool> predicate)
  37. {
  38. if (source == null)
  39. throw Error.ArgumentNull(nameof(source));
  40. if (predicate == null)
  41. throw Error.ArgumentNull(nameof(predicate));
  42. return Create(Core);
  43. async IAsyncEnumerator<TSource> Core(CancellationToken cancellationToken)
  44. {
  45. await using var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false);
  46. var index = -1;
  47. while (await e.MoveNextAsync())
  48. {
  49. checked
  50. {
  51. index++;
  52. }
  53. var element = e.Current;
  54. if (!predicate(element, index))
  55. {
  56. yield return element;
  57. while (await e.MoveNextAsync())
  58. {
  59. yield return e.Current;
  60. }
  61. yield break;
  62. }
  63. }
  64. }
  65. }
  66. internal static IAsyncEnumerable<TSource> SkipWhileAwaitCore<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, ValueTask<bool>> predicate)
  67. {
  68. if (source == null)
  69. throw Error.ArgumentNull(nameof(source));
  70. if (predicate == null)
  71. throw Error.ArgumentNull(nameof(predicate));
  72. return Create(Core);
  73. async IAsyncEnumerator<TSource> Core(CancellationToken cancellationToken)
  74. {
  75. await using var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false);
  76. while (await e.MoveNextAsync())
  77. {
  78. var element = e.Current;
  79. if (!await predicate(element).ConfigureAwait(false))
  80. {
  81. yield return element;
  82. while (await e.MoveNextAsync())
  83. {
  84. yield return e.Current;
  85. }
  86. yield break;
  87. }
  88. }
  89. }
  90. }
  91. #if !NO_DEEP_CANCELLATION
  92. internal static IAsyncEnumerable<TSource> SkipWhileAwaitWithCancellationCore<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask<bool>> predicate)
  93. {
  94. if (source == null)
  95. throw Error.ArgumentNull(nameof(source));
  96. if (predicate == null)
  97. throw Error.ArgumentNull(nameof(predicate));
  98. return Create(Core);
  99. async IAsyncEnumerator<TSource> Core(CancellationToken cancellationToken)
  100. {
  101. await using var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false);
  102. while (await e.MoveNextAsync())
  103. {
  104. var element = e.Current;
  105. if (!await predicate(element, cancellationToken).ConfigureAwait(false))
  106. {
  107. yield return element;
  108. while (await e.MoveNextAsync())
  109. {
  110. yield return e.Current;
  111. }
  112. yield break;
  113. }
  114. }
  115. }
  116. }
  117. #endif
  118. internal static IAsyncEnumerable<TSource> SkipWhileAwaitCore<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, int, ValueTask<bool>> predicate)
  119. {
  120. if (source == null)
  121. throw Error.ArgumentNull(nameof(source));
  122. if (predicate == null)
  123. throw Error.ArgumentNull(nameof(predicate));
  124. return Create(Core);
  125. async IAsyncEnumerator<TSource> Core(CancellationToken cancellationToken)
  126. {
  127. await using var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false);
  128. var index = -1;
  129. while (await e.MoveNextAsync())
  130. {
  131. checked
  132. {
  133. index++;
  134. }
  135. var element = e.Current;
  136. if (!await predicate(element, index).ConfigureAwait(false))
  137. {
  138. yield return element;
  139. while (await e.MoveNextAsync())
  140. {
  141. yield return e.Current;
  142. }
  143. yield break;
  144. }
  145. }
  146. }
  147. }
  148. #if !NO_DEEP_CANCELLATION
  149. internal static IAsyncEnumerable<TSource> SkipWhileAwaitWithCancellationCore<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, int, CancellationToken, ValueTask<bool>> predicate)
  150. {
  151. if (source == null)
  152. throw Error.ArgumentNull(nameof(source));
  153. if (predicate == null)
  154. throw Error.ArgumentNull(nameof(predicate));
  155. return Create(Core);
  156. async IAsyncEnumerator<TSource> Core(CancellationToken cancellationToken)
  157. {
  158. await using var e = source.GetConfiguredAsyncEnumerator(cancellationToken, false);
  159. var index = -1;
  160. while (await e.MoveNextAsync())
  161. {
  162. checked
  163. {
  164. index++;
  165. }
  166. var element = e.Current;
  167. if (!await predicate(element, index, cancellationToken).ConfigureAwait(false))
  168. {
  169. yield return element;
  170. while (await e.MoveNextAsync())
  171. {
  172. yield return e.Current;
  173. }
  174. yield break;
  175. }
  176. }
  177. }
  178. }
  179. #endif
  180. }
  181. }