|
@@ -30,28 +30,28 @@ namespace System.Linq
|
|
return new ScanAsyncEnumerable<TSource, TAccumulate>(source, seed, accumulator);
|
|
return new ScanAsyncEnumerable<TSource, TAccumulate>(source, seed, accumulator);
|
|
}
|
|
}
|
|
|
|
|
|
- private sealed class ScanAsyncEnumerable<TSource, TAccumulate> : AsyncIterator<TAccumulate>
|
|
|
|
|
|
+ private sealed class ScanAsyncEnumerable<TSource> : AsyncIterator<TSource>
|
|
{
|
|
{
|
|
- private readonly Func<TAccumulate, TSource, TAccumulate> accumulator;
|
|
|
|
- private readonly TAccumulate seed;
|
|
|
|
|
|
+ private readonly Func<TSource, TSource, TSource> accumulator;
|
|
private readonly IAsyncEnumerable<TSource> source;
|
|
private readonly IAsyncEnumerable<TSource> source;
|
|
|
|
|
|
- private TAccumulate accumulated;
|
|
|
|
|
|
+ private TSource accumulated;
|
|
private IAsyncEnumerator<TSource> enumerator;
|
|
private IAsyncEnumerator<TSource> enumerator;
|
|
|
|
|
|
- public ScanAsyncEnumerable(IAsyncEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator)
|
|
|
|
|
|
+ private bool hasSeed;
|
|
|
|
+
|
|
|
|
+ public ScanAsyncEnumerable(IAsyncEnumerable<TSource> source, Func<TSource, TSource, TSource> accumulator)
|
|
{
|
|
{
|
|
Debug.Assert(source != null);
|
|
Debug.Assert(source != null);
|
|
Debug.Assert(accumulator != null);
|
|
Debug.Assert(accumulator != null);
|
|
|
|
|
|
this.source = source;
|
|
this.source = source;
|
|
- this.seed = seed;
|
|
|
|
this.accumulator = accumulator;
|
|
this.accumulator = accumulator;
|
|
}
|
|
}
|
|
|
|
|
|
- public override AsyncIterator<TAccumulate> Clone()
|
|
|
|
|
|
+ public override AsyncIterator<TSource> Clone()
|
|
{
|
|
{
|
|
- return new ScanAsyncEnumerable<TSource, TAccumulate>(source, seed, accumulator);
|
|
|
|
|
|
+ return new ScanAsyncEnumerable<TSource>(source, accumulator);
|
|
}
|
|
}
|
|
|
|
|
|
public override async Task DisposeAsync()
|
|
public override async Task DisposeAsync()
|
|
@@ -60,7 +60,7 @@ namespace System.Linq
|
|
{
|
|
{
|
|
await enumerator.DisposeAsync().ConfigureAwait(false);
|
|
await enumerator.DisposeAsync().ConfigureAwait(false);
|
|
enumerator = null;
|
|
enumerator = null;
|
|
- accumulated = default(TAccumulate);
|
|
|
|
|
|
+ accumulated = default(TSource);
|
|
}
|
|
}
|
|
|
|
|
|
await base.DisposeAsync().ConfigureAwait(false);
|
|
await base.DisposeAsync().ConfigureAwait(false);
|
|
@@ -72,23 +72,31 @@ namespace System.Linq
|
|
{
|
|
{
|
|
case AsyncIteratorState.Allocated:
|
|
case AsyncIteratorState.Allocated:
|
|
enumerator = source.GetAsyncEnumerator();
|
|
enumerator = source.GetAsyncEnumerator();
|
|
- accumulated = seed;
|
|
|
|
|
|
+ hasSeed = false;
|
|
|
|
+ accumulated = default(TSource);
|
|
|
|
|
|
state = AsyncIteratorState.Iterating;
|
|
state = AsyncIteratorState.Iterating;
|
|
goto case AsyncIteratorState.Iterating;
|
|
goto case AsyncIteratorState.Iterating;
|
|
|
|
|
|
case AsyncIteratorState.Iterating:
|
|
case AsyncIteratorState.Iterating:
|
|
- if (await enumerator.MoveNextAsync()
|
|
|
|
- .ConfigureAwait(false))
|
|
|
|
|
|
+
|
|
|
|
+ while (await enumerator.MoveNextAsync().ConfigureAwait(false))
|
|
{
|
|
{
|
|
var item = enumerator.Current;
|
|
var item = enumerator.Current;
|
|
|
|
+ if (!hasSeed)
|
|
|
|
+ {
|
|
|
|
+ hasSeed = true;
|
|
|
|
+ accumulated = item;
|
|
|
|
+ continue; // loop
|
|
|
|
+ }
|
|
|
|
+
|
|
accumulated = accumulator(accumulated, item);
|
|
accumulated = accumulator(accumulated, item);
|
|
current = accumulated;
|
|
current = accumulated;
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
|
|
+ break; // case
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
await DisposeAsync().ConfigureAwait(false);
|
|
await DisposeAsync().ConfigureAwait(false);
|
|
@@ -96,28 +104,28 @@ namespace System.Linq
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- private sealed class ScanAsyncEnumerable<TSource> : AsyncIterator<TSource>
|
|
|
|
|
|
+ private sealed class ScanAsyncEnumerable<TSource, TAccumulate> : AsyncIterator<TAccumulate>
|
|
{
|
|
{
|
|
- private readonly Func<TSource, TSource, TSource> accumulator;
|
|
|
|
|
|
+ private readonly Func<TAccumulate, TSource, TAccumulate> accumulator;
|
|
|
|
+ private readonly TAccumulate seed;
|
|
private readonly IAsyncEnumerable<TSource> source;
|
|
private readonly IAsyncEnumerable<TSource> source;
|
|
|
|
|
|
- private TSource accumulated;
|
|
|
|
|
|
+ private TAccumulate accumulated;
|
|
private IAsyncEnumerator<TSource> enumerator;
|
|
private IAsyncEnumerator<TSource> enumerator;
|
|
|
|
|
|
- private bool hasSeed;
|
|
|
|
-
|
|
|
|
- public ScanAsyncEnumerable(IAsyncEnumerable<TSource> source, Func<TSource, TSource, TSource> accumulator)
|
|
|
|
|
|
+ public ScanAsyncEnumerable(IAsyncEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator)
|
|
{
|
|
{
|
|
Debug.Assert(source != null);
|
|
Debug.Assert(source != null);
|
|
Debug.Assert(accumulator != null);
|
|
Debug.Assert(accumulator != null);
|
|
|
|
|
|
this.source = source;
|
|
this.source = source;
|
|
|
|
+ this.seed = seed;
|
|
this.accumulator = accumulator;
|
|
this.accumulator = accumulator;
|
|
}
|
|
}
|
|
|
|
|
|
- public override AsyncIterator<TSource> Clone()
|
|
|
|
|
|
+ public override AsyncIterator<TAccumulate> Clone()
|
|
{
|
|
{
|
|
- return new ScanAsyncEnumerable<TSource>(source, accumulator);
|
|
|
|
|
|
+ return new ScanAsyncEnumerable<TSource, TAccumulate>(source, seed, accumulator);
|
|
}
|
|
}
|
|
|
|
|
|
public override async Task DisposeAsync()
|
|
public override async Task DisposeAsync()
|
|
@@ -126,7 +134,7 @@ namespace System.Linq
|
|
{
|
|
{
|
|
await enumerator.DisposeAsync().ConfigureAwait(false);
|
|
await enumerator.DisposeAsync().ConfigureAwait(false);
|
|
enumerator = null;
|
|
enumerator = null;
|
|
- accumulated = default(TSource);
|
|
|
|
|
|
+ accumulated = default(TAccumulate);
|
|
}
|
|
}
|
|
|
|
|
|
await base.DisposeAsync().ConfigureAwait(false);
|
|
await base.DisposeAsync().ConfigureAwait(false);
|
|
@@ -138,31 +146,23 @@ namespace System.Linq
|
|
{
|
|
{
|
|
case AsyncIteratorState.Allocated:
|
|
case AsyncIteratorState.Allocated:
|
|
enumerator = source.GetAsyncEnumerator();
|
|
enumerator = source.GetAsyncEnumerator();
|
|
- hasSeed = false;
|
|
|
|
- accumulated = default(TSource);
|
|
|
|
|
|
+ accumulated = seed;
|
|
|
|
|
|
state = AsyncIteratorState.Iterating;
|
|
state = AsyncIteratorState.Iterating;
|
|
goto case AsyncIteratorState.Iterating;
|
|
goto case AsyncIteratorState.Iterating;
|
|
|
|
|
|
case AsyncIteratorState.Iterating:
|
|
case AsyncIteratorState.Iterating:
|
|
-
|
|
|
|
- while (await enumerator.MoveNextAsync().ConfigureAwait(false))
|
|
|
|
|
|
+ if (await enumerator.MoveNextAsync()
|
|
|
|
+ .ConfigureAwait(false))
|
|
{
|
|
{
|
|
var item = enumerator.Current;
|
|
var item = enumerator.Current;
|
|
- if (!hasSeed)
|
|
|
|
- {
|
|
|
|
- hasSeed = true;
|
|
|
|
- accumulated = item;
|
|
|
|
- continue; // loop
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
accumulated = accumulator(accumulated, item);
|
|
accumulated = accumulator(accumulated, item);
|
|
current = accumulated;
|
|
current = accumulated;
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
- break; // case
|
|
|
|
-
|
|
|
|
|
|
+ break;
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
await DisposeAsync().ConfigureAwait(false);
|
|
await DisposeAsync().ConfigureAwait(false);
|