SkipWhile.cs 8.0 KB

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