diff --git a/src/MoreAsyncLINQ.Generators/AggregateGenerator.cs b/src/MoreAsyncLINQ.Generators/AggregateGenerator.cs
new file mode 100644
index 0000000..3a3819d
--- /dev/null
+++ b/src/MoreAsyncLINQ.Generators/AggregateGenerator.cs
@@ -0,0 +1,319 @@
+using System.CodeDom.Compiler;
+using System.IO;
+using System.Linq;
+using Microsoft.CodeAnalysis;
+
+namespace MoreAsyncLINQ.Generators;
+
+[Generator]
+public class AggregateGenerator : IIncrementalGenerator
+{
+ private const int MinAccumulators = 2;
+ private const int MaxAccumulators = 8;
+
+ private static readonly string[] _ordinals = ["first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eighth"];
+
+ public void Initialize(IncrementalGeneratorInitializationContext context) =>
+ context.RegisterPostInitializationOutput(postInitializationContext =>
+ {
+ var source = GenerateOverloads();
+ postInitializationContext.AddSource("MoreAsyncEnumerable.Aggregate.g.cs", source);
+ });
+
+ private string GenerateOverloads()
+ {
+ using var stringWriter = new StringWriter();
+ using var writer = new IndentedTextWriter(stringWriter);
+
+ writer.WriteLine("// ");
+ writer.WriteLine("#nullable enable");
+ writer.WriteLine();
+ writer.WriteLine("using System;");
+ writer.WriteLine("using System.Collections.Generic;");
+ writer.WriteLine("using System.Linq;");
+ writer.WriteLine("using System.Threading;");
+ writer.WriteLine("using System.Threading.Tasks;");
+ writer.WriteLine();
+ writer.WriteLine("namespace MoreAsyncLINQ;");
+ writer.WriteLine();
+ writer.WriteLine("static partial class MoreAsyncEnumerable");
+ writer.WriteLine("{");
+ writer.Indent++;
+
+ for (var arity = MinAccumulators; arity <= MaxAccumulators; arity++)
+ {
+ GenerateSyncOverload(writer, arity);
+ writer.WriteLine();
+ GenerateAsyncOverload(writer, arity);
+
+ if (arity < MaxAccumulators)
+ {
+ writer.WriteLine();
+ }
+ }
+
+ writer.Indent--;
+ writer.WriteLine("}");
+
+ return stringWriter.ToString();
+ }
+
+ private void GenerateSyncOverload(IndentedTextWriter writer, int arity)
+ {
+ WriteXmlDocumentation(writer, arity);
+ WriteMethodSignature(writer, arity, isAsync: false);
+
+ writer.WriteLine("{");
+ writer.Indent++;
+
+ WriteNullChecks(writer, arity);
+ writer.WriteLine();
+
+ writer.WriteLine("return source.IsKnownEmpty()");
+ writer.Indent++;
+ writer.WriteLine("? ValueTasks.FromResult(");
+ writer.Indent++;
+ writer.WriteLine("resultSelector(");
+ writer.Indent++;
+ WriteSeedArgs(writer, arity);
+ writer.WriteLine("))");
+ writer.Indent--;
+ writer.Indent--;
+ writer.WriteLine(": Core(");
+ writer.Indent++;
+ WriteCoreCallArgs(writer, arity);
+ writer.WriteLine(");");
+ writer.Indent--;
+ writer.Indent--;
+
+ writer.WriteLine();
+ WriteCoreMethod(writer, arity, isAsync: false);
+
+ writer.Indent--;
+ writer.WriteLine("}");
+ }
+
+ private void GenerateAsyncOverload(IndentedTextWriter writer, int arity)
+ {
+ WriteXmlDocumentation(writer, arity);
+ WriteMethodSignature(writer, arity, isAsync: true);
+
+ writer.WriteLine("{");
+ writer.Indent++;
+
+ WriteNullChecks(writer, arity);
+ writer.WriteLine();
+
+ writer.WriteLine("return Core(");
+ writer.Indent++;
+ WriteCoreCallArgs(writer, arity);
+ writer.WriteLine(");");
+ writer.Indent--;
+
+ writer.WriteLine();
+ WriteCoreMethod(writer, arity, isAsync: true);
+
+ writer.Indent--;
+ writer.WriteLine("}");
+ }
+
+ private void WriteXmlDocumentation(IndentedTextWriter writer, int arity)
+ {
+ writer = new IndentedTextWriter(writer, "/// ");
+ writer.Indent++;
+
+ writer.WriteLine("");
+ writer.WriteLine($"Applies {_ordinals[arity - 1]} accumulators sequentially in a single pass over a");
+ writer.WriteLine("sequence.");
+ writer.WriteLine("");
+ writer.WriteLine("The type of elements in .");
+
+ for (var index = 1; index <= arity; index++)
+ {
+ writer.WriteLine($"The type of {_ordinals[index - 1]} accumulator value.");
+ }
+
+ writer.WriteLine("The type of the accumulated result.");
+ writer.WriteLine("The source sequence");
+
+ for (var index = 1; index <= arity; index++)
+ {
+ writer.WriteLine($"The seed value for the {_ordinals[index - 1]} accumulator.");
+ writer.WriteLine($"The {_ordinals[index - 1]} accumulator.");
+ }
+
+ writer.WriteLine("");
+ writer.WriteLine("A function that projects a single result given the result of each");
+ writer.WriteLine("accumulator.");
+ writer.WriteLine("The optional cancellation token to be used for cancelling the sequence at any time.");
+ writer.WriteLine("The value returned by .");
+ writer.WriteLine("");
+ writer.WriteLine("This operator executes immediately.");
+ writer.WriteLine("");
+ }
+
+ private void WriteMethodSignature(IndentedTextWriter writer, int arity, bool isAsync)
+ {
+ writer.WriteLine("public static ValueTask AggregateAsync<");
+ writer.Indent++;
+
+ // Type parameters
+ writer.WriteLine("TSource,");
+ for (var index = 1; index <= arity; index++)
+ {
+ writer.WriteLine($"TAccumulate{index},");
+ }
+ writer.WriteLine("TResult>(");
+
+ // Method parameters
+ writer.WriteLine("this IAsyncEnumerable source,");
+
+ for (var index = 1; index <= arity; index++)
+ {
+ writer.WriteLine($"TAccumulate{index} seed{index},");
+
+ var funcType =
+ isAsync
+ ? $"Func>"
+ : $"Func";
+
+ writer.WriteLine($"{funcType} accumulator{index},");
+ }
+
+ var resultSelectorTypes = string.Join(", ", Enumerable.Range(1, arity).Select(index => $"TAccumulate{index}"));
+ var resultSelectorType =
+ isAsync
+ ? $"Func<{resultSelectorTypes}, CancellationToken, ValueTask>"
+ : $"Func<{resultSelectorTypes}, TResult>";
+
+ writer.WriteLine($"{resultSelectorType} resultSelector,");
+ writer.WriteLine("CancellationToken cancellationToken = default)");
+
+ writer.Indent--;
+ }
+
+ private void WriteNullChecks(IndentedTextWriter writer, int arity)
+ {
+ writer.WriteLine("if (source is null) throw new ArgumentNullException(nameof(source));");
+
+ for (var index = 1; index <= arity; index++)
+ {
+ writer.WriteLine($"if (accumulator{index} is null) throw new ArgumentNullException(nameof(accumulator{index}));");
+ }
+
+ writer.WriteLine("if (resultSelector is null) throw new ArgumentNullException(nameof(resultSelector));");
+ }
+
+ private void WriteCoreCallArgs(IndentedTextWriter writer, int arity)
+ {
+ writer.WriteLine("source,");
+
+ for (var index = 1; index <= arity; index++)
+ {
+ writer.WriteLine($"seed{index},");
+ writer.WriteLine($"accumulator{index},");
+ }
+
+ writer.WriteLine("resultSelector,");
+ writer.Write("cancellationToken");
+ }
+
+ private void WriteSeedArgs(IndentedTextWriter writer, int arity)
+ {
+ for (var index = 1; index <= arity; index++)
+ {
+ writer.Write($"seed{index}");
+
+ if (index < arity)
+ {
+ writer.WriteLine(",");
+ }
+ }
+ }
+
+ private void WriteCoreMethod(IndentedTextWriter writer, int arity, bool isAsync)
+ {
+ writer.WriteLine("static async ValueTask Core(");
+ writer.Indent++;
+
+ writer.WriteLine("IAsyncEnumerable source,");
+
+ for (var index = 1; index <= arity; index++)
+ {
+ writer.WriteLine($"TAccumulate{index} seed{index},");
+
+ var funcType =
+ isAsync
+ ? $"Func>"
+ : $"Func";
+
+ writer.WriteLine($"{funcType} accumulator{index},");
+ }
+
+ var resultSelectorTypes = string.Join(", ", Enumerable.Range(1, arity).Select(index => $"TAccumulate{index}"));
+ var resultSelectorType =
+ isAsync
+ ? $"Func<{resultSelectorTypes}, CancellationToken, ValueTask>"
+ : $"Func<{resultSelectorTypes}, TResult>";
+
+ writer.WriteLine($"{resultSelectorType} resultSelector,");
+ writer.WriteLine("CancellationToken cancellationToken)");
+
+ writer.Indent--;
+ writer.WriteLine("{");
+ writer.Indent++;
+
+ for (var index = 1; index <= arity; index++)
+ {
+ writer.WriteLine($"var accumulate{index} = seed{index};");
+ }
+
+ writer.WriteLine();
+ writer.WriteLine("await foreach (var element in source.WithCancellation(cancellationToken))");
+ writer.WriteLine("{");
+ writer.Indent++;
+
+ for (var index = 1; index <= arity; index++)
+ {
+ writer.WriteLine(
+ isAsync
+ ? $"accumulate{index} = await accumulator{index}(accumulate{index}, element, cancellationToken);"
+ : $"accumulate{index} = accumulator{index}(accumulate{index}, element);");
+ }
+
+ writer.Indent--;
+ writer.WriteLine("}");
+ writer.WriteLine();
+
+ if (isAsync)
+ {
+ writer.WriteLine("return await resultSelector(");
+ writer.Indent++;
+
+ for (var index = 1; index <= arity; index++)
+ {
+ writer.WriteLine($"accumulate{index},");
+ }
+
+ writer.WriteLine("cancellationToken);");
+ }
+ else
+ {
+ writer.WriteLine("return resultSelector(");
+ writer.Indent++;
+
+ for (var index = 1; index <= arity; index++)
+ {
+ writer.WriteLine(
+ index < arity
+ ? $"accumulate{index},"
+ : $"accumulate{index});");
+ }
+ }
+
+ writer.Indent--;
+
+ writer.Indent--;
+ writer.WriteLine("}");
+ }
+}
diff --git a/src/MoreAsyncLINQ/Operators/Aggregate.cs b/src/MoreAsyncLINQ/Operators/Aggregate.cs
deleted file mode 100644
index 2d0ac64..0000000
--- a/src/MoreAsyncLINQ/Operators/Aggregate.cs
+++ /dev/null
@@ -1,1668 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace MoreAsyncLINQ;
-
-static partial class MoreAsyncEnumerable
-{
- ///
- /// Applies two accumulators sequentially in a single pass over a
- /// sequence.
- ///
- /// The type of elements in .
- /// The type of first accumulator value.
- /// The type of second accumulator value.
- /// The type of the accumulated result.
- /// The source sequence
- /// The seed value for the first accumulator.
- /// The first accumulator.
- /// The seed value for the second accumulator.
- /// The second accumulator.
- ///
- /// A function that projects a single result given the result of each
- /// accumulator.
- /// The optional cancellation token to be used for cancelling the sequence at any time.
- /// The value returned by .
- ///
- /// This operator executes immediately.
- ///
- public static ValueTask AggregateAsync<
- TSource,
- TAccumulate1,
- TAccumulate2,
- TResult>(
- this IAsyncEnumerable source,
- TAccumulate1 seed1,
- Func accumulator1,
- TAccumulate2 seed2,
- Func accumulator2,
- Func resultSelector,
- CancellationToken cancellationToken = default)
- {
- if (source is null) throw new ArgumentNullException(nameof(source));
- if (accumulator1 is null) throw new ArgumentNullException(nameof(accumulator1));
- if (accumulator2 is null) throw new ArgumentNullException(nameof(accumulator2));
- if (resultSelector is null) throw new ArgumentNullException(nameof(resultSelector));
-
- return source.IsKnownEmpty()
- ? ValueTasks.FromResult(
- resultSelector(
- seed1,
- seed2))
- : Core(
- source,
- seed1,
- accumulator1,
- seed2,
- accumulator2,
- resultSelector,
- cancellationToken);
-
- static async ValueTask Core(
- IAsyncEnumerable source,
- TAccumulate1 seed1,
- Func accumulator1,
- TAccumulate2 seed2,
- Func accumulator2,
- Func resultSelector,
- CancellationToken cancellationToken)
- {
- var accumulate1 = seed1;
- var accumulate2 = seed2;
-
- await foreach (var element in source.WithCancellation(cancellationToken))
- {
- accumulate1 = accumulator1(accumulate1, element);
- accumulate2 = accumulator2(accumulate2, element);
- }
-
- return resultSelector(
- accumulate1,
- accumulate2);
- }
- }
-
- ///
- /// Applies three accumulators sequentially in a single pass over a
- /// sequence.
- ///
- /// The type of elements in .
- /// The type of first accumulator value.
- /// The type of second accumulator value.
- /// The type of third accumulator value.
- /// The type of the accumulated result.
- /// The source sequence
- /// The seed value for the first accumulator.
- /// The first accumulator.
- /// The seed value for the second accumulator.
- /// The second accumulator.
- /// The seed value for the third accumulator.
- /// The third accumulator.
- ///
- /// A function that projects a single result given the result of each
- /// accumulator.
- /// The optional cancellation token to be used for cancelling the sequence at any time.
- /// The value returned by .
- ///
- /// This operator executes immediately.
- ///
- public static ValueTask AggregateAsync<
- TSource,
- TAccumulate1,
- TAccumulate2,
- TAccumulate3,
- TResult>(
- this IAsyncEnumerable source,
- TAccumulate1 seed1,
- Func accumulator1,
- TAccumulate2 seed2,
- Func accumulator2,
- TAccumulate3 seed3,
- Func accumulator3,
- Func resultSelector,
- CancellationToken cancellationToken = default)
- {
- if (source is null) throw new ArgumentNullException(nameof(source));
- if (accumulator1 is null) throw new ArgumentNullException(nameof(accumulator1));
- if (accumulator2 is null) throw new ArgumentNullException(nameof(accumulator2));
- if (accumulator3 is null) throw new ArgumentNullException(nameof(accumulator3));
- if (resultSelector is null) throw new ArgumentNullException(nameof(resultSelector));
-
- return source.IsKnownEmpty()
- ? ValueTasks.FromResult(
- resultSelector(
- seed1,
- seed2,
- seed3))
- : Core(
- source,
- seed1,
- accumulator1,
- seed2,
- accumulator2,
- seed3,
- accumulator3,
- resultSelector,
- cancellationToken);
-
- static async ValueTask Core(
- IAsyncEnumerable source,
- TAccumulate1 seed1,
- Func accumulator1,
- TAccumulate2 seed2,
- Func accumulator2,
- TAccumulate3 seed3,
- Func accumulator3,
- Func resultSelector,
- CancellationToken cancellationToken)
- {
- var accumulate1 = seed1;
- var accumulate2 = seed2;
- var accumulate3 = seed3;
-
- await foreach (var element in source.WithCancellation(cancellationToken))
- {
- accumulate1 = accumulator1(accumulate1, element);
- accumulate2 = accumulator2(accumulate2, element);
- accumulate3 = accumulator3(accumulate3, element);
- }
-
- return resultSelector(
- accumulate1,
- accumulate2,
- accumulate3);
- }
- }
-
- ///
- /// Applies four accumulators sequentially in a single pass over a
- /// sequence.
- ///
- /// The type of elements in .
- /// The type of first accumulator value.
- /// The type of second accumulator value.
- /// The type of third accumulator value.
- /// The type of fourth accumulator value.
- /// The type of the accumulated result.
- /// The source sequence
- /// The seed value for the first accumulator.
- /// The first accumulator.
- /// The seed value for the second accumulator.
- /// The second accumulator.
- /// The seed value for the third accumulator.
- /// The third accumulator.
- /// The seed value for the fourth accumulator.
- /// The fourth accumulator.
- ///
- /// A function that projects a single result given the result of each
- /// accumulator.
- /// The optional cancellation token to be used for cancelling the sequence at any time.
- /// The value returned by .
- ///
- /// This operator executes immediately.
- ///
- public static ValueTask AggregateAsync<
- TSource,
- TAccumulate1,
- TAccumulate2,
- TAccumulate3,
- TAccumulate4,
- TResult>(
- this IAsyncEnumerable source,
- TAccumulate1 seed1,
- Func accumulator1,
- TAccumulate2 seed2,
- Func accumulator2,
- TAccumulate3 seed3,
- Func accumulator3,
- TAccumulate4 seed4,
- Func accumulator4,
- Func resultSelector,
- CancellationToken cancellationToken = default)
- {
- if (source is null) throw new ArgumentNullException(nameof(source));
- if (accumulator1 is null) throw new ArgumentNullException(nameof(accumulator1));
- if (accumulator2 is null) throw new ArgumentNullException(nameof(accumulator2));
- if (accumulator3 is null) throw new ArgumentNullException(nameof(accumulator3));
- if (accumulator4 is null) throw new ArgumentNullException(nameof(accumulator4));
- if (resultSelector is null) throw new ArgumentNullException(nameof(resultSelector));
-
- return source.IsKnownEmpty()
- ? ValueTasks.FromResult(
- resultSelector(
- seed1,
- seed2,
- seed3,
- seed4))
- : Core(
- source,
- seed1,
- accumulator1,
- seed2,
- accumulator2,
- seed3,
- accumulator3,
- seed4,
- accumulator4,
- resultSelector,
- cancellationToken);
-
- static async ValueTask Core(
- IAsyncEnumerable source,
- TAccumulate1 seed1,
- Func accumulator1,
- TAccumulate2 seed2,
- Func accumulator2,
- TAccumulate3 seed3,
- Func accumulator3,
- TAccumulate4 seed4,
- Func accumulator4,
- Func resultSelector,
- CancellationToken cancellationToken)
- {
- var accumulate1 = seed1;
- var accumulate2 = seed2;
- var accumulate3 = seed3;
- var accumulate4 = seed4;
-
- await foreach (var element in source.WithCancellation(cancellationToken))
- {
- accumulate1 = accumulator1(accumulate1, element);
- accumulate2 = accumulator2(accumulate2, element);
- accumulate3 = accumulator3(accumulate3, element);
- accumulate4 = accumulator4(accumulate4, element);
- }
-
- return resultSelector(
- accumulate1,
- accumulate2,
- accumulate3,
- accumulate4);
- }
- }
-
- ///
- /// Applies five accumulators sequentially in a single pass over a
- /// sequence.
- ///
- /// The type of elements in .
- /// The type of first accumulator value.
- /// The type of second accumulator value.
- /// The type of third accumulator value.
- /// The type of fourth accumulator value.
- /// The type of fifth accumulator value.
- /// The type of the accumulated result.
- /// The source sequence
- /// The seed value for the first accumulator.
- /// The first accumulator.
- /// The seed value for the second accumulator.
- /// The second accumulator.
- /// The seed value for the third accumulator.
- /// The third accumulator.
- /// The seed value for the fourth accumulator.
- /// The fourth accumulator.
- /// The seed value for the fifth accumulator.
- /// The fifth accumulator.
- ///
- /// A function that projects a single result given the result of each
- /// accumulator.
- /// The optional cancellation token to be used for cancelling the sequence at any time.
- /// The value returned by .
- ///
- /// This operator executes immediately.
- ///
- public static ValueTask AggregateAsync<
- TSource,
- TAccumulate1,
- TAccumulate2,
- TAccumulate3,
- TAccumulate4,
- TAccumulate5,
- TResult>(
- this IAsyncEnumerable source,
- TAccumulate1 seed1,
- Func accumulator1,
- TAccumulate2 seed2,
- Func accumulator2,
- TAccumulate3 seed3,
- Func accumulator3,
- TAccumulate4 seed4,
- Func accumulator4,
- TAccumulate5 seed5,
- Func accumulator5,
- Func resultSelector,
- CancellationToken cancellationToken = default)
- {
- if (source is null) throw new ArgumentNullException(nameof(source));
- if (accumulator1 is null) throw new ArgumentNullException(nameof(accumulator1));
- if (accumulator2 is null) throw new ArgumentNullException(nameof(accumulator2));
- if (accumulator3 is null) throw new ArgumentNullException(nameof(accumulator3));
- if (accumulator4 is null) throw new ArgumentNullException(nameof(accumulator4));
- if (accumulator5 is null) throw new ArgumentNullException(nameof(accumulator5));
- if (resultSelector is null) throw new ArgumentNullException(nameof(resultSelector));
-
- return source.IsKnownEmpty()
- ? ValueTasks.FromResult(
- resultSelector(
- seed1,
- seed2,
- seed3,
- seed4,
- seed5))
- : Core(
- source,
- seed1,
- accumulator1,
- seed2,
- accumulator2,
- seed3,
- accumulator3,
- seed4,
- accumulator4,
- seed5,
- accumulator5,
- resultSelector,
- cancellationToken);
-
- static async ValueTask Core(
- IAsyncEnumerable source,
- TAccumulate1 seed1,
- Func accumulator1,
- TAccumulate2 seed2,
- Func accumulator2,
- TAccumulate3 seed3,
- Func accumulator3,
- TAccumulate4 seed4,
- Func accumulator4,
- TAccumulate5 seed5,
- Func accumulator5,
- Func resultSelector,
- CancellationToken cancellationToken)
- {
- var accumulate1 = seed1;
- var accumulate2 = seed2;
- var accumulate3 = seed3;
- var accumulate4 = seed4;
- var accumulate5 = seed5;
-
- await foreach (var element in source.WithCancellation(cancellationToken))
- {
- accumulate1 = accumulator1(accumulate1, element);
- accumulate2 = accumulator2(accumulate2, element);
- accumulate3 = accumulator3(accumulate3, element);
- accumulate4 = accumulator4(accumulate4, element);
- accumulate5 = accumulator5(accumulate5, element);
- }
-
- return resultSelector(
- accumulate1,
- accumulate2,
- accumulate3,
- accumulate4,
- accumulate5);
- }
- }
-
- ///
- /// Applies six accumulators sequentially in a single pass over a
- /// sequence.
- ///
- /// The type of elements in .
- /// The type of first accumulator value.
- /// The type of second accumulator value.
- /// The type of third accumulator value.
- /// The type of fourth accumulator value.
- /// The type of fifth accumulator value.
- /// The type of sixth accumulator value.
- /// The type of the accumulated result.
- /// The source sequence
- /// The seed value for the first accumulator.
- /// The first accumulator.
- /// The seed value for the second accumulator.
- /// The second accumulator.
- /// The seed value for the third accumulator.
- /// The third accumulator.
- /// The seed value for the fourth accumulator.
- /// The fourth accumulator.
- /// The seed value for the fifth accumulator.
- /// The fifth accumulator.
- /// The seed value for the sixth accumulator.
- /// The sixth accumulator.
- ///
- /// A function that projects a single result given the result of each
- /// accumulator.
- /// The optional cancellation token to be used for cancelling the sequence at any time.
- /// The value returned by .
- ///
- /// This operator executes immediately.
- ///
- public static ValueTask AggregateAsync<
- TSource,
- TAccumulate1,
- TAccumulate2,
- TAccumulate3,
- TAccumulate4,
- TAccumulate5,
- TAccumulate6,
- TResult>(
- this IAsyncEnumerable source,
- TAccumulate1 seed1,
- Func accumulator1,
- TAccumulate2 seed2,
- Func accumulator2,
- TAccumulate3 seed3,
- Func accumulator3,
- TAccumulate4 seed4,
- Func accumulator4,
- TAccumulate5 seed5,
- Func accumulator5,
- TAccumulate6 seed6,
- Func accumulator6,
- Func resultSelector,
- CancellationToken cancellationToken = default)
- {
- if (source is null) throw new ArgumentNullException(nameof(source));
- if (accumulator1 is null) throw new ArgumentNullException(nameof(accumulator1));
- if (accumulator2 is null) throw new ArgumentNullException(nameof(accumulator2));
- if (accumulator3 is null) throw new ArgumentNullException(nameof(accumulator3));
- if (accumulator4 is null) throw new ArgumentNullException(nameof(accumulator4));
- if (accumulator5 is null) throw new ArgumentNullException(nameof(accumulator5));
- if (accumulator6 is null) throw new ArgumentNullException(nameof(accumulator6));
- if (resultSelector is null) throw new ArgumentNullException(nameof(resultSelector));
-
- return source.IsKnownEmpty()
- ? ValueTasks.FromResult(
- resultSelector(
- seed1,
- seed2,
- seed3,
- seed4,
- seed5,
- seed6))
- : Core(
- source,
- seed1,
- accumulator1,
- seed2,
- accumulator2,
- seed3,
- accumulator3,
- seed4,
- accumulator4,
- seed5,
- accumulator5,
- seed6,
- accumulator6,
- resultSelector,
- cancellationToken);
-
- static async ValueTask Core(
- IAsyncEnumerable source,
- TAccumulate1 seed1,
- Func accumulator1,
- TAccumulate2 seed2,
- Func accumulator2,
- TAccumulate3 seed3,
- Func accumulator3,
- TAccumulate4 seed4,
- Func accumulator4,
- TAccumulate5 seed5,
- Func accumulator5,
- TAccumulate6 seed6,
- Func accumulator6,
- Func resultSelector,
- CancellationToken cancellationToken)
- {
- var accumulate1 = seed1;
- var accumulate2 = seed2;
- var accumulate3 = seed3;
- var accumulate4 = seed4;
- var accumulate5 = seed5;
- var accumulate6 = seed6;
-
- await foreach (var element in source.WithCancellation(cancellationToken))
- {
- accumulate1 = accumulator1(accumulate1, element);
- accumulate2 = accumulator2(accumulate2, element);
- accumulate3 = accumulator3(accumulate3, element);
- accumulate4 = accumulator4(accumulate4, element);
- accumulate5 = accumulator5(accumulate5, element);
- accumulate6 = accumulator6(accumulate6, element);
- }
-
- return resultSelector(
- accumulate1,
- accumulate2,
- accumulate3,
- accumulate4,
- accumulate5,
- accumulate6);
- }
- }
-
- ///
- /// Applies seven accumulators sequentially in a single pass over a
- /// sequence.
- ///
- /// The type of elements in .
- /// The type of first accumulator value.
- /// The type of second accumulator value.
- /// The type of third accumulator value.
- /// The type of fourth accumulator value.
- /// The type of fifth accumulator value.
- /// The type of sixth accumulator value.
- /// The type of seventh accumulator value.
- /// The type of the accumulated result.
- /// The source sequence
- /// The seed value for the first accumulator.
- /// The first accumulator.
- /// The seed value for the second accumulator.
- /// The second accumulator.
- /// The seed value for the third accumulator.
- /// The third accumulator.
- /// The seed value for the fourth accumulator.
- /// The fourth accumulator.
- /// The seed value for the fifth accumulator.
- /// The fifth accumulator.
- /// The seed value for the sixth accumulator.
- /// The sixth accumulator.
- /// The seed value for the seventh accumulator.
- /// The seventh accumulator.
- ///
- /// A function that projects a single result given the result of each
- /// accumulator.
- /// The optional cancellation token to be used for cancelling the sequence at any time.
- /// The value returned by .
- ///
- /// This operator executes immediately.
- ///
- public static ValueTask AggregateAsync<
- TSource,
- TAccumulate1,
- TAccumulate2,
- TAccumulate3,
- TAccumulate4,
- TAccumulate5,
- TAccumulate6,
- TAccumulate7,
- TResult>(
- this IAsyncEnumerable source,
- TAccumulate1 seed1,
- Func accumulator1,
- TAccumulate2 seed2,
- Func accumulator2,
- TAccumulate3 seed3,
- Func accumulator3,
- TAccumulate4 seed4,
- Func accumulator4,
- TAccumulate5 seed5,
- Func accumulator5,
- TAccumulate6 seed6,
- Func accumulator6,
- TAccumulate7 seed7,
- Func accumulator7,
- Func resultSelector,
- CancellationToken cancellationToken = default)
- {
- if (source is null) throw new ArgumentNullException(nameof(source));
- if (accumulator1 is null) throw new ArgumentNullException(nameof(accumulator1));
- if (accumulator2 is null) throw new ArgumentNullException(nameof(accumulator2));
- if (accumulator3 is null) throw new ArgumentNullException(nameof(accumulator3));
- if (accumulator4 is null) throw new ArgumentNullException(nameof(accumulator4));
- if (accumulator5 is null) throw new ArgumentNullException(nameof(accumulator5));
- if (accumulator6 is null) throw new ArgumentNullException(nameof(accumulator6));
- if (accumulator7 is null) throw new ArgumentNullException(nameof(accumulator7));
- if (resultSelector is null) throw new ArgumentNullException(nameof(resultSelector));
-
- return source.IsKnownEmpty()
- ? ValueTasks.FromResult(
- resultSelector(
- seed1,
- seed2,
- seed3,
- seed4,
- seed5,
- seed6,
- seed7))
- : Core(
- source,
- seed1,
- accumulator1,
- seed2,
- accumulator2,
- seed3,
- accumulator3,
- seed4,
- accumulator4,
- seed5,
- accumulator5,
- seed6,
- accumulator6,
- seed7,
- accumulator7,
- resultSelector,
- cancellationToken);
-
- static async ValueTask Core(
- IAsyncEnumerable source,
- TAccumulate1 seed1,
- Func accumulator1,
- TAccumulate2 seed2,
- Func accumulator2,
- TAccumulate3 seed3,
- Func accumulator3,
- TAccumulate4 seed4,
- Func accumulator4,
- TAccumulate5 seed5,
- Func accumulator5,
- TAccumulate6 seed6,
- Func accumulator6,
- TAccumulate7 seed7,
- Func accumulator7,
- Func resultSelector,
- CancellationToken cancellationToken)
- {
- var accumulate1 = seed1;
- var accumulate2 = seed2;
- var accumulate3 = seed3;
- var accumulate4 = seed4;
- var accumulate5 = seed5;
- var accumulate6 = seed6;
- var accumulate7 = seed7;
-
- await foreach (var element in source.WithCancellation(cancellationToken))
- {
- accumulate1 = accumulator1(accumulate1, element);
- accumulate2 = accumulator2(accumulate2, element);
- accumulate3 = accumulator3(accumulate3, element);
- accumulate4 = accumulator4(accumulate4, element);
- accumulate5 = accumulator5(accumulate5, element);
- accumulate6 = accumulator6(accumulate6, element);
- accumulate7 = accumulator7(accumulate7, element);
- }
-
- return resultSelector(
- accumulate1,
- accumulate2,
- accumulate3,
- accumulate4,
- accumulate5,
- accumulate6,
- accumulate7);
- }
- }
-
- ///
- /// Applies eight accumulators sequentially in a single pass over a
- /// sequence.
- ///
- /// The type of elements in .
- /// The type of first accumulator value.
- /// The type of second accumulator value.
- /// The type of third accumulator value.
- /// The type of fourth accumulator value.
- /// The type of fifth accumulator value.
- /// The type of sixth accumulator value.
- /// The type of seventh accumulator value.
- /// The type of eighth accumulator value.
- /// The type of the accumulated result.
- /// The source sequence
- /// The seed value for the first accumulator.
- /// The first accumulator.
- /// The seed value for the second accumulator.
- /// The second accumulator.
- /// The seed value for the third accumulator.
- /// The third accumulator.
- /// The seed value for the fourth accumulator.
- /// The fourth accumulator.
- /// The seed value for the fifth accumulator.
- /// The fifth accumulator.
- /// The seed value for the sixth accumulator.
- /// The sixth accumulator.
- /// The seed value for the seventh accumulator.
- /// The seventh accumulator.
- /// The seed value for the eighth accumulator.
- /// The eighth accumulator.
- ///
- /// A function that projects a single result given the result of each
- /// accumulator.
- /// The optional cancellation token to be used for cancelling the sequence at any time.
- /// The value returned by .
- ///
- /// This operator executes immediately.
- ///
- public static ValueTask AggregateAsync<
- TSource,
- TAccumulate1,
- TAccumulate2,
- TAccumulate3,
- TAccumulate4,
- TAccumulate5,
- TAccumulate6,
- TAccumulate7,
- TAccumulate8,
- TResult>(
- this IAsyncEnumerable source,
- TAccumulate1 seed1,
- Func accumulator1,
- TAccumulate2 seed2,
- Func accumulator2,
- TAccumulate3 seed3,
- Func accumulator3,
- TAccumulate4 seed4,
- Func accumulator4,
- TAccumulate5 seed5,
- Func accumulator5,
- TAccumulate6 seed6,
- Func accumulator6,
- TAccumulate7 seed7,
- Func accumulator7,
- TAccumulate8 seed8,
- Func accumulator8,
- Func resultSelector,
- CancellationToken cancellationToken = default)
- {
- if (source is null) throw new ArgumentNullException(nameof(source));
- if (accumulator1 is null) throw new ArgumentNullException(nameof(accumulator1));
- if (accumulator2 is null) throw new ArgumentNullException(nameof(accumulator2));
- if (accumulator3 is null) throw new ArgumentNullException(nameof(accumulator3));
- if (accumulator4 is null) throw new ArgumentNullException(nameof(accumulator4));
- if (accumulator5 is null) throw new ArgumentNullException(nameof(accumulator5));
- if (accumulator6 is null) throw new ArgumentNullException(nameof(accumulator6));
- if (accumulator7 is null) throw new ArgumentNullException(nameof(accumulator7));
- if (accumulator8 is null) throw new ArgumentNullException(nameof(accumulator8));
- if (resultSelector is null) throw new ArgumentNullException(nameof(resultSelector));
-
- return source.IsKnownEmpty()
- ? ValueTasks.FromResult(
- resultSelector(
- seed1,
- seed2,
- seed3,
- seed4,
- seed5,
- seed6,
- seed7,
- seed8))
- : Core(
- source,
- seed1,
- accumulator1,
- seed2,
- accumulator2,
- seed3,
- accumulator3,
- seed4,
- accumulator4,
- seed5,
- accumulator5,
- seed6,
- accumulator6,
- seed7,
- accumulator7,
- seed8,
- accumulator8,
- resultSelector,
- cancellationToken);
-
- static async ValueTask Core(
- IAsyncEnumerable source,
- TAccumulate1 seed1,
- Func accumulator1,
- TAccumulate2 seed2,
- Func accumulator2,
- TAccumulate3 seed3,
- Func accumulator3,
- TAccumulate4 seed4,
- Func accumulator4,
- TAccumulate5 seed5,
- Func accumulator5,
- TAccumulate6 seed6,
- Func accumulator6,
- TAccumulate7 seed7,
- Func accumulator7,
- TAccumulate8 seed8,
- Func accumulator8,
- Func resultSelector,
- CancellationToken cancellationToken)
- {
- var accumulate1 = seed1;
- var accumulate2 = seed2;
- var accumulate3 = seed3;
- var accumulate4 = seed4;
- var accumulate5 = seed5;
- var accumulate6 = seed6;
- var accumulate7 = seed7;
- var accumulate8 = seed8;
-
- await foreach (var element in source.WithCancellation(cancellationToken))
- {
- accumulate1 = accumulator1(accumulate1, element);
- accumulate2 = accumulator2(accumulate2, element);
- accumulate3 = accumulator3(accumulate3, element);
- accumulate4 = accumulator4(accumulate4, element);
- accumulate5 = accumulator5(accumulate5, element);
- accumulate6 = accumulator6(accumulate6, element);
- accumulate7 = accumulator7(accumulate7, element);
- accumulate8 = accumulator8(accumulate8, element);
- }
-
- return resultSelector(
- accumulate1,
- accumulate2,
- accumulate3,
- accumulate4,
- accumulate5,
- accumulate6,
- accumulate7,
- accumulate8);
- }
- }
- ///
- /// Applies two accumulators sequentially in a single pass over a
- /// sequence.
- ///
- /// The type of elements in .
- /// The type of first accumulator value.
- /// The type of second accumulator value.
- /// The type of the accumulated result.
- /// The source sequence
- /// The seed value for the first accumulator.
- /// The first accumulator.
- /// The seed value for the second accumulator.
- /// The second accumulator.
- ///
- /// A function that projects a single result given the result of each
- /// accumulator.
- /// The optional cancellation token to be used for cancelling the sequence at any time.
- /// The value returned by .
- ///
- /// This operator executes immediately.
- ///
- public static ValueTask AggregateAsync<
- TSource,
- TAccumulate1,
- TAccumulate2,
- TResult>(
- this IAsyncEnumerable source,
- TAccumulate1 seed1,
- Func> accumulator1,
- TAccumulate2 seed2,
- Func> accumulator2,
- Func> resultSelector,
- CancellationToken cancellationToken = default)
- {
- if (source is null) throw new ArgumentNullException(nameof(source));
- if (accumulator1 is null) throw new ArgumentNullException(nameof(accumulator1));
- if (accumulator2 is null) throw new ArgumentNullException(nameof(accumulator2));
- if (resultSelector is null) throw new ArgumentNullException(nameof(resultSelector));
-
- return Core(
- source,
- seed1,
- accumulator1,
- seed2,
- accumulator2,
- resultSelector,
- cancellationToken);
-
- static async ValueTask Core(
- IAsyncEnumerable source,
- TAccumulate1 seed1,
- Func> accumulator1,
- TAccumulate2 seed2,
- Func> accumulator2,
- Func> resultSelector,
- CancellationToken cancellationToken)
- {
- var accumulate1 = seed1;
- var accumulate2 = seed2;
-
- await foreach (var element in source.WithCancellation(cancellationToken))
- {
- accumulate1 = await accumulator1(accumulate1, element, cancellationToken);
- accumulate2 = await accumulator2(accumulate2, element, cancellationToken);
- }
-
- return await resultSelector(
- accumulate1,
- accumulate2,
- cancellationToken);
- }
- }
-
- ///
- /// Applies three accumulators sequentially in a single pass over a
- /// sequence.
- ///
- /// The type of elements in .
- /// The type of first accumulator value.
- /// The type of second accumulator value.
- /// The type of third accumulator value.
- /// The type of the accumulated result.
- /// The source sequence
- /// The seed value for the first accumulator.
- /// The first accumulator.
- /// The seed value for the second accumulator.
- /// The second accumulator.
- /// The seed value for the third accumulator.
- /// The third accumulator.
- ///
- /// A function that projects a single result given the result of each
- /// accumulator.
- /// The optional cancellation token to be used for cancelling the sequence at any time.
- /// The value returned by .
- ///
- /// This operator executes immediately.
- ///
- public static ValueTask AggregateAsync<
- TSource,
- TAccumulate1,
- TAccumulate2,
- TAccumulate3,
- TResult>(
- this IAsyncEnumerable source,
- TAccumulate1 seed1,
- Func> accumulator1,
- TAccumulate2 seed2,
- Func> accumulator2,
- TAccumulate3 seed3,
- Func> accumulator3,
- Func> resultSelector,
- CancellationToken cancellationToken = default)
- {
- if (source is null) throw new ArgumentNullException(nameof(source));
- if (accumulator1 is null) throw new ArgumentNullException(nameof(accumulator1));
- if (accumulator2 is null) throw new ArgumentNullException(nameof(accumulator2));
- if (accumulator3 is null) throw new ArgumentNullException(nameof(accumulator3));
- if (resultSelector is null) throw new ArgumentNullException(nameof(resultSelector));
-
- return Core(
- source,
- seed1,
- accumulator1,
- seed2,
- accumulator2,
- seed3,
- accumulator3,
- resultSelector,
- cancellationToken);
-
- static async ValueTask Core(
- IAsyncEnumerable source,
- TAccumulate1 seed1,
- Func> accumulator1,
- TAccumulate2 seed2,
- Func> accumulator2,
- TAccumulate3 seed3,
- Func> accumulator3,
- Func> resultSelector,
- CancellationToken cancellationToken)
- {
- var accumulate1 = seed1;
- var accumulate2 = seed2;
- var accumulate3 = seed3;
-
- await foreach (var element in source.WithCancellation(cancellationToken))
- {
- accumulate1 = await accumulator1(accumulate1, element, cancellationToken);
- accumulate2 = await accumulator2(accumulate2, element, cancellationToken);
- accumulate3 = await accumulator3(accumulate3, element, cancellationToken);
- }
-
- return await resultSelector(
- accumulate1,
- accumulate2,
- accumulate3,
- cancellationToken);
- }
- }
-
- ///
- /// Applies four accumulators sequentially in a single pass over a
- /// sequence.
- ///
- /// The type of elements in .
- /// The type of first accumulator value.
- /// The type of second accumulator value.
- /// The type of third accumulator value.
- /// The type of fourth accumulator value.
- /// The type of the accumulated result.
- /// The source sequence
- /// The seed value for the first accumulator.
- /// The first accumulator.
- /// The seed value for the second accumulator.
- /// The second accumulator.
- /// The seed value for the third accumulator.
- /// The third accumulator.
- /// The seed value for the fourth accumulator.
- /// The fourth accumulator.
- ///
- /// A function that projects a single result given the result of each
- /// accumulator.
- /// The optional cancellation token to be used for cancelling the sequence at any time.
- /// The value returned by .
- ///
- /// This operator executes immediately.
- ///
- public static ValueTask AggregateAsync<
- TSource,
- TAccumulate1,
- TAccumulate2,
- TAccumulate3,
- TAccumulate4,
- TResult>(
- this IAsyncEnumerable source,
- TAccumulate1 seed1,
- Func> accumulator1,
- TAccumulate2 seed2,
- Func> accumulator2,
- TAccumulate3 seed3,
- Func> accumulator3,
- TAccumulate4 seed4,
- Func> accumulator4,
- Func> resultSelector,
- CancellationToken cancellationToken = default)
- {
- if (source is null) throw new ArgumentNullException(nameof(source));
- if (accumulator1 is null) throw new ArgumentNullException(nameof(accumulator1));
- if (accumulator2 is null) throw new ArgumentNullException(nameof(accumulator2));
- if (accumulator3 is null) throw new ArgumentNullException(nameof(accumulator3));
- if (accumulator4 is null) throw new ArgumentNullException(nameof(accumulator4));
- if (resultSelector is null) throw new ArgumentNullException(nameof(resultSelector));
-
- return Core(
- source,
- seed1,
- accumulator1,
- seed2,
- accumulator2,
- seed3,
- accumulator3,
- seed4,
- accumulator4,
- resultSelector,
- cancellationToken);
-
- static async ValueTask Core(
- IAsyncEnumerable source,
- TAccumulate1 seed1,
- Func> accumulator1,
- TAccumulate2 seed2,
- Func> accumulator2,
- TAccumulate3 seed3,
- Func> accumulator3,
- TAccumulate4 seed4,
- Func> accumulator4,
- Func> resultSelector,
- CancellationToken cancellationToken)
- {
- var accumulate1 = seed1;
- var accumulate2 = seed2;
- var accumulate3 = seed3;
- var accumulate4 = seed4;
-
- await foreach (var element in source.WithCancellation(cancellationToken))
- {
- accumulate1 = await accumulator1(accumulate1, element, cancellationToken);
- accumulate2 = await accumulator2(accumulate2, element, cancellationToken);
- accumulate3 = await accumulator3(accumulate3, element, cancellationToken);
- accumulate4 = await accumulator4(accumulate4, element, cancellationToken);
- }
-
- return await resultSelector(
- accumulate1,
- accumulate2,
- accumulate3,
- accumulate4,
- cancellationToken);
- }
- }
-
- ///
- /// Applies five accumulators sequentially in a single pass over a
- /// sequence.
- ///
- /// The type of elements in .
- /// The type of first accumulator value.
- /// The type of second accumulator value.
- /// The type of third accumulator value.
- /// The type of fourth accumulator value.
- /// The type of fifth accumulator value.
- /// The type of the accumulated result.
- /// The source sequence
- /// The seed value for the first accumulator.
- /// The first accumulator.
- /// The seed value for the second accumulator.
- /// The second accumulator.
- /// The seed value for the third accumulator.
- /// The third accumulator.
- /// The seed value for the fourth accumulator.
- /// The fourth accumulator.
- /// The seed value for the fifth accumulator.
- /// The fifth accumulator.
- ///
- /// A function that projects a single result given the result of each
- /// accumulator.
- /// The optional cancellation token to be used for cancelling the sequence at any time.
- /// The value returned by .
- ///
- /// This operator executes immediately.
- ///
- public static ValueTask AggregateAsync<
- TSource,
- TAccumulate1,
- TAccumulate2,
- TAccumulate3,
- TAccumulate4,
- TAccumulate5,
- TResult>(
- this IAsyncEnumerable source,
- TAccumulate1 seed1,
- Func> accumulator1,
- TAccumulate2 seed2,
- Func> accumulator2,
- TAccumulate3 seed3,
- Func> accumulator3,
- TAccumulate4 seed4,
- Func> accumulator4,
- TAccumulate5 seed5,
- Func> accumulator5,
- Func> resultSelector,
- CancellationToken cancellationToken = default)
- {
- if (source is null) throw new ArgumentNullException(nameof(source));
- if (accumulator1 is null) throw new ArgumentNullException(nameof(accumulator1));
- if (accumulator2 is null) throw new ArgumentNullException(nameof(accumulator2));
- if (accumulator3 is null) throw new ArgumentNullException(nameof(accumulator3));
- if (accumulator4 is null) throw new ArgumentNullException(nameof(accumulator4));
- if (accumulator5 is null) throw new ArgumentNullException(nameof(accumulator5));
- if (resultSelector is null) throw new ArgumentNullException(nameof(resultSelector));
-
- return Core(
- source,
- seed1,
- accumulator1,
- seed2,
- accumulator2,
- seed3,
- accumulator3,
- seed4,
- accumulator4,
- seed5,
- accumulator5,
- resultSelector,
- cancellationToken);
-
- static async ValueTask Core(
- IAsyncEnumerable source,
- TAccumulate1 seed1,
- Func> accumulator1,
- TAccumulate2 seed2,
- Func> accumulator2,
- TAccumulate3 seed3,
- Func> accumulator3,
- TAccumulate4 seed4,
- Func> accumulator4,
- TAccumulate5 seed5,
- Func> accumulator5,
- Func> resultSelector,
- CancellationToken cancellationToken)
- {
- var accumulate1 = seed1;
- var accumulate2 = seed2;
- var accumulate3 = seed3;
- var accumulate4 = seed4;
- var accumulate5 = seed5;
-
- await foreach (var element in source.WithCancellation(cancellationToken))
- {
- accumulate1 = await accumulator1(accumulate1, element, cancellationToken);
- accumulate2 = await accumulator2(accumulate2, element, cancellationToken);
- accumulate3 = await accumulator3(accumulate3, element, cancellationToken);
- accumulate4 = await accumulator4(accumulate4, element, cancellationToken);
- accumulate5 = await accumulator5(accumulate5, element, cancellationToken);
- }
-
- return await resultSelector(
- accumulate1,
- accumulate2,
- accumulate3,
- accumulate4,
- accumulate5,
- cancellationToken);
- }
- }
-
- ///
- /// Applies six accumulators sequentially in a single pass over a
- /// sequence.
- ///
- /// The type of elements in .
- /// The type of first accumulator value.
- /// The type of second accumulator value.
- /// The type of third accumulator value.
- /// The type of fourth accumulator value.
- /// The type of fifth accumulator value.
- /// The type of sixth accumulator value.
- /// The type of the accumulated result.
- /// The source sequence
- /// The seed value for the first accumulator.
- /// The first accumulator.
- /// The seed value for the second accumulator.
- /// The second accumulator.
- /// The seed value for the third accumulator.
- /// The third accumulator.
- /// The seed value for the fourth accumulator.
- /// The fourth accumulator.
- /// The seed value for the fifth accumulator.
- /// The fifth accumulator.
- /// The seed value for the sixth accumulator.
- /// The sixth accumulator.
- ///
- /// A function that projects a single result given the result of each
- /// accumulator.
- /// The optional cancellation token to be used for cancelling the sequence at any time.
- /// The value returned by .
- ///
- /// This operator executes immediately.
- ///
- public static ValueTask AggregateAsync<
- TSource,
- TAccumulate1,
- TAccumulate2,
- TAccumulate3,
- TAccumulate4,
- TAccumulate5,
- TAccumulate6,
- TResult>(
- this IAsyncEnumerable source,
- TAccumulate1 seed1,
- Func> accumulator1,
- TAccumulate2 seed2,
- Func> accumulator2,
- TAccumulate3 seed3,
- Func> accumulator3,
- TAccumulate4 seed4,
- Func> accumulator4,
- TAccumulate5 seed5,
- Func> accumulator5,
- TAccumulate6 seed6,
- Func> accumulator6,
- Func> resultSelector,
- CancellationToken cancellationToken = default)
- {
- if (source is null) throw new ArgumentNullException(nameof(source));
- if (accumulator1 is null) throw new ArgumentNullException(nameof(accumulator1));
- if (accumulator2 is null) throw new ArgumentNullException(nameof(accumulator2));
- if (accumulator3 is null) throw new ArgumentNullException(nameof(accumulator3));
- if (accumulator4 is null) throw new ArgumentNullException(nameof(accumulator4));
- if (accumulator5 is null) throw new ArgumentNullException(nameof(accumulator5));
- if (accumulator6 is null) throw new ArgumentNullException(nameof(accumulator6));
- if (resultSelector is null) throw new ArgumentNullException(nameof(resultSelector));
-
- return Core(
- source,
- seed1,
- accumulator1,
- seed2,
- accumulator2,
- seed3,
- accumulator3,
- seed4,
- accumulator4,
- seed5,
- accumulator5,
- seed6,
- accumulator6,
- resultSelector,
- cancellationToken);
-
- static async ValueTask Core(
- IAsyncEnumerable source,
- TAccumulate1 seed1,
- Func> accumulator1,
- TAccumulate2 seed2,
- Func> accumulator2,
- TAccumulate3 seed3,
- Func> accumulator3,
- TAccumulate4 seed4,
- Func> accumulator4,
- TAccumulate5 seed5,
- Func> accumulator5,
- TAccumulate6 seed6,
- Func> accumulator6,
- Func> resultSelector,
- CancellationToken cancellationToken)
- {
- var accumulate1 = seed1;
- var accumulate2 = seed2;
- var accumulate3 = seed3;
- var accumulate4 = seed4;
- var accumulate5 = seed5;
- var accumulate6 = seed6;
-
- await foreach (var element in source.WithCancellation(cancellationToken))
- {
- accumulate1 = await accumulator1(accumulate1, element, cancellationToken);
- accumulate2 = await accumulator2(accumulate2, element, cancellationToken);
- accumulate3 = await accumulator3(accumulate3, element, cancellationToken);
- accumulate4 = await accumulator4(accumulate4, element, cancellationToken);
- accumulate5 = await accumulator5(accumulate5, element, cancellationToken);
- accumulate6 = await accumulator6(accumulate6, element, cancellationToken);
- }
-
- return await resultSelector(
- accumulate1,
- accumulate2,
- accumulate3,
- accumulate4,
- accumulate5,
- accumulate6,
- cancellationToken);
- }
- }
-
- ///
- /// Applies seven accumulators sequentially in a single pass over a
- /// sequence.
- ///
- /// The type of elements in .
- /// The type of first accumulator value.
- /// The type of second accumulator value.
- /// The type of third accumulator value.
- /// The type of fourth accumulator value.
- /// The type of fifth accumulator value.
- /// The type of sixth accumulator value.
- /// The type of seventh accumulator value.
- /// The type of the accumulated result.
- /// The source sequence
- /// The seed value for the first accumulator.
- /// The first accumulator.
- /// The seed value for the second accumulator.
- /// The second accumulator.
- /// The seed value for the third accumulator.
- /// The third accumulator.
- /// The seed value for the fourth accumulator.
- /// The fourth accumulator.
- /// The seed value for the fifth accumulator.
- /// The fifth accumulator.
- /// The seed value for the sixth accumulator.
- /// The sixth accumulator.
- /// The seed value for the seventh accumulator.
- /// The seventh accumulator.
- ///
- /// A function that projects a single result given the result of each
- /// accumulator.
- /// The optional cancellation token to be used for cancelling the sequence at any time.
- /// The value returned by .
- ///
- /// This operator executes immediately.
- ///
- public static ValueTask AggregateAsync<
- TSource,
- TAccumulate1,
- TAccumulate2,
- TAccumulate3,
- TAccumulate4,
- TAccumulate5,
- TAccumulate6,
- TAccumulate7,
- TResult>(
- this IAsyncEnumerable source,
- TAccumulate1 seed1,
- Func> accumulator1,
- TAccumulate2 seed2,
- Func> accumulator2,
- TAccumulate3 seed3,
- Func> accumulator3,
- TAccumulate4 seed4,
- Func> accumulator4,
- TAccumulate5 seed5,
- Func> accumulator5,
- TAccumulate6 seed6,
- Func> accumulator6,
- TAccumulate7 seed7,
- Func> accumulator7,
- Func> resultSelector,
- CancellationToken cancellationToken = default)
- {
- if (source is null) throw new ArgumentNullException(nameof(source));
- if (accumulator1 is null) throw new ArgumentNullException(nameof(accumulator1));
- if (accumulator2 is null) throw new ArgumentNullException(nameof(accumulator2));
- if (accumulator3 is null) throw new ArgumentNullException(nameof(accumulator3));
- if (accumulator4 is null) throw new ArgumentNullException(nameof(accumulator4));
- if (accumulator5 is null) throw new ArgumentNullException(nameof(accumulator5));
- if (accumulator6 is null) throw new ArgumentNullException(nameof(accumulator6));
- if (accumulator7 is null) throw new ArgumentNullException(nameof(accumulator7));
- if (resultSelector is null) throw new ArgumentNullException(nameof(resultSelector));
-
- return Core(
- source,
- seed1,
- accumulator1,
- seed2,
- accumulator2,
- seed3,
- accumulator3,
- seed4,
- accumulator4,
- seed5,
- accumulator5,
- seed6,
- accumulator6,
- seed7,
- accumulator7,
- resultSelector,
- cancellationToken);
-
- static async ValueTask Core(
- IAsyncEnumerable source,
- TAccumulate1 seed1,
- Func> accumulator1,
- TAccumulate2 seed2,
- Func> accumulator2,
- TAccumulate3 seed3,
- Func> accumulator3,
- TAccumulate4 seed4,
- Func> accumulator4,
- TAccumulate5 seed5,
- Func> accumulator5,
- TAccumulate6 seed6,
- Func> accumulator6,
- TAccumulate7 seed7,
- Func> accumulator7,
- Func> resultSelector,
- CancellationToken cancellationToken)
- {
- var accumulate1 = seed1;
- var accumulate2 = seed2;
- var accumulate3 = seed3;
- var accumulate4 = seed4;
- var accumulate5 = seed5;
- var accumulate6 = seed6;
- var accumulate7 = seed7;
-
- await foreach (var element in source.WithCancellation(cancellationToken))
- {
- accumulate1 = await accumulator1(accumulate1, element, cancellationToken);
- accumulate2 = await accumulator2(accumulate2, element, cancellationToken);
- accumulate3 = await accumulator3(accumulate3, element, cancellationToken);
- accumulate4 = await accumulator4(accumulate4, element, cancellationToken);
- accumulate5 = await accumulator5(accumulate5, element, cancellationToken);
- accumulate6 = await accumulator6(accumulate6, element, cancellationToken);
- accumulate7 = await accumulator7(accumulate7, element, cancellationToken);
- }
-
- return await resultSelector(
- accumulate1,
- accumulate2,
- accumulate3,
- accumulate4,
- accumulate5,
- accumulate6,
- accumulate7,
- cancellationToken);
- }
- }
-
- ///
- /// Applies eight accumulators sequentially in a single pass over a
- /// sequence.
- ///
- /// The type of elements in .
- /// The type of first accumulator value.
- /// The type of second accumulator value.
- /// The type of third accumulator value.
- /// The type of fourth accumulator value.
- /// The type of fifth accumulator value.
- /// The type of sixth accumulator value.
- /// The type of seventh accumulator value.
- /// The type of eighth accumulator value.
- /// The type of the accumulated result.
- /// The source sequence
- /// The seed value for the first accumulator.
- /// The first accumulator.
- /// The seed value for the second accumulator.
- /// The second accumulator.
- /// The seed value for the third accumulator.
- /// The third accumulator.
- /// The seed value for the fourth accumulator.
- /// The fourth accumulator.
- /// The seed value for the fifth accumulator.
- /// The fifth accumulator.
- /// The seed value for the sixth accumulator.
- /// The sixth accumulator.
- /// The seed value for the seventh accumulator.
- /// The seventh accumulator.
- /// The seed value for the eighth accumulator.
- /// The eighth accumulator.
- ///
- /// A function that projects a single result given the result of each
- /// accumulator.
- /// The optional cancellation token to be used for cancelling the sequence at any time.
- /// The value returned by .
- ///
- /// This operator executes immediately.
- ///
- public static ValueTask AggregateAsync<
- TSource,
- TAccumulate1,
- TAccumulate2,
- TAccumulate3,
- TAccumulate4,
- TAccumulate5,
- TAccumulate6,
- TAccumulate7,
- TAccumulate8,
- TResult>(
- this IAsyncEnumerable source,
- TAccumulate1 seed1,
- Func> accumulator1,
- TAccumulate2 seed2,
- Func> accumulator2,
- TAccumulate3 seed3,
- Func> accumulator3,
- TAccumulate4 seed4,
- Func> accumulator4,
- TAccumulate5 seed5,
- Func> accumulator5,
- TAccumulate6 seed6,
- Func> accumulator6,
- TAccumulate7 seed7,
- Func> accumulator7,
- TAccumulate8 seed8,
- Func> accumulator8,
- Func> resultSelector,
- CancellationToken cancellationToken = default)
- {
- if (source is null) throw new ArgumentNullException(nameof(source));
- if (accumulator1 is null) throw new ArgumentNullException(nameof(accumulator1));
- if (accumulator2 is null) throw new ArgumentNullException(nameof(accumulator2));
- if (accumulator3 is null) throw new ArgumentNullException(nameof(accumulator3));
- if (accumulator4 is null) throw new ArgumentNullException(nameof(accumulator4));
- if (accumulator5 is null) throw new ArgumentNullException(nameof(accumulator5));
- if (accumulator6 is null) throw new ArgumentNullException(nameof(accumulator6));
- if (accumulator7 is null) throw new ArgumentNullException(nameof(accumulator7));
- if (accumulator8 is null) throw new ArgumentNullException(nameof(accumulator8));
- if (resultSelector is null) throw new ArgumentNullException(nameof(resultSelector));
-
- return Core(
- source,
- seed1,
- accumulator1,
- seed2,
- accumulator2,
- seed3,
- accumulator3,
- seed4,
- accumulator4,
- seed5,
- accumulator5,
- seed6,
- accumulator6,
- seed7,
- accumulator7,
- seed8,
- accumulator8,
- resultSelector,
- cancellationToken);
-
- static async ValueTask Core(
- IAsyncEnumerable source,
- TAccumulate1 seed1,
- Func> accumulator1,
- TAccumulate2 seed2,
- Func> accumulator2,
- TAccumulate3 seed3,
- Func> accumulator3,
- TAccumulate4 seed4,
- Func> accumulator4,
- TAccumulate5 seed5,
- Func> accumulator5,
- TAccumulate6 seed6,
- Func> accumulator6,
- TAccumulate7 seed7,
- Func> accumulator7,
- TAccumulate8 seed8,
- Func> accumulator8,
- Func> resultSelector,
- CancellationToken cancellationToken)
- {
- var accumulate1 = seed1;
- var accumulate2 = seed2;
- var accumulate3 = seed3;
- var accumulate4 = seed4;
- var accumulate5 = seed5;
- var accumulate6 = seed6;
- var accumulate7 = seed7;
- var accumulate8 = seed8;
-
- await foreach (var element in source.WithCancellation(cancellationToken))
- {
- accumulate1 = await accumulator1(accumulate1, element, cancellationToken);
- accumulate2 = await accumulator2(accumulate2, element, cancellationToken);
- accumulate3 = await accumulator3(accumulate3, element, cancellationToken);
- accumulate4 = await accumulator4(accumulate4, element, cancellationToken);
- accumulate5 = await accumulator5(accumulate5, element, cancellationToken);
- accumulate6 = await accumulator6(accumulate6, element, cancellationToken);
- accumulate7 = await accumulator7(accumulate7, element, cancellationToken);
- accumulate8 = await accumulator8(accumulate8, element, cancellationToken);
- }
-
- return await resultSelector(
- accumulate1,
- accumulate2,
- accumulate3,
- accumulate4,
- accumulate5,
- accumulate6,
- accumulate7,
- accumulate8,
- cancellationToken);
- }
- }
-}
\ No newline at end of file
diff --git a/tests/MoreAsyncLINQ.Tests/Operators/AggregateTests.cs b/tests/MoreAsyncLINQ.Tests/Operators/AggregateTests.cs
new file mode 100644
index 0000000..103707d
--- /dev/null
+++ b/tests/MoreAsyncLINQ.Tests/Operators/AggregateTests.cs
@@ -0,0 +1,762 @@
+using MoreLinq;
+using static System.Linq.AsyncEnumerable;
+
+namespace MoreAsyncLINQ.Tests;
+
+public class AggregateTests : AsyncEnumerableTests
+{
+ [Fact]
+ public void InvalidInputs_TwoAccumulators_Throws()
+ {
+ Assert.Throws(
+ "source",
+ () =>
+ MoreAsyncEnumerable.AggregateAsync(
+ null!,
+ 0,
+ (acc, x) => acc + x,
+ 0,
+ (acc, x) => acc + x,
+ (a1, a2) => a1 + a2));
+
+ Assert.Throws(
+ "accumulator1",
+ () =>
+ Empty().
+ AggregateAsync(
+ 0,
+ null!,
+ 0,
+ (acc, x) => acc + x,
+ (a1, a2) => a1 + a2));
+
+ Assert.Throws(
+ "accumulator2",
+ () =>
+ Empty().
+ AggregateAsync(
+ 0,
+ (acc, x) => acc + x,
+ 0,
+ null!,
+ (a1, a2) => a1 + a2));
+
+ Assert.Throws(
+ "resultSelector",
+ () =>
+ Empty().
+ AggregateAsync(
+ 0,
+ (acc, x) => acc + x,
+ 0,
+ (acc, x) => acc + x,
+ (Func)null!));
+
+ Assert.Throws(
+ "source",
+ () =>
+ MoreAsyncEnumerable.AggregateAsync(
+ null!,
+ 0,
+ (acc, x, _) => ValueTask.FromResult(acc + x),
+ 0,
+ (acc, x, _) => ValueTask.FromResult(acc + x),
+ (a1, a2, _) => ValueTask.FromResult(a1 + a2)));
+
+ Assert.Throws(
+ "accumulator1",
+ () =>
+ Empty().
+ AggregateAsync(
+ 0,
+ null!,
+ 0,
+ (acc, x, _) => ValueTask.FromResult(acc + x),
+ (a1, a2, _) => ValueTask.FromResult(a1 + a2)));
+
+ Assert.Throws(
+ "accumulator2",
+ () =>
+ Empty().
+ AggregateAsync(
+ 0,
+ (acc, x, _) => ValueTask.FromResult(acc + x),
+ 0,
+ null!,
+ (a1, a2, _) => ValueTask.FromResult(a1 + a2)));
+
+ Assert.Throws(
+ "resultSelector",
+ () =>
+ Empty().
+ AggregateAsync(
+ 0,
+ (acc, x, _) => ValueTask.FromResult(acc + x),
+ 0,
+ (acc, x, _) => ValueTask.FromResult(acc + x),
+ (Func>)null!));
+ }
+
+ [Fact]
+ public void InvalidInputs_ThreeAccumulators_Throws()
+ {
+ Assert.Throws(
+ "source",
+ () =>
+ MoreAsyncEnumerable.AggregateAsync(
+ null!,
+ 0,
+ (acc, x) => acc + x,
+ 0,
+ (acc, x) => acc + x,
+ 0,
+ (acc, x) => acc + x,
+ (a1, a2, a3) => a1 + a2 + a3));
+
+ Assert.Throws