|
@@ -19,39 +19,40 @@ namespace System.Linq
|
|
if (count < 0)
|
|
if (count < 0)
|
|
throw new ArgumentOutOfRangeException(nameof(count));
|
|
throw new ArgumentOutOfRangeException(nameof(count));
|
|
|
|
|
|
- return Create(() =>
|
|
|
|
- {
|
|
|
|
- var e = source.GetEnumerator();
|
|
|
|
- var n = count;
|
|
|
|
-
|
|
|
|
- var cts = new CancellationTokenDisposable();
|
|
|
|
- var d = Disposable.Create(cts, e);
|
|
|
|
-
|
|
|
|
- var f = default(Func<CancellationToken, Task<bool>>);
|
|
|
|
- f = async ct =>
|
|
|
|
- {
|
|
|
|
- var moveNext = await e.MoveNext(ct)
|
|
|
|
- .ConfigureAwait(false);
|
|
|
|
- if (n == 0)
|
|
|
|
- {
|
|
|
|
- return moveNext;
|
|
|
|
- }
|
|
|
|
- --n;
|
|
|
|
- if (!moveNext)
|
|
|
|
- {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- return await f(ct)
|
|
|
|
- .ConfigureAwait(false);
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
- return Create(
|
|
|
|
- ct => f(cts.Token),
|
|
|
|
- () => e.Current,
|
|
|
|
- d.Dispose,
|
|
|
|
- e
|
|
|
|
- );
|
|
|
|
- });
|
|
|
|
|
|
+ return CreateEnumerable(
|
|
|
|
+ () =>
|
|
|
|
+ {
|
|
|
|
+ var e = source.GetEnumerator();
|
|
|
|
+ var n = count;
|
|
|
|
+
|
|
|
|
+ var cts = new CancellationTokenDisposable();
|
|
|
|
+ var d = Disposable.Create(cts, e);
|
|
|
|
+
|
|
|
|
+ var f = default(Func<CancellationToken, Task<bool>>);
|
|
|
|
+ f = async ct =>
|
|
|
|
+ {
|
|
|
|
+ var moveNext = await e.MoveNext(ct)
|
|
|
|
+ .ConfigureAwait(false);
|
|
|
|
+ if (n == 0)
|
|
|
|
+ {
|
|
|
|
+ return moveNext;
|
|
|
|
+ }
|
|
|
|
+ --n;
|
|
|
|
+ if (!moveNext)
|
|
|
|
+ {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ return await f(ct)
|
|
|
|
+ .ConfigureAwait(false);
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ return CreateEnumerator(
|
|
|
|
+ ct => f(cts.Token),
|
|
|
|
+ () => e.Current,
|
|
|
|
+ d.Dispose,
|
|
|
|
+ e
|
|
|
|
+ );
|
|
|
|
+ });
|
|
}
|
|
}
|
|
|
|
|
|
public static IAsyncEnumerable<TSource> SkipLast<TSource>(this IAsyncEnumerable<TSource> source, int count)
|
|
public static IAsyncEnumerable<TSource> SkipLast<TSource>(this IAsyncEnumerable<TSource> source, int count)
|
|
@@ -61,43 +62,44 @@ namespace System.Linq
|
|
if (count < 0)
|
|
if (count < 0)
|
|
throw new ArgumentOutOfRangeException(nameof(count));
|
|
throw new ArgumentOutOfRangeException(nameof(count));
|
|
|
|
|
|
- return Create(() =>
|
|
|
|
- {
|
|
|
|
- var e = source.GetEnumerator();
|
|
|
|
-
|
|
|
|
- var cts = new CancellationTokenDisposable();
|
|
|
|
- var d = Disposable.Create(cts, e);
|
|
|
|
-
|
|
|
|
- var q = new Queue<TSource>();
|
|
|
|
- var current = default(TSource);
|
|
|
|
-
|
|
|
|
- var f = default(Func<CancellationToken, Task<bool>>);
|
|
|
|
- f = async ct =>
|
|
|
|
- {
|
|
|
|
- if (await e.MoveNext(ct)
|
|
|
|
- .ConfigureAwait(false))
|
|
|
|
- {
|
|
|
|
- var item = e.Current;
|
|
|
|
-
|
|
|
|
- q.Enqueue(item);
|
|
|
|
- if (q.Count > count)
|
|
|
|
- {
|
|
|
|
- current = q.Dequeue();
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- return await f(ct)
|
|
|
|
- .ConfigureAwait(false);
|
|
|
|
- }
|
|
|
|
- return false;
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
- return Create(
|
|
|
|
- f,
|
|
|
|
- () => current,
|
|
|
|
- d.Dispose,
|
|
|
|
- e
|
|
|
|
- );
|
|
|
|
- });
|
|
|
|
|
|
+ return CreateEnumerable(
|
|
|
|
+ () =>
|
|
|
|
+ {
|
|
|
|
+ var e = source.GetEnumerator();
|
|
|
|
+
|
|
|
|
+ var cts = new CancellationTokenDisposable();
|
|
|
|
+ var d = Disposable.Create(cts, e);
|
|
|
|
+
|
|
|
|
+ var q = new Queue<TSource>();
|
|
|
|
+ var current = default(TSource);
|
|
|
|
+
|
|
|
|
+ var f = default(Func<CancellationToken, Task<bool>>);
|
|
|
|
+ f = async ct =>
|
|
|
|
+ {
|
|
|
|
+ if (await e.MoveNext(ct)
|
|
|
|
+ .ConfigureAwait(false))
|
|
|
|
+ {
|
|
|
|
+ var item = e.Current;
|
|
|
|
+
|
|
|
|
+ q.Enqueue(item);
|
|
|
|
+ if (q.Count > count)
|
|
|
|
+ {
|
|
|
|
+ current = q.Dequeue();
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ return await f(ct)
|
|
|
|
+ .ConfigureAwait(false);
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ return CreateEnumerator(
|
|
|
|
+ f,
|
|
|
|
+ () => current,
|
|
|
|
+ d.Dispose,
|
|
|
|
+ e
|
|
|
|
+ );
|
|
|
|
+ });
|
|
}
|
|
}
|
|
|
|
|
|
public static IAsyncEnumerable<TSource> SkipWhile<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, bool> predicate)
|
|
public static IAsyncEnumerable<TSource> SkipWhile<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, bool> predicate)
|
|
@@ -107,41 +109,42 @@ namespace System.Linq
|
|
if (predicate == null)
|
|
if (predicate == null)
|
|
throw new ArgumentNullException(nameof(predicate));
|
|
throw new ArgumentNullException(nameof(predicate));
|
|
|
|
|
|
- return Create(() =>
|
|
|
|
- {
|
|
|
|
- var e = source.GetEnumerator();
|
|
|
|
- var skipping = true;
|
|
|
|
-
|
|
|
|
- var cts = new CancellationTokenDisposable();
|
|
|
|
- var d = Disposable.Create(cts, e);
|
|
|
|
-
|
|
|
|
- var f = default(Func<CancellationToken, Task<bool>>);
|
|
|
|
- f = async ct =>
|
|
|
|
- {
|
|
|
|
- if (skipping)
|
|
|
|
- {
|
|
|
|
- if (await e.MoveNext(ct)
|
|
|
|
- .ConfigureAwait(false))
|
|
|
|
- {
|
|
|
|
- if (predicate(e.Current))
|
|
|
|
- return await f(ct)
|
|
|
|
- .ConfigureAwait(false);
|
|
|
|
- skipping = false;
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- return await e.MoveNext(ct)
|
|
|
|
- .ConfigureAwait(false);
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
- return Create(
|
|
|
|
- f,
|
|
|
|
- () => e.Current,
|
|
|
|
- d.Dispose,
|
|
|
|
- e
|
|
|
|
- );
|
|
|
|
- });
|
|
|
|
|
|
+ return CreateEnumerable(
|
|
|
|
+ () =>
|
|
|
|
+ {
|
|
|
|
+ var e = source.GetEnumerator();
|
|
|
|
+ var skipping = true;
|
|
|
|
+
|
|
|
|
+ var cts = new CancellationTokenDisposable();
|
|
|
|
+ var d = Disposable.Create(cts, e);
|
|
|
|
+
|
|
|
|
+ var f = default(Func<CancellationToken, Task<bool>>);
|
|
|
|
+ f = async ct =>
|
|
|
|
+ {
|
|
|
|
+ if (skipping)
|
|
|
|
+ {
|
|
|
|
+ if (await e.MoveNext(ct)
|
|
|
|
+ .ConfigureAwait(false))
|
|
|
|
+ {
|
|
|
|
+ if (predicate(e.Current))
|
|
|
|
+ return await f(ct)
|
|
|
|
+ .ConfigureAwait(false);
|
|
|
|
+ skipping = false;
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ return await e.MoveNext(ct)
|
|
|
|
+ .ConfigureAwait(false);
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ return CreateEnumerator(
|
|
|
|
+ f,
|
|
|
|
+ () => e.Current,
|
|
|
|
+ d.Dispose,
|
|
|
|
+ e
|
|
|
|
+ );
|
|
|
|
+ });
|
|
}
|
|
}
|
|
|
|
|
|
public static IAsyncEnumerable<TSource> SkipWhile<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, int, bool> predicate)
|
|
public static IAsyncEnumerable<TSource> SkipWhile<TSource>(this IAsyncEnumerable<TSource> source, Func<TSource, int, bool> predicate)
|
|
@@ -151,42 +154,43 @@ namespace System.Linq
|
|
if (predicate == null)
|
|
if (predicate == null)
|
|
throw new ArgumentNullException(nameof(predicate));
|
|
throw new ArgumentNullException(nameof(predicate));
|
|
|
|
|
|
- return Create(() =>
|
|
|
|
- {
|
|
|
|
- var e = source.GetEnumerator();
|
|
|
|
- var skipping = true;
|
|
|
|
- var index = 0;
|
|
|
|
-
|
|
|
|
- var cts = new CancellationTokenDisposable();
|
|
|
|
- var d = Disposable.Create(cts, e);
|
|
|
|
-
|
|
|
|
- var f = default(Func<CancellationToken, Task<bool>>);
|
|
|
|
- f = async ct =>
|
|
|
|
- {
|
|
|
|
- if (skipping)
|
|
|
|
- {
|
|
|
|
- if (await e.MoveNext(ct)
|
|
|
|
- .ConfigureAwait(false))
|
|
|
|
- {
|
|
|
|
- if (predicate(e.Current, checked(index++)))
|
|
|
|
- return await f(ct)
|
|
|
|
- .ConfigureAwait(false);
|
|
|
|
- skipping = false;
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- return await e.MoveNext(ct)
|
|
|
|
- .ConfigureAwait(false);
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
- return Create(
|
|
|
|
- f,
|
|
|
|
- () => e.Current,
|
|
|
|
- d.Dispose,
|
|
|
|
- e
|
|
|
|
- );
|
|
|
|
- });
|
|
|
|
|
|
+ return CreateEnumerable(
|
|
|
|
+ () =>
|
|
|
|
+ {
|
|
|
|
+ var e = source.GetEnumerator();
|
|
|
|
+ var skipping = true;
|
|
|
|
+ var index = 0;
|
|
|
|
+
|
|
|
|
+ var cts = new CancellationTokenDisposable();
|
|
|
|
+ var d = Disposable.Create(cts, e);
|
|
|
|
+
|
|
|
|
+ var f = default(Func<CancellationToken, Task<bool>>);
|
|
|
|
+ f = async ct =>
|
|
|
|
+ {
|
|
|
|
+ if (skipping)
|
|
|
|
+ {
|
|
|
|
+ if (await e.MoveNext(ct)
|
|
|
|
+ .ConfigureAwait(false))
|
|
|
|
+ {
|
|
|
|
+ if (predicate(e.Current, checked(index++)))
|
|
|
|
+ return await f(ct)
|
|
|
|
+ .ConfigureAwait(false);
|
|
|
|
+ skipping = false;
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ return await e.MoveNext(ct)
|
|
|
|
+ .ConfigureAwait(false);
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ return CreateEnumerator(
|
|
|
|
+ f,
|
|
|
|
+ () => e.Current,
|
|
|
|
+ d.Dispose,
|
|
|
|
+ e
|
|
|
|
+ );
|
|
|
|
+ });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|