From 56a5bfadbd67c4e31ef45e1336adb8c4747e069b Mon Sep 17 00:00:00 2001 From: Orace Date: Mon, 4 Nov 2019 17:57:43 +0100 Subject: [PATCH 01/11] Zip refactoring. - introduce CustomZip with separate behavior by source - use CustomZip for EquiZip, ZipLongest and ZipShortest - add ValueTuple overloads - use t4 file to have up to 8 input sequences. --- MoreLinq/EquiZip.cs | 213 --- MoreLinq/Extensions.g.cs | 1611 +++++++++++++++++++---- MoreLinq/MoreLinq.csproj | 9 + MoreLinq/Zip.g.cs | 2660 ++++++++++++++++++++++++++++++++++++++ MoreLinq/Zip.g.tt | 458 +++++++ MoreLinq/ZipImpl.cs | 97 -- MoreLinq/ZipLongest.cs | 169 --- MoreLinq/ZipShortest.cs | 185 --- README.md | 6 +- 9 files changed, 4496 insertions(+), 912 deletions(-) delete mode 100644 MoreLinq/EquiZip.cs create mode 100644 MoreLinq/Zip.g.cs create mode 100644 MoreLinq/Zip.g.tt delete mode 100644 MoreLinq/ZipImpl.cs delete mode 100644 MoreLinq/ZipLongest.cs delete mode 100644 MoreLinq/ZipShortest.cs diff --git a/MoreLinq/EquiZip.cs b/MoreLinq/EquiZip.cs deleted file mode 100644 index edede6ef1..000000000 --- a/MoreLinq/EquiZip.cs +++ /dev/null @@ -1,213 +0,0 @@ -#region License and Terms -// MoreLINQ - Extensions to LINQ to Objects -// Copyright (c) 2008 Jonathan Skeet. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#endregion - -namespace MoreLinq -{ - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.Linq; - - static partial class MoreEnumerable - { - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. An exception is thrown - /// if the input sequences are of different lengths. - /// - /// Type of elements in first sequence. - /// Type of elements in second sequence. - /// Type of elements in result sequence. - /// The first sequence. - /// The second sequence. - /// - /// Function to apply to each pair of elements. - /// - /// A sequence that contains elements of the two input sequences, - /// combined by . - /// - /// - /// The input sequences are of different lengths. - /// - /// - /// n + l); - /// ]]> - /// The zipped variable, when iterated over, will yield "1A", - /// "2B", "3C", "4D" in turn. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable EquiZip( - this IEnumerable first, - IEnumerable second, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return EquiZipImpl(first, second, null, null, (a, b, c, d) => resultSelector(a, b)); - } - - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. An exception is thrown - /// if the input sequences are of different lengths. - /// - /// Type of elements in first sequence. - /// Type of elements in second sequence. - /// Type of elements in third sequence. - /// Type of elements in result sequence. - /// The first sequence. - /// The second sequence. - /// The third sequence. - /// - /// Function to apply to each triplet of elements. - /// - /// A sequence that contains elements of the three input sequences, - /// combined by . - /// - /// - /// The input sequences are of different lengths. - /// - /// - /// n + l + c); - /// ]]> - /// The zipped variable, when iterated over, will yield "1Aa", - /// "2Bb", "3Cc", "4Dd" in turn. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable EquiZip( - this IEnumerable first, - IEnumerable second, IEnumerable third, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (third == null) throw new ArgumentNullException(nameof(third)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return EquiZipImpl(first, second, third, null, (a, b, c, _) => resultSelector(a, b, c)); - } - - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. An exception is thrown - /// if the input sequences are of different lengths. - /// - /// Type of elements in first sequence - /// Type of elements in second sequence - /// Type of elements in third sequence - /// Type of elements in fourth sequence - /// Type of elements in result sequence - /// The first sequence. - /// The second sequence. - /// The third sequence. - /// The fourth sequence. - /// - /// Function to apply to each quadruplet of elements. - /// - /// A sequence that contains elements of the four input sequences, - /// combined by . - /// - /// - /// The input sequences are of different lengths. - /// - /// - /// n + l + c + f); - /// ]]> - /// The zipped variable, when iterated over, will yield "1AaTrue", - /// "2BbFalse", "3CcTrue", "4DdFalse" in turn. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable EquiZip( - this IEnumerable first, - IEnumerable second, IEnumerable third, IEnumerable fourth, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (third == null) throw new ArgumentNullException(nameof(third)); - if (fourth == null) throw new ArgumentNullException(nameof(fourth)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return EquiZipImpl(first, second, third, fourth, resultSelector); - } - - static IEnumerable EquiZipImpl( - IEnumerable s1, - IEnumerable s2, - IEnumerable s3, - IEnumerable s4, - Func resultSelector) - { - Debug.Assert(s1 != null); - Debug.Assert(s2 != null); - - const int zero = 0, one = 1; - - var limit = 1 + (s3 != null ? one : zero) - + (s4 != null ? one : zero); - - return ZipImpl(s1, s2, s3, s4, resultSelector, limit, enumerators => - { - var i = enumerators.Index().First(x => x.Value == null).Key; - return new InvalidOperationException(OrdinalNumbers[i] + " sequence too short."); - }); - } - - static readonly string[] OrdinalNumbers = - { - "First", - "Second", - "Third", - "Fourth", - // "Fifth", - // "Sixth", - // "Seventh", - // "Eighth", - // "Ninth", - // "Tenth", - // "Eleventh", - // "Twelfth", - // "Thirteenth", - // "Fourteenth", - // "Fifteenth", - // "Sixteenth", - }; - } -} diff --git a/MoreLinq/Extensions.g.cs b/MoreLinq/Extensions.g.cs index 9c0485718..acd6a1d69 100644 --- a/MoreLinq/Extensions.g.cs +++ b/MoreLinq/Extensions.g.cs @@ -650,7 +650,21 @@ public static partial class BatchExtension /// Size of buckets. /// A sequence of equally sized buckets containing elements of the source collection. /// - /// This operator uses deferred execution and streams its results (buckets and bucket content). + /// + /// This operator uses deferred execution and streams its results + /// (buckets are streamed but their content buffered). + /// + /// When more than one bucket is streamed, all buckets except the last + /// is guaranteed to have elements. The last + /// bucket may be smaller depending on the remaining elements in the + /// sequence. + /// + /// Each bucket is pre-allocated to elements. + /// If is set to a very large value, e.g. + /// to effectively disable batching by just + /// hoping for a single bucket, then it can lead to memory exhaustion + /// (). + /// /// public static IEnumerable> Batch(this IEnumerable source, int size) @@ -665,9 +679,21 @@ public static IEnumerable> Batch(this IEnumerable< /// Size of buckets. /// The projection to apply to each bucket. /// A sequence of projections on equally sized buckets containing elements of the source collection. - /// - /// This operator uses deferred execution and streams its results (buckets and bucket content). - /// + /// + /// This operator uses deferred execution and streams its results + /// (buckets are streamed but their content buffered). + /// + /// + /// When more than one bucket is streamed, all buckets except the last + /// is guaranteed to have elements. The last + /// bucket may be smaller depending on the remaining elements in the + /// sequence. + /// Each bucket is pre-allocated to elements. + /// If is set to a very large value, e.g. + /// to effectively disable batching by just + /// hoping for a single bucket, then it can lead to memory exhaustion + /// (). + /// public static IEnumerable Batch(this IEnumerable source, int size, Func, TResult> resultSelector) @@ -1298,128 +1324,481 @@ public static bool EndsWith(this IEnumerable first, IEnumerable second, [GeneratedCode("MoreLinq.ExtensionsGenerator", "1.0.0.0")] public static partial class EquiZipExtension { + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// The first source sequence. + /// The second source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable<(T1, T2)> EquiZip( + this IEnumerable firstSource, + IEnumerable secondSource) + => MoreEnumerable.EquiZip(firstSource, secondSource); + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable<(T1, T2, T3)> EquiZip( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource) + => MoreEnumerable.EquiZip(firstSource, secondSource, thirdSource); /// /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. An exception is thrown + /// element from each of the input sequences. An exception is thrown /// if the input sequences are of different lengths. /// - /// Type of elements in first sequence. - /// Type of elements in second sequence. + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. /// Type of elements in result sequence. - /// The first sequence. - /// The second sequence. + /// The first source sequence. + /// The second source sequence. /// - /// Function to apply to each pair of elements. + /// Function to apply to each tuple of elements. /// - /// A sequence that contains elements of the two input sequences, - /// combined by . - /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. /// /// The input sequences are of different lengths. /// - /// - /// n + l); - /// ]]> - /// The zipped variable, when iterated over, will yield "1A", - /// "2B", "3C", "4D" in turn. - /// /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable EquiZip( + this IEnumerable firstSource, + IEnumerable secondSource, + Func resultSelector) + => MoreEnumerable.EquiZip(firstSource, secondSource, resultSelector); - public static IEnumerable EquiZip( - this IEnumerable first, - IEnumerable second, - Func resultSelector) - => MoreEnumerable.EquiZip(first, second, resultSelector); + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable<(T1, T2, T3, T4)> EquiZip( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource) + => MoreEnumerable.EquiZip(firstSource, secondSource, thirdSource, fourthSource); /// /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. An exception is thrown + /// element from each of the input sequences. An exception is thrown /// if the input sequences are of different lengths. /// - /// Type of elements in first sequence. - /// Type of elements in second sequence. - /// Type of elements in third sequence. + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. /// Type of elements in result sequence. - /// The first sequence. - /// The second sequence. - /// The third sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. /// - /// Function to apply to each triplet of elements. + /// Function to apply to each tuple of elements. /// - /// A sequence that contains elements of the three input sequences, - /// combined by . - /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. /// /// The input sequences are of different lengths. /// - /// - /// n + l + c); - /// ]]> - /// The zipped variable, when iterated over, will yield "1Aa", - /// "2Bb", "3Cc", "4Dd" in turn. - /// /// /// This operator uses deferred execution and streams its results. /// - public static IEnumerable EquiZip( - this IEnumerable first, - IEnumerable second, IEnumerable third, + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, Func resultSelector) - => MoreEnumerable.EquiZip(first, second, third, resultSelector); + => MoreEnumerable.EquiZip(firstSource, secondSource, thirdSource, resultSelector); + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable<(T1, T2, T3, T4, T5)> EquiZip( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource) + => MoreEnumerable.EquiZip(firstSource, secondSource, thirdSource, fourthSource, fifthSource); /// /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. An exception is thrown + /// element from each of the input sequences. An exception is thrown /// if the input sequences are of different lengths. /// - /// Type of elements in first sequence - /// Type of elements in second sequence - /// Type of elements in third sequence - /// Type of elements in fourth sequence - /// Type of elements in result sequence - /// The first sequence. - /// The second sequence. - /// The third sequence. - /// The fourth sequence. + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. /// - /// Function to apply to each quadruplet of elements. + /// Function to apply to each tuple of elements. /// - /// A sequence that contains elements of the four input sequences, - /// combined by . - /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. /// /// The input sequences are of different lengths. /// - /// - /// n + l + c + f); - /// ]]> - /// The zipped variable, when iterated over, will yield "1AaTrue", - /// "2BbFalse", "3CcTrue", "4DdFalse" in turn. - /// /// /// This operator uses deferred execution and streams its results. /// - public static IEnumerable EquiZip( - this IEnumerable first, - IEnumerable second, IEnumerable third, IEnumerable fourth, + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, Func resultSelector) - => MoreEnumerable.EquiZip(first, second, third, fourth, resultSelector); + => MoreEnumerable.EquiZip(firstSource, secondSource, thirdSource, fourthSource, resultSelector); + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable<(T1, T2, T3, T4, T5, T6)> EquiZip( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource) + => MoreEnumerable.EquiZip(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource); + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable EquiZip( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + Func resultSelector) + => MoreEnumerable.EquiZip(firstSource, secondSource, thirdSource, fourthSource, fifthSource, resultSelector); + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7)> EquiZip( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + IEnumerable seventhSource) + => MoreEnumerable.EquiZip(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, seventhSource); + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable EquiZip( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + Func resultSelector) + => MoreEnumerable.EquiZip(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, resultSelector); + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// Type of elements in eighth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7, T8)> EquiZip( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + IEnumerable seventhSource, + IEnumerable eighthSource) + => MoreEnumerable.EquiZip(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, seventhSource, eighthSource); + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable EquiZip( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + IEnumerable seventhSource, + Func resultSelector) + => MoreEnumerable.EquiZip(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, seventhSource, resultSelector); + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// Type of elements in eighth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable EquiZip( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + IEnumerable seventhSource, + IEnumerable eighthSource, + Func resultSelector) + => MoreEnumerable.EquiZip(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, seventhSource, eighthSource, resultSelector); } @@ -6761,159 +7140,489 @@ public static IEnumerable> WindowRight(this IEnumerable< [GeneratedCode("MoreLinq.ExtensionsGenerator", "1.0.0.0")] public static partial class ZipLongestExtension { + /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. The resulting sequence + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence /// will always be as long as the longest of input sequences where the /// default value of each of the shorter sequence element types is used /// for padding. /// - /// Type of elements in first sequence. - /// Type of elements in second sequence. - /// Type of elements in result sequence. - /// The first sequence. - /// The second sequence. - /// - /// Function to apply to each pair of elements. + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// The first source sequence. + /// The second source sequence. /// - /// A sequence that contains elements of the two input sequences, - /// combined by . - /// - /// - /// n + l); - /// ]]> - /// The zipped variable, when iterated over, will yield "1A", - /// "2B", "3C", "0D" in turn. - /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable<(T1, T2)> ZipLongest( + this IEnumerable firstSource, + IEnumerable secondSource) + => MoreEnumerable.ZipLongest(firstSource, secondSource); - public static IEnumerable ZipLongest( - this IEnumerable first, - IEnumerable second, - Func resultSelector) - => MoreEnumerable.ZipLongest(first, second, resultSelector); + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable<(T1, T2, T3)> ZipLongest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource) + => MoreEnumerable.ZipLongest(firstSource, secondSource, thirdSource); /// /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. The resulting sequence + /// element from each of the input sequences. The resulting sequence /// will always be as long as the longest of input sequences where the /// default value of each of the shorter sequence element types is used /// for padding. /// - /// Type of elements in first sequence. - /// Type of elements in second sequence. - /// Type of elements in third sequence. + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. /// Type of elements in result sequence. - /// The first sequence. - /// The second sequence. - /// The third sequence. + /// The first source sequence. + /// The second source sequence. /// - /// Function to apply to each triplet of elements. + /// Function to apply to each tuple of elements. /// - /// A sequence that contains elements of the three input sequences, - /// combined by . - /// - /// - /// n + l + c); - /// ]]> - /// The zipped variable, when iterated over, will yield "1Aa", - /// "2Bb", "3Cc", "0Dd", "0e" in turn. - /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. /// /// This operator uses deferred execution and streams its results. /// - - public static IEnumerable ZipLongest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - Func resultSelector) - => MoreEnumerable.ZipLongest(first, second, third, resultSelector); + public static IEnumerable ZipLongest( + this IEnumerable firstSource, + IEnumerable secondSource, + Func resultSelector) + => MoreEnumerable.ZipLongest(firstSource, secondSource, resultSelector); /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. The resulting sequence + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence /// will always be as long as the longest of input sequences where the /// default value of each of the shorter sequence element types is used /// for padding. /// - /// Type of elements in first sequence - /// Type of elements in second sequence - /// Type of elements in third sequence - /// Type of elements in fourth sequence - /// Type of elements in result sequence - /// The first sequence. - /// The second sequence. - /// The third sequence. - /// The fourth sequence. - /// - /// Function to apply to each quadruplet of elements. + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. /// - /// A sequence that contains elements of the four input sequences, - /// combined by . - /// - /// - /// n + l + c + f); - /// ]]> - /// The zipped variable, when iterated over, will yield "1AaTrue", - /// "2BbFalse", "3CcTrue", "0DdFalse", "0eTrue", "0\0False" in turn. - /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable<(T1, T2, T3, T4)> ZipLongest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource) + => MoreEnumerable.ZipLongest(firstSource, secondSource, thirdSource, fourthSource); - public static IEnumerable ZipLongest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - Func resultSelector) - => MoreEnumerable.ZipLongest(first, second, third, fourth, resultSelector); - - } - - /// ZipShortest extension. - - [GeneratedCode("MoreLinq.ExtensionsGenerator", "1.0.0.0")] - public static partial class ZipShortestExtension - { /// /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. The resulting sequence - /// is as short as the shortest input sequence. + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. /// - /// Type of elements in first sequence. - /// Type of elements in second sequence. + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. /// Type of elements in result sequence. - /// The first sequence. - /// The second sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. /// - /// Function to apply to each pair of elements. + /// Function to apply to each tuple of elements. /// /// A projection of tuples, where each tuple contains the N-th element /// from each of the argument sequences. - /// - /// n + l); - /// ]]> - /// The zipped variable, when iterated over, will yield "1A", "2B", "3C", in turn. - /// + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable ZipLongest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + Func resultSelector) + => MoreEnumerable.ZipLongest(firstSource, secondSource, thirdSource, resultSelector); + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable<(T1, T2, T3, T4, T5)> ZipLongest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource) + => MoreEnumerable.ZipLongest(firstSource, secondSource, thirdSource, fourthSource, fifthSource); + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable ZipLongest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + Func resultSelector) + => MoreEnumerable.ZipLongest(firstSource, secondSource, thirdSource, fourthSource, resultSelector); + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable<(T1, T2, T3, T4, T5, T6)> ZipLongest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource) + => MoreEnumerable.ZipLongest(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource); + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable ZipLongest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + Func resultSelector) + => MoreEnumerable.ZipLongest(firstSource, secondSource, thirdSource, fourthSource, fifthSource, resultSelector); + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7)> ZipLongest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + IEnumerable seventhSource) + => MoreEnumerable.ZipLongest(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, seventhSource); + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable ZipLongest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + Func resultSelector) + => MoreEnumerable.ZipLongest(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, resultSelector); + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// Type of elements in eighth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7, T8)> ZipLongest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + IEnumerable seventhSource, + IEnumerable eighthSource) + => MoreEnumerable.ZipLongest(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, seventhSource, eighthSource); + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable ZipLongest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + IEnumerable seventhSource, + Func resultSelector) + => MoreEnumerable.ZipLongest(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, seventhSource, resultSelector); + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// Type of elements in eighth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable ZipLongest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + IEnumerable seventhSource, + IEnumerable eighthSource, + Func resultSelector) + => MoreEnumerable.ZipLongest(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, seventhSource, eighthSource, resultSelector); + + } + + /// ZipShortest extension. + + [GeneratedCode("MoreLinq.ExtensionsGenerator", "1.0.0.0")] + public static partial class ZipShortestExtension + { + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// The first source sequence. + /// The second source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. /// /// /// If the input sequences are of different lengths, the result sequence @@ -6924,39 +7633,122 @@ public static partial class ZipShortestExtension /// This operator uses deferred execution and streams its results. /// - public static IEnumerable ZipShortest( - this IEnumerable first, - IEnumerable second, - Func resultSelector) - => MoreEnumerable.ZipShortest(first, second, resultSelector); + public static IEnumerable<(T1, T2)> ZipShortest( + this IEnumerable firstSource, + IEnumerable secondSource) + => MoreEnumerable.ZipShortest(firstSource, secondSource); + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3)> ZipShortest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource) + => MoreEnumerable.ZipShortest(firstSource, secondSource, thirdSource); /// /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. The resulting sequence + /// element from each of the input sequences. The resulting sequence /// is as short as the shortest input sequence. /// - /// Type of elements in first sequence. - /// Type of elements in second sequence. - /// Type of elements in third sequence. + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. /// Type of elements in result sequence. - /// First sequence - /// Second sequence - /// Third sequence + /// The first source sequence. + /// The second source sequence. /// - /// Function to apply to each triplet of elements. + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipShortest( + this IEnumerable firstSource, + IEnumerable secondSource, + Func resultSelector) + => MoreEnumerable.ZipShortest(firstSource, secondSource, resultSelector); + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3, T4)> ZipShortest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource) + => MoreEnumerable.ZipShortest(firstSource, secondSource, thirdSource, fourthSource); + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// + /// Function to apply to each tuple of elements. /// /// A projection of tuples, where each tuple contains the N-th element /// from each of the argument sequences. - /// - /// c + n + l); - /// ]]> - /// The zipped variable, when iterated over, will yield - /// "98A", "100B", "102C", in turn. - /// /// /// /// If the input sequences are of different lengths, the result sequence @@ -6968,42 +7760,67 @@ public static IEnumerable ZipShortest( /// public static IEnumerable ZipShortest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, Func resultSelector) - => MoreEnumerable.ZipShortest(first, second, third, resultSelector); + => MoreEnumerable.ZipShortest(firstSource, secondSource, thirdSource, resultSelector); + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3, T4, T5)> ZipShortest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource) + => MoreEnumerable.ZipShortest(firstSource, secondSource, thirdSource, fourthSource, fifthSource); /// /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. The resulting sequence + /// element from each of the input sequences. The resulting sequence /// is as short as the shortest input sequence. /// - /// Type of elements in first sequence. - /// Type of elements in second sequence. - /// Type of elements in third sequence. - /// Type of elements in fourth sequence. + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. /// Type of elements in result sequence. - /// The first sequence. - /// The second sequence. - /// The third sequence. - /// The fourth sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. /// - /// Function to apply to each quadruplet of elements. + /// Function to apply to each tuple of elements. /// /// A projection of tuples, where each tuple contains the N-th element /// from each of the argument sequences. - /// - /// n + l + c + f); - /// ]]> - /// The zipped variable, when iterated over, will yield - /// "1AaTrue", "2BbFalse" in turn. - /// /// /// /// If the input sequences are of different lengths, the result sequence @@ -7015,12 +7832,316 @@ public static IEnumerable ZipShortest( /// public static IEnumerable ZipShortest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, Func resultSelector) - => MoreEnumerable.ZipShortest(first, second, third, fourth, resultSelector); + => MoreEnumerable.ZipShortest(firstSource, secondSource, thirdSource, fourthSource, resultSelector); + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3, T4, T5, T6)> ZipShortest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource) + => MoreEnumerable.ZipShortest(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource); + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipShortest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + Func resultSelector) + => MoreEnumerable.ZipShortest(firstSource, secondSource, thirdSource, fourthSource, fifthSource, resultSelector); + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7)> ZipShortest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + IEnumerable seventhSource) + => MoreEnumerable.ZipShortest(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, seventhSource); + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipShortest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + Func resultSelector) + => MoreEnumerable.ZipShortest(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, resultSelector); + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// Type of elements in eighth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7, T8)> ZipShortest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + IEnumerable seventhSource, + IEnumerable eighthSource) + => MoreEnumerable.ZipShortest(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, seventhSource, eighthSource); + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipShortest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + IEnumerable seventhSource, + Func resultSelector) + => MoreEnumerable.ZipShortest(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, seventhSource, resultSelector); + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// Type of elements in eighth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipShortest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + IEnumerable seventhSource, + IEnumerable eighthSource, + Func resultSelector) + => MoreEnumerable.ZipShortest(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, seventhSource, eighthSource, resultSelector); } } diff --git a/MoreLinq/MoreLinq.csproj b/MoreLinq/MoreLinq.csproj index 551c30fc1..db2b6cc08 100644 --- a/MoreLinq/MoreLinq.csproj +++ b/MoreLinq/MoreLinq.csproj @@ -171,6 +171,10 @@ TextTemplatingFileGenerator ToDelimitedString.g.cs + + TextTemplatingFileGenerator + Zip.g.cs + @@ -235,6 +239,11 @@ True ToDelimitedString.g.tt + + True + True + Zip.g.tt + diff --git a/MoreLinq/Zip.g.cs b/MoreLinq/Zip.g.cs new file mode 100644 index 000000000..c2ace5253 --- /dev/null +++ b/MoreLinq/Zip.g.cs @@ -0,0 +1,2660 @@ +#region License and Terms +// MoreLINQ - Extensions to LINQ to Objects +// Copyright (c) 2019 Pierre Lando. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +namespace MoreLinq +{ + using System; + using System.Collections.Generic; + + static partial class MoreEnumerable + { + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable EquiZip( + this IEnumerable firstSource, + IEnumerable secondSource, + Func resultSelector) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return CustomZip( + firstSource, ZipSourceConfiguration.ThrowOnShort, + secondSource, ZipSourceConfiguration.ThrowOnShort, + resultSelector); + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// The first source sequence. + /// The second source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable<(T1, T2)> EquiZip( + this IEnumerable firstSource, + IEnumerable secondSource) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + + return CustomZip( + firstSource, ZipSourceConfiguration.ThrowOnShort, + secondSource, ZipSourceConfiguration.ThrowOnShort, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable ZipLongest( + this IEnumerable firstSource, + IEnumerable secondSource, + Func resultSelector) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return CustomZip( + firstSource, ZipSourceConfiguration.PaddingWith(default), + secondSource, ZipSourceConfiguration.PaddingWith(default), + resultSelector); + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// The first source sequence. + /// The second source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable<(T1, T2)> ZipLongest( + this IEnumerable firstSource, + IEnumerable secondSource) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + + return CustomZip( + firstSource, ZipSourceConfiguration.PaddingWith(default), + secondSource, ZipSourceConfiguration.PaddingWith(default), + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipShortest( + this IEnumerable firstSource, + IEnumerable secondSource, + Func resultSelector) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return CustomZip( + firstSource, ZipSourceConfiguration.StopOnShort, + secondSource, ZipSourceConfiguration.StopOnShort, + resultSelector); + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// The first source sequence. + /// The second source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2)> ZipShortest( + this IEnumerable firstSource, + IEnumerable secondSource) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + + return CustomZip( + firstSource, ZipSourceConfiguration.StopOnShort, + secondSource, ZipSourceConfiguration.StopOnShort, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable EquiZip( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + Func resultSelector) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return CustomZip( + firstSource, ZipSourceConfiguration.ThrowOnShort, + secondSource, ZipSourceConfiguration.ThrowOnShort, + thirdSource, ZipSourceConfiguration.ThrowOnShort, + resultSelector); + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable<(T1, T2, T3)> EquiZip( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + + return CustomZip( + firstSource, ZipSourceConfiguration.ThrowOnShort, + secondSource, ZipSourceConfiguration.ThrowOnShort, + thirdSource, ZipSourceConfiguration.ThrowOnShort, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable ZipLongest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + Func resultSelector) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return CustomZip( + firstSource, ZipSourceConfiguration.PaddingWith(default), + secondSource, ZipSourceConfiguration.PaddingWith(default), + thirdSource, ZipSourceConfiguration.PaddingWith(default), + resultSelector); + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable<(T1, T2, T3)> ZipLongest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + + return CustomZip( + firstSource, ZipSourceConfiguration.PaddingWith(default), + secondSource, ZipSourceConfiguration.PaddingWith(default), + thirdSource, ZipSourceConfiguration.PaddingWith(default), + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipShortest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + Func resultSelector) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return CustomZip( + firstSource, ZipSourceConfiguration.StopOnShort, + secondSource, ZipSourceConfiguration.StopOnShort, + thirdSource, ZipSourceConfiguration.StopOnShort, + resultSelector); + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3)> ZipShortest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + + return CustomZip( + firstSource, ZipSourceConfiguration.StopOnShort, + secondSource, ZipSourceConfiguration.StopOnShort, + thirdSource, ZipSourceConfiguration.StopOnShort, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable EquiZip( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + Func resultSelector) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return CustomZip( + firstSource, ZipSourceConfiguration.ThrowOnShort, + secondSource, ZipSourceConfiguration.ThrowOnShort, + thirdSource, ZipSourceConfiguration.ThrowOnShort, + fourthSource, ZipSourceConfiguration.ThrowOnShort, + resultSelector); + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable<(T1, T2, T3, T4)> EquiZip( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + + return CustomZip( + firstSource, ZipSourceConfiguration.ThrowOnShort, + secondSource, ZipSourceConfiguration.ThrowOnShort, + thirdSource, ZipSourceConfiguration.ThrowOnShort, + fourthSource, ZipSourceConfiguration.ThrowOnShort, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable ZipLongest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + Func resultSelector) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return CustomZip( + firstSource, ZipSourceConfiguration.PaddingWith(default), + secondSource, ZipSourceConfiguration.PaddingWith(default), + thirdSource, ZipSourceConfiguration.PaddingWith(default), + fourthSource, ZipSourceConfiguration.PaddingWith(default), + resultSelector); + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable<(T1, T2, T3, T4)> ZipLongest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + + return CustomZip( + firstSource, ZipSourceConfiguration.PaddingWith(default), + secondSource, ZipSourceConfiguration.PaddingWith(default), + thirdSource, ZipSourceConfiguration.PaddingWith(default), + fourthSource, ZipSourceConfiguration.PaddingWith(default), + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipShortest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + Func resultSelector) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return CustomZip( + firstSource, ZipSourceConfiguration.StopOnShort, + secondSource, ZipSourceConfiguration.StopOnShort, + thirdSource, ZipSourceConfiguration.StopOnShort, + fourthSource, ZipSourceConfiguration.StopOnShort, + resultSelector); + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3, T4)> ZipShortest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + + return CustomZip( + firstSource, ZipSourceConfiguration.StopOnShort, + secondSource, ZipSourceConfiguration.StopOnShort, + thirdSource, ZipSourceConfiguration.StopOnShort, + fourthSource, ZipSourceConfiguration.StopOnShort, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable EquiZip( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + Func resultSelector) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return CustomZip( + firstSource, ZipSourceConfiguration.ThrowOnShort, + secondSource, ZipSourceConfiguration.ThrowOnShort, + thirdSource, ZipSourceConfiguration.ThrowOnShort, + fourthSource, ZipSourceConfiguration.ThrowOnShort, + fifthSource, ZipSourceConfiguration.ThrowOnShort, + resultSelector); + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable<(T1, T2, T3, T4, T5)> EquiZip( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); + + return CustomZip( + firstSource, ZipSourceConfiguration.ThrowOnShort, + secondSource, ZipSourceConfiguration.ThrowOnShort, + thirdSource, ZipSourceConfiguration.ThrowOnShort, + fourthSource, ZipSourceConfiguration.ThrowOnShort, + fifthSource, ZipSourceConfiguration.ThrowOnShort, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable ZipLongest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + Func resultSelector) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return CustomZip( + firstSource, ZipSourceConfiguration.PaddingWith(default), + secondSource, ZipSourceConfiguration.PaddingWith(default), + thirdSource, ZipSourceConfiguration.PaddingWith(default), + fourthSource, ZipSourceConfiguration.PaddingWith(default), + fifthSource, ZipSourceConfiguration.PaddingWith(default), + resultSelector); + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable<(T1, T2, T3, T4, T5)> ZipLongest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); + + return CustomZip( + firstSource, ZipSourceConfiguration.PaddingWith(default), + secondSource, ZipSourceConfiguration.PaddingWith(default), + thirdSource, ZipSourceConfiguration.PaddingWith(default), + fourthSource, ZipSourceConfiguration.PaddingWith(default), + fifthSource, ZipSourceConfiguration.PaddingWith(default), + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipShortest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + Func resultSelector) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return CustomZip( + firstSource, ZipSourceConfiguration.StopOnShort, + secondSource, ZipSourceConfiguration.StopOnShort, + thirdSource, ZipSourceConfiguration.StopOnShort, + fourthSource, ZipSourceConfiguration.StopOnShort, + fifthSource, ZipSourceConfiguration.StopOnShort, + resultSelector); + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3, T4, T5)> ZipShortest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); + + return CustomZip( + firstSource, ZipSourceConfiguration.StopOnShort, + secondSource, ZipSourceConfiguration.StopOnShort, + thirdSource, ZipSourceConfiguration.StopOnShort, + fourthSource, ZipSourceConfiguration.StopOnShort, + fifthSource, ZipSourceConfiguration.StopOnShort, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable EquiZip( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + Func resultSelector) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); + if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return CustomZip( + firstSource, ZipSourceConfiguration.ThrowOnShort, + secondSource, ZipSourceConfiguration.ThrowOnShort, + thirdSource, ZipSourceConfiguration.ThrowOnShort, + fourthSource, ZipSourceConfiguration.ThrowOnShort, + fifthSource, ZipSourceConfiguration.ThrowOnShort, + sixthSource, ZipSourceConfiguration.ThrowOnShort, + resultSelector); + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable<(T1, T2, T3, T4, T5, T6)> EquiZip( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); + if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); + + return CustomZip( + firstSource, ZipSourceConfiguration.ThrowOnShort, + secondSource, ZipSourceConfiguration.ThrowOnShort, + thirdSource, ZipSourceConfiguration.ThrowOnShort, + fourthSource, ZipSourceConfiguration.ThrowOnShort, + fifthSource, ZipSourceConfiguration.ThrowOnShort, + sixthSource, ZipSourceConfiguration.ThrowOnShort, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable ZipLongest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + Func resultSelector) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); + if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return CustomZip( + firstSource, ZipSourceConfiguration.PaddingWith(default), + secondSource, ZipSourceConfiguration.PaddingWith(default), + thirdSource, ZipSourceConfiguration.PaddingWith(default), + fourthSource, ZipSourceConfiguration.PaddingWith(default), + fifthSource, ZipSourceConfiguration.PaddingWith(default), + sixthSource, ZipSourceConfiguration.PaddingWith(default), + resultSelector); + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable<(T1, T2, T3, T4, T5, T6)> ZipLongest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); + if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); + + return CustomZip( + firstSource, ZipSourceConfiguration.PaddingWith(default), + secondSource, ZipSourceConfiguration.PaddingWith(default), + thirdSource, ZipSourceConfiguration.PaddingWith(default), + fourthSource, ZipSourceConfiguration.PaddingWith(default), + fifthSource, ZipSourceConfiguration.PaddingWith(default), + sixthSource, ZipSourceConfiguration.PaddingWith(default), + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipShortest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + Func resultSelector) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); + if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return CustomZip( + firstSource, ZipSourceConfiguration.StopOnShort, + secondSource, ZipSourceConfiguration.StopOnShort, + thirdSource, ZipSourceConfiguration.StopOnShort, + fourthSource, ZipSourceConfiguration.StopOnShort, + fifthSource, ZipSourceConfiguration.StopOnShort, + sixthSource, ZipSourceConfiguration.StopOnShort, + resultSelector); + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3, T4, T5, T6)> ZipShortest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); + if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); + + return CustomZip( + firstSource, ZipSourceConfiguration.StopOnShort, + secondSource, ZipSourceConfiguration.StopOnShort, + thirdSource, ZipSourceConfiguration.StopOnShort, + fourthSource, ZipSourceConfiguration.StopOnShort, + fifthSource, ZipSourceConfiguration.StopOnShort, + sixthSource, ZipSourceConfiguration.StopOnShort, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable EquiZip( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + IEnumerable seventhSource, + Func resultSelector) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); + if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); + if (seventhSource == null) throw new ArgumentNullException(nameof(seventhSource)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return CustomZip( + firstSource, ZipSourceConfiguration.ThrowOnShort, + secondSource, ZipSourceConfiguration.ThrowOnShort, + thirdSource, ZipSourceConfiguration.ThrowOnShort, + fourthSource, ZipSourceConfiguration.ThrowOnShort, + fifthSource, ZipSourceConfiguration.ThrowOnShort, + sixthSource, ZipSourceConfiguration.ThrowOnShort, + seventhSource, ZipSourceConfiguration.ThrowOnShort, + resultSelector); + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7)> EquiZip( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + IEnumerable seventhSource) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); + if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); + if (seventhSource == null) throw new ArgumentNullException(nameof(seventhSource)); + + return CustomZip( + firstSource, ZipSourceConfiguration.ThrowOnShort, + secondSource, ZipSourceConfiguration.ThrowOnShort, + thirdSource, ZipSourceConfiguration.ThrowOnShort, + fourthSource, ZipSourceConfiguration.ThrowOnShort, + fifthSource, ZipSourceConfiguration.ThrowOnShort, + sixthSource, ZipSourceConfiguration.ThrowOnShort, + seventhSource, ZipSourceConfiguration.ThrowOnShort, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable ZipLongest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + IEnumerable seventhSource, + Func resultSelector) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); + if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); + if (seventhSource == null) throw new ArgumentNullException(nameof(seventhSource)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return CustomZip( + firstSource, ZipSourceConfiguration.PaddingWith(default), + secondSource, ZipSourceConfiguration.PaddingWith(default), + thirdSource, ZipSourceConfiguration.PaddingWith(default), + fourthSource, ZipSourceConfiguration.PaddingWith(default), + fifthSource, ZipSourceConfiguration.PaddingWith(default), + sixthSource, ZipSourceConfiguration.PaddingWith(default), + seventhSource, ZipSourceConfiguration.PaddingWith(default), + resultSelector); + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7)> ZipLongest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + IEnumerable seventhSource) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); + if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); + if (seventhSource == null) throw new ArgumentNullException(nameof(seventhSource)); + + return CustomZip( + firstSource, ZipSourceConfiguration.PaddingWith(default), + secondSource, ZipSourceConfiguration.PaddingWith(default), + thirdSource, ZipSourceConfiguration.PaddingWith(default), + fourthSource, ZipSourceConfiguration.PaddingWith(default), + fifthSource, ZipSourceConfiguration.PaddingWith(default), + sixthSource, ZipSourceConfiguration.PaddingWith(default), + seventhSource, ZipSourceConfiguration.PaddingWith(default), + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipShortest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + IEnumerable seventhSource, + Func resultSelector) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); + if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); + if (seventhSource == null) throw new ArgumentNullException(nameof(seventhSource)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return CustomZip( + firstSource, ZipSourceConfiguration.StopOnShort, + secondSource, ZipSourceConfiguration.StopOnShort, + thirdSource, ZipSourceConfiguration.StopOnShort, + fourthSource, ZipSourceConfiguration.StopOnShort, + fifthSource, ZipSourceConfiguration.StopOnShort, + sixthSource, ZipSourceConfiguration.StopOnShort, + seventhSource, ZipSourceConfiguration.StopOnShort, + resultSelector); + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7)> ZipShortest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + IEnumerable seventhSource) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); + if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); + if (seventhSource == null) throw new ArgumentNullException(nameof(seventhSource)); + + return CustomZip( + firstSource, ZipSourceConfiguration.StopOnShort, + secondSource, ZipSourceConfiguration.StopOnShort, + thirdSource, ZipSourceConfiguration.StopOnShort, + fourthSource, ZipSourceConfiguration.StopOnShort, + fifthSource, ZipSourceConfiguration.StopOnShort, + sixthSource, ZipSourceConfiguration.StopOnShort, + seventhSource, ZipSourceConfiguration.StopOnShort, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// Type of elements in eighth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable EquiZip( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + IEnumerable seventhSource, + IEnumerable eighthSource, + Func resultSelector) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); + if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); + if (seventhSource == null) throw new ArgumentNullException(nameof(seventhSource)); + if (eighthSource == null) throw new ArgumentNullException(nameof(eighthSource)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return CustomZip( + firstSource, ZipSourceConfiguration.ThrowOnShort, + secondSource, ZipSourceConfiguration.ThrowOnShort, + thirdSource, ZipSourceConfiguration.ThrowOnShort, + fourthSource, ZipSourceConfiguration.ThrowOnShort, + fifthSource, ZipSourceConfiguration.ThrowOnShort, + sixthSource, ZipSourceConfiguration.ThrowOnShort, + seventhSource, ZipSourceConfiguration.ThrowOnShort, + eighthSource, ZipSourceConfiguration.ThrowOnShort, + resultSelector); + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// Type of elements in eighth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7, T8)> EquiZip( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + IEnumerable seventhSource, + IEnumerable eighthSource) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); + if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); + if (seventhSource == null) throw new ArgumentNullException(nameof(seventhSource)); + if (eighthSource == null) throw new ArgumentNullException(nameof(eighthSource)); + + return CustomZip( + firstSource, ZipSourceConfiguration.ThrowOnShort, + secondSource, ZipSourceConfiguration.ThrowOnShort, + thirdSource, ZipSourceConfiguration.ThrowOnShort, + fourthSource, ZipSourceConfiguration.ThrowOnShort, + fifthSource, ZipSourceConfiguration.ThrowOnShort, + sixthSource, ZipSourceConfiguration.ThrowOnShort, + seventhSource, ZipSourceConfiguration.ThrowOnShort, + eighthSource, ZipSourceConfiguration.ThrowOnShort, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// Type of elements in eighth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable ZipLongest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + IEnumerable seventhSource, + IEnumerable eighthSource, + Func resultSelector) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); + if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); + if (seventhSource == null) throw new ArgumentNullException(nameof(seventhSource)); + if (eighthSource == null) throw new ArgumentNullException(nameof(eighthSource)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return CustomZip( + firstSource, ZipSourceConfiguration.PaddingWith(default), + secondSource, ZipSourceConfiguration.PaddingWith(default), + thirdSource, ZipSourceConfiguration.PaddingWith(default), + fourthSource, ZipSourceConfiguration.PaddingWith(default), + fifthSource, ZipSourceConfiguration.PaddingWith(default), + sixthSource, ZipSourceConfiguration.PaddingWith(default), + seventhSource, ZipSourceConfiguration.PaddingWith(default), + eighthSource, ZipSourceConfiguration.PaddingWith(default), + resultSelector); + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// Type of elements in eighth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7, T8)> ZipLongest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + IEnumerable seventhSource, + IEnumerable eighthSource) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); + if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); + if (seventhSource == null) throw new ArgumentNullException(nameof(seventhSource)); + if (eighthSource == null) throw new ArgumentNullException(nameof(eighthSource)); + + return CustomZip( + firstSource, ZipSourceConfiguration.PaddingWith(default), + secondSource, ZipSourceConfiguration.PaddingWith(default), + thirdSource, ZipSourceConfiguration.PaddingWith(default), + fourthSource, ZipSourceConfiguration.PaddingWith(default), + fifthSource, ZipSourceConfiguration.PaddingWith(default), + sixthSource, ZipSourceConfiguration.PaddingWith(default), + seventhSource, ZipSourceConfiguration.PaddingWith(default), + eighthSource, ZipSourceConfiguration.PaddingWith(default), + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// Type of elements in eighth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipShortest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + IEnumerable seventhSource, + IEnumerable eighthSource, + Func resultSelector) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); + if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); + if (seventhSource == null) throw new ArgumentNullException(nameof(seventhSource)); + if (eighthSource == null) throw new ArgumentNullException(nameof(eighthSource)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return CustomZip( + firstSource, ZipSourceConfiguration.StopOnShort, + secondSource, ZipSourceConfiguration.StopOnShort, + thirdSource, ZipSourceConfiguration.StopOnShort, + fourthSource, ZipSourceConfiguration.StopOnShort, + fifthSource, ZipSourceConfiguration.StopOnShort, + sixthSource, ZipSourceConfiguration.StopOnShort, + seventhSource, ZipSourceConfiguration.StopOnShort, + eighthSource, ZipSourceConfiguration.StopOnShort, + resultSelector); + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// Type of elements in eighth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7, T8)> ZipShortest( + this IEnumerable firstSource, + IEnumerable secondSource, + IEnumerable thirdSource, + IEnumerable fourthSource, + IEnumerable fifthSource, + IEnumerable sixthSource, + IEnumerable seventhSource, + IEnumerable eighthSource) + { + if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); + if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); + if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); + if (seventhSource == null) throw new ArgumentNullException(nameof(seventhSource)); + if (eighthSource == null) throw new ArgumentNullException(nameof(eighthSource)); + + return CustomZip( + firstSource, ZipSourceConfiguration.StopOnShort, + secondSource, ZipSourceConfiguration.StopOnShort, + thirdSource, ZipSourceConfiguration.StopOnShort, + fourthSource, ZipSourceConfiguration.StopOnShort, + fifthSource, ZipSourceConfiguration.StopOnShort, + sixthSource, ZipSourceConfiguration.StopOnShort, + seventhSource, ZipSourceConfiguration.StopOnShort, + eighthSource, ZipSourceConfiguration.StopOnShort, + ValueTuple.Create); + } + + + internal static IEnumerable CustomZip( + this IEnumerable firstSource, ZipSourceConfiguration firstSourceConfiguration, + IEnumerable secondSource, ZipSourceConfiguration secondSourceConfiguration, + Func resultSelector) + { + using var firstEnumerator = new ZipEnumerator(firstSource.GetEnumerator(), nameof(firstSource), firstSourceConfiguration); + using var secondEnumerator = new ZipEnumerator(secondSource.GetEnumerator(), nameof(secondSource), secondSourceConfiguration); + + var enumerators = new IZipEnumerator[] + { + firstEnumerator, + secondEnumerator + }; + + for (;;) + { + var isEnd = true; + IZipEnumerator equiStopper = null; + + foreach (var enumerator in enumerators) + { + switch (enumerator.MoveNext()) + { + case ZipEnumeratorStatus.AskForStop: + yield break; + case ZipEnumeratorStatus.AskForEquiStop: + if (!isEnd) // there is some sequences ahead + { + enumerator.ThrowToShort(); + } + equiStopper = enumerator; + break; + case ZipEnumeratorStatus.Continue: + equiStopper?.ThrowToShort(); + isEnd = false; + break; + case ZipEnumeratorStatus.EndOfStream: + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + if (isEnd) + { + yield break; + } + + yield return resultSelector( + firstEnumerator.Current, + secondEnumerator.Current + ); + } + } + + internal static IEnumerable CustomZip( + this IEnumerable firstSource, ZipSourceConfiguration firstSourceConfiguration, + IEnumerable secondSource, ZipSourceConfiguration secondSourceConfiguration, + IEnumerable thirdSource, ZipSourceConfiguration thirdSourceConfiguration, + Func resultSelector) + { + using var firstEnumerator = new ZipEnumerator(firstSource.GetEnumerator(), nameof(firstSource), firstSourceConfiguration); + using var secondEnumerator = new ZipEnumerator(secondSource.GetEnumerator(), nameof(secondSource), secondSourceConfiguration); + using var thirdEnumerator = new ZipEnumerator(thirdSource.GetEnumerator(), nameof(thirdSource), thirdSourceConfiguration); + + var enumerators = new IZipEnumerator[] + { + firstEnumerator, + secondEnumerator, + thirdEnumerator + }; + + for (;;) + { + var isEnd = true; + IZipEnumerator equiStopper = null; + + foreach (var enumerator in enumerators) + { + switch (enumerator.MoveNext()) + { + case ZipEnumeratorStatus.AskForStop: + yield break; + case ZipEnumeratorStatus.AskForEquiStop: + if (!isEnd) // there is some sequences ahead + { + enumerator.ThrowToShort(); + } + equiStopper = enumerator; + break; + case ZipEnumeratorStatus.Continue: + equiStopper?.ThrowToShort(); + isEnd = false; + break; + case ZipEnumeratorStatus.EndOfStream: + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + if (isEnd) + { + yield break; + } + + yield return resultSelector( + firstEnumerator.Current, + secondEnumerator.Current, + thirdEnumerator.Current + ); + } + } + + internal static IEnumerable CustomZip( + this IEnumerable firstSource, ZipSourceConfiguration firstSourceConfiguration, + IEnumerable secondSource, ZipSourceConfiguration secondSourceConfiguration, + IEnumerable thirdSource, ZipSourceConfiguration thirdSourceConfiguration, + IEnumerable fourthSource, ZipSourceConfiguration fourthSourceConfiguration, + Func resultSelector) + { + using var firstEnumerator = new ZipEnumerator(firstSource.GetEnumerator(), nameof(firstSource), firstSourceConfiguration); + using var secondEnumerator = new ZipEnumerator(secondSource.GetEnumerator(), nameof(secondSource), secondSourceConfiguration); + using var thirdEnumerator = new ZipEnumerator(thirdSource.GetEnumerator(), nameof(thirdSource), thirdSourceConfiguration); + using var fourthEnumerator = new ZipEnumerator(fourthSource.GetEnumerator(), nameof(fourthSource), fourthSourceConfiguration); + + var enumerators = new IZipEnumerator[] + { + firstEnumerator, + secondEnumerator, + thirdEnumerator, + fourthEnumerator + }; + + for (;;) + { + var isEnd = true; + IZipEnumerator equiStopper = null; + + foreach (var enumerator in enumerators) + { + switch (enumerator.MoveNext()) + { + case ZipEnumeratorStatus.AskForStop: + yield break; + case ZipEnumeratorStatus.AskForEquiStop: + if (!isEnd) // there is some sequences ahead + { + enumerator.ThrowToShort(); + } + equiStopper = enumerator; + break; + case ZipEnumeratorStatus.Continue: + equiStopper?.ThrowToShort(); + isEnd = false; + break; + case ZipEnumeratorStatus.EndOfStream: + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + if (isEnd) + { + yield break; + } + + yield return resultSelector( + firstEnumerator.Current, + secondEnumerator.Current, + thirdEnumerator.Current, + fourthEnumerator.Current + ); + } + } + + internal static IEnumerable CustomZip( + this IEnumerable firstSource, ZipSourceConfiguration firstSourceConfiguration, + IEnumerable secondSource, ZipSourceConfiguration secondSourceConfiguration, + IEnumerable thirdSource, ZipSourceConfiguration thirdSourceConfiguration, + IEnumerable fourthSource, ZipSourceConfiguration fourthSourceConfiguration, + IEnumerable fifthSource, ZipSourceConfiguration fifthSourceConfiguration, + Func resultSelector) + { + using var firstEnumerator = new ZipEnumerator(firstSource.GetEnumerator(), nameof(firstSource), firstSourceConfiguration); + using var secondEnumerator = new ZipEnumerator(secondSource.GetEnumerator(), nameof(secondSource), secondSourceConfiguration); + using var thirdEnumerator = new ZipEnumerator(thirdSource.GetEnumerator(), nameof(thirdSource), thirdSourceConfiguration); + using var fourthEnumerator = new ZipEnumerator(fourthSource.GetEnumerator(), nameof(fourthSource), fourthSourceConfiguration); + using var fifthEnumerator = new ZipEnumerator(fifthSource.GetEnumerator(), nameof(fifthSource), fifthSourceConfiguration); + + var enumerators = new IZipEnumerator[] + { + firstEnumerator, + secondEnumerator, + thirdEnumerator, + fourthEnumerator, + fifthEnumerator + }; + + for (;;) + { + var isEnd = true; + IZipEnumerator equiStopper = null; + + foreach (var enumerator in enumerators) + { + switch (enumerator.MoveNext()) + { + case ZipEnumeratorStatus.AskForStop: + yield break; + case ZipEnumeratorStatus.AskForEquiStop: + if (!isEnd) // there is some sequences ahead + { + enumerator.ThrowToShort(); + } + equiStopper = enumerator; + break; + case ZipEnumeratorStatus.Continue: + equiStopper?.ThrowToShort(); + isEnd = false; + break; + case ZipEnumeratorStatus.EndOfStream: + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + if (isEnd) + { + yield break; + } + + yield return resultSelector( + firstEnumerator.Current, + secondEnumerator.Current, + thirdEnumerator.Current, + fourthEnumerator.Current, + fifthEnumerator.Current + ); + } + } + + internal static IEnumerable CustomZip( + this IEnumerable firstSource, ZipSourceConfiguration firstSourceConfiguration, + IEnumerable secondSource, ZipSourceConfiguration secondSourceConfiguration, + IEnumerable thirdSource, ZipSourceConfiguration thirdSourceConfiguration, + IEnumerable fourthSource, ZipSourceConfiguration fourthSourceConfiguration, + IEnumerable fifthSource, ZipSourceConfiguration fifthSourceConfiguration, + IEnumerable sixthSource, ZipSourceConfiguration sixthSourceConfiguration, + Func resultSelector) + { + using var firstEnumerator = new ZipEnumerator(firstSource.GetEnumerator(), nameof(firstSource), firstSourceConfiguration); + using var secondEnumerator = new ZipEnumerator(secondSource.GetEnumerator(), nameof(secondSource), secondSourceConfiguration); + using var thirdEnumerator = new ZipEnumerator(thirdSource.GetEnumerator(), nameof(thirdSource), thirdSourceConfiguration); + using var fourthEnumerator = new ZipEnumerator(fourthSource.GetEnumerator(), nameof(fourthSource), fourthSourceConfiguration); + using var fifthEnumerator = new ZipEnumerator(fifthSource.GetEnumerator(), nameof(fifthSource), fifthSourceConfiguration); + using var sixthEnumerator = new ZipEnumerator(sixthSource.GetEnumerator(), nameof(sixthSource), sixthSourceConfiguration); + + var enumerators = new IZipEnumerator[] + { + firstEnumerator, + secondEnumerator, + thirdEnumerator, + fourthEnumerator, + fifthEnumerator, + sixthEnumerator + }; + + for (;;) + { + var isEnd = true; + IZipEnumerator equiStopper = null; + + foreach (var enumerator in enumerators) + { + switch (enumerator.MoveNext()) + { + case ZipEnumeratorStatus.AskForStop: + yield break; + case ZipEnumeratorStatus.AskForEquiStop: + if (!isEnd) // there is some sequences ahead + { + enumerator.ThrowToShort(); + } + equiStopper = enumerator; + break; + case ZipEnumeratorStatus.Continue: + equiStopper?.ThrowToShort(); + isEnd = false; + break; + case ZipEnumeratorStatus.EndOfStream: + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + if (isEnd) + { + yield break; + } + + yield return resultSelector( + firstEnumerator.Current, + secondEnumerator.Current, + thirdEnumerator.Current, + fourthEnumerator.Current, + fifthEnumerator.Current, + sixthEnumerator.Current + ); + } + } + + internal static IEnumerable CustomZip( + this IEnumerable firstSource, ZipSourceConfiguration firstSourceConfiguration, + IEnumerable secondSource, ZipSourceConfiguration secondSourceConfiguration, + IEnumerable thirdSource, ZipSourceConfiguration thirdSourceConfiguration, + IEnumerable fourthSource, ZipSourceConfiguration fourthSourceConfiguration, + IEnumerable fifthSource, ZipSourceConfiguration fifthSourceConfiguration, + IEnumerable sixthSource, ZipSourceConfiguration sixthSourceConfiguration, + IEnumerable seventhSource, ZipSourceConfiguration seventhSourceConfiguration, + Func resultSelector) + { + using var firstEnumerator = new ZipEnumerator(firstSource.GetEnumerator(), nameof(firstSource), firstSourceConfiguration); + using var secondEnumerator = new ZipEnumerator(secondSource.GetEnumerator(), nameof(secondSource), secondSourceConfiguration); + using var thirdEnumerator = new ZipEnumerator(thirdSource.GetEnumerator(), nameof(thirdSource), thirdSourceConfiguration); + using var fourthEnumerator = new ZipEnumerator(fourthSource.GetEnumerator(), nameof(fourthSource), fourthSourceConfiguration); + using var fifthEnumerator = new ZipEnumerator(fifthSource.GetEnumerator(), nameof(fifthSource), fifthSourceConfiguration); + using var sixthEnumerator = new ZipEnumerator(sixthSource.GetEnumerator(), nameof(sixthSource), sixthSourceConfiguration); + using var seventhEnumerator = new ZipEnumerator(seventhSource.GetEnumerator(), nameof(seventhSource), seventhSourceConfiguration); + + var enumerators = new IZipEnumerator[] + { + firstEnumerator, + secondEnumerator, + thirdEnumerator, + fourthEnumerator, + fifthEnumerator, + sixthEnumerator, + seventhEnumerator + }; + + for (;;) + { + var isEnd = true; + IZipEnumerator equiStopper = null; + + foreach (var enumerator in enumerators) + { + switch (enumerator.MoveNext()) + { + case ZipEnumeratorStatus.AskForStop: + yield break; + case ZipEnumeratorStatus.AskForEquiStop: + if (!isEnd) // there is some sequences ahead + { + enumerator.ThrowToShort(); + } + equiStopper = enumerator; + break; + case ZipEnumeratorStatus.Continue: + equiStopper?.ThrowToShort(); + isEnd = false; + break; + case ZipEnumeratorStatus.EndOfStream: + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + if (isEnd) + { + yield break; + } + + yield return resultSelector( + firstEnumerator.Current, + secondEnumerator.Current, + thirdEnumerator.Current, + fourthEnumerator.Current, + fifthEnumerator.Current, + sixthEnumerator.Current, + seventhEnumerator.Current + ); + } + } + + internal static IEnumerable CustomZip( + this IEnumerable firstSource, ZipSourceConfiguration firstSourceConfiguration, + IEnumerable secondSource, ZipSourceConfiguration secondSourceConfiguration, + IEnumerable thirdSource, ZipSourceConfiguration thirdSourceConfiguration, + IEnumerable fourthSource, ZipSourceConfiguration fourthSourceConfiguration, + IEnumerable fifthSource, ZipSourceConfiguration fifthSourceConfiguration, + IEnumerable sixthSource, ZipSourceConfiguration sixthSourceConfiguration, + IEnumerable seventhSource, ZipSourceConfiguration seventhSourceConfiguration, + IEnumerable eighthSource, ZipSourceConfiguration eighthSourceConfiguration, + Func resultSelector) + { + using var firstEnumerator = new ZipEnumerator(firstSource.GetEnumerator(), nameof(firstSource), firstSourceConfiguration); + using var secondEnumerator = new ZipEnumerator(secondSource.GetEnumerator(), nameof(secondSource), secondSourceConfiguration); + using var thirdEnumerator = new ZipEnumerator(thirdSource.GetEnumerator(), nameof(thirdSource), thirdSourceConfiguration); + using var fourthEnumerator = new ZipEnumerator(fourthSource.GetEnumerator(), nameof(fourthSource), fourthSourceConfiguration); + using var fifthEnumerator = new ZipEnumerator(fifthSource.GetEnumerator(), nameof(fifthSource), fifthSourceConfiguration); + using var sixthEnumerator = new ZipEnumerator(sixthSource.GetEnumerator(), nameof(sixthSource), sixthSourceConfiguration); + using var seventhEnumerator = new ZipEnumerator(seventhSource.GetEnumerator(), nameof(seventhSource), seventhSourceConfiguration); + using var eighthEnumerator = new ZipEnumerator(eighthSource.GetEnumerator(), nameof(eighthSource), eighthSourceConfiguration); + + var enumerators = new IZipEnumerator[] + { + firstEnumerator, + secondEnumerator, + thirdEnumerator, + fourthEnumerator, + fifthEnumerator, + sixthEnumerator, + seventhEnumerator, + eighthEnumerator + }; + + for (;;) + { + var isEnd = true; + IZipEnumerator equiStopper = null; + + foreach (var enumerator in enumerators) + { + switch (enumerator.MoveNext()) + { + case ZipEnumeratorStatus.AskForStop: + yield break; + case ZipEnumeratorStatus.AskForEquiStop: + if (!isEnd) // there is some sequences ahead + { + enumerator.ThrowToShort(); + } + equiStopper = enumerator; + break; + case ZipEnumeratorStatus.Continue: + equiStopper?.ThrowToShort(); + isEnd = false; + break; + case ZipEnumeratorStatus.EndOfStream: + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + if (isEnd) + { + yield break; + } + + yield return resultSelector( + firstEnumerator.Current, + secondEnumerator.Current, + thirdEnumerator.Current, + fourthEnumerator.Current, + fifthEnumerator.Current, + sixthEnumerator.Current, + seventhEnumerator.Current, + eighthEnumerator.Current + ); + } + } + + } + + internal interface IZipEnumerator + { + ZipEnumeratorStatus MoveNext(); + void ThrowToShort(); + } + + internal class ZipEnumerator : IZipEnumerator, IDisposable + { + private readonly ZipSourceConfiguration _configuration; + private readonly string _name; + private IEnumerator _source; + + public ZipEnumerator(IEnumerator source, string name, ZipSourceConfiguration configuration) + { + _source = source; + _name = name; + _configuration = configuration; + } + + public T Current => _source == null ? _configuration.PaddingValue : _source.Current; + + public void Dispose() => _source?.Dispose(); + + public ZipEnumeratorStatus MoveNext() + { + if (_source?.MoveNext() == false) + { + _source.Dispose(); + _source = null; + } + + if (_source != null) + { + return ZipEnumeratorStatus.Continue; + } + + switch (_configuration.Behavior) + { + case ZipEnumeratorBehavior.StopOnShort: + return ZipEnumeratorStatus.AskForStop; + case ZipEnumeratorBehavior.Padding: + return ZipEnumeratorStatus.EndOfStream; + case ZipEnumeratorBehavior.ThrowOnShort: + return ZipEnumeratorStatus.AskForEquiStop; + default: + throw new ArgumentOutOfRangeException(); + } + } + + public void Reset() => _source.Reset(); + + public void ThrowToShort() => throw new InvalidOperationException($"{_name} sequence too short."); + } + + internal enum ZipEnumeratorBehavior + { + StopOnShort, + ThrowOnShort, + Padding + } + + internal enum ZipEnumeratorStatus + { + AskForStop, + AskForEquiStop, + Continue, + EndOfStream + } + + internal class ZipSourceConfiguration + { + public static ZipSourceConfiguration StopOnShort { get; } = new ZipSourceConfiguration(ZipEnumeratorBehavior.StopOnShort, default); + public static ZipSourceConfiguration ThrowOnShort { get; } = new ZipSourceConfiguration(ZipEnumeratorBehavior.ThrowOnShort, default); + public static ZipSourceConfiguration PaddingWith(T paddingValue) => new ZipSourceConfiguration(ZipEnumeratorBehavior.Padding, paddingValue); + + ZipSourceConfiguration(ZipEnumeratorBehavior behavior, T paddingValue) + { + Behavior = behavior; + PaddingValue = paddingValue; + } + + public ZipEnumeratorBehavior Behavior { get; } + public T PaddingValue { get; } + } +} diff --git a/MoreLinq/Zip.g.tt b/MoreLinq/Zip.g.tt new file mode 100644 index 000000000..e58e9b54d --- /dev/null +++ b/MoreLinq/Zip.g.tt @@ -0,0 +1,458 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ output extension=".cs" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Collections" #> +<#@ import namespace="System.Globalization" #> +<#@ import namespace="System.Linq" #> +#region License and Terms +// MoreLINQ - Extensions to LINQ to Objects +// Copyright (c) 2019 Pierre Lando. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +<# + var overloads = + from args in new[] + { + new[] + { + new { Ordinal = "first" , Arity = "one" }, + new { Ordinal = "second" , Arity = "two" }, + new { Ordinal = "third" , Arity = "three" }, + new { Ordinal = "fourth" , Arity = "four" }, + new { Ordinal = "fifth" , Arity = "five" }, + new { Ordinal = "sixth" , Arity = "six" }, + new { Ordinal = "seventh", Arity = "seven" }, + new { Ordinal = "eighth" , Arity = "eight" }, + } + } + select args.Select((a, i) => new + { + a.Ordinal, + a.Arity, + Count = i + 1, + Number = (i + 1).ToString(CultureInfo.InvariantCulture), + }) + into args + select args.ToList() into args + from a in args.Skip(1) + select new + { + a.Arity, + a.Count, + Arguments = args.Take(a.Count) + .Select(aa => new { aa.Number, Num = aa.Count, aa.Ordinal }) + .ToList(), + Types = string.Join(", ", Enumerable.Range(1, a.Count).Select(i => $"T{i}")), + }; +#> +namespace MoreLinq +{ + using System; + using System.Collections.Generic; + + static partial class MoreEnumerable + { +<# foreach (var o in overloads) + { +#> + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// +<# foreach (var arg in o.Arguments) { #> + /// Type of elements in <#= arg.Ordinal #> input sequence. +<#} #> + /// Type of elements in result sequence. +<# foreach (var arg in o.Arguments) { #> + /// The <#= arg.Ordinal #> source sequence. +<#} #> + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable EquiZip<<#= o.Types#>, TResult>( +<# foreach (var arg in o.Arguments) { #> + <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #>Source, +<#}#> + Func<<#= o.Types#>, TResult> resultSelector) + { +<# foreach (var arg in o.Arguments) { #> + if (<#= arg.Ordinal #>Source == null) throw new ArgumentNullException(nameof(<#= arg.Ordinal #>Source)); +<#} #> + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return CustomZip( +<# foreach (var arg in o.Arguments) { #> + <#= arg.Ordinal #>Source, ZipSourceConfiguration>.ThrowOnShort, +<#}#> + resultSelector); + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// +<# foreach (var arg in o.Arguments) { #> + /// Type of elements in <#= arg.Ordinal #> input sequence. +<#} #> +<# foreach (var arg in o.Arguments) { #> + /// The <#= arg.Ordinal #> source sequence. +<#} #> + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable<(<#= o.Types#>)> EquiZip<<#= o.Types#>>( +<# foreach (var arg in o.Arguments) { #> + <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #>Source<#= arg.Num < o.Count ? "," : ")" #> +<#}#> + { +<# foreach (var arg in o.Arguments) { #> + if (<#= arg.Ordinal #>Source == null) throw new ArgumentNullException(nameof(<#= arg.Ordinal #>Source)); +<#} #> + + return CustomZip( +<# foreach (var arg in o.Arguments) { #> + <#= arg.Ordinal #>Source, ZipSourceConfiguration>.ThrowOnShort, +<#}#> + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// +<# foreach (var arg in o.Arguments) { #> + /// Type of elements in <#= arg.Ordinal #> input sequence. +<#} #> + /// Type of elements in result sequence. +<# foreach (var arg in o.Arguments) { #> + /// The <#= arg.Ordinal #> source sequence. +<#} #> + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable ZipLongest<<#= o.Types#>, TResult>( +<# foreach (var arg in o.Arguments) { #> + <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #>Source, +<#}#> + Func<<#= o.Types#>, TResult> resultSelector) + { +<# foreach (var arg in o.Arguments) { #> + if (<#= arg.Ordinal #>Source == null) throw new ArgumentNullException(nameof(<#= arg.Ordinal #>Source)); +<#} #> + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return CustomZip( +<# foreach (var arg in o.Arguments) { #> + <#= arg.Ordinal #>Source, ZipSourceConfiguration>.PaddingWith(default), +<#}#> + resultSelector); + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// +<# foreach (var arg in o.Arguments) { #> + /// Type of elements in <#= arg.Ordinal #> input sequence. +<#} #> +<# foreach (var arg in o.Arguments) { #> + /// The <#= arg.Ordinal #> source sequence. +<#} #> + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + public static IEnumerable<(<#= o.Types#>)> ZipLongest<<#= o.Types#>>( +<# foreach (var arg in o.Arguments) { #> + <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #>Source<#= arg.Num < o.Count ? "," : ")" #> +<#}#> + { +<# foreach (var arg in o.Arguments) { #> + if (<#= arg.Ordinal #>Source == null) throw new ArgumentNullException(nameof(<#= arg.Ordinal #>Source)); +<#} #> + + return CustomZip( +<# foreach (var arg in o.Arguments) { #> + <#= arg.Ordinal #>Source, ZipSourceConfiguration>.PaddingWith(default), +<#}#> + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// +<# foreach (var arg in o.Arguments) { #> + /// Type of elements in <#= arg.Ordinal #> input sequence. +<#} #> + /// Type of elements in result sequence. +<# foreach (var arg in o.Arguments) { #> + /// The <#= arg.Ordinal #> source sequence. +<#} #> + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipShortest<<#= o.Types#>, TResult>( +<# foreach (var arg in o.Arguments) { #> + <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #>Source, +<#}#> + Func<<#= o.Types#>, TResult> resultSelector) + { +<# foreach (var arg in o.Arguments) { #> + if (<#= arg.Ordinal #>Source == null) throw new ArgumentNullException(nameof(<#= arg.Ordinal #>Source)); +<#} #> + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return CustomZip( +<# foreach (var arg in o.Arguments) { #> + <#= arg.Ordinal #>Source, ZipSourceConfiguration>.StopOnShort, +<#}#> + resultSelector); + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// +<# foreach (var arg in o.Arguments) { #> + /// Type of elements in <#= arg.Ordinal #> input sequence. +<#} #> +<# foreach (var arg in o.Arguments) { #> + /// The <#= arg.Ordinal #> source sequence. +<#} #> + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(<#= o.Types#>)> ZipShortest<<#= o.Types#>>( +<# foreach (var arg in o.Arguments) { #> + <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #>Source<#= arg.Num < o.Count ? "," : ")" #> +<#}#> + { +<# foreach (var arg in o.Arguments) { #> + if (<#= arg.Ordinal #>Source == null) throw new ArgumentNullException(nameof(<#= arg.Ordinal #>Source)); +<#} #> + + return CustomZip( +<# foreach (var arg in o.Arguments) { #> + <#= arg.Ordinal #>Source, ZipSourceConfiguration>.StopOnShort, +<#}#> + ValueTuple.Create); + } + +<# } #> + +<# foreach (var o in overloads) + { +#> + internal static IEnumerable CustomZip<<#= o.Types#>, TResult>( +<# foreach (var arg in o.Arguments) { #> + <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #>Source, ZipSourceConfiguration> <#= arg.Ordinal #>SourceConfiguration, +<#}#> + Func<<#= o.Types#>, TResult> resultSelector) + { +<# foreach (var arg in o.Arguments) { #> + using var <#= arg.Ordinal #>Enumerator = new ZipEnumerator>(<#= arg.Ordinal #>Source.GetEnumerator(), nameof(<#= arg.Ordinal #>Source), <#= arg.Ordinal #>SourceConfiguration); +<#} #> + + var enumerators = new IZipEnumerator[] + { +<# foreach (var arg in o.Arguments) { #> + <#= arg.Ordinal #>Enumerator<#= arg.Num < o.Count ? "," : "" #> +<#}#> + }; + + for (;;) + { + var isEnd = true; + IZipEnumerator equiStopper = null; + + foreach (var enumerator in enumerators) + { + switch (enumerator.MoveNext()) + { + case ZipEnumeratorStatus.AskForStop: + yield break; + case ZipEnumeratorStatus.AskForEquiStop: + if (!isEnd) // there is some sequences ahead + { + enumerator.ThrowToShort(); + } + equiStopper = enumerator; + break; + case ZipEnumeratorStatus.Continue: + equiStopper?.ThrowToShort(); + isEnd = false; + break; + case ZipEnumeratorStatus.EndOfStream: + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + if (isEnd) + { + yield break; + } + + yield return resultSelector( +<# foreach (var arg in o.Arguments) { #> + <#= arg.Ordinal #>Enumerator.Current<#= arg.Num < o.Count ? "," : "" #> +<#}#> + ); + } + } + +<# } #> + } + + internal interface IZipEnumerator + { + ZipEnumeratorStatus MoveNext(); + void ThrowToShort(); + } + + internal class ZipEnumerator : IZipEnumerator, IDisposable + { + private readonly ZipSourceConfiguration _configuration; + private readonly string _name; + private IEnumerator _source; + + public ZipEnumerator(IEnumerator source, string name, ZipSourceConfiguration configuration) + { + _source = source; + _name = name; + _configuration = configuration; + } + + public T Current => _source == null ? _configuration.PaddingValue : _source.Current; + + public void Dispose() => _source?.Dispose(); + + public ZipEnumeratorStatus MoveNext() + { + if (_source?.MoveNext() == false) + { + _source.Dispose(); + _source = null; + } + + if (_source != null) + { + return ZipEnumeratorStatus.Continue; + } + + switch (_configuration.Behavior) + { + case ZipEnumeratorBehavior.StopOnShort: + return ZipEnumeratorStatus.AskForStop; + case ZipEnumeratorBehavior.Padding: + return ZipEnumeratorStatus.EndOfStream; + case ZipEnumeratorBehavior.ThrowOnShort: + return ZipEnumeratorStatus.AskForEquiStop; + default: + throw new ArgumentOutOfRangeException(); + } + } + + public void Reset() => _source.Reset(); + + public void ThrowToShort() => throw new InvalidOperationException($"{_name} sequence too short."); + } + + internal enum ZipEnumeratorBehavior + { + StopOnShort, + ThrowOnShort, + Padding + } + + internal enum ZipEnumeratorStatus + { + AskForStop, + AskForEquiStop, + Continue, + EndOfStream + } + + internal class ZipSourceConfiguration + { + public static ZipSourceConfiguration StopOnShort { get; } = new ZipSourceConfiguration(ZipEnumeratorBehavior.StopOnShort, default); + public static ZipSourceConfiguration ThrowOnShort { get; } = new ZipSourceConfiguration(ZipEnumeratorBehavior.ThrowOnShort, default); + public static ZipSourceConfiguration PaddingWith(T paddingValue) => new ZipSourceConfiguration(ZipEnumeratorBehavior.Padding, paddingValue); + + ZipSourceConfiguration(ZipEnumeratorBehavior behavior, T paddingValue) + { + Behavior = behavior; + PaddingValue = paddingValue; + } + + public ZipEnumeratorBehavior Behavior { get; } + public T PaddingValue { get; } + } +} diff --git a/MoreLinq/ZipImpl.cs b/MoreLinq/ZipImpl.cs deleted file mode 100644 index 2005660cb..000000000 --- a/MoreLinq/ZipImpl.cs +++ /dev/null @@ -1,97 +0,0 @@ -#region License and Terms -// MoreLINQ - Extensions to LINQ to Objects -// Copyright (c) 2018 Leandro F. Vieira (leandromoh). All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#endregion - -namespace MoreLinq -{ - using System; - using System.Collections.Generic; - using System.Collections; - - static partial class MoreEnumerable - { - delegate TResult Folder(params T[] args); - - static IEnumerable ZipImpl( - IEnumerable s1, - IEnumerable s2, - IEnumerable s3, - IEnumerable s4, - Func resultSelector, - int limit, - Folder errorSelector = null) - { - IEnumerator e1 = null; - IEnumerator e2 = null; - IEnumerator e3 = null; - IEnumerator e4 = null; - var terminations = 0; - - try - { - e1 = s1 .GetEnumerator(); - e2 = s2 .GetEnumerator(); - e3 = s3?.GetEnumerator(); - e4 = s4?.GetEnumerator(); - - while (true) - { - var n = 0; - var v1 = Read(ref e1, ++n); - var v2 = Read(ref e2, ++n); - var v3 = Read(ref e3, ++n); - var v4 = Read(ref e4, ++n); - - if (terminations <= limit) - yield return resultSelector(v1, v2, v3, v4); - else - yield break; - } - } - finally - { - e1?.Dispose(); - e2?.Dispose(); - e3?.Dispose(); - e4?.Dispose(); - } - - T Read(ref IEnumerator e, int n) - { - if (e == null || terminations > limit) - return default; - - T value; - if (e.MoveNext()) - { - value = e.Current; - } - else - { - e.Dispose(); - e = null; - terminations++; - value = default; - } - - if (errorSelector != null && terminations > 0 && terminations < n) - throw errorSelector(e1, e2, e3, e4); - - return value; - } - } - } -} diff --git a/MoreLinq/ZipLongest.cs b/MoreLinq/ZipLongest.cs deleted file mode 100644 index ec5a240e6..000000000 --- a/MoreLinq/ZipLongest.cs +++ /dev/null @@ -1,169 +0,0 @@ -#region License and Terms -// MoreLINQ - Extensions to LINQ to Objects -// Copyright (c) 2008 Jonathan Skeet. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#endregion - -namespace MoreLinq -{ - using System; - using System.Collections.Generic; - - static partial class MoreEnumerable - { - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. - /// - /// Type of elements in first sequence. - /// Type of elements in second sequence. - /// Type of elements in result sequence. - /// The first sequence. - /// The second sequence. - /// - /// Function to apply to each pair of elements. - /// - /// A sequence that contains elements of the two input sequences, - /// combined by . - /// - /// - /// n + l); - /// ]]> - /// The zipped variable, when iterated over, will yield "1A", - /// "2B", "3C", "0D" in turn. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable ZipLongest( - this IEnumerable first, - IEnumerable second, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return ZipImpl(first, second, null, null, (a, b, c, d) => resultSelector(a, b), 1); - } - - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. - /// - /// Type of elements in first sequence. - /// Type of elements in second sequence. - /// Type of elements in third sequence. - /// Type of elements in result sequence. - /// The first sequence. - /// The second sequence. - /// The third sequence. - /// - /// Function to apply to each triplet of elements. - /// - /// A sequence that contains elements of the three input sequences, - /// combined by . - /// - /// - /// n + l + c); - /// ]]> - /// The zipped variable, when iterated over, will yield "1Aa", - /// "2Bb", "3Cc", "0Dd", "0e" in turn. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable ZipLongest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (third == null) throw new ArgumentNullException(nameof(third)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return ZipImpl(first, second, third, null, (a, b, c, d) => resultSelector(a, b, c), 2); - } - - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. - /// - /// Type of elements in first sequence - /// Type of elements in second sequence - /// Type of elements in third sequence - /// Type of elements in fourth sequence - /// Type of elements in result sequence - /// The first sequence. - /// The second sequence. - /// The third sequence. - /// The fourth sequence. - /// - /// Function to apply to each quadruplet of elements. - /// - /// A sequence that contains elements of the four input sequences, - /// combined by . - /// - /// - /// n + l + c + f); - /// ]]> - /// The zipped variable, when iterated over, will yield "1AaTrue", - /// "2BbFalse", "3CcTrue", "0DdFalse", "0eTrue", "0\0False" in turn. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable ZipLongest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (third == null) throw new ArgumentNullException(nameof(third)); - if (fourth == null) throw new ArgumentNullException(nameof(fourth)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return ZipImpl(first, second, third, fourth, resultSelector, 3); - } - } -} diff --git a/MoreLinq/ZipShortest.cs b/MoreLinq/ZipShortest.cs deleted file mode 100644 index 06920e2df..000000000 --- a/MoreLinq/ZipShortest.cs +++ /dev/null @@ -1,185 +0,0 @@ -#region License and Terms -// MoreLINQ - Extensions to LINQ to Objects -// Copyright (c) 2008 Jonathan Skeet. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#endregion - -namespace MoreLinq -{ - using System; - using System.Collections.Generic; - - static partial class MoreEnumerable - { - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. The resulting sequence - /// is as short as the shortest input sequence. - /// - /// Type of elements in first sequence. - /// Type of elements in second sequence. - /// Type of elements in result sequence. - /// The first sequence. - /// The second sequence. - /// - /// Function to apply to each pair of elements. - /// - /// A projection of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// n + l); - /// ]]> - /// The zipped variable, when iterated over, will yield "1A", "2B", "3C", in turn. - /// - /// - /// - /// If the input sequences are of different lengths, the result sequence - /// is terminated as soon as the shortest input sequence is exhausted - /// and remainder elements from the longer sequences are never consumed. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable ZipShortest( - this IEnumerable first, - IEnumerable second, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return ZipImpl(first, second, null, null, (a, b, c, d) => resultSelector(a, b)); - } - - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. The resulting sequence - /// is as short as the shortest input sequence. - /// - /// Type of elements in first sequence. - /// Type of elements in second sequence. - /// Type of elements in third sequence. - /// Type of elements in result sequence. - /// First sequence - /// Second sequence - /// Third sequence - /// - /// Function to apply to each triplet of elements. - /// - /// A projection of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// c + n + l); - /// ]]> - /// The zipped variable, when iterated over, will yield - /// "98A", "100B", "102C", in turn. - /// - /// - /// - /// If the input sequences are of different lengths, the result sequence - /// is terminated as soon as the shortest input sequence is exhausted - /// and remainder elements from the longer sequences are never consumed. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable ZipShortest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (third == null) throw new ArgumentNullException(nameof(third)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return ZipImpl(first, second, third, null, (a, b, c, _) => resultSelector(a, b, c)); - } - - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the argument sequences. The resulting sequence - /// is as short as the shortest input sequence. - /// - /// Type of elements in first sequence. - /// Type of elements in second sequence. - /// Type of elements in third sequence. - /// Type of elements in fourth sequence. - /// Type of elements in result sequence. - /// The first sequence. - /// The second sequence. - /// The third sequence. - /// The fourth sequence. - /// - /// Function to apply to each quadruplet of elements. - /// - /// A projection of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// n + l + c + f); - /// ]]> - /// The zipped variable, when iterated over, will yield - /// "1AaTrue", "2BbFalse" in turn. - /// - /// - /// - /// If the input sequences are of different lengths, the result sequence - /// is terminated as soon as the shortest input sequence is exhausted - /// and remainder elements from the longer sequences are never consumed. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable ZipShortest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (third == null) throw new ArgumentNullException(nameof(third)); - if (fourth == null) throw new ArgumentNullException(nameof(fourth)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return ZipImpl(first, second, third, fourth, resultSelector); - } - - static IEnumerable ZipImpl( - IEnumerable s1, IEnumerable s2, - IEnumerable s3, IEnumerable s4, - Func resultSelector) - { - return ZipImpl(s1, s2, s3, s4, resultSelector, 0); - } - } -} diff --git a/README.md b/README.md index d6923b81d..e643b9193 100644 --- a/README.md +++ b/README.md @@ -222,7 +222,7 @@ Returns a projection of tuples, where each tuple contains the N-th element from each of the argument sequences. An exception is thrown if the input sequences are of different lengths. -This method has 3 overloads. +This method has 14 overloads. ### Exactly @@ -717,7 +717,7 @@ will always be as long as the longest of input sequences where the default value of each of the shorter sequence element types is used for padding. -This method has 3 overloads. +This method has 14 overloads. ### ZipShortest @@ -725,7 +725,7 @@ Returns a projection of tuples, where each tuple contains the N-th element from each of the argument sequences. The resulting sequence is as short as the shortest input sequence. -This method has 3 overloads. +This method has 14 overloads. ## Experimental Operators From 2dd59ad1fc1e0b792007049ad1ebab7c341e680f Mon Sep 17 00:00:00 2001 From: Orace Date: Mon, 4 Nov 2019 18:24:30 +0100 Subject: [PATCH 02/11] code factorisartion in CustomZip --- MoreLinq/Zip.g.cs | 317 +++++++--------------------------------------- MoreLinq/Zip.g.tt | 73 +++++------ 2 files changed, 79 insertions(+), 311 deletions(-) diff --git a/MoreLinq/Zip.g.cs b/MoreLinq/Zip.g.cs index c2ace5253..8fcaf1ff2 100644 --- a/MoreLinq/Zip.g.cs +++ b/MoreLinq/Zip.g.cs @@ -2110,53 +2110,16 @@ internal static IEnumerable CustomZip( using var firstEnumerator = new ZipEnumerator(firstSource.GetEnumerator(), nameof(firstSource), firstSourceConfiguration); using var secondEnumerator = new ZipEnumerator(secondSource.GetEnumerator(), nameof(secondSource), secondSourceConfiguration); - var enumerators = new IZipEnumerator[] - { + while (MoveNext( firstEnumerator, - secondEnumerator - }; - - for (;;) + secondEnumerator)) { - var isEnd = true; - IZipEnumerator equiStopper = null; - - foreach (var enumerator in enumerators) - { - switch (enumerator.MoveNext()) - { - case ZipEnumeratorStatus.AskForStop: - yield break; - case ZipEnumeratorStatus.AskForEquiStop: - if (!isEnd) // there is some sequences ahead - { - enumerator.ThrowToShort(); - } - equiStopper = enumerator; - break; - case ZipEnumeratorStatus.Continue: - equiStopper?.ThrowToShort(); - isEnd = false; - break; - case ZipEnumeratorStatus.EndOfStream: - break; - default: - throw new ArgumentOutOfRangeException(); - } - } - - if (isEnd) - { - yield break; - } - yield return resultSelector( firstEnumerator.Current, secondEnumerator.Current ); } } - internal static IEnumerable CustomZip( this IEnumerable firstSource, ZipSourceConfiguration firstSourceConfiguration, IEnumerable secondSource, ZipSourceConfiguration secondSourceConfiguration, @@ -2167,47 +2130,11 @@ internal static IEnumerable CustomZip( using var secondEnumerator = new ZipEnumerator(secondSource.GetEnumerator(), nameof(secondSource), secondSourceConfiguration); using var thirdEnumerator = new ZipEnumerator(thirdSource.GetEnumerator(), nameof(thirdSource), thirdSourceConfiguration); - var enumerators = new IZipEnumerator[] - { + while (MoveNext( firstEnumerator, secondEnumerator, - thirdEnumerator - }; - - for (;;) + thirdEnumerator)) { - var isEnd = true; - IZipEnumerator equiStopper = null; - - foreach (var enumerator in enumerators) - { - switch (enumerator.MoveNext()) - { - case ZipEnumeratorStatus.AskForStop: - yield break; - case ZipEnumeratorStatus.AskForEquiStop: - if (!isEnd) // there is some sequences ahead - { - enumerator.ThrowToShort(); - } - equiStopper = enumerator; - break; - case ZipEnumeratorStatus.Continue: - equiStopper?.ThrowToShort(); - isEnd = false; - break; - case ZipEnumeratorStatus.EndOfStream: - break; - default: - throw new ArgumentOutOfRangeException(); - } - } - - if (isEnd) - { - yield break; - } - yield return resultSelector( firstEnumerator.Current, secondEnumerator.Current, @@ -2215,7 +2142,6 @@ internal static IEnumerable CustomZip( ); } } - internal static IEnumerable CustomZip( this IEnumerable firstSource, ZipSourceConfiguration firstSourceConfiguration, IEnumerable secondSource, ZipSourceConfiguration secondSourceConfiguration, @@ -2228,48 +2154,12 @@ internal static IEnumerable CustomZip( using var thirdEnumerator = new ZipEnumerator(thirdSource.GetEnumerator(), nameof(thirdSource), thirdSourceConfiguration); using var fourthEnumerator = new ZipEnumerator(fourthSource.GetEnumerator(), nameof(fourthSource), fourthSourceConfiguration); - var enumerators = new IZipEnumerator[] - { + while (MoveNext( firstEnumerator, secondEnumerator, thirdEnumerator, - fourthEnumerator - }; - - for (;;) + fourthEnumerator)) { - var isEnd = true; - IZipEnumerator equiStopper = null; - - foreach (var enumerator in enumerators) - { - switch (enumerator.MoveNext()) - { - case ZipEnumeratorStatus.AskForStop: - yield break; - case ZipEnumeratorStatus.AskForEquiStop: - if (!isEnd) // there is some sequences ahead - { - enumerator.ThrowToShort(); - } - equiStopper = enumerator; - break; - case ZipEnumeratorStatus.Continue: - equiStopper?.ThrowToShort(); - isEnd = false; - break; - case ZipEnumeratorStatus.EndOfStream: - break; - default: - throw new ArgumentOutOfRangeException(); - } - } - - if (isEnd) - { - yield break; - } - yield return resultSelector( firstEnumerator.Current, secondEnumerator.Current, @@ -2278,7 +2168,6 @@ internal static IEnumerable CustomZip( ); } } - internal static IEnumerable CustomZip( this IEnumerable firstSource, ZipSourceConfiguration firstSourceConfiguration, IEnumerable secondSource, ZipSourceConfiguration secondSourceConfiguration, @@ -2293,49 +2182,13 @@ internal static IEnumerable CustomZip( using var fourthEnumerator = new ZipEnumerator(fourthSource.GetEnumerator(), nameof(fourthSource), fourthSourceConfiguration); using var fifthEnumerator = new ZipEnumerator(fifthSource.GetEnumerator(), nameof(fifthSource), fifthSourceConfiguration); - var enumerators = new IZipEnumerator[] - { + while (MoveNext( firstEnumerator, secondEnumerator, thirdEnumerator, fourthEnumerator, - fifthEnumerator - }; - - for (;;) + fifthEnumerator)) { - var isEnd = true; - IZipEnumerator equiStopper = null; - - foreach (var enumerator in enumerators) - { - switch (enumerator.MoveNext()) - { - case ZipEnumeratorStatus.AskForStop: - yield break; - case ZipEnumeratorStatus.AskForEquiStop: - if (!isEnd) // there is some sequences ahead - { - enumerator.ThrowToShort(); - } - equiStopper = enumerator; - break; - case ZipEnumeratorStatus.Continue: - equiStopper?.ThrowToShort(); - isEnd = false; - break; - case ZipEnumeratorStatus.EndOfStream: - break; - default: - throw new ArgumentOutOfRangeException(); - } - } - - if (isEnd) - { - yield break; - } - yield return resultSelector( firstEnumerator.Current, secondEnumerator.Current, @@ -2345,7 +2198,6 @@ internal static IEnumerable CustomZip( ); } } - internal static IEnumerable CustomZip( this IEnumerable firstSource, ZipSourceConfiguration firstSourceConfiguration, IEnumerable secondSource, ZipSourceConfiguration secondSourceConfiguration, @@ -2362,50 +2214,14 @@ internal static IEnumerable CustomZip( using var fifthEnumerator = new ZipEnumerator(fifthSource.GetEnumerator(), nameof(fifthSource), fifthSourceConfiguration); using var sixthEnumerator = new ZipEnumerator(sixthSource.GetEnumerator(), nameof(sixthSource), sixthSourceConfiguration); - var enumerators = new IZipEnumerator[] - { + while (MoveNext( firstEnumerator, secondEnumerator, thirdEnumerator, fourthEnumerator, fifthEnumerator, - sixthEnumerator - }; - - for (;;) + sixthEnumerator)) { - var isEnd = true; - IZipEnumerator equiStopper = null; - - foreach (var enumerator in enumerators) - { - switch (enumerator.MoveNext()) - { - case ZipEnumeratorStatus.AskForStop: - yield break; - case ZipEnumeratorStatus.AskForEquiStop: - if (!isEnd) // there is some sequences ahead - { - enumerator.ThrowToShort(); - } - equiStopper = enumerator; - break; - case ZipEnumeratorStatus.Continue: - equiStopper?.ThrowToShort(); - isEnd = false; - break; - case ZipEnumeratorStatus.EndOfStream: - break; - default: - throw new ArgumentOutOfRangeException(); - } - } - - if (isEnd) - { - yield break; - } - yield return resultSelector( firstEnumerator.Current, secondEnumerator.Current, @@ -2416,7 +2232,6 @@ internal static IEnumerable CustomZip( ); } } - internal static IEnumerable CustomZip( this IEnumerable firstSource, ZipSourceConfiguration firstSourceConfiguration, IEnumerable secondSource, ZipSourceConfiguration secondSourceConfiguration, @@ -2435,51 +2250,15 @@ internal static IEnumerable CustomZip(sixthSource.GetEnumerator(), nameof(sixthSource), sixthSourceConfiguration); using var seventhEnumerator = new ZipEnumerator(seventhSource.GetEnumerator(), nameof(seventhSource), seventhSourceConfiguration); - var enumerators = new IZipEnumerator[] - { + while (MoveNext( firstEnumerator, secondEnumerator, thirdEnumerator, fourthEnumerator, fifthEnumerator, sixthEnumerator, - seventhEnumerator - }; - - for (;;) + seventhEnumerator)) { - var isEnd = true; - IZipEnumerator equiStopper = null; - - foreach (var enumerator in enumerators) - { - switch (enumerator.MoveNext()) - { - case ZipEnumeratorStatus.AskForStop: - yield break; - case ZipEnumeratorStatus.AskForEquiStop: - if (!isEnd) // there is some sequences ahead - { - enumerator.ThrowToShort(); - } - equiStopper = enumerator; - break; - case ZipEnumeratorStatus.Continue: - equiStopper?.ThrowToShort(); - isEnd = false; - break; - case ZipEnumeratorStatus.EndOfStream: - break; - default: - throw new ArgumentOutOfRangeException(); - } - } - - if (isEnd) - { - yield break; - } - yield return resultSelector( firstEnumerator.Current, secondEnumerator.Current, @@ -2491,7 +2270,6 @@ internal static IEnumerable CustomZip CustomZip( this IEnumerable firstSource, ZipSourceConfiguration firstSourceConfiguration, IEnumerable secondSource, ZipSourceConfiguration secondSourceConfiguration, @@ -2512,8 +2290,7 @@ internal static IEnumerable CustomZip(seventhSource.GetEnumerator(), nameof(seventhSource), seventhSourceConfiguration); using var eighthEnumerator = new ZipEnumerator(eighthSource.GetEnumerator(), nameof(eighthSource), eighthSourceConfiguration); - var enumerators = new IZipEnumerator[] - { + while (MoveNext( firstEnumerator, secondEnumerator, thirdEnumerator, @@ -2521,43 +2298,8 @@ internal static IEnumerable CustomZip CustomZipEnumerator = new ZipEnumerator>(<#= arg.Ordinal #>Source.GetEnumerator(), nameof(<#= arg.Ordinal #>Source), <#= arg.Ordinal #>SourceConfiguration); <#} #> - var enumerators = new IZipEnumerator[] - { + while (MoveNext( <# foreach (var arg in o.Arguments) { #> - <#= arg.Ordinal #>Enumerator<#= arg.Num < o.Count ? "," : "" #> + <#= arg.Ordinal #>Enumerator<#= arg.Num < o.Count ? "," : "))" #> <#}#> - }; - - for (;;) { - var isEnd = true; - IZipEnumerator equiStopper = null; - - foreach (var enumerator in enumerators) - { - switch (enumerator.MoveNext()) - { - case ZipEnumeratorStatus.AskForStop: - yield break; - case ZipEnumeratorStatus.AskForEquiStop: - if (!isEnd) // there is some sequences ahead - { - enumerator.ThrowToShort(); - } - equiStopper = enumerator; - break; - case ZipEnumeratorStatus.Continue: - equiStopper?.ThrowToShort(); - isEnd = false; - break; - case ZipEnumeratorStatus.EndOfStream: - break; - default: - throw new ArgumentOutOfRangeException(); - } - } - - if (isEnd) - { - yield break; - } - yield return resultSelector( <# foreach (var arg in o.Arguments) { #> <#= arg.Ordinal #>Enumerator.Current<#= arg.Num < o.Count ? "," : "" #> @@ -367,8 +331,39 @@ namespace MoreLinq ); } } - <# } #> + + private static bool MoveNext(params IZipEnumerator[] enumerators) + { + var hasNext = false; + IZipEnumerator equiStopper = null; + + foreach (var enumerator in enumerators) + { + switch (enumerator.MoveNext()) + { + case ZipEnumeratorStatus.AskForStop: + return false; + case ZipEnumeratorStatus.AskForEquiStop: + if (hasNext) // there is some sequences ahead + { + enumerator.ThrowToShort(); + } + equiStopper = enumerator; + break; + case ZipEnumeratorStatus.Continue: + equiStopper?.ThrowToShort(); + hasNext = true; + break; + case ZipEnumeratorStatus.EndOfStream: + break; + default: + throw new ArgumentOutOfRangeException(); + } + } + + return hasNext; + } } internal interface IZipEnumerator From 57011783fcf28d5d4307cc46b46fb40f9a29bcf6 Mon Sep 17 00:00:00 2001 From: Orace Date: Tue, 5 Nov 2019 09:25:21 +0100 Subject: [PATCH 03/11] KISS for Zip --- MoreLinq/Zip.g.cs | 1488 +++++++++++++++++++++++---------------------- MoreLinq/Zip.g.tt | 256 +++----- 2 files changed, 860 insertions(+), 884 deletions(-) diff --git a/MoreLinq/Zip.g.cs b/MoreLinq/Zip.g.cs index 8fcaf1ff2..5136c03e3 100644 --- a/MoreLinq/Zip.g.cs +++ b/MoreLinq/Zip.g.cs @@ -52,10 +52,39 @@ public static IEnumerable EquiZip( if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return CustomZip( - firstSource, ZipSourceConfiguration.ThrowOnShort, - secondSource, ZipSourceConfiguration.ThrowOnShort, - resultSelector); + return _(); IEnumerable _() + { + using var e1 = firstSource.GetEnumerator(); + using var e2 = secondSource.GetEnumerator(); + + for (;;) + { + if (e1.MoveNext()) + { + if (e2.MoveNext()) + { + yield return resultSelector(e1.Current,e2.Current); + } + else + { + break; + } + } + else + { + if (e2.MoveNext()) + { + break; + } + else + { + yield break; + } + } + } + + throw new InvalidOperationException($"Sequences differ in length."); + } } /// @@ -80,12 +109,9 @@ public static IEnumerable EquiZip( this IEnumerable firstSource, IEnumerable secondSource) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - - return CustomZip( - firstSource, ZipSourceConfiguration.ThrowOnShort, - secondSource, ZipSourceConfiguration.ThrowOnShort, + return EquiZip( + firstSource, + secondSource, ValueTuple.Create); } @@ -118,10 +144,32 @@ public static IEnumerable ZipLongest( if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return CustomZip( - firstSource, ZipSourceConfiguration.PaddingWith(default), - secondSource, ZipSourceConfiguration.PaddingWith(default), - resultSelector); + return _(); IEnumerable _() + { + IEnumerator e1 = null; + IEnumerator e2 = null; + + try + { + e1 = firstSource.GetEnumerator(); + e2 = secondSource.GetEnumerator(); + + var v1 = default(T1); + var v2 = default(T2); + + while ( + ZipHelper.MoveNextOrDefault(ref e1, ref v1) | + ZipHelper.MoveNextOrDefault(ref e2, ref v2)) + { + yield return resultSelector(v1,v2); + } + } + finally + { + e1?.Dispose(); + e2?.Dispose(); + } + } } /// @@ -145,12 +193,9 @@ public static IEnumerable ZipLongest( this IEnumerable firstSource, IEnumerable secondSource) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - - return CustomZip( - firstSource, ZipSourceConfiguration.PaddingWith(default), - secondSource, ZipSourceConfiguration.PaddingWith(default), + return ZipLongest( + firstSource, + secondSource, ValueTuple.Create); } @@ -188,10 +233,16 @@ public static IEnumerable ZipShortest( if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return CustomZip( - firstSource, ZipSourceConfiguration.StopOnShort, - secondSource, ZipSourceConfiguration.StopOnShort, - resultSelector); + return _(); IEnumerable _() + { + using var e1 = firstSource.GetEnumerator(); + using var e2 = secondSource.GetEnumerator(); + + while (e1.MoveNext() && e2.MoveNext()) + { + yield return resultSelector(e1.Current,e2.Current); + } + } } /// @@ -220,12 +271,9 @@ public static IEnumerable ZipShortest( this IEnumerable firstSource, IEnumerable secondSource) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - - return CustomZip( - firstSource, ZipSourceConfiguration.StopOnShort, - secondSource, ZipSourceConfiguration.StopOnShort, + return ZipShortest( + firstSource, + secondSource, ValueTuple.Create); } @@ -263,11 +311,40 @@ public static IEnumerable EquiZip( if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return CustomZip( - firstSource, ZipSourceConfiguration.ThrowOnShort, - secondSource, ZipSourceConfiguration.ThrowOnShort, - thirdSource, ZipSourceConfiguration.ThrowOnShort, - resultSelector); + return _(); IEnumerable _() + { + using var e1 = firstSource.GetEnumerator(); + using var e2 = secondSource.GetEnumerator(); + using var e3 = thirdSource.GetEnumerator(); + + for (;;) + { + if (e1.MoveNext()) + { + if (e2.MoveNext() && e3.MoveNext()) + { + yield return resultSelector(e1.Current,e2.Current,e3.Current); + } + else + { + break; + } + } + else + { + if (e2.MoveNext() || e3.MoveNext()) + { + break; + } + else + { + yield break; + } + } + } + + throw new InvalidOperationException($"Sequences differ in length."); + } } /// @@ -295,14 +372,10 @@ public static IEnumerable EquiZip( IEnumerable secondSource, IEnumerable thirdSource) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - - return CustomZip( - firstSource, ZipSourceConfiguration.ThrowOnShort, - secondSource, ZipSourceConfiguration.ThrowOnShort, - thirdSource, ZipSourceConfiguration.ThrowOnShort, + return EquiZip( + firstSource, + secondSource, + thirdSource, ValueTuple.Create); } @@ -339,11 +412,37 @@ public static IEnumerable ZipLongest( if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return CustomZip( - firstSource, ZipSourceConfiguration.PaddingWith(default), - secondSource, ZipSourceConfiguration.PaddingWith(default), - thirdSource, ZipSourceConfiguration.PaddingWith(default), - resultSelector); + return _(); IEnumerable _() + { + IEnumerator e1 = null; + IEnumerator e2 = null; + IEnumerator e3 = null; + + try + { + e1 = firstSource.GetEnumerator(); + e2 = secondSource.GetEnumerator(); + e3 = thirdSource.GetEnumerator(); + + var v1 = default(T1); + var v2 = default(T2); + var v3 = default(T3); + + while ( + ZipHelper.MoveNextOrDefault(ref e1, ref v1) | + ZipHelper.MoveNextOrDefault(ref e2, ref v2) | + ZipHelper.MoveNextOrDefault(ref e3, ref v3)) + { + yield return resultSelector(v1,v2,v3); + } + } + finally + { + e1?.Dispose(); + e2?.Dispose(); + e3?.Dispose(); + } + } } /// @@ -370,14 +469,10 @@ public static IEnumerable ZipLongest( IEnumerable secondSource, IEnumerable thirdSource) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - - return CustomZip( - firstSource, ZipSourceConfiguration.PaddingWith(default), - secondSource, ZipSourceConfiguration.PaddingWith(default), - thirdSource, ZipSourceConfiguration.PaddingWith(default), + return ZipLongest( + firstSource, + secondSource, + thirdSource, ValueTuple.Create); } @@ -419,11 +514,17 @@ public static IEnumerable ZipShortest( if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return CustomZip( - firstSource, ZipSourceConfiguration.StopOnShort, - secondSource, ZipSourceConfiguration.StopOnShort, - thirdSource, ZipSourceConfiguration.StopOnShort, - resultSelector); + return _(); IEnumerable _() + { + using var e1 = firstSource.GetEnumerator(); + using var e2 = secondSource.GetEnumerator(); + using var e3 = thirdSource.GetEnumerator(); + + while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext()) + { + yield return resultSelector(e1.Current,e2.Current,e3.Current); + } + } } /// @@ -455,14 +556,10 @@ public static IEnumerable ZipShortest( IEnumerable secondSource, IEnumerable thirdSource) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - - return CustomZip( - firstSource, ZipSourceConfiguration.StopOnShort, - secondSource, ZipSourceConfiguration.StopOnShort, - thirdSource, ZipSourceConfiguration.StopOnShort, + return ZipShortest( + firstSource, + secondSource, + thirdSource, ValueTuple.Create); } @@ -504,12 +601,41 @@ public static IEnumerable EquiZip( if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return CustomZip( - firstSource, ZipSourceConfiguration.ThrowOnShort, - secondSource, ZipSourceConfiguration.ThrowOnShort, - thirdSource, ZipSourceConfiguration.ThrowOnShort, - fourthSource, ZipSourceConfiguration.ThrowOnShort, - resultSelector); + return _(); IEnumerable _() + { + using var e1 = firstSource.GetEnumerator(); + using var e2 = secondSource.GetEnumerator(); + using var e3 = thirdSource.GetEnumerator(); + using var e4 = fourthSource.GetEnumerator(); + + for (;;) + { + if (e1.MoveNext()) + { + if (e2.MoveNext() && e3.MoveNext() && e4.MoveNext()) + { + yield return resultSelector(e1.Current,e2.Current,e3.Current,e4.Current); + } + else + { + break; + } + } + else + { + if (e2.MoveNext() || e3.MoveNext() || e4.MoveNext()) + { + break; + } + else + { + yield break; + } + } + } + + throw new InvalidOperationException($"Sequences differ in length."); + } } /// @@ -540,16 +666,11 @@ public static IEnumerable EquiZip( IEnumerable thirdSource, IEnumerable fourthSource) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); - - return CustomZip( - firstSource, ZipSourceConfiguration.ThrowOnShort, - secondSource, ZipSourceConfiguration.ThrowOnShort, - thirdSource, ZipSourceConfiguration.ThrowOnShort, - fourthSource, ZipSourceConfiguration.ThrowOnShort, + return EquiZip( + firstSource, + secondSource, + thirdSource, + fourthSource, ValueTuple.Create); } @@ -590,12 +711,42 @@ public static IEnumerable ZipLongest( if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return CustomZip( - firstSource, ZipSourceConfiguration.PaddingWith(default), - secondSource, ZipSourceConfiguration.PaddingWith(default), - thirdSource, ZipSourceConfiguration.PaddingWith(default), - fourthSource, ZipSourceConfiguration.PaddingWith(default), - resultSelector); + return _(); IEnumerable _() + { + IEnumerator e1 = null; + IEnumerator e2 = null; + IEnumerator e3 = null; + IEnumerator e4 = null; + + try + { + e1 = firstSource.GetEnumerator(); + e2 = secondSource.GetEnumerator(); + e3 = thirdSource.GetEnumerator(); + e4 = fourthSource.GetEnumerator(); + + var v1 = default(T1); + var v2 = default(T2); + var v3 = default(T3); + var v4 = default(T4); + + while ( + ZipHelper.MoveNextOrDefault(ref e1, ref v1) | + ZipHelper.MoveNextOrDefault(ref e2, ref v2) | + ZipHelper.MoveNextOrDefault(ref e3, ref v3) | + ZipHelper.MoveNextOrDefault(ref e4, ref v4)) + { + yield return resultSelector(v1,v2,v3,v4); + } + } + finally + { + e1?.Dispose(); + e2?.Dispose(); + e3?.Dispose(); + e4?.Dispose(); + } + } } /// @@ -625,16 +776,11 @@ public static IEnumerable ZipLongest( IEnumerable thirdSource, IEnumerable fourthSource) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); - - return CustomZip( - firstSource, ZipSourceConfiguration.PaddingWith(default), - secondSource, ZipSourceConfiguration.PaddingWith(default), - thirdSource, ZipSourceConfiguration.PaddingWith(default), - fourthSource, ZipSourceConfiguration.PaddingWith(default), + return ZipLongest( + firstSource, + secondSource, + thirdSource, + fourthSource, ValueTuple.Create); } @@ -680,12 +826,18 @@ public static IEnumerable ZipShortest( if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return CustomZip( - firstSource, ZipSourceConfiguration.StopOnShort, - secondSource, ZipSourceConfiguration.StopOnShort, - thirdSource, ZipSourceConfiguration.StopOnShort, - fourthSource, ZipSourceConfiguration.StopOnShort, - resultSelector); + return _(); IEnumerable _() + { + using var e1 = firstSource.GetEnumerator(); + using var e2 = secondSource.GetEnumerator(); + using var e3 = thirdSource.GetEnumerator(); + using var e4 = fourthSource.GetEnumerator(); + + while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext() && e4.MoveNext()) + { + yield return resultSelector(e1.Current,e2.Current,e3.Current,e4.Current); + } + } } /// @@ -720,16 +872,11 @@ public static IEnumerable ZipShortest( IEnumerable thirdSource, IEnumerable fourthSource) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); - - return CustomZip( - firstSource, ZipSourceConfiguration.StopOnShort, - secondSource, ZipSourceConfiguration.StopOnShort, - thirdSource, ZipSourceConfiguration.StopOnShort, - fourthSource, ZipSourceConfiguration.StopOnShort, + return ZipShortest( + firstSource, + secondSource, + thirdSource, + fourthSource, ValueTuple.Create); } @@ -775,13 +922,42 @@ public static IEnumerable EquiZip( if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return CustomZip( - firstSource, ZipSourceConfiguration.ThrowOnShort, - secondSource, ZipSourceConfiguration.ThrowOnShort, - thirdSource, ZipSourceConfiguration.ThrowOnShort, - fourthSource, ZipSourceConfiguration.ThrowOnShort, - fifthSource, ZipSourceConfiguration.ThrowOnShort, - resultSelector); + return _(); IEnumerable _() + { + using var e1 = firstSource.GetEnumerator(); + using var e2 = secondSource.GetEnumerator(); + using var e3 = thirdSource.GetEnumerator(); + using var e4 = fourthSource.GetEnumerator(); + using var e5 = fifthSource.GetEnumerator(); + + for (;;) + { + if (e1.MoveNext()) + { + if (e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext()) + { + yield return resultSelector(e1.Current,e2.Current,e3.Current,e4.Current,e5.Current); + } + else + { + break; + } + } + else + { + if (e2.MoveNext() || e3.MoveNext() || e4.MoveNext() || e5.MoveNext()) + { + break; + } + else + { + yield break; + } + } + } + + throw new InvalidOperationException($"Sequences differ in length."); + } } /// @@ -815,18 +991,12 @@ public static IEnumerable EquiZip( IEnumerable fourthSource, IEnumerable fifthSource) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); - if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); - - return CustomZip( - firstSource, ZipSourceConfiguration.ThrowOnShort, - secondSource, ZipSourceConfiguration.ThrowOnShort, - thirdSource, ZipSourceConfiguration.ThrowOnShort, - fourthSource, ZipSourceConfiguration.ThrowOnShort, - fifthSource, ZipSourceConfiguration.ThrowOnShort, + return EquiZip( + firstSource, + secondSource, + thirdSource, + fourthSource, + fifthSource, ValueTuple.Create); } @@ -871,13 +1041,47 @@ public static IEnumerable ZipLongest( if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return CustomZip( - firstSource, ZipSourceConfiguration.PaddingWith(default), - secondSource, ZipSourceConfiguration.PaddingWith(default), - thirdSource, ZipSourceConfiguration.PaddingWith(default), - fourthSource, ZipSourceConfiguration.PaddingWith(default), - fifthSource, ZipSourceConfiguration.PaddingWith(default), - resultSelector); + return _(); IEnumerable _() + { + IEnumerator e1 = null; + IEnumerator e2 = null; + IEnumerator e3 = null; + IEnumerator e4 = null; + IEnumerator e5 = null; + + try + { + e1 = firstSource.GetEnumerator(); + e2 = secondSource.GetEnumerator(); + e3 = thirdSource.GetEnumerator(); + e4 = fourthSource.GetEnumerator(); + e5 = fifthSource.GetEnumerator(); + + var v1 = default(T1); + var v2 = default(T2); + var v3 = default(T3); + var v4 = default(T4); + var v5 = default(T5); + + while ( + ZipHelper.MoveNextOrDefault(ref e1, ref v1) | + ZipHelper.MoveNextOrDefault(ref e2, ref v2) | + ZipHelper.MoveNextOrDefault(ref e3, ref v3) | + ZipHelper.MoveNextOrDefault(ref e4, ref v4) | + ZipHelper.MoveNextOrDefault(ref e5, ref v5)) + { + yield return resultSelector(v1,v2,v3,v4,v5); + } + } + finally + { + e1?.Dispose(); + e2?.Dispose(); + e3?.Dispose(); + e4?.Dispose(); + e5?.Dispose(); + } + } } /// @@ -910,18 +1114,12 @@ public static IEnumerable ZipLongest( IEnumerable fourthSource, IEnumerable fifthSource) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); - if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); - - return CustomZip( - firstSource, ZipSourceConfiguration.PaddingWith(default), - secondSource, ZipSourceConfiguration.PaddingWith(default), - thirdSource, ZipSourceConfiguration.PaddingWith(default), - fourthSource, ZipSourceConfiguration.PaddingWith(default), - fifthSource, ZipSourceConfiguration.PaddingWith(default), + return ZipLongest( + firstSource, + secondSource, + thirdSource, + fourthSource, + fifthSource, ValueTuple.Create); } @@ -971,13 +1169,19 @@ public static IEnumerable ZipShortest( if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return CustomZip( - firstSource, ZipSourceConfiguration.StopOnShort, - secondSource, ZipSourceConfiguration.StopOnShort, - thirdSource, ZipSourceConfiguration.StopOnShort, - fourthSource, ZipSourceConfiguration.StopOnShort, - fifthSource, ZipSourceConfiguration.StopOnShort, - resultSelector); + return _(); IEnumerable _() + { + using var e1 = firstSource.GetEnumerator(); + using var e2 = secondSource.GetEnumerator(); + using var e3 = thirdSource.GetEnumerator(); + using var e4 = fourthSource.GetEnumerator(); + using var e5 = fifthSource.GetEnumerator(); + + while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext()) + { + yield return resultSelector(e1.Current,e2.Current,e3.Current,e4.Current,e5.Current); + } + } } /// @@ -1015,18 +1219,12 @@ public static IEnumerable ZipShortest( IEnumerable fourthSource, IEnumerable fifthSource) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); - if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); - - return CustomZip( - firstSource, ZipSourceConfiguration.StopOnShort, - secondSource, ZipSourceConfiguration.StopOnShort, - thirdSource, ZipSourceConfiguration.StopOnShort, - fourthSource, ZipSourceConfiguration.StopOnShort, - fifthSource, ZipSourceConfiguration.StopOnShort, + return ZipShortest( + firstSource, + secondSource, + thirdSource, + fourthSource, + fifthSource, ValueTuple.Create); } @@ -1076,14 +1274,43 @@ public static IEnumerable EquiZip( if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return CustomZip( - firstSource, ZipSourceConfiguration.ThrowOnShort, - secondSource, ZipSourceConfiguration.ThrowOnShort, - thirdSource, ZipSourceConfiguration.ThrowOnShort, - fourthSource, ZipSourceConfiguration.ThrowOnShort, - fifthSource, ZipSourceConfiguration.ThrowOnShort, - sixthSource, ZipSourceConfiguration.ThrowOnShort, - resultSelector); + return _(); IEnumerable _() + { + using var e1 = firstSource.GetEnumerator(); + using var e2 = secondSource.GetEnumerator(); + using var e3 = thirdSource.GetEnumerator(); + using var e4 = fourthSource.GetEnumerator(); + using var e5 = fifthSource.GetEnumerator(); + using var e6 = sixthSource.GetEnumerator(); + + for (;;) + { + if (e1.MoveNext()) + { + if (e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext() && e6.MoveNext()) + { + yield return resultSelector(e1.Current,e2.Current,e3.Current,e4.Current,e5.Current,e6.Current); + } + else + { + break; + } + } + else + { + if (e2.MoveNext() || e3.MoveNext() || e4.MoveNext() || e5.MoveNext() || e6.MoveNext()) + { + break; + } + else + { + yield break; + } + } + } + + throw new InvalidOperationException($"Sequences differ in length."); + } } /// @@ -1120,20 +1347,13 @@ public static IEnumerable EquiZip( IEnumerable fifthSource, IEnumerable sixthSource) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); - if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); - if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); - - return CustomZip( - firstSource, ZipSourceConfiguration.ThrowOnShort, - secondSource, ZipSourceConfiguration.ThrowOnShort, - thirdSource, ZipSourceConfiguration.ThrowOnShort, - fourthSource, ZipSourceConfiguration.ThrowOnShort, - fifthSource, ZipSourceConfiguration.ThrowOnShort, - sixthSource, ZipSourceConfiguration.ThrowOnShort, + return EquiZip( + firstSource, + secondSource, + thirdSource, + fourthSource, + fifthSource, + sixthSource, ValueTuple.Create); } @@ -1182,14 +1402,52 @@ public static IEnumerable ZipLongest( if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return CustomZip( - firstSource, ZipSourceConfiguration.PaddingWith(default), - secondSource, ZipSourceConfiguration.PaddingWith(default), - thirdSource, ZipSourceConfiguration.PaddingWith(default), - fourthSource, ZipSourceConfiguration.PaddingWith(default), - fifthSource, ZipSourceConfiguration.PaddingWith(default), - sixthSource, ZipSourceConfiguration.PaddingWith(default), - resultSelector); + return _(); IEnumerable _() + { + IEnumerator e1 = null; + IEnumerator e2 = null; + IEnumerator e3 = null; + IEnumerator e4 = null; + IEnumerator e5 = null; + IEnumerator e6 = null; + + try + { + e1 = firstSource.GetEnumerator(); + e2 = secondSource.GetEnumerator(); + e3 = thirdSource.GetEnumerator(); + e4 = fourthSource.GetEnumerator(); + e5 = fifthSource.GetEnumerator(); + e6 = sixthSource.GetEnumerator(); + + var v1 = default(T1); + var v2 = default(T2); + var v3 = default(T3); + var v4 = default(T4); + var v5 = default(T5); + var v6 = default(T6); + + while ( + ZipHelper.MoveNextOrDefault(ref e1, ref v1) | + ZipHelper.MoveNextOrDefault(ref e2, ref v2) | + ZipHelper.MoveNextOrDefault(ref e3, ref v3) | + ZipHelper.MoveNextOrDefault(ref e4, ref v4) | + ZipHelper.MoveNextOrDefault(ref e5, ref v5) | + ZipHelper.MoveNextOrDefault(ref e6, ref v6)) + { + yield return resultSelector(v1,v2,v3,v4,v5,v6); + } + } + finally + { + e1?.Dispose(); + e2?.Dispose(); + e3?.Dispose(); + e4?.Dispose(); + e5?.Dispose(); + e6?.Dispose(); + } + } } /// @@ -1225,20 +1483,13 @@ public static IEnumerable ZipLongest( IEnumerable fifthSource, IEnumerable sixthSource) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); - if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); - if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); - - return CustomZip( - firstSource, ZipSourceConfiguration.PaddingWith(default), - secondSource, ZipSourceConfiguration.PaddingWith(default), - thirdSource, ZipSourceConfiguration.PaddingWith(default), - fourthSource, ZipSourceConfiguration.PaddingWith(default), - fifthSource, ZipSourceConfiguration.PaddingWith(default), - sixthSource, ZipSourceConfiguration.PaddingWith(default), + return ZipLongest( + firstSource, + secondSource, + thirdSource, + fourthSource, + fifthSource, + sixthSource, ValueTuple.Create); } @@ -1292,14 +1543,20 @@ public static IEnumerable ZipShortest( if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return CustomZip( - firstSource, ZipSourceConfiguration.StopOnShort, - secondSource, ZipSourceConfiguration.StopOnShort, - thirdSource, ZipSourceConfiguration.StopOnShort, - fourthSource, ZipSourceConfiguration.StopOnShort, - fifthSource, ZipSourceConfiguration.StopOnShort, - sixthSource, ZipSourceConfiguration.StopOnShort, - resultSelector); + return _(); IEnumerable _() + { + using var e1 = firstSource.GetEnumerator(); + using var e2 = secondSource.GetEnumerator(); + using var e3 = thirdSource.GetEnumerator(); + using var e4 = fourthSource.GetEnumerator(); + using var e5 = fifthSource.GetEnumerator(); + using var e6 = sixthSource.GetEnumerator(); + + while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext() && e6.MoveNext()) + { + yield return resultSelector(e1.Current,e2.Current,e3.Current,e4.Current,e5.Current,e6.Current); + } + } } /// @@ -1340,20 +1597,13 @@ public static IEnumerable ZipShortest( IEnumerable fifthSource, IEnumerable sixthSource) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); - if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); - if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); - - return CustomZip( - firstSource, ZipSourceConfiguration.StopOnShort, - secondSource, ZipSourceConfiguration.StopOnShort, - thirdSource, ZipSourceConfiguration.StopOnShort, - fourthSource, ZipSourceConfiguration.StopOnShort, - fifthSource, ZipSourceConfiguration.StopOnShort, - sixthSource, ZipSourceConfiguration.StopOnShort, + return ZipShortest( + firstSource, + secondSource, + thirdSource, + fourthSource, + fifthSource, + sixthSource, ValueTuple.Create); } @@ -1407,15 +1657,44 @@ public static IEnumerable EquiZip( if (seventhSource == null) throw new ArgumentNullException(nameof(seventhSource)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return CustomZip( - firstSource, ZipSourceConfiguration.ThrowOnShort, - secondSource, ZipSourceConfiguration.ThrowOnShort, - thirdSource, ZipSourceConfiguration.ThrowOnShort, - fourthSource, ZipSourceConfiguration.ThrowOnShort, - fifthSource, ZipSourceConfiguration.ThrowOnShort, - sixthSource, ZipSourceConfiguration.ThrowOnShort, - seventhSource, ZipSourceConfiguration.ThrowOnShort, - resultSelector); + return _(); IEnumerable _() + { + using var e1 = firstSource.GetEnumerator(); + using var e2 = secondSource.GetEnumerator(); + using var e3 = thirdSource.GetEnumerator(); + using var e4 = fourthSource.GetEnumerator(); + using var e5 = fifthSource.GetEnumerator(); + using var e6 = sixthSource.GetEnumerator(); + using var e7 = seventhSource.GetEnumerator(); + + for (;;) + { + if (e1.MoveNext()) + { + if (e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext() && e6.MoveNext() && e7.MoveNext()) + { + yield return resultSelector(e1.Current,e2.Current,e3.Current,e4.Current,e5.Current,e6.Current,e7.Current); + } + else + { + break; + } + } + else + { + if (e2.MoveNext() || e3.MoveNext() || e4.MoveNext() || e5.MoveNext() || e6.MoveNext() || e7.MoveNext()) + { + break; + } + else + { + yield break; + } + } + } + + throw new InvalidOperationException($"Sequences differ in length."); + } } /// @@ -1455,22 +1734,14 @@ public static IEnumerable EquiZip( IEnumerable sixthSource, IEnumerable seventhSource) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); - if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); - if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); - if (seventhSource == null) throw new ArgumentNullException(nameof(seventhSource)); - - return CustomZip( - firstSource, ZipSourceConfiguration.ThrowOnShort, - secondSource, ZipSourceConfiguration.ThrowOnShort, - thirdSource, ZipSourceConfiguration.ThrowOnShort, - fourthSource, ZipSourceConfiguration.ThrowOnShort, - fifthSource, ZipSourceConfiguration.ThrowOnShort, - sixthSource, ZipSourceConfiguration.ThrowOnShort, - seventhSource, ZipSourceConfiguration.ThrowOnShort, + return EquiZip( + firstSource, + secondSource, + thirdSource, + fourthSource, + fifthSource, + sixthSource, + seventhSource, ValueTuple.Create); } @@ -1523,15 +1794,57 @@ public static IEnumerable ZipLongest.PaddingWith(default), - secondSource, ZipSourceConfiguration.PaddingWith(default), - thirdSource, ZipSourceConfiguration.PaddingWith(default), - fourthSource, ZipSourceConfiguration.PaddingWith(default), - fifthSource, ZipSourceConfiguration.PaddingWith(default), - sixthSource, ZipSourceConfiguration.PaddingWith(default), - seventhSource, ZipSourceConfiguration.PaddingWith(default), - resultSelector); + return _(); IEnumerable _() + { + IEnumerator e1 = null; + IEnumerator e2 = null; + IEnumerator e3 = null; + IEnumerator e4 = null; + IEnumerator e5 = null; + IEnumerator e6 = null; + IEnumerator e7 = null; + + try + { + e1 = firstSource.GetEnumerator(); + e2 = secondSource.GetEnumerator(); + e3 = thirdSource.GetEnumerator(); + e4 = fourthSource.GetEnumerator(); + e5 = fifthSource.GetEnumerator(); + e6 = sixthSource.GetEnumerator(); + e7 = seventhSource.GetEnumerator(); + + var v1 = default(T1); + var v2 = default(T2); + var v3 = default(T3); + var v4 = default(T4); + var v5 = default(T5); + var v6 = default(T6); + var v7 = default(T7); + + while ( + ZipHelper.MoveNextOrDefault(ref e1, ref v1) | + ZipHelper.MoveNextOrDefault(ref e2, ref v2) | + ZipHelper.MoveNextOrDefault(ref e3, ref v3) | + ZipHelper.MoveNextOrDefault(ref e4, ref v4) | + ZipHelper.MoveNextOrDefault(ref e5, ref v5) | + ZipHelper.MoveNextOrDefault(ref e6, ref v6) | + ZipHelper.MoveNextOrDefault(ref e7, ref v7)) + { + yield return resultSelector(v1,v2,v3,v4,v5,v6,v7); + } + } + finally + { + e1?.Dispose(); + e2?.Dispose(); + e3?.Dispose(); + e4?.Dispose(); + e5?.Dispose(); + e6?.Dispose(); + e7?.Dispose(); + } + } } /// @@ -1570,22 +1883,14 @@ public static IEnumerable ZipLongest sixthSource, IEnumerable seventhSource) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); - if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); - if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); - if (seventhSource == null) throw new ArgumentNullException(nameof(seventhSource)); - - return CustomZip( - firstSource, ZipSourceConfiguration.PaddingWith(default), - secondSource, ZipSourceConfiguration.PaddingWith(default), - thirdSource, ZipSourceConfiguration.PaddingWith(default), - fourthSource, ZipSourceConfiguration.PaddingWith(default), - fifthSource, ZipSourceConfiguration.PaddingWith(default), - sixthSource, ZipSourceConfiguration.PaddingWith(default), - seventhSource, ZipSourceConfiguration.PaddingWith(default), + return ZipLongest( + firstSource, + secondSource, + thirdSource, + fourthSource, + fifthSource, + sixthSource, + seventhSource, ValueTuple.Create); } @@ -1643,15 +1948,21 @@ public static IEnumerable ZipShortest.StopOnShort, - secondSource, ZipSourceConfiguration.StopOnShort, - thirdSource, ZipSourceConfiguration.StopOnShort, - fourthSource, ZipSourceConfiguration.StopOnShort, - fifthSource, ZipSourceConfiguration.StopOnShort, - sixthSource, ZipSourceConfiguration.StopOnShort, - seventhSource, ZipSourceConfiguration.StopOnShort, - resultSelector); + return _(); IEnumerable _() + { + using var e1 = firstSource.GetEnumerator(); + using var e2 = secondSource.GetEnumerator(); + using var e3 = thirdSource.GetEnumerator(); + using var e4 = fourthSource.GetEnumerator(); + using var e5 = fifthSource.GetEnumerator(); + using var e6 = sixthSource.GetEnumerator(); + using var e7 = seventhSource.GetEnumerator(); + + while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext() && e6.MoveNext() && e7.MoveNext()) + { + yield return resultSelector(e1.Current,e2.Current,e3.Current,e4.Current,e5.Current,e6.Current,e7.Current); + } + } } /// @@ -1695,22 +2006,14 @@ public static IEnumerable ZipShortest sixthSource, IEnumerable seventhSource) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); - if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); - if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); - if (seventhSource == null) throw new ArgumentNullException(nameof(seventhSource)); - - return CustomZip( - firstSource, ZipSourceConfiguration.StopOnShort, - secondSource, ZipSourceConfiguration.StopOnShort, - thirdSource, ZipSourceConfiguration.StopOnShort, - fourthSource, ZipSourceConfiguration.StopOnShort, - fifthSource, ZipSourceConfiguration.StopOnShort, - sixthSource, ZipSourceConfiguration.StopOnShort, - seventhSource, ZipSourceConfiguration.StopOnShort, + return ZipShortest( + firstSource, + secondSource, + thirdSource, + fourthSource, + fifthSource, + sixthSource, + seventhSource, ValueTuple.Create); } @@ -1768,16 +2071,45 @@ public static IEnumerable EquiZip.ThrowOnShort, - secondSource, ZipSourceConfiguration.ThrowOnShort, - thirdSource, ZipSourceConfiguration.ThrowOnShort, - fourthSource, ZipSourceConfiguration.ThrowOnShort, - fifthSource, ZipSourceConfiguration.ThrowOnShort, - sixthSource, ZipSourceConfiguration.ThrowOnShort, - seventhSource, ZipSourceConfiguration.ThrowOnShort, - eighthSource, ZipSourceConfiguration.ThrowOnShort, - resultSelector); + return _(); IEnumerable _() + { + using var e1 = firstSource.GetEnumerator(); + using var e2 = secondSource.GetEnumerator(); + using var e3 = thirdSource.GetEnumerator(); + using var e4 = fourthSource.GetEnumerator(); + using var e5 = fifthSource.GetEnumerator(); + using var e6 = sixthSource.GetEnumerator(); + using var e7 = seventhSource.GetEnumerator(); + using var e8 = eighthSource.GetEnumerator(); + + for (;;) + { + if (e1.MoveNext()) + { + if (e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext() && e6.MoveNext() && e7.MoveNext() && e8.MoveNext()) + { + yield return resultSelector(e1.Current,e2.Current,e3.Current,e4.Current,e5.Current,e6.Current,e7.Current,e8.Current); + } + else + { + break; + } + } + else + { + if (e2.MoveNext() || e3.MoveNext() || e4.MoveNext() || e5.MoveNext() || e6.MoveNext() || e7.MoveNext() || e8.MoveNext()) + { + break; + } + else + { + yield break; + } + } + } + + throw new InvalidOperationException($"Sequences differ in length."); + } } /// @@ -1820,24 +2152,15 @@ public static IEnumerable EquiZip seventhSource, IEnumerable eighthSource) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); - if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); - if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); - if (seventhSource == null) throw new ArgumentNullException(nameof(seventhSource)); - if (eighthSource == null) throw new ArgumentNullException(nameof(eighthSource)); - - return CustomZip( - firstSource, ZipSourceConfiguration.ThrowOnShort, - secondSource, ZipSourceConfiguration.ThrowOnShort, - thirdSource, ZipSourceConfiguration.ThrowOnShort, - fourthSource, ZipSourceConfiguration.ThrowOnShort, - fifthSource, ZipSourceConfiguration.ThrowOnShort, - sixthSource, ZipSourceConfiguration.ThrowOnShort, - seventhSource, ZipSourceConfiguration.ThrowOnShort, - eighthSource, ZipSourceConfiguration.ThrowOnShort, + return EquiZip( + firstSource, + secondSource, + thirdSource, + fourthSource, + fifthSource, + sixthSource, + seventhSource, + eighthSource, ValueTuple.Create); } @@ -1894,16 +2217,62 @@ public static IEnumerable ZipLongest.PaddingWith(default), - secondSource, ZipSourceConfiguration.PaddingWith(default), - thirdSource, ZipSourceConfiguration.PaddingWith(default), - fourthSource, ZipSourceConfiguration.PaddingWith(default), - fifthSource, ZipSourceConfiguration.PaddingWith(default), - sixthSource, ZipSourceConfiguration.PaddingWith(default), - seventhSource, ZipSourceConfiguration.PaddingWith(default), - eighthSource, ZipSourceConfiguration.PaddingWith(default), - resultSelector); + return _(); IEnumerable _() + { + IEnumerator e1 = null; + IEnumerator e2 = null; + IEnumerator e3 = null; + IEnumerator e4 = null; + IEnumerator e5 = null; + IEnumerator e6 = null; + IEnumerator e7 = null; + IEnumerator e8 = null; + + try + { + e1 = firstSource.GetEnumerator(); + e2 = secondSource.GetEnumerator(); + e3 = thirdSource.GetEnumerator(); + e4 = fourthSource.GetEnumerator(); + e5 = fifthSource.GetEnumerator(); + e6 = sixthSource.GetEnumerator(); + e7 = seventhSource.GetEnumerator(); + e8 = eighthSource.GetEnumerator(); + + var v1 = default(T1); + var v2 = default(T2); + var v3 = default(T3); + var v4 = default(T4); + var v5 = default(T5); + var v6 = default(T6); + var v7 = default(T7); + var v8 = default(T8); + + while ( + ZipHelper.MoveNextOrDefault(ref e1, ref v1) | + ZipHelper.MoveNextOrDefault(ref e2, ref v2) | + ZipHelper.MoveNextOrDefault(ref e3, ref v3) | + ZipHelper.MoveNextOrDefault(ref e4, ref v4) | + ZipHelper.MoveNextOrDefault(ref e5, ref v5) | + ZipHelper.MoveNextOrDefault(ref e6, ref v6) | + ZipHelper.MoveNextOrDefault(ref e7, ref v7) | + ZipHelper.MoveNextOrDefault(ref e8, ref v8)) + { + yield return resultSelector(v1,v2,v3,v4,v5,v6,v7,v8); + } + } + finally + { + e1?.Dispose(); + e2?.Dispose(); + e3?.Dispose(); + e4?.Dispose(); + e5?.Dispose(); + e6?.Dispose(); + e7?.Dispose(); + e8?.Dispose(); + } + } } /// @@ -1945,24 +2314,15 @@ public static IEnumerable ZipLongest seventhSource, IEnumerable eighthSource) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); - if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); - if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); - if (seventhSource == null) throw new ArgumentNullException(nameof(seventhSource)); - if (eighthSource == null) throw new ArgumentNullException(nameof(eighthSource)); - - return CustomZip( - firstSource, ZipSourceConfiguration.PaddingWith(default), - secondSource, ZipSourceConfiguration.PaddingWith(default), - thirdSource, ZipSourceConfiguration.PaddingWith(default), - fourthSource, ZipSourceConfiguration.PaddingWith(default), - fifthSource, ZipSourceConfiguration.PaddingWith(default), - sixthSource, ZipSourceConfiguration.PaddingWith(default), - seventhSource, ZipSourceConfiguration.PaddingWith(default), - eighthSource, ZipSourceConfiguration.PaddingWith(default), + return ZipLongest( + firstSource, + secondSource, + thirdSource, + fourthSource, + fifthSource, + sixthSource, + seventhSource, + eighthSource, ValueTuple.Create); } @@ -2024,16 +2384,22 @@ public static IEnumerable ZipShortest.StopOnShort, - secondSource, ZipSourceConfiguration.StopOnShort, - thirdSource, ZipSourceConfiguration.StopOnShort, - fourthSource, ZipSourceConfiguration.StopOnShort, - fifthSource, ZipSourceConfiguration.StopOnShort, - sixthSource, ZipSourceConfiguration.StopOnShort, - seventhSource, ZipSourceConfiguration.StopOnShort, - eighthSource, ZipSourceConfiguration.StopOnShort, - resultSelector); + return _(); IEnumerable _() + { + using var e1 = firstSource.GetEnumerator(); + using var e2 = secondSource.GetEnumerator(); + using var e3 = thirdSource.GetEnumerator(); + using var e4 = fourthSource.GetEnumerator(); + using var e5 = fifthSource.GetEnumerator(); + using var e6 = sixthSource.GetEnumerator(); + using var e7 = seventhSource.GetEnumerator(); + using var e8 = eighthSource.GetEnumerator(); + + while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext() && e6.MoveNext() && e7.MoveNext() && e8.MoveNext()) + { + yield return resultSelector(e1.Current,e2.Current,e3.Current,e4.Current,e5.Current,e6.Current,e7.Current,e8.Current); + } + } } /// @@ -2080,354 +2446,38 @@ public static IEnumerable ZipShortest seventhSource, IEnumerable eighthSource) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); - if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); - if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); - if (seventhSource == null) throw new ArgumentNullException(nameof(seventhSource)); - if (eighthSource == null) throw new ArgumentNullException(nameof(eighthSource)); - - return CustomZip( - firstSource, ZipSourceConfiguration.StopOnShort, - secondSource, ZipSourceConfiguration.StopOnShort, - thirdSource, ZipSourceConfiguration.StopOnShort, - fourthSource, ZipSourceConfiguration.StopOnShort, - fifthSource, ZipSourceConfiguration.StopOnShort, - sixthSource, ZipSourceConfiguration.StopOnShort, - seventhSource, ZipSourceConfiguration.StopOnShort, - eighthSource, ZipSourceConfiguration.StopOnShort, + return ZipShortest( + firstSource, + secondSource, + thirdSource, + fourthSource, + fifthSource, + sixthSource, + seventhSource, + eighthSource, ValueTuple.Create); } - - internal static IEnumerable CustomZip( - this IEnumerable firstSource, ZipSourceConfiguration firstSourceConfiguration, - IEnumerable secondSource, ZipSourceConfiguration secondSourceConfiguration, - Func resultSelector) - { - using var firstEnumerator = new ZipEnumerator(firstSource.GetEnumerator(), nameof(firstSource), firstSourceConfiguration); - using var secondEnumerator = new ZipEnumerator(secondSource.GetEnumerator(), nameof(secondSource), secondSourceConfiguration); - - while (MoveNext( - firstEnumerator, - secondEnumerator)) - { - yield return resultSelector( - firstEnumerator.Current, - secondEnumerator.Current - ); - } - } - internal static IEnumerable CustomZip( - this IEnumerable firstSource, ZipSourceConfiguration firstSourceConfiguration, - IEnumerable secondSource, ZipSourceConfiguration secondSourceConfiguration, - IEnumerable thirdSource, ZipSourceConfiguration thirdSourceConfiguration, - Func resultSelector) - { - using var firstEnumerator = new ZipEnumerator(firstSource.GetEnumerator(), nameof(firstSource), firstSourceConfiguration); - using var secondEnumerator = new ZipEnumerator(secondSource.GetEnumerator(), nameof(secondSource), secondSourceConfiguration); - using var thirdEnumerator = new ZipEnumerator(thirdSource.GetEnumerator(), nameof(thirdSource), thirdSourceConfiguration); - - while (MoveNext( - firstEnumerator, - secondEnumerator, - thirdEnumerator)) - { - yield return resultSelector( - firstEnumerator.Current, - secondEnumerator.Current, - thirdEnumerator.Current - ); - } - } - internal static IEnumerable CustomZip( - this IEnumerable firstSource, ZipSourceConfiguration firstSourceConfiguration, - IEnumerable secondSource, ZipSourceConfiguration secondSourceConfiguration, - IEnumerable thirdSource, ZipSourceConfiguration thirdSourceConfiguration, - IEnumerable fourthSource, ZipSourceConfiguration fourthSourceConfiguration, - Func resultSelector) - { - using var firstEnumerator = new ZipEnumerator(firstSource.GetEnumerator(), nameof(firstSource), firstSourceConfiguration); - using var secondEnumerator = new ZipEnumerator(secondSource.GetEnumerator(), nameof(secondSource), secondSourceConfiguration); - using var thirdEnumerator = new ZipEnumerator(thirdSource.GetEnumerator(), nameof(thirdSource), thirdSourceConfiguration); - using var fourthEnumerator = new ZipEnumerator(fourthSource.GetEnumerator(), nameof(fourthSource), fourthSourceConfiguration); - - while (MoveNext( - firstEnumerator, - secondEnumerator, - thirdEnumerator, - fourthEnumerator)) - { - yield return resultSelector( - firstEnumerator.Current, - secondEnumerator.Current, - thirdEnumerator.Current, - fourthEnumerator.Current - ); - } - } - internal static IEnumerable CustomZip( - this IEnumerable firstSource, ZipSourceConfiguration firstSourceConfiguration, - IEnumerable secondSource, ZipSourceConfiguration secondSourceConfiguration, - IEnumerable thirdSource, ZipSourceConfiguration thirdSourceConfiguration, - IEnumerable fourthSource, ZipSourceConfiguration fourthSourceConfiguration, - IEnumerable fifthSource, ZipSourceConfiguration fifthSourceConfiguration, - Func resultSelector) - { - using var firstEnumerator = new ZipEnumerator(firstSource.GetEnumerator(), nameof(firstSource), firstSourceConfiguration); - using var secondEnumerator = new ZipEnumerator(secondSource.GetEnumerator(), nameof(secondSource), secondSourceConfiguration); - using var thirdEnumerator = new ZipEnumerator(thirdSource.GetEnumerator(), nameof(thirdSource), thirdSourceConfiguration); - using var fourthEnumerator = new ZipEnumerator(fourthSource.GetEnumerator(), nameof(fourthSource), fourthSourceConfiguration); - using var fifthEnumerator = new ZipEnumerator(fifthSource.GetEnumerator(), nameof(fifthSource), fifthSourceConfiguration); - - while (MoveNext( - firstEnumerator, - secondEnumerator, - thirdEnumerator, - fourthEnumerator, - fifthEnumerator)) - { - yield return resultSelector( - firstEnumerator.Current, - secondEnumerator.Current, - thirdEnumerator.Current, - fourthEnumerator.Current, - fifthEnumerator.Current - ); - } - } - internal static IEnumerable CustomZip( - this IEnumerable firstSource, ZipSourceConfiguration firstSourceConfiguration, - IEnumerable secondSource, ZipSourceConfiguration secondSourceConfiguration, - IEnumerable thirdSource, ZipSourceConfiguration thirdSourceConfiguration, - IEnumerable fourthSource, ZipSourceConfiguration fourthSourceConfiguration, - IEnumerable fifthSource, ZipSourceConfiguration fifthSourceConfiguration, - IEnumerable sixthSource, ZipSourceConfiguration sixthSourceConfiguration, - Func resultSelector) - { - using var firstEnumerator = new ZipEnumerator(firstSource.GetEnumerator(), nameof(firstSource), firstSourceConfiguration); - using var secondEnumerator = new ZipEnumerator(secondSource.GetEnumerator(), nameof(secondSource), secondSourceConfiguration); - using var thirdEnumerator = new ZipEnumerator(thirdSource.GetEnumerator(), nameof(thirdSource), thirdSourceConfiguration); - using var fourthEnumerator = new ZipEnumerator(fourthSource.GetEnumerator(), nameof(fourthSource), fourthSourceConfiguration); - using var fifthEnumerator = new ZipEnumerator(fifthSource.GetEnumerator(), nameof(fifthSource), fifthSourceConfiguration); - using var sixthEnumerator = new ZipEnumerator(sixthSource.GetEnumerator(), nameof(sixthSource), sixthSourceConfiguration); - - while (MoveNext( - firstEnumerator, - secondEnumerator, - thirdEnumerator, - fourthEnumerator, - fifthEnumerator, - sixthEnumerator)) - { - yield return resultSelector( - firstEnumerator.Current, - secondEnumerator.Current, - thirdEnumerator.Current, - fourthEnumerator.Current, - fifthEnumerator.Current, - sixthEnumerator.Current - ); - } - } - internal static IEnumerable CustomZip( - this IEnumerable firstSource, ZipSourceConfiguration firstSourceConfiguration, - IEnumerable secondSource, ZipSourceConfiguration secondSourceConfiguration, - IEnumerable thirdSource, ZipSourceConfiguration thirdSourceConfiguration, - IEnumerable fourthSource, ZipSourceConfiguration fourthSourceConfiguration, - IEnumerable fifthSource, ZipSourceConfiguration fifthSourceConfiguration, - IEnumerable sixthSource, ZipSourceConfiguration sixthSourceConfiguration, - IEnumerable seventhSource, ZipSourceConfiguration seventhSourceConfiguration, - Func resultSelector) - { - using var firstEnumerator = new ZipEnumerator(firstSource.GetEnumerator(), nameof(firstSource), firstSourceConfiguration); - using var secondEnumerator = new ZipEnumerator(secondSource.GetEnumerator(), nameof(secondSource), secondSourceConfiguration); - using var thirdEnumerator = new ZipEnumerator(thirdSource.GetEnumerator(), nameof(thirdSource), thirdSourceConfiguration); - using var fourthEnumerator = new ZipEnumerator(fourthSource.GetEnumerator(), nameof(fourthSource), fourthSourceConfiguration); - using var fifthEnumerator = new ZipEnumerator(fifthSource.GetEnumerator(), nameof(fifthSource), fifthSourceConfiguration); - using var sixthEnumerator = new ZipEnumerator(sixthSource.GetEnumerator(), nameof(sixthSource), sixthSourceConfiguration); - using var seventhEnumerator = new ZipEnumerator(seventhSource.GetEnumerator(), nameof(seventhSource), seventhSourceConfiguration); - - while (MoveNext( - firstEnumerator, - secondEnumerator, - thirdEnumerator, - fourthEnumerator, - fifthEnumerator, - sixthEnumerator, - seventhEnumerator)) - { - yield return resultSelector( - firstEnumerator.Current, - secondEnumerator.Current, - thirdEnumerator.Current, - fourthEnumerator.Current, - fifthEnumerator.Current, - sixthEnumerator.Current, - seventhEnumerator.Current - ); - } - } - internal static IEnumerable CustomZip( - this IEnumerable firstSource, ZipSourceConfiguration firstSourceConfiguration, - IEnumerable secondSource, ZipSourceConfiguration secondSourceConfiguration, - IEnumerable thirdSource, ZipSourceConfiguration thirdSourceConfiguration, - IEnumerable fourthSource, ZipSourceConfiguration fourthSourceConfiguration, - IEnumerable fifthSource, ZipSourceConfiguration fifthSourceConfiguration, - IEnumerable sixthSource, ZipSourceConfiguration sixthSourceConfiguration, - IEnumerable seventhSource, ZipSourceConfiguration seventhSourceConfiguration, - IEnumerable eighthSource, ZipSourceConfiguration eighthSourceConfiguration, - Func resultSelector) - { - using var firstEnumerator = new ZipEnumerator(firstSource.GetEnumerator(), nameof(firstSource), firstSourceConfiguration); - using var secondEnumerator = new ZipEnumerator(secondSource.GetEnumerator(), nameof(secondSource), secondSourceConfiguration); - using var thirdEnumerator = new ZipEnumerator(thirdSource.GetEnumerator(), nameof(thirdSource), thirdSourceConfiguration); - using var fourthEnumerator = new ZipEnumerator(fourthSource.GetEnumerator(), nameof(fourthSource), fourthSourceConfiguration); - using var fifthEnumerator = new ZipEnumerator(fifthSource.GetEnumerator(), nameof(fifthSource), fifthSourceConfiguration); - using var sixthEnumerator = new ZipEnumerator(sixthSource.GetEnumerator(), nameof(sixthSource), sixthSourceConfiguration); - using var seventhEnumerator = new ZipEnumerator(seventhSource.GetEnumerator(), nameof(seventhSource), seventhSourceConfiguration); - using var eighthEnumerator = new ZipEnumerator(eighthSource.GetEnumerator(), nameof(eighthSource), eighthSourceConfiguration); - - while (MoveNext( - firstEnumerator, - secondEnumerator, - thirdEnumerator, - fourthEnumerator, - fifthEnumerator, - sixthEnumerator, - seventhEnumerator, - eighthEnumerator)) - { - yield return resultSelector( - firstEnumerator.Current, - secondEnumerator.Current, - thirdEnumerator.Current, - fourthEnumerator.Current, - fifthEnumerator.Current, - sixthEnumerator.Current, - seventhEnumerator.Current, - eighthEnumerator.Current - ); - } - } - - private static bool MoveNext(params IZipEnumerator[] enumerators) + static class ZipHelper { - var hasNext = false; - IZipEnumerator equiStopper = null; - - foreach (var enumerator in enumerators) + public static bool MoveNextOrDefault(ref IEnumerator enumerator, ref T value) { - switch (enumerator.MoveNext()) + if (enumerator == null) { - case ZipEnumeratorStatus.AskForStop: - return false; - case ZipEnumeratorStatus.AskForEquiStop: - if (hasNext) // there is some sequences ahead - { - enumerator.ThrowToShort(); - } - equiStopper = enumerator; - break; - case ZipEnumeratorStatus.Continue: - equiStopper?.ThrowToShort(); - hasNext = true; - break; - case ZipEnumeratorStatus.EndOfStream: - break; - default: - throw new ArgumentOutOfRangeException(); + return false; } - } - - return hasNext; - } - } - - internal interface IZipEnumerator - { - ZipEnumeratorStatus MoveNext(); - void ThrowToShort(); - } - - internal class ZipEnumerator : IZipEnumerator, IDisposable - { - private readonly ZipSourceConfiguration _configuration; - private readonly string _name; - private IEnumerator _source; - public ZipEnumerator(IEnumerator source, string name, ZipSourceConfiguration configuration) - { - _source = source; - _name = name; - _configuration = configuration; - } - - public T Current => _source == null ? _configuration.PaddingValue : _source.Current; - - public void Dispose() => _source?.Dispose(); - - public ZipEnumeratorStatus MoveNext() - { - if (_source?.MoveNext() == false) - { - _source.Dispose(); - _source = null; - } - - if (_source != null) - { - return ZipEnumeratorStatus.Continue; - } + if (enumerator.MoveNext()) + { + value = enumerator.Current; + return true; + } - switch (_configuration.Behavior) - { - case ZipEnumeratorBehavior.StopOnShort: - return ZipEnumeratorStatus.AskForStop; - case ZipEnumeratorBehavior.Padding: - return ZipEnumeratorStatus.EndOfStream; - case ZipEnumeratorBehavior.ThrowOnShort: - return ZipEnumeratorStatus.AskForEquiStop; - default: - throw new ArgumentOutOfRangeException(); + enumerator.Dispose(); + enumerator = null; + value = default; + return false; } } - - public void Reset() => _source.Reset(); - - public void ThrowToShort() => throw new InvalidOperationException($"{_name} sequence too short."); - } - - internal enum ZipEnumeratorBehavior - { - StopOnShort, - ThrowOnShort, - Padding - } - - internal enum ZipEnumeratorStatus - { - AskForStop, - AskForEquiStop, - Continue, - EndOfStream - } - - internal class ZipSourceConfiguration - { - public static ZipSourceConfiguration StopOnShort { get; } = new ZipSourceConfiguration(ZipEnumeratorBehavior.StopOnShort, default); - public static ZipSourceConfiguration ThrowOnShort { get; } = new ZipSourceConfiguration(ZipEnumeratorBehavior.ThrowOnShort, default); - public static ZipSourceConfiguration PaddingWith(T paddingValue) => new ZipSourceConfiguration(ZipEnumeratorBehavior.Padding, paddingValue); - - ZipSourceConfiguration(ZipEnumeratorBehavior behavior, T paddingValue) - { - Behavior = behavior; - PaddingValue = paddingValue; - } - - public ZipEnumeratorBehavior Behavior { get; } - public T PaddingValue { get; } } } diff --git a/MoreLinq/Zip.g.tt b/MoreLinq/Zip.g.tt index 933d92fab..fb16b1369 100644 --- a/MoreLinq/Zip.g.tt +++ b/MoreLinq/Zip.g.tt @@ -101,11 +101,40 @@ namespace MoreLinq <#} #> if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return CustomZip( + return _(); IEnumerable _() + { <# foreach (var arg in o.Arguments) { #> - <#= arg.Ordinal #>Source, ZipSourceConfiguration>.ThrowOnShort, -<#}#> - resultSelector); + using var e<#= arg.Number #> = <#= arg.Ordinal #>Source.GetEnumerator(); +<#} #> + + for (;;) + { + if (e<#= o.Arguments.First().Number #>.MoveNext()) + { + if (<# foreach (var arg in o.Arguments.Skip(1)) { #>e<#= arg.Number #>.MoveNext()<#= arg.Num < o.Count ? " && " : "" #><#}#>) + { + yield return resultSelector(<# foreach (var arg in o.Arguments) { #>e<#= arg.Number #>.Current<#= arg.Num < o.Count ? "," : "" #><#}#>); + } + else + { + break; + } + } + else + { + if (<# foreach (var arg in o.Arguments.Skip(1)) { #>e<#= arg.Number #>.MoveNext()<#= arg.Num < o.Count ? " || " : "" #><#}#>) + { + break; + } + else + { + yield break; + } + } + } + + throw new InvalidOperationException($"Sequences differ in length."); + } } /// @@ -133,13 +162,9 @@ namespace MoreLinq <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #>Source<#= arg.Num < o.Count ? "," : ")" #> <#}#> { + return EquiZip( <# foreach (var arg in o.Arguments) { #> - if (<#= arg.Ordinal #>Source == null) throw new ArgumentNullException(nameof(<#= arg.Ordinal #>Source)); -<#} #> - - return CustomZip( -<# foreach (var arg in o.Arguments) { #> - <#= arg.Ordinal #>Source, ZipSourceConfiguration>.ThrowOnShort, + <#= arg.Ordinal #>Source, <#}#> ValueTuple.Create); } @@ -177,11 +202,37 @@ namespace MoreLinq <#} #> if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return CustomZip( + return _(); IEnumerable _() + { +<# foreach (var arg in o.Arguments) { #> + IEnumerator> e<#= arg.Number #> = null; +<#} #> + + try + { <# foreach (var arg in o.Arguments) { #> - <#= arg.Ordinal #>Source, ZipSourceConfiguration>.PaddingWith(default), + e<#= arg.Number #> = <#= arg.Ordinal #>Source.GetEnumerator(); +<#} #> + +<# foreach (var arg in o.Arguments) { #> + var v<#= arg.Number #> = default(T<#= arg.Number #>); +<#} #> + + while ( +<# foreach (var arg in o.Arguments) { #> + ZipHelper.MoveNextOrDefault>(ref e<#= arg.Number #>, ref v<#= arg.Number #>)<#= arg.Num < o.Count ? " | " : ")" #> <#}#> - resultSelector); + { + yield return resultSelector(<# foreach (var arg in o.Arguments) { #>v<#= arg.Number #><#= arg.Num < o.Count ? "," : "" #><#}#>); + } + } + finally + { +<# foreach (var arg in o.Arguments) { #> + e<#= arg.Number #>?.Dispose(); +<#} #> + } + } } /// @@ -208,13 +259,9 @@ namespace MoreLinq <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #>Source<#= arg.Num < o.Count ? "," : ")" #> <#}#> { + return ZipLongest( <# foreach (var arg in o.Arguments) { #> - if (<#= arg.Ordinal #>Source == null) throw new ArgumentNullException(nameof(<#= arg.Ordinal #>Source)); -<#} #> - - return CustomZip( -<# foreach (var arg in o.Arguments) { #> - <#= arg.Ordinal #>Source, ZipSourceConfiguration>.PaddingWith(default), + <#= arg.Ordinal #>Source, <#}#> ValueTuple.Create); } @@ -257,11 +304,17 @@ namespace MoreLinq <#} #> if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - return CustomZip( + return _(); IEnumerable _() + { <# foreach (var arg in o.Arguments) { #> - <#= arg.Ordinal #>Source, ZipSourceConfiguration>.StopOnShort, -<#}#> - resultSelector); + using var e<#= arg.Number #> = <#= arg.Ordinal #>Source.GetEnumerator(); +<#} #> + + while (<# foreach (var arg in o.Arguments) { #>e<#= arg.Number #>.MoveNext()<#= arg.Num < o.Count ? " && " : "" #><#}#>) + { + yield return resultSelector(<# foreach (var arg in o.Arguments) { #>e<#= arg.Number #>.Current<#= arg.Num < o.Count ? "," : "" #><#}#>); + } + } } /// @@ -293,161 +346,34 @@ namespace MoreLinq <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #>Source<#= arg.Num < o.Count ? "," : ")" #> <#}#> { + return ZipShortest( <# foreach (var arg in o.Arguments) { #> - if (<#= arg.Ordinal #>Source == null) throw new ArgumentNullException(nameof(<#= arg.Ordinal #>Source)); -<#} #> - - return CustomZip( -<# foreach (var arg in o.Arguments) { #> - <#= arg.Ordinal #>Source, ZipSourceConfiguration>.StopOnShort, + <#= arg.Ordinal #>Source, <#}#> ValueTuple.Create); } <# } #> - -<# foreach (var o in overloads) - { -#> - internal static IEnumerable CustomZip<<#= o.Types#>, TResult>( -<# foreach (var arg in o.Arguments) { #> - <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #>Source, ZipSourceConfiguration> <#= arg.Ordinal #>SourceConfiguration, -<#}#> - Func<<#= o.Types#>, TResult> resultSelector) - { -<# foreach (var arg in o.Arguments) { #> - using var <#= arg.Ordinal #>Enumerator = new ZipEnumerator>(<#= arg.Ordinal #>Source.GetEnumerator(), nameof(<#= arg.Ordinal #>Source), <#= arg.Ordinal #>SourceConfiguration); -<#} #> - - while (MoveNext( -<# foreach (var arg in o.Arguments) { #> - <#= arg.Ordinal #>Enumerator<#= arg.Num < o.Count ? "," : "))" #> -<#}#> - { - yield return resultSelector( -<# foreach (var arg in o.Arguments) { #> - <#= arg.Ordinal #>Enumerator.Current<#= arg.Num < o.Count ? "," : "" #> -<#}#> - ); - } - } -<# } #> - - private static bool MoveNext(params IZipEnumerator[] enumerators) + static class ZipHelper { - var hasNext = false; - IZipEnumerator equiStopper = null; - - foreach (var enumerator in enumerators) + public static bool MoveNextOrDefault(ref IEnumerator enumerator, ref T value) { - switch (enumerator.MoveNext()) + if (enumerator == null) { - case ZipEnumeratorStatus.AskForStop: - return false; - case ZipEnumeratorStatus.AskForEquiStop: - if (hasNext) // there is some sequences ahead - { - enumerator.ThrowToShort(); - } - equiStopper = enumerator; - break; - case ZipEnumeratorStatus.Continue: - equiStopper?.ThrowToShort(); - hasNext = true; - break; - case ZipEnumeratorStatus.EndOfStream: - break; - default: - throw new ArgumentOutOfRangeException(); + return false; } - } - - return hasNext; - } - } - - internal interface IZipEnumerator - { - ZipEnumeratorStatus MoveNext(); - void ThrowToShort(); - } - - internal class ZipEnumerator : IZipEnumerator, IDisposable - { - private readonly ZipSourceConfiguration _configuration; - private readonly string _name; - private IEnumerator _source; - - public ZipEnumerator(IEnumerator source, string name, ZipSourceConfiguration configuration) - { - _source = source; - _name = name; - _configuration = configuration; - } - - public T Current => _source == null ? _configuration.PaddingValue : _source.Current; - - public void Dispose() => _source?.Dispose(); - - public ZipEnumeratorStatus MoveNext() - { - if (_source?.MoveNext() == false) - { - _source.Dispose(); - _source = null; - } - if (_source != null) - { - return ZipEnumeratorStatus.Continue; - } + if (enumerator.MoveNext()) + { + value = enumerator.Current; + return true; + } - switch (_configuration.Behavior) - { - case ZipEnumeratorBehavior.StopOnShort: - return ZipEnumeratorStatus.AskForStop; - case ZipEnumeratorBehavior.Padding: - return ZipEnumeratorStatus.EndOfStream; - case ZipEnumeratorBehavior.ThrowOnShort: - return ZipEnumeratorStatus.AskForEquiStop; - default: - throw new ArgumentOutOfRangeException(); + enumerator.Dispose(); + enumerator = null; + value = default; + return false; } } - - public void Reset() => _source.Reset(); - - public void ThrowToShort() => throw new InvalidOperationException($"{_name} sequence too short."); - } - - internal enum ZipEnumeratorBehavior - { - StopOnShort, - ThrowOnShort, - Padding - } - - internal enum ZipEnumeratorStatus - { - AskForStop, - AskForEquiStop, - Continue, - EndOfStream - } - - internal class ZipSourceConfiguration - { - public static ZipSourceConfiguration StopOnShort { get; } = new ZipSourceConfiguration(ZipEnumeratorBehavior.StopOnShort, default); - public static ZipSourceConfiguration ThrowOnShort { get; } = new ZipSourceConfiguration(ZipEnumeratorBehavior.ThrowOnShort, default); - public static ZipSourceConfiguration PaddingWith(T paddingValue) => new ZipSourceConfiguration(ZipEnumeratorBehavior.Padding, paddingValue); - - ZipSourceConfiguration(ZipEnumeratorBehavior behavior, T paddingValue) - { - Behavior = behavior; - PaddingValue = paddingValue; - } - - public ZipEnumeratorBehavior Behavior { get; } - public T PaddingValue { get; } } } From ea231978bf3c76e0950790a02b8dbdfc22d8a2d1 Mon Sep 17 00:00:00 2001 From: Orace Date: Tue, 5 Nov 2019 09:29:01 +0100 Subject: [PATCH 04/11] Fix unexpected trailing whitespace --- MoreLinq/Zip.g.cs | 56 +++++++++++++++++++++++------------------------ MoreLinq/Zip.g.tt | 2 +- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/MoreLinq/Zip.g.cs b/MoreLinq/Zip.g.cs index 5136c03e3..e80f3dc2f 100644 --- a/MoreLinq/Zip.g.cs +++ b/MoreLinq/Zip.g.cs @@ -158,7 +158,7 @@ public static IEnumerable ZipLongest( var v2 = default(T2); while ( - ZipHelper.MoveNextOrDefault(ref e1, ref v1) | + ZipHelper.MoveNextOrDefault(ref e1, ref v1) | ZipHelper.MoveNextOrDefault(ref e2, ref v2)) { yield return resultSelector(v1,v2); @@ -429,8 +429,8 @@ public static IEnumerable ZipLongest( var v3 = default(T3); while ( - ZipHelper.MoveNextOrDefault(ref e1, ref v1) | - ZipHelper.MoveNextOrDefault(ref e2, ref v2) | + ZipHelper.MoveNextOrDefault(ref e1, ref v1) | + ZipHelper.MoveNextOrDefault(ref e2, ref v2) | ZipHelper.MoveNextOrDefault(ref e3, ref v3)) { yield return resultSelector(v1,v2,v3); @@ -731,9 +731,9 @@ public static IEnumerable ZipLongest( var v4 = default(T4); while ( - ZipHelper.MoveNextOrDefault(ref e1, ref v1) | - ZipHelper.MoveNextOrDefault(ref e2, ref v2) | - ZipHelper.MoveNextOrDefault(ref e3, ref v3) | + ZipHelper.MoveNextOrDefault(ref e1, ref v1) | + ZipHelper.MoveNextOrDefault(ref e2, ref v2) | + ZipHelper.MoveNextOrDefault(ref e3, ref v3) | ZipHelper.MoveNextOrDefault(ref e4, ref v4)) { yield return resultSelector(v1,v2,v3,v4); @@ -1064,10 +1064,10 @@ public static IEnumerable ZipLongest( var v5 = default(T5); while ( - ZipHelper.MoveNextOrDefault(ref e1, ref v1) | - ZipHelper.MoveNextOrDefault(ref e2, ref v2) | - ZipHelper.MoveNextOrDefault(ref e3, ref v3) | - ZipHelper.MoveNextOrDefault(ref e4, ref v4) | + ZipHelper.MoveNextOrDefault(ref e1, ref v1) | + ZipHelper.MoveNextOrDefault(ref e2, ref v2) | + ZipHelper.MoveNextOrDefault(ref e3, ref v3) | + ZipHelper.MoveNextOrDefault(ref e4, ref v4) | ZipHelper.MoveNextOrDefault(ref e5, ref v5)) { yield return resultSelector(v1,v2,v3,v4,v5); @@ -1428,11 +1428,11 @@ public static IEnumerable ZipLongest( var v6 = default(T6); while ( - ZipHelper.MoveNextOrDefault(ref e1, ref v1) | - ZipHelper.MoveNextOrDefault(ref e2, ref v2) | - ZipHelper.MoveNextOrDefault(ref e3, ref v3) | - ZipHelper.MoveNextOrDefault(ref e4, ref v4) | - ZipHelper.MoveNextOrDefault(ref e5, ref v5) | + ZipHelper.MoveNextOrDefault(ref e1, ref v1) | + ZipHelper.MoveNextOrDefault(ref e2, ref v2) | + ZipHelper.MoveNextOrDefault(ref e3, ref v3) | + ZipHelper.MoveNextOrDefault(ref e4, ref v4) | + ZipHelper.MoveNextOrDefault(ref e5, ref v5) | ZipHelper.MoveNextOrDefault(ref e6, ref v6)) { yield return resultSelector(v1,v2,v3,v4,v5,v6); @@ -1823,12 +1823,12 @@ public static IEnumerable ZipLongest(ref e1, ref v1) | - ZipHelper.MoveNextOrDefault(ref e2, ref v2) | - ZipHelper.MoveNextOrDefault(ref e3, ref v3) | - ZipHelper.MoveNextOrDefault(ref e4, ref v4) | - ZipHelper.MoveNextOrDefault(ref e5, ref v5) | - ZipHelper.MoveNextOrDefault(ref e6, ref v6) | + ZipHelper.MoveNextOrDefault(ref e1, ref v1) | + ZipHelper.MoveNextOrDefault(ref e2, ref v2) | + ZipHelper.MoveNextOrDefault(ref e3, ref v3) | + ZipHelper.MoveNextOrDefault(ref e4, ref v4) | + ZipHelper.MoveNextOrDefault(ref e5, ref v5) | + ZipHelper.MoveNextOrDefault(ref e6, ref v6) | ZipHelper.MoveNextOrDefault(ref e7, ref v7)) { yield return resultSelector(v1,v2,v3,v4,v5,v6,v7); @@ -2249,13 +2249,13 @@ public static IEnumerable ZipLongest(ref e1, ref v1) | - ZipHelper.MoveNextOrDefault(ref e2, ref v2) | - ZipHelper.MoveNextOrDefault(ref e3, ref v3) | - ZipHelper.MoveNextOrDefault(ref e4, ref v4) | - ZipHelper.MoveNextOrDefault(ref e5, ref v5) | - ZipHelper.MoveNextOrDefault(ref e6, ref v6) | - ZipHelper.MoveNextOrDefault(ref e7, ref v7) | + ZipHelper.MoveNextOrDefault(ref e1, ref v1) | + ZipHelper.MoveNextOrDefault(ref e2, ref v2) | + ZipHelper.MoveNextOrDefault(ref e3, ref v3) | + ZipHelper.MoveNextOrDefault(ref e4, ref v4) | + ZipHelper.MoveNextOrDefault(ref e5, ref v5) | + ZipHelper.MoveNextOrDefault(ref e6, ref v6) | + ZipHelper.MoveNextOrDefault(ref e7, ref v7) | ZipHelper.MoveNextOrDefault(ref e8, ref v8)) { yield return resultSelector(v1,v2,v3,v4,v5,v6,v7,v8); diff --git a/MoreLinq/Zip.g.tt b/MoreLinq/Zip.g.tt index fb16b1369..e187f183b 100644 --- a/MoreLinq/Zip.g.tt +++ b/MoreLinq/Zip.g.tt @@ -220,7 +220,7 @@ namespace MoreLinq while ( <# foreach (var arg in o.Arguments) { #> - ZipHelper.MoveNextOrDefault>(ref e<#= arg.Number #>, ref v<#= arg.Number #>)<#= arg.Num < o.Count ? " | " : ")" #> + ZipHelper.MoveNextOrDefault>(ref e<#= arg.Number #>, ref v<#= arg.Number #>)<#= arg.Num < o.Count ? " |" : ")" #> <#}#> { yield return resultSelector(<# foreach (var arg in o.Arguments) { #>v<#= arg.Number #><#= arg.Num < o.Count ? "," : "" #><#}#>); From 38969b36efc476a842923f5599d692cffec76536 Mon Sep 17 00:00:00 2001 From: Orace Date: Tue, 5 Nov 2019 11:54:25 +0100 Subject: [PATCH 05/11] Typo --- MoreLinq/Zip.g.cs | 42 +++++++++++++++++++++--------------------- MoreLinq/Zip.g.tt | 6 +++--- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/MoreLinq/Zip.g.cs b/MoreLinq/Zip.g.cs index e80f3dc2f..648dc4814 100644 --- a/MoreLinq/Zip.g.cs +++ b/MoreLinq/Zip.g.cs @@ -63,7 +63,7 @@ public static IEnumerable EquiZip( { if (e2.MoveNext()) { - yield return resultSelector(e1.Current,e2.Current); + yield return resultSelector(e1.Current, e2.Current); } else { @@ -161,7 +161,7 @@ public static IEnumerable ZipLongest( ZipHelper.MoveNextOrDefault(ref e1, ref v1) | ZipHelper.MoveNextOrDefault(ref e2, ref v2)) { - yield return resultSelector(v1,v2); + yield return resultSelector(v1, v2); } } finally @@ -240,7 +240,7 @@ public static IEnumerable ZipShortest( while (e1.MoveNext() && e2.MoveNext()) { - yield return resultSelector(e1.Current,e2.Current); + yield return resultSelector(e1.Current, e2.Current); } } } @@ -323,7 +323,7 @@ public static IEnumerable EquiZip( { if (e2.MoveNext() && e3.MoveNext()) { - yield return resultSelector(e1.Current,e2.Current,e3.Current); + yield return resultSelector(e1.Current, e2.Current, e3.Current); } else { @@ -433,7 +433,7 @@ public static IEnumerable ZipLongest( ZipHelper.MoveNextOrDefault(ref e2, ref v2) | ZipHelper.MoveNextOrDefault(ref e3, ref v3)) { - yield return resultSelector(v1,v2,v3); + yield return resultSelector(v1, v2, v3); } } finally @@ -522,7 +522,7 @@ public static IEnumerable ZipShortest( while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext()) { - yield return resultSelector(e1.Current,e2.Current,e3.Current); + yield return resultSelector(e1.Current, e2.Current, e3.Current); } } } @@ -614,7 +614,7 @@ public static IEnumerable EquiZip( { if (e2.MoveNext() && e3.MoveNext() && e4.MoveNext()) { - yield return resultSelector(e1.Current,e2.Current,e3.Current,e4.Current); + yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current); } else { @@ -736,7 +736,7 @@ public static IEnumerable ZipLongest( ZipHelper.MoveNextOrDefault(ref e3, ref v3) | ZipHelper.MoveNextOrDefault(ref e4, ref v4)) { - yield return resultSelector(v1,v2,v3,v4); + yield return resultSelector(v1, v2, v3, v4); } } finally @@ -835,7 +835,7 @@ public static IEnumerable ZipShortest( while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext() && e4.MoveNext()) { - yield return resultSelector(e1.Current,e2.Current,e3.Current,e4.Current); + yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current); } } } @@ -936,7 +936,7 @@ public static IEnumerable EquiZip( { if (e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext()) { - yield return resultSelector(e1.Current,e2.Current,e3.Current,e4.Current,e5.Current); + yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current, e5.Current); } else { @@ -1070,7 +1070,7 @@ public static IEnumerable ZipLongest( ZipHelper.MoveNextOrDefault(ref e4, ref v4) | ZipHelper.MoveNextOrDefault(ref e5, ref v5)) { - yield return resultSelector(v1,v2,v3,v4,v5); + yield return resultSelector(v1, v2, v3, v4, v5); } } finally @@ -1179,7 +1179,7 @@ public static IEnumerable ZipShortest( while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext()) { - yield return resultSelector(e1.Current,e2.Current,e3.Current,e4.Current,e5.Current); + yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current, e5.Current); } } } @@ -1289,7 +1289,7 @@ public static IEnumerable EquiZip( { if (e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext() && e6.MoveNext()) { - yield return resultSelector(e1.Current,e2.Current,e3.Current,e4.Current,e5.Current,e6.Current); + yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current, e5.Current, e6.Current); } else { @@ -1435,7 +1435,7 @@ public static IEnumerable ZipLongest( ZipHelper.MoveNextOrDefault(ref e5, ref v5) | ZipHelper.MoveNextOrDefault(ref e6, ref v6)) { - yield return resultSelector(v1,v2,v3,v4,v5,v6); + yield return resultSelector(v1, v2, v3, v4, v5, v6); } } finally @@ -1554,7 +1554,7 @@ public static IEnumerable ZipShortest( while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext() && e6.MoveNext()) { - yield return resultSelector(e1.Current,e2.Current,e3.Current,e4.Current,e5.Current,e6.Current); + yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current, e5.Current, e6.Current); } } } @@ -1673,7 +1673,7 @@ public static IEnumerable EquiZip( { if (e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext() && e6.MoveNext() && e7.MoveNext()) { - yield return resultSelector(e1.Current,e2.Current,e3.Current,e4.Current,e5.Current,e6.Current,e7.Current); + yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current, e5.Current, e6.Current, e7.Current); } else { @@ -1831,7 +1831,7 @@ public static IEnumerable ZipLongest(ref e6, ref v6) | ZipHelper.MoveNextOrDefault(ref e7, ref v7)) { - yield return resultSelector(v1,v2,v3,v4,v5,v6,v7); + yield return resultSelector(v1, v2, v3, v4, v5, v6, v7); } } finally @@ -1960,7 +1960,7 @@ public static IEnumerable ZipShortest EquiZip ZipLongest(ref e7, ref v7) | ZipHelper.MoveNextOrDefault(ref e8, ref v8)) { - yield return resultSelector(v1,v2,v3,v4,v5,v6,v7,v8); + yield return resultSelector(v1, v2, v3, v4, v5, v6, v7, v8); } } finally @@ -2397,7 +2397,7 @@ public static IEnumerable ZipShorteste<#= arg.Number #>.MoveNext()<#= arg.Num < o.Count ? " && " : "" #><#}#>) { - yield return resultSelector(<# foreach (var arg in o.Arguments) { #>e<#= arg.Number #>.Current<#= arg.Num < o.Count ? "," : "" #><#}#>); + yield return resultSelector(<# foreach (var arg in o.Arguments) { #>e<#= arg.Number #>.Current<#= arg.Num < o.Count ? ", " : "" #><#}#>); } else { @@ -223,7 +223,7 @@ namespace MoreLinq ZipHelper.MoveNextOrDefault>(ref e<#= arg.Number #>, ref v<#= arg.Number #>)<#= arg.Num < o.Count ? " |" : ")" #> <#}#> { - yield return resultSelector(<# foreach (var arg in o.Arguments) { #>v<#= arg.Number #><#= arg.Num < o.Count ? "," : "" #><#}#>); + yield return resultSelector(<# foreach (var arg in o.Arguments) { #>v<#= arg.Number #><#= arg.Num < o.Count ? ", " : "" #><#}#>); } } finally @@ -312,7 +312,7 @@ namespace MoreLinq while (<# foreach (var arg in o.Arguments) { #>e<#= arg.Number #>.MoveNext()<#= arg.Num < o.Count ? " && " : "" #><#}#>) { - yield return resultSelector(<# foreach (var arg in o.Arguments) { #>e<#= arg.Number #>.Current<#= arg.Num < o.Count ? "," : "" #><#}#>); + yield return resultSelector(<# foreach (var arg in o.Arguments) { #>e<#= arg.Number #>.Current<#= arg.Num < o.Count ? ", " : "" #><#}#>); } } } From 48720bfd3f894e7a33397adcdcb72012bd87acd4 Mon Sep 17 00:00:00 2001 From: Orace Date: Tue, 5 Nov 2019 22:02:28 +0100 Subject: [PATCH 06/11] Remove non generated code from Zip.g.tt Remove "Source" from the name of the Zip method parameters. Typos --- MoreLinq/Extensions.g.cs | 931 +++++++++++------------ MoreLinq/Zip.cs | 43 ++ MoreLinq/Zip.g.cs | 1554 ++++++++++++++++++-------------------- MoreLinq/Zip.g.tt | 72 +- 4 files changed, 1276 insertions(+), 1324 deletions(-) create mode 100644 MoreLinq/Zip.cs diff --git a/MoreLinq/Extensions.g.cs b/MoreLinq/Extensions.g.cs index acd6a1d69..4b2a4d2e2 100644 --- a/MoreLinq/Extensions.g.cs +++ b/MoreLinq/Extensions.g.cs @@ -1332,8 +1332,8 @@ public static partial class EquiZipExtension /// /// Type of elements in first input sequence. /// Type of elements in second input sequence. - /// The first source sequence. - /// The second source sequence. + /// The first source sequence. + /// The second source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -1344,9 +1344,9 @@ public static partial class EquiZipExtension /// This operator uses deferred execution and streams its results. /// public static IEnumerable<(T1, T2)> EquiZip( - this IEnumerable firstSource, - IEnumerable secondSource) - => MoreEnumerable.EquiZip(firstSource, secondSource); + this IEnumerable first, + IEnumerable second) + => MoreEnumerable.EquiZip(first, second); /// /// Returns a sequence of tuples, where each tuple contains the N-th @@ -1356,9 +1356,9 @@ public static partial class EquiZipExtension /// Type of elements in first input sequence. /// Type of elements in second input sequence. /// Type of elements in third input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -1369,10 +1369,10 @@ public static partial class EquiZipExtension /// This operator uses deferred execution and streams its results. /// public static IEnumerable<(T1, T2, T3)> EquiZip( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource) - => MoreEnumerable.EquiZip(firstSource, secondSource, thirdSource); + this IEnumerable first, + IEnumerable second, + IEnumerable third) + => MoreEnumerable.EquiZip(first, second, third); /// /// Returns a projection of tuples, where each tuple contains the N-th /// element from each of the input sequences. An exception is thrown @@ -1381,8 +1381,8 @@ public static partial class EquiZipExtension /// Type of elements in first input sequence. /// Type of elements in second input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. + /// The first source sequence. + /// The second source sequence. /// /// Function to apply to each tuple of elements. /// @@ -1394,11 +1394,12 @@ public static partial class EquiZipExtension /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable EquiZip( - this IEnumerable firstSource, - IEnumerable secondSource, + this IEnumerable first, + IEnumerable second, Func resultSelector) - => MoreEnumerable.EquiZip(firstSource, secondSource, resultSelector); + => MoreEnumerable.EquiZip(first, second, resultSelector); /// /// Returns a sequence of tuples, where each tuple contains the N-th @@ -1409,10 +1410,10 @@ public static IEnumerable EquiZip( /// Type of elements in second input sequence. /// Type of elements in third input sequence. /// Type of elements in fourth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -1423,11 +1424,11 @@ public static IEnumerable EquiZip( /// This operator uses deferred execution and streams its results. /// public static IEnumerable<(T1, T2, T3, T4)> EquiZip( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource) - => MoreEnumerable.EquiZip(firstSource, secondSource, thirdSource, fourthSource); + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth) + => MoreEnumerable.EquiZip(first, second, third, fourth); /// /// Returns a projection of tuples, where each tuple contains the N-th @@ -1438,9 +1439,9 @@ public static IEnumerable EquiZip( /// Type of elements in second input sequence. /// Type of elements in third input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. /// /// Function to apply to each tuple of elements. /// @@ -1452,12 +1453,13 @@ public static IEnumerable EquiZip( /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable EquiZip( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, Func resultSelector) - => MoreEnumerable.EquiZip(firstSource, secondSource, thirdSource, resultSelector); + => MoreEnumerable.EquiZip(first, second, third, resultSelector); /// /// Returns a sequence of tuples, where each tuple contains the N-th @@ -1469,11 +1471,11 @@ public static IEnumerable EquiZip( /// Type of elements in third input sequence. /// Type of elements in fourth input sequence. /// Type of elements in fifth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -1484,12 +1486,12 @@ public static IEnumerable EquiZip( /// This operator uses deferred execution and streams its results. /// public static IEnumerable<(T1, T2, T3, T4, T5)> EquiZip( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource) - => MoreEnumerable.EquiZip(firstSource, secondSource, thirdSource, fourthSource, fifthSource); + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth) + => MoreEnumerable.EquiZip(first, second, third, fourth, fifth); /// /// Returns a projection of tuples, where each tuple contains the N-th @@ -1501,10 +1503,10 @@ public static IEnumerable EquiZip( /// Type of elements in third input sequence. /// Type of elements in fourth input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. /// /// Function to apply to each tuple of elements. /// @@ -1516,13 +1518,14 @@ public static IEnumerable EquiZip( /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable EquiZip( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, Func resultSelector) - => MoreEnumerable.EquiZip(firstSource, secondSource, thirdSource, fourthSource, resultSelector); + => MoreEnumerable.EquiZip(first, second, third, fourth, resultSelector); /// /// Returns a sequence of tuples, where each tuple contains the N-th @@ -1535,12 +1538,12 @@ public static IEnumerable EquiZip( /// Type of elements in fourth input sequence. /// Type of elements in fifth input sequence. /// Type of elements in sixth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -1551,13 +1554,13 @@ public static IEnumerable EquiZip( /// This operator uses deferred execution and streams its results. /// public static IEnumerable<(T1, T2, T3, T4, T5, T6)> EquiZip( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource) - => MoreEnumerable.EquiZip(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource); + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth) + => MoreEnumerable.EquiZip(first, second, third, fourth, fifth, sixth); /// /// Returns a projection of tuples, where each tuple contains the N-th @@ -1570,11 +1573,11 @@ public static IEnumerable EquiZip( /// Type of elements in fourth input sequence. /// Type of elements in fifth input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. /// /// Function to apply to each tuple of elements. /// @@ -1586,14 +1589,15 @@ public static IEnumerable EquiZip( /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable EquiZip( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, Func resultSelector) - => MoreEnumerable.EquiZip(firstSource, secondSource, thirdSource, fourthSource, fifthSource, resultSelector); + => MoreEnumerable.EquiZip(first, second, third, fourth, fifth, resultSelector); /// /// Returns a sequence of tuples, where each tuple contains the N-th @@ -1607,13 +1611,13 @@ public static IEnumerable EquiZip( /// Type of elements in fifth input sequence. /// Type of elements in sixth input sequence. /// Type of elements in seventh input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -1624,14 +1628,14 @@ public static IEnumerable EquiZip( /// This operator uses deferred execution and streams its results. /// public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7)> EquiZip( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, - IEnumerable seventhSource) - => MoreEnumerable.EquiZip(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, seventhSource); + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh) + => MoreEnumerable.EquiZip(first, second, third, fourth, fifth, sixth, seventh); /// /// Returns a projection of tuples, where each tuple contains the N-th @@ -1645,12 +1649,12 @@ public static IEnumerable EquiZip( /// Type of elements in fifth input sequence. /// Type of elements in sixth input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. /// /// Function to apply to each tuple of elements. /// @@ -1662,15 +1666,16 @@ public static IEnumerable EquiZip( /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable EquiZip( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, Func resultSelector) - => MoreEnumerable.EquiZip(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, resultSelector); + => MoreEnumerable.EquiZip(first, second, third, fourth, fifth, sixth, resultSelector); /// /// Returns a sequence of tuples, where each tuple contains the N-th @@ -1685,14 +1690,14 @@ public static IEnumerable EquiZip( /// Type of elements in sixth input sequence. /// Type of elements in seventh input sequence. /// Type of elements in eighth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. - /// The eighth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -1703,15 +1708,15 @@ public static IEnumerable EquiZip( /// This operator uses deferred execution and streams its results. /// public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7, T8)> EquiZip( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, - IEnumerable seventhSource, - IEnumerable eighthSource) - => MoreEnumerable.EquiZip(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, seventhSource, eighthSource); + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, + IEnumerable eighth) + => MoreEnumerable.EquiZip(first, second, third, fourth, fifth, sixth, seventh, eighth); /// /// Returns a projection of tuples, where each tuple contains the N-th @@ -1726,13 +1731,13 @@ public static IEnumerable EquiZip( /// Type of elements in sixth input sequence. /// Type of elements in seventh input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. /// /// Function to apply to each tuple of elements. /// @@ -1744,16 +1749,17 @@ public static IEnumerable EquiZip( /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable EquiZip( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, - IEnumerable seventhSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, Func resultSelector) - => MoreEnumerable.EquiZip(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, seventhSource, resultSelector); + => MoreEnumerable.EquiZip(first, second, third, fourth, fifth, sixth, seventh, resultSelector); /// /// Returns a projection of tuples, where each tuple contains the N-th @@ -1769,14 +1775,14 @@ public static IEnumerable EquiZip( /// Type of elements in seventh input sequence. /// Type of elements in eighth input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. - /// The eighth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. /// /// Function to apply to each tuple of elements. /// @@ -1788,17 +1794,18 @@ public static IEnumerable EquiZip( /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable EquiZip( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, - IEnumerable seventhSource, - IEnumerable eighthSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, + IEnumerable eighth, Func resultSelector) - => MoreEnumerable.EquiZip(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, seventhSource, eighthSource, resultSelector); + => MoreEnumerable.EquiZip(first, second, third, fourth, fifth, sixth, seventh, eighth, resultSelector); } @@ -7150,8 +7157,8 @@ public static partial class ZipLongestExtension /// /// Type of elements in first input sequence. /// Type of elements in second input sequence. - /// The first source sequence. - /// The second source sequence. + /// The first source sequence. + /// The second source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -7159,9 +7166,9 @@ public static partial class ZipLongestExtension /// This operator uses deferred execution and streams its results. /// public static IEnumerable<(T1, T2)> ZipLongest( - this IEnumerable firstSource, - IEnumerable secondSource) - => MoreEnumerable.ZipLongest(firstSource, secondSource); + this IEnumerable first, + IEnumerable second) + => MoreEnumerable.ZipLongest(first, second); /// /// Returns a sequence of tuples, where each tuple contains the N-th @@ -7173,9 +7180,9 @@ public static partial class ZipLongestExtension /// Type of elements in first input sequence. /// Type of elements in second input sequence. /// Type of elements in third input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -7183,10 +7190,10 @@ public static partial class ZipLongestExtension /// This operator uses deferred execution and streams its results. /// public static IEnumerable<(T1, T2, T3)> ZipLongest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource) - => MoreEnumerable.ZipLongest(firstSource, secondSource, thirdSource); + this IEnumerable first, + IEnumerable second, + IEnumerable third) + => MoreEnumerable.ZipLongest(first, second, third); /// /// Returns a projection of tuples, where each tuple contains the N-th @@ -7198,8 +7205,8 @@ public static partial class ZipLongestExtension /// Type of elements in first input sequence. /// Type of elements in second input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. + /// The first source sequence. + /// The second source sequence. /// /// Function to apply to each tuple of elements. /// @@ -7209,10 +7216,10 @@ public static partial class ZipLongestExtension /// This operator uses deferred execution and streams its results. /// public static IEnumerable ZipLongest( - this IEnumerable firstSource, - IEnumerable secondSource, + this IEnumerable first, + IEnumerable second, Func resultSelector) - => MoreEnumerable.ZipLongest(firstSource, secondSource, resultSelector); + => MoreEnumerable.ZipLongest(first, second, resultSelector); /// /// Returns a sequence of tuples, where each tuple contains the N-th @@ -7225,10 +7232,10 @@ public static IEnumerable ZipLongest( /// Type of elements in second input sequence. /// Type of elements in third input sequence. /// Type of elements in fourth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -7236,11 +7243,11 @@ public static IEnumerable ZipLongest( /// This operator uses deferred execution and streams its results. /// public static IEnumerable<(T1, T2, T3, T4)> ZipLongest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource) - => MoreEnumerable.ZipLongest(firstSource, secondSource, thirdSource, fourthSource); + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth) + => MoreEnumerable.ZipLongest(first, second, third, fourth); /// /// Returns a projection of tuples, where each tuple contains the N-th @@ -7253,9 +7260,9 @@ public static IEnumerable ZipLongest( /// Type of elements in second input sequence. /// Type of elements in third input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. /// /// Function to apply to each tuple of elements. /// @@ -7265,11 +7272,11 @@ public static IEnumerable ZipLongest( /// This operator uses deferred execution and streams its results. /// public static IEnumerable ZipLongest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, Func resultSelector) - => MoreEnumerable.ZipLongest(firstSource, secondSource, thirdSource, resultSelector); + => MoreEnumerable.ZipLongest(first, second, third, resultSelector); /// /// Returns a sequence of tuples, where each tuple contains the N-th @@ -7283,11 +7290,11 @@ public static IEnumerable ZipLongest( /// Type of elements in third input sequence. /// Type of elements in fourth input sequence. /// Type of elements in fifth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -7295,12 +7302,12 @@ public static IEnumerable ZipLongest( /// This operator uses deferred execution and streams its results. /// public static IEnumerable<(T1, T2, T3, T4, T5)> ZipLongest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource) - => MoreEnumerable.ZipLongest(firstSource, secondSource, thirdSource, fourthSource, fifthSource); + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth) + => MoreEnumerable.ZipLongest(first, second, third, fourth, fifth); /// /// Returns a projection of tuples, where each tuple contains the N-th @@ -7314,10 +7321,10 @@ public static IEnumerable ZipLongest( /// Type of elements in third input sequence. /// Type of elements in fourth input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. /// /// Function to apply to each tuple of elements. /// @@ -7327,12 +7334,12 @@ public static IEnumerable ZipLongest( /// This operator uses deferred execution and streams its results. /// public static IEnumerable ZipLongest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, Func resultSelector) - => MoreEnumerable.ZipLongest(firstSource, secondSource, thirdSource, fourthSource, resultSelector); + => MoreEnumerable.ZipLongest(first, second, third, fourth, resultSelector); /// /// Returns a sequence of tuples, where each tuple contains the N-th @@ -7347,12 +7354,12 @@ public static IEnumerable ZipLongest( /// Type of elements in fourth input sequence. /// Type of elements in fifth input sequence. /// Type of elements in sixth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -7360,13 +7367,13 @@ public static IEnumerable ZipLongest( /// This operator uses deferred execution and streams its results. /// public static IEnumerable<(T1, T2, T3, T4, T5, T6)> ZipLongest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource) - => MoreEnumerable.ZipLongest(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource); + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth) + => MoreEnumerable.ZipLongest(first, second, third, fourth, fifth, sixth); /// /// Returns a projection of tuples, where each tuple contains the N-th @@ -7381,11 +7388,11 @@ public static IEnumerable ZipLongest( /// Type of elements in fourth input sequence. /// Type of elements in fifth input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. /// /// Function to apply to each tuple of elements. /// @@ -7395,13 +7402,13 @@ public static IEnumerable ZipLongest( /// This operator uses deferred execution and streams its results. /// public static IEnumerable ZipLongest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, Func resultSelector) - => MoreEnumerable.ZipLongest(firstSource, secondSource, thirdSource, fourthSource, fifthSource, resultSelector); + => MoreEnumerable.ZipLongest(first, second, third, fourth, fifth, resultSelector); /// /// Returns a sequence of tuples, where each tuple contains the N-th @@ -7417,13 +7424,13 @@ public static IEnumerable ZipLongest( /// Type of elements in fifth input sequence. /// Type of elements in sixth input sequence. /// Type of elements in seventh input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -7431,14 +7438,14 @@ public static IEnumerable ZipLongest( /// This operator uses deferred execution and streams its results. /// public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7)> ZipLongest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, - IEnumerable seventhSource) - => MoreEnumerable.ZipLongest(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, seventhSource); + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh) + => MoreEnumerable.ZipLongest(first, second, third, fourth, fifth, sixth, seventh); /// /// Returns a projection of tuples, where each tuple contains the N-th @@ -7454,12 +7461,12 @@ public static IEnumerable ZipLongest( /// Type of elements in fifth input sequence. /// Type of elements in sixth input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. /// /// Function to apply to each tuple of elements. /// @@ -7469,14 +7476,14 @@ public static IEnumerable ZipLongest( /// This operator uses deferred execution and streams its results. /// public static IEnumerable ZipLongest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, Func resultSelector) - => MoreEnumerable.ZipLongest(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, resultSelector); + => MoreEnumerable.ZipLongest(first, second, third, fourth, fifth, sixth, resultSelector); /// /// Returns a sequence of tuples, where each tuple contains the N-th @@ -7493,14 +7500,14 @@ public static IEnumerable ZipLongest( /// Type of elements in sixth input sequence. /// Type of elements in seventh input sequence. /// Type of elements in eighth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. - /// The eighth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -7508,15 +7515,15 @@ public static IEnumerable ZipLongest( /// This operator uses deferred execution and streams its results. /// public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7, T8)> ZipLongest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, - IEnumerable seventhSource, - IEnumerable eighthSource) - => MoreEnumerable.ZipLongest(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, seventhSource, eighthSource); + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, + IEnumerable eighth) + => MoreEnumerable.ZipLongest(first, second, third, fourth, fifth, sixth, seventh, eighth); /// /// Returns a projection of tuples, where each tuple contains the N-th @@ -7533,13 +7540,13 @@ public static IEnumerable ZipLongest( /// Type of elements in sixth input sequence. /// Type of elements in seventh input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. /// /// Function to apply to each tuple of elements. /// @@ -7549,15 +7556,15 @@ public static IEnumerable ZipLongest( /// This operator uses deferred execution and streams its results. /// public static IEnumerable ZipLongest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, - IEnumerable seventhSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, Func resultSelector) - => MoreEnumerable.ZipLongest(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, seventhSource, resultSelector); + => MoreEnumerable.ZipLongest(first, second, third, fourth, fifth, sixth, seventh, resultSelector); /// /// Returns a projection of tuples, where each tuple contains the N-th @@ -7575,14 +7582,14 @@ public static IEnumerable ZipLongestType of elements in seventh input sequence. /// Type of elements in eighth input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. - /// The eighth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. /// /// Function to apply to each tuple of elements. /// @@ -7592,16 +7599,16 @@ public static IEnumerable ZipLongest public static IEnumerable ZipLongest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, - IEnumerable seventhSource, - IEnumerable eighthSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, + IEnumerable eighth, Func resultSelector) - => MoreEnumerable.ZipLongest(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, seventhSource, eighthSource, resultSelector); + => MoreEnumerable.ZipLongest(first, second, third, fourth, fifth, sixth, seventh, eighth, resultSelector); } @@ -7618,8 +7625,8 @@ public static partial class ZipShortestExtension /// /// Type of elements in first input sequence. /// Type of elements in second input sequence. - /// The first source sequence. - /// The second source sequence. + /// The first source sequence. + /// The second source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -7634,9 +7641,9 @@ public static partial class ZipShortestExtension /// public static IEnumerable<(T1, T2)> ZipShortest( - this IEnumerable firstSource, - IEnumerable secondSource) - => MoreEnumerable.ZipShortest(firstSource, secondSource); + this IEnumerable first, + IEnumerable second) + => MoreEnumerable.ZipShortest(first, second); /// /// Returns a sequence of tuples, where each tuple contains the N-th @@ -7646,9 +7653,9 @@ public static partial class ZipShortestExtension /// Type of elements in first input sequence. /// Type of elements in second input sequence. /// Type of elements in third input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -7663,10 +7670,10 @@ public static partial class ZipShortestExtension /// public static IEnumerable<(T1, T2, T3)> ZipShortest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource) - => MoreEnumerable.ZipShortest(firstSource, secondSource, thirdSource); + this IEnumerable first, + IEnumerable second, + IEnumerable third) + => MoreEnumerable.ZipShortest(first, second, third); /// /// Returns a projection of tuples, where each tuple contains the N-th @@ -7676,8 +7683,8 @@ public static partial class ZipShortestExtension /// Type of elements in first input sequence. /// Type of elements in second input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. + /// The first source sequence. + /// The second source sequence. /// /// Function to apply to each tuple of elements. /// @@ -7694,10 +7701,10 @@ public static partial class ZipShortestExtension /// public static IEnumerable ZipShortest( - this IEnumerable firstSource, - IEnumerable secondSource, + this IEnumerable first, + IEnumerable second, Func resultSelector) - => MoreEnumerable.ZipShortest(firstSource, secondSource, resultSelector); + => MoreEnumerable.ZipShortest(first, second, resultSelector); /// /// Returns a sequence of tuples, where each tuple contains the N-th @@ -7708,10 +7715,10 @@ public static IEnumerable ZipShortest( /// Type of elements in second input sequence. /// Type of elements in third input sequence. /// Type of elements in fourth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -7726,11 +7733,11 @@ public static IEnumerable ZipShortest( /// public static IEnumerable<(T1, T2, T3, T4)> ZipShortest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource) - => MoreEnumerable.ZipShortest(firstSource, secondSource, thirdSource, fourthSource); + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth) + => MoreEnumerable.ZipShortest(first, second, third, fourth); /// /// Returns a projection of tuples, where each tuple contains the N-th @@ -7741,9 +7748,9 @@ public static IEnumerable ZipShortest( /// Type of elements in second input sequence. /// Type of elements in third input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. /// /// Function to apply to each tuple of elements. /// @@ -7760,11 +7767,11 @@ public static IEnumerable ZipShortest( /// public static IEnumerable ZipShortest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, Func resultSelector) - => MoreEnumerable.ZipShortest(firstSource, secondSource, thirdSource, resultSelector); + => MoreEnumerable.ZipShortest(first, second, third, resultSelector); /// /// Returns a sequence of tuples, where each tuple contains the N-th @@ -7776,11 +7783,11 @@ public static IEnumerable ZipShortest( /// Type of elements in third input sequence. /// Type of elements in fourth input sequence. /// Type of elements in fifth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -7795,12 +7802,12 @@ public static IEnumerable ZipShortest( /// public static IEnumerable<(T1, T2, T3, T4, T5)> ZipShortest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource) - => MoreEnumerable.ZipShortest(firstSource, secondSource, thirdSource, fourthSource, fifthSource); + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth) + => MoreEnumerable.ZipShortest(first, second, third, fourth, fifth); /// /// Returns a projection of tuples, where each tuple contains the N-th @@ -7812,10 +7819,10 @@ public static IEnumerable ZipShortest( /// Type of elements in third input sequence. /// Type of elements in fourth input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. /// /// Function to apply to each tuple of elements. /// @@ -7832,12 +7839,12 @@ public static IEnumerable ZipShortest( /// public static IEnumerable ZipShortest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, Func resultSelector) - => MoreEnumerable.ZipShortest(firstSource, secondSource, thirdSource, fourthSource, resultSelector); + => MoreEnumerable.ZipShortest(first, second, third, fourth, resultSelector); /// /// Returns a sequence of tuples, where each tuple contains the N-th @@ -7850,12 +7857,12 @@ public static IEnumerable ZipShortest( /// Type of elements in fourth input sequence. /// Type of elements in fifth input sequence. /// Type of elements in sixth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -7870,13 +7877,13 @@ public static IEnumerable ZipShortest( /// public static IEnumerable<(T1, T2, T3, T4, T5, T6)> ZipShortest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource) - => MoreEnumerable.ZipShortest(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource); + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth) + => MoreEnumerable.ZipShortest(first, second, third, fourth, fifth, sixth); /// /// Returns a projection of tuples, where each tuple contains the N-th @@ -7889,11 +7896,11 @@ public static IEnumerable ZipShortest( /// Type of elements in fourth input sequence. /// Type of elements in fifth input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. /// /// Function to apply to each tuple of elements. /// @@ -7910,13 +7917,13 @@ public static IEnumerable ZipShortest( /// public static IEnumerable ZipShortest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, Func resultSelector) - => MoreEnumerable.ZipShortest(firstSource, secondSource, thirdSource, fourthSource, fifthSource, resultSelector); + => MoreEnumerable.ZipShortest(first, second, third, fourth, fifth, resultSelector); /// /// Returns a sequence of tuples, where each tuple contains the N-th @@ -7930,13 +7937,13 @@ public static IEnumerable ZipShortest( /// Type of elements in fifth input sequence. /// Type of elements in sixth input sequence. /// Type of elements in seventh input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -7951,14 +7958,14 @@ public static IEnumerable ZipShortest( /// public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7)> ZipShortest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, - IEnumerable seventhSource) - => MoreEnumerable.ZipShortest(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, seventhSource); + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh) + => MoreEnumerable.ZipShortest(first, second, third, fourth, fifth, sixth, seventh); /// /// Returns a projection of tuples, where each tuple contains the N-th @@ -7972,12 +7979,12 @@ public static IEnumerable ZipShortest( /// Type of elements in fifth input sequence. /// Type of elements in sixth input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. /// /// Function to apply to each tuple of elements. /// @@ -7994,14 +8001,14 @@ public static IEnumerable ZipShortest( /// public static IEnumerable ZipShortest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, Func resultSelector) - => MoreEnumerable.ZipShortest(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, resultSelector); + => MoreEnumerable.ZipShortest(first, second, third, fourth, fifth, sixth, resultSelector); /// /// Returns a sequence of tuples, where each tuple contains the N-th @@ -8016,14 +8023,14 @@ public static IEnumerable ZipShortest( /// Type of elements in sixth input sequence. /// Type of elements in seventh input sequence. /// Type of elements in eighth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. - /// The eighth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -8038,15 +8045,15 @@ public static IEnumerable ZipShortest( /// public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7, T8)> ZipShortest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, - IEnumerable seventhSource, - IEnumerable eighthSource) - => MoreEnumerable.ZipShortest(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, seventhSource, eighthSource); + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, + IEnumerable eighth) + => MoreEnumerable.ZipShortest(first, second, third, fourth, fifth, sixth, seventh, eighth); /// /// Returns a projection of tuples, where each tuple contains the N-th @@ -8061,13 +8068,13 @@ public static IEnumerable ZipShortest( /// Type of elements in sixth input sequence. /// Type of elements in seventh input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. /// /// Function to apply to each tuple of elements. /// @@ -8084,15 +8091,15 @@ public static IEnumerable ZipShortest( /// public static IEnumerable ZipShortest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, - IEnumerable seventhSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, Func resultSelector) - => MoreEnumerable.ZipShortest(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, seventhSource, resultSelector); + => MoreEnumerable.ZipShortest(first, second, third, fourth, fifth, sixth, seventh, resultSelector); /// /// Returns a projection of tuples, where each tuple contains the N-th @@ -8108,14 +8115,14 @@ public static IEnumerable ZipShortestType of elements in seventh input sequence. /// Type of elements in eighth input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. - /// The eighth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. /// /// Function to apply to each tuple of elements. /// @@ -8132,16 +8139,16 @@ public static IEnumerable ZipShortest public static IEnumerable ZipShortest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, - IEnumerable seventhSource, - IEnumerable eighthSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, + IEnumerable eighth, Func resultSelector) - => MoreEnumerable.ZipShortest(firstSource, secondSource, thirdSource, fourthSource, fifthSource, sixthSource, seventhSource, eighthSource, resultSelector); + => MoreEnumerable.ZipShortest(first, second, third, fourth, fifth, sixth, seventh, eighth, resultSelector); } } diff --git a/MoreLinq/Zip.cs b/MoreLinq/Zip.cs new file mode 100644 index 000000000..b03e3c9e0 --- /dev/null +++ b/MoreLinq/Zip.cs @@ -0,0 +1,43 @@ +#region License and Terms +// MoreLINQ - Extensions to LINQ to Objects +// Copyright (c) 2019 Pierre Lando. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +namespace MoreLinq +{ + using System.Collections.Generic; + + static class ZipHelper + { + public static bool MoveNextOrDefault(ref IEnumerator enumerator, ref T value) + { + if (enumerator == null) + { + return false; + } + + if (enumerator.MoveNext()) + { + value = enumerator.Current; + return true; + } + + enumerator.Dispose(); + enumerator = null; + value = default; + return false; + } + } +} diff --git a/MoreLinq/Zip.g.cs b/MoreLinq/Zip.g.cs index 648dc4814..f191db6f6 100644 --- a/MoreLinq/Zip.g.cs +++ b/MoreLinq/Zip.g.cs @@ -30,8 +30,8 @@ static partial class MoreEnumerable /// Type of elements in first input sequence. /// Type of elements in second input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. + /// The first source sequence. + /// The second source sequence. /// /// Function to apply to each tuple of elements. /// @@ -43,43 +43,36 @@ static partial class MoreEnumerable /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable EquiZip( - this IEnumerable firstSource, - IEnumerable secondSource, + this IEnumerable first, + IEnumerable second, Func resultSelector) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); return _(); IEnumerable _() { - using var e1 = firstSource.GetEnumerator(); - using var e2 = secondSource.GetEnumerator(); + using var e1 = first.GetEnumerator(); + using var e2 = second.GetEnumerator(); for (;;) { if (e1.MoveNext()) { if (e2.MoveNext()) - { yield return resultSelector(e1.Current, e2.Current); - } else - { break; - } } else { if (e2.MoveNext()) - { break; - } else - { yield break; - } } } @@ -94,8 +87,8 @@ public static IEnumerable EquiZip( /// /// Type of elements in first input sequence. /// Type of elements in second input sequence. - /// The first source sequence. - /// The second source sequence. + /// The first source sequence. + /// The second source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -106,12 +99,12 @@ public static IEnumerable EquiZip( /// This operator uses deferred execution and streams its results. /// public static IEnumerable<(T1, T2)> EquiZip( - this IEnumerable firstSource, - IEnumerable secondSource) + this IEnumerable first, + IEnumerable second) { return EquiZip( - firstSource, - secondSource, + first, + second, ValueTuple.Create); } @@ -125,8 +118,8 @@ public static IEnumerable EquiZip( /// Type of elements in first input sequence. /// Type of elements in second input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. + /// The first source sequence. + /// The second source sequence. /// /// Function to apply to each tuple of elements. /// @@ -136,12 +129,12 @@ public static IEnumerable EquiZip( /// This operator uses deferred execution and streams its results. /// public static IEnumerable ZipLongest( - this IEnumerable firstSource, - IEnumerable secondSource, + this IEnumerable first, + IEnumerable second, Func resultSelector) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); return _(); IEnumerable _() @@ -151,8 +144,8 @@ public static IEnumerable ZipLongest( try { - e1 = firstSource.GetEnumerator(); - e2 = secondSource.GetEnumerator(); + e1 = first.GetEnumerator(); + e2 = second.GetEnumerator(); var v1 = default(T1); var v2 = default(T2); @@ -181,8 +174,8 @@ public static IEnumerable ZipLongest( /// /// Type of elements in first input sequence. /// Type of elements in second input sequence. - /// The first source sequence. - /// The second source sequence. + /// The first source sequence. + /// The second source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -190,12 +183,12 @@ public static IEnumerable ZipLongest( /// This operator uses deferred execution and streams its results. /// public static IEnumerable<(T1, T2)> ZipLongest( - this IEnumerable firstSource, - IEnumerable secondSource) + this IEnumerable first, + IEnumerable second) { return ZipLongest( - firstSource, - secondSource, + first, + second, ValueTuple.Create); } @@ -207,8 +200,8 @@ public static IEnumerable ZipLongest( /// Type of elements in first input sequence. /// Type of elements in second input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. + /// The first source sequence. + /// The second source sequence. /// /// Function to apply to each tuple of elements. /// @@ -225,18 +218,18 @@ public static IEnumerable ZipLongest( /// public static IEnumerable ZipShortest( - this IEnumerable firstSource, - IEnumerable secondSource, + this IEnumerable first, + IEnumerable second, Func resultSelector) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); return _(); IEnumerable _() { - using var e1 = firstSource.GetEnumerator(); - using var e2 = secondSource.GetEnumerator(); + using var e1 = first.GetEnumerator(); + using var e2 = second.GetEnumerator(); while (e1.MoveNext() && e2.MoveNext()) { @@ -252,8 +245,8 @@ public static IEnumerable ZipShortest( /// /// Type of elements in first input sequence. /// Type of elements in second input sequence. - /// The first source sequence. - /// The second source sequence. + /// The first source sequence. + /// The second source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -268,12 +261,12 @@ public static IEnumerable ZipShortest( /// public static IEnumerable<(T1, T2)> ZipShortest( - this IEnumerable firstSource, - IEnumerable secondSource) + this IEnumerable first, + IEnumerable second) { return ZipShortest( - firstSource, - secondSource, + first, + second, ValueTuple.Create); } @@ -286,9 +279,9 @@ public static IEnumerable ZipShortest( /// Type of elements in second input sequence. /// Type of elements in third input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. /// /// Function to apply to each tuple of elements. /// @@ -300,46 +293,39 @@ public static IEnumerable ZipShortest( /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable EquiZip( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, Func resultSelector) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); return _(); IEnumerable _() { - using var e1 = firstSource.GetEnumerator(); - using var e2 = secondSource.GetEnumerator(); - using var e3 = thirdSource.GetEnumerator(); + using var e1 = first.GetEnumerator(); + using var e2 = second.GetEnumerator(); + using var e3 = third.GetEnumerator(); for (;;) { if (e1.MoveNext()) { if (e2.MoveNext() && e3.MoveNext()) - { yield return resultSelector(e1.Current, e2.Current, e3.Current); - } else - { break; - } } else { if (e2.MoveNext() || e3.MoveNext()) - { break; - } else - { yield break; - } } } @@ -355,9 +341,9 @@ public static IEnumerable EquiZip( /// Type of elements in first input sequence. /// Type of elements in second input sequence. /// Type of elements in third input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -368,14 +354,14 @@ public static IEnumerable EquiZip( /// This operator uses deferred execution and streams its results. /// public static IEnumerable<(T1, T2, T3)> EquiZip( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource) + this IEnumerable first, + IEnumerable second, + IEnumerable third) { return EquiZip( - firstSource, - secondSource, - thirdSource, + first, + second, + third, ValueTuple.Create); } @@ -390,9 +376,9 @@ public static IEnumerable EquiZip( /// Type of elements in second input sequence. /// Type of elements in third input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. /// /// Function to apply to each tuple of elements. /// @@ -402,14 +388,14 @@ public static IEnumerable EquiZip( /// This operator uses deferred execution and streams its results. /// public static IEnumerable ZipLongest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, Func resultSelector) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); return _(); IEnumerable _() @@ -420,9 +406,9 @@ public static IEnumerable ZipLongest( try { - e1 = firstSource.GetEnumerator(); - e2 = secondSource.GetEnumerator(); - e3 = thirdSource.GetEnumerator(); + e1 = first.GetEnumerator(); + e2 = second.GetEnumerator(); + e3 = third.GetEnumerator(); var v1 = default(T1); var v2 = default(T2); @@ -455,9 +441,9 @@ public static IEnumerable ZipLongest( /// Type of elements in first input sequence. /// Type of elements in second input sequence. /// Type of elements in third input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -465,14 +451,14 @@ public static IEnumerable ZipLongest( /// This operator uses deferred execution and streams its results. /// public static IEnumerable<(T1, T2, T3)> ZipLongest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource) + this IEnumerable first, + IEnumerable second, + IEnumerable third) { return ZipLongest( - firstSource, - secondSource, - thirdSource, + first, + second, + third, ValueTuple.Create); } @@ -485,9 +471,9 @@ public static IEnumerable ZipLongest( /// Type of elements in second input sequence. /// Type of elements in third input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. /// /// Function to apply to each tuple of elements. /// @@ -504,21 +490,21 @@ public static IEnumerable ZipLongest( /// public static IEnumerable ZipShortest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, Func resultSelector) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); return _(); IEnumerable _() { - using var e1 = firstSource.GetEnumerator(); - using var e2 = secondSource.GetEnumerator(); - using var e3 = thirdSource.GetEnumerator(); + using var e1 = first.GetEnumerator(); + using var e2 = second.GetEnumerator(); + using var e3 = third.GetEnumerator(); while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext()) { @@ -535,9 +521,9 @@ public static IEnumerable ZipShortest( /// Type of elements in first input sequence. /// Type of elements in second input sequence. /// Type of elements in third input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -552,14 +538,14 @@ public static IEnumerable ZipShortest( /// public static IEnumerable<(T1, T2, T3)> ZipShortest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource) + this IEnumerable first, + IEnumerable second, + IEnumerable third) { return ZipShortest( - firstSource, - secondSource, - thirdSource, + first, + second, + third, ValueTuple.Create); } @@ -573,10 +559,10 @@ public static IEnumerable ZipShortest( /// Type of elements in third input sequence. /// Type of elements in fourth input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. /// /// Function to apply to each tuple of elements. /// @@ -588,49 +574,42 @@ public static IEnumerable ZipShortest( /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable EquiZip( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, Func resultSelector) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); return _(); IEnumerable _() { - using var e1 = firstSource.GetEnumerator(); - using var e2 = secondSource.GetEnumerator(); - using var e3 = thirdSource.GetEnumerator(); - using var e4 = fourthSource.GetEnumerator(); + using var e1 = first.GetEnumerator(); + using var e2 = second.GetEnumerator(); + using var e3 = third.GetEnumerator(); + using var e4 = fourth.GetEnumerator(); for (;;) { if (e1.MoveNext()) { if (e2.MoveNext() && e3.MoveNext() && e4.MoveNext()) - { yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current); - } else - { break; - } } else { if (e2.MoveNext() || e3.MoveNext() || e4.MoveNext()) - { break; - } else - { yield break; - } } } @@ -647,10 +626,10 @@ public static IEnumerable EquiZip( /// Type of elements in second input sequence. /// Type of elements in third input sequence. /// Type of elements in fourth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -661,16 +640,16 @@ public static IEnumerable EquiZip( /// This operator uses deferred execution and streams its results. /// public static IEnumerable<(T1, T2, T3, T4)> EquiZip( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource) + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth) { return EquiZip( - firstSource, - secondSource, - thirdSource, - fourthSource, + first, + second, + third, + fourth, ValueTuple.Create); } @@ -686,10 +665,10 @@ public static IEnumerable EquiZip( /// Type of elements in third input sequence. /// Type of elements in fourth input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. /// /// Function to apply to each tuple of elements. /// @@ -699,16 +678,16 @@ public static IEnumerable EquiZip( /// This operator uses deferred execution and streams its results. /// public static IEnumerable ZipLongest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, Func resultSelector) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); return _(); IEnumerable _() @@ -720,10 +699,10 @@ public static IEnumerable ZipLongest( try { - e1 = firstSource.GetEnumerator(); - e2 = secondSource.GetEnumerator(); - e3 = thirdSource.GetEnumerator(); - e4 = fourthSource.GetEnumerator(); + e1 = first.GetEnumerator(); + e2 = second.GetEnumerator(); + e3 = third.GetEnumerator(); + e4 = fourth.GetEnumerator(); var v1 = default(T1); var v2 = default(T2); @@ -760,10 +739,10 @@ public static IEnumerable ZipLongest( /// Type of elements in second input sequence. /// Type of elements in third input sequence. /// Type of elements in fourth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -771,16 +750,16 @@ public static IEnumerable ZipLongest( /// This operator uses deferred execution and streams its results. /// public static IEnumerable<(T1, T2, T3, T4)> ZipLongest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource) + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth) { return ZipLongest( - firstSource, - secondSource, - thirdSource, - fourthSource, + first, + second, + third, + fourth, ValueTuple.Create); } @@ -794,10 +773,10 @@ public static IEnumerable ZipLongest( /// Type of elements in third input sequence. /// Type of elements in fourth input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. /// /// Function to apply to each tuple of elements. /// @@ -814,24 +793,24 @@ public static IEnumerable ZipLongest( /// public static IEnumerable ZipShortest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, Func resultSelector) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); return _(); IEnumerable _() { - using var e1 = firstSource.GetEnumerator(); - using var e2 = secondSource.GetEnumerator(); - using var e3 = thirdSource.GetEnumerator(); - using var e4 = fourthSource.GetEnumerator(); + using var e1 = first.GetEnumerator(); + using var e2 = second.GetEnumerator(); + using var e3 = third.GetEnumerator(); + using var e4 = fourth.GetEnumerator(); while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext() && e4.MoveNext()) { @@ -849,10 +828,10 @@ public static IEnumerable ZipShortest( /// Type of elements in second input sequence. /// Type of elements in third input sequence. /// Type of elements in fourth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -867,16 +846,16 @@ public static IEnumerable ZipShortest( /// public static IEnumerable<(T1, T2, T3, T4)> ZipShortest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource) + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth) { return ZipShortest( - firstSource, - secondSource, - thirdSource, - fourthSource, + first, + second, + third, + fourth, ValueTuple.Create); } @@ -891,11 +870,11 @@ public static IEnumerable ZipShortest( /// Type of elements in fourth input sequence. /// Type of elements in fifth input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. /// /// Function to apply to each tuple of elements. /// @@ -907,52 +886,45 @@ public static IEnumerable ZipShortest( /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable EquiZip( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, Func resultSelector) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); - if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); + if (fifth == null) throw new ArgumentNullException(nameof(fifth)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); return _(); IEnumerable _() { - using var e1 = firstSource.GetEnumerator(); - using var e2 = secondSource.GetEnumerator(); - using var e3 = thirdSource.GetEnumerator(); - using var e4 = fourthSource.GetEnumerator(); - using var e5 = fifthSource.GetEnumerator(); + using var e1 = first.GetEnumerator(); + using var e2 = second.GetEnumerator(); + using var e3 = third.GetEnumerator(); + using var e4 = fourth.GetEnumerator(); + using var e5 = fifth.GetEnumerator(); for (;;) { if (e1.MoveNext()) { if (e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext()) - { yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current, e5.Current); - } else - { break; - } } else { if (e2.MoveNext() || e3.MoveNext() || e4.MoveNext() || e5.MoveNext()) - { break; - } else - { yield break; - } } } @@ -970,11 +942,11 @@ public static IEnumerable EquiZip( /// Type of elements in third input sequence. /// Type of elements in fourth input sequence. /// Type of elements in fifth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -985,18 +957,18 @@ public static IEnumerable EquiZip( /// This operator uses deferred execution and streams its results. /// public static IEnumerable<(T1, T2, T3, T4, T5)> EquiZip( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource) + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth) { return EquiZip( - firstSource, - secondSource, - thirdSource, - fourthSource, - fifthSource, + first, + second, + third, + fourth, + fifth, ValueTuple.Create); } @@ -1013,11 +985,11 @@ public static IEnumerable EquiZip( /// Type of elements in fourth input sequence. /// Type of elements in fifth input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. /// /// Function to apply to each tuple of elements. /// @@ -1027,18 +999,18 @@ public static IEnumerable EquiZip( /// This operator uses deferred execution and streams its results. /// public static IEnumerable ZipLongest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, Func resultSelector) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); - if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); + if (fifth == null) throw new ArgumentNullException(nameof(fifth)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); return _(); IEnumerable _() @@ -1051,11 +1023,11 @@ public static IEnumerable ZipLongest( try { - e1 = firstSource.GetEnumerator(); - e2 = secondSource.GetEnumerator(); - e3 = thirdSource.GetEnumerator(); - e4 = fourthSource.GetEnumerator(); - e5 = fifthSource.GetEnumerator(); + e1 = first.GetEnumerator(); + e2 = second.GetEnumerator(); + e3 = third.GetEnumerator(); + e4 = fourth.GetEnumerator(); + e5 = fifth.GetEnumerator(); var v1 = default(T1); var v2 = default(T2); @@ -1096,11 +1068,11 @@ public static IEnumerable ZipLongest( /// Type of elements in third input sequence. /// Type of elements in fourth input sequence. /// Type of elements in fifth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -1108,18 +1080,18 @@ public static IEnumerable ZipLongest( /// This operator uses deferred execution and streams its results. /// public static IEnumerable<(T1, T2, T3, T4, T5)> ZipLongest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource) + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth) { return ZipLongest( - firstSource, - secondSource, - thirdSource, - fourthSource, - fifthSource, + first, + second, + third, + fourth, + fifth, ValueTuple.Create); } @@ -1134,11 +1106,11 @@ public static IEnumerable ZipLongest( /// Type of elements in fourth input sequence. /// Type of elements in fifth input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. /// /// Function to apply to each tuple of elements. /// @@ -1155,27 +1127,27 @@ public static IEnumerable ZipLongest( /// public static IEnumerable ZipShortest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, Func resultSelector) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); - if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); + if (fifth == null) throw new ArgumentNullException(nameof(fifth)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); return _(); IEnumerable _() { - using var e1 = firstSource.GetEnumerator(); - using var e2 = secondSource.GetEnumerator(); - using var e3 = thirdSource.GetEnumerator(); - using var e4 = fourthSource.GetEnumerator(); - using var e5 = fifthSource.GetEnumerator(); + using var e1 = first.GetEnumerator(); + using var e2 = second.GetEnumerator(); + using var e3 = third.GetEnumerator(); + using var e4 = fourth.GetEnumerator(); + using var e5 = fifth.GetEnumerator(); while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext()) { @@ -1194,11 +1166,11 @@ public static IEnumerable ZipShortest( /// Type of elements in third input sequence. /// Type of elements in fourth input sequence. /// Type of elements in fifth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -1213,18 +1185,18 @@ public static IEnumerable ZipShortest( /// public static IEnumerable<(T1, T2, T3, T4, T5)> ZipShortest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource) + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth) { return ZipShortest( - firstSource, - secondSource, - thirdSource, - fourthSource, - fifthSource, + first, + second, + third, + fourth, + fifth, ValueTuple.Create); } @@ -1240,12 +1212,12 @@ public static IEnumerable ZipShortest( /// Type of elements in fifth input sequence. /// Type of elements in sixth input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. /// /// Function to apply to each tuple of elements. /// @@ -1257,55 +1229,48 @@ public static IEnumerable ZipShortest( /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable EquiZip( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, Func resultSelector) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); - if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); - if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); + if (fifth == null) throw new ArgumentNullException(nameof(fifth)); + if (sixth == null) throw new ArgumentNullException(nameof(sixth)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); return _(); IEnumerable _() { - using var e1 = firstSource.GetEnumerator(); - using var e2 = secondSource.GetEnumerator(); - using var e3 = thirdSource.GetEnumerator(); - using var e4 = fourthSource.GetEnumerator(); - using var e5 = fifthSource.GetEnumerator(); - using var e6 = sixthSource.GetEnumerator(); + using var e1 = first.GetEnumerator(); + using var e2 = second.GetEnumerator(); + using var e3 = third.GetEnumerator(); + using var e4 = fourth.GetEnumerator(); + using var e5 = fifth.GetEnumerator(); + using var e6 = sixth.GetEnumerator(); for (;;) { if (e1.MoveNext()) { if (e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext() && e6.MoveNext()) - { yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current, e5.Current, e6.Current); - } else - { break; - } } else { if (e2.MoveNext() || e3.MoveNext() || e4.MoveNext() || e5.MoveNext() || e6.MoveNext()) - { break; - } else - { yield break; - } } } @@ -1324,12 +1289,12 @@ public static IEnumerable EquiZip( /// Type of elements in fourth input sequence. /// Type of elements in fifth input sequence. /// Type of elements in sixth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -1340,20 +1305,20 @@ public static IEnumerable EquiZip( /// This operator uses deferred execution and streams its results. /// public static IEnumerable<(T1, T2, T3, T4, T5, T6)> EquiZip( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource) + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth) { return EquiZip( - firstSource, - secondSource, - thirdSource, - fourthSource, - fifthSource, - sixthSource, + first, + second, + third, + fourth, + fifth, + sixth, ValueTuple.Create); } @@ -1371,12 +1336,12 @@ public static IEnumerable EquiZip( /// Type of elements in fifth input sequence. /// Type of elements in sixth input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. /// /// Function to apply to each tuple of elements. /// @@ -1386,20 +1351,20 @@ public static IEnumerable EquiZip( /// This operator uses deferred execution and streams its results. /// public static IEnumerable ZipLongest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, Func resultSelector) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); - if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); - if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); + if (fifth == null) throw new ArgumentNullException(nameof(fifth)); + if (sixth == null) throw new ArgumentNullException(nameof(sixth)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); return _(); IEnumerable _() @@ -1413,12 +1378,12 @@ public static IEnumerable ZipLongest( try { - e1 = firstSource.GetEnumerator(); - e2 = secondSource.GetEnumerator(); - e3 = thirdSource.GetEnumerator(); - e4 = fourthSource.GetEnumerator(); - e5 = fifthSource.GetEnumerator(); - e6 = sixthSource.GetEnumerator(); + e1 = first.GetEnumerator(); + e2 = second.GetEnumerator(); + e3 = third.GetEnumerator(); + e4 = fourth.GetEnumerator(); + e5 = fifth.GetEnumerator(); + e6 = sixth.GetEnumerator(); var v1 = default(T1); var v2 = default(T2); @@ -1463,12 +1428,12 @@ public static IEnumerable ZipLongest( /// Type of elements in fourth input sequence. /// Type of elements in fifth input sequence. /// Type of elements in sixth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -1476,20 +1441,20 @@ public static IEnumerable ZipLongest( /// This operator uses deferred execution and streams its results. /// public static IEnumerable<(T1, T2, T3, T4, T5, T6)> ZipLongest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource) + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth) { return ZipLongest( - firstSource, - secondSource, - thirdSource, - fourthSource, - fifthSource, - sixthSource, + first, + second, + third, + fourth, + fifth, + sixth, ValueTuple.Create); } @@ -1505,12 +1470,12 @@ public static IEnumerable ZipLongest( /// Type of elements in fifth input sequence. /// Type of elements in sixth input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. /// /// Function to apply to each tuple of elements. /// @@ -1527,30 +1492,30 @@ public static IEnumerable ZipLongest( /// public static IEnumerable ZipShortest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, Func resultSelector) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); - if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); - if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); + if (fifth == null) throw new ArgumentNullException(nameof(fifth)); + if (sixth == null) throw new ArgumentNullException(nameof(sixth)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); return _(); IEnumerable _() { - using var e1 = firstSource.GetEnumerator(); - using var e2 = secondSource.GetEnumerator(); - using var e3 = thirdSource.GetEnumerator(); - using var e4 = fourthSource.GetEnumerator(); - using var e5 = fifthSource.GetEnumerator(); - using var e6 = sixthSource.GetEnumerator(); + using var e1 = first.GetEnumerator(); + using var e2 = second.GetEnumerator(); + using var e3 = third.GetEnumerator(); + using var e4 = fourth.GetEnumerator(); + using var e5 = fifth.GetEnumerator(); + using var e6 = sixth.GetEnumerator(); while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext() && e6.MoveNext()) { @@ -1570,12 +1535,12 @@ public static IEnumerable ZipShortest( /// Type of elements in fourth input sequence. /// Type of elements in fifth input sequence. /// Type of elements in sixth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -1590,20 +1555,20 @@ public static IEnumerable ZipShortest( /// public static IEnumerable<(T1, T2, T3, T4, T5, T6)> ZipShortest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource) + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth) { return ZipShortest( - firstSource, - secondSource, - thirdSource, - fourthSource, - fifthSource, - sixthSource, + first, + second, + third, + fourth, + fifth, + sixth, ValueTuple.Create); } @@ -1620,13 +1585,13 @@ public static IEnumerable ZipShortest( /// Type of elements in sixth input sequence. /// Type of elements in seventh input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. /// /// Function to apply to each tuple of elements. /// @@ -1638,58 +1603,51 @@ public static IEnumerable ZipShortest( /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable EquiZip( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, - IEnumerable seventhSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, Func resultSelector) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); - if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); - if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); - if (seventhSource == null) throw new ArgumentNullException(nameof(seventhSource)); + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); + if (fifth == null) throw new ArgumentNullException(nameof(fifth)); + if (sixth == null) throw new ArgumentNullException(nameof(sixth)); + if (seventh == null) throw new ArgumentNullException(nameof(seventh)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); return _(); IEnumerable _() { - using var e1 = firstSource.GetEnumerator(); - using var e2 = secondSource.GetEnumerator(); - using var e3 = thirdSource.GetEnumerator(); - using var e4 = fourthSource.GetEnumerator(); - using var e5 = fifthSource.GetEnumerator(); - using var e6 = sixthSource.GetEnumerator(); - using var e7 = seventhSource.GetEnumerator(); + using var e1 = first.GetEnumerator(); + using var e2 = second.GetEnumerator(); + using var e3 = third.GetEnumerator(); + using var e4 = fourth.GetEnumerator(); + using var e5 = fifth.GetEnumerator(); + using var e6 = sixth.GetEnumerator(); + using var e7 = seventh.GetEnumerator(); for (;;) { if (e1.MoveNext()) { if (e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext() && e6.MoveNext() && e7.MoveNext()) - { yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current, e5.Current, e6.Current, e7.Current); - } else - { break; - } } else { if (e2.MoveNext() || e3.MoveNext() || e4.MoveNext() || e5.MoveNext() || e6.MoveNext() || e7.MoveNext()) - { break; - } else - { yield break; - } } } @@ -1709,13 +1667,13 @@ public static IEnumerable EquiZip( /// Type of elements in fifth input sequence. /// Type of elements in sixth input sequence. /// Type of elements in seventh input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -1726,22 +1684,22 @@ public static IEnumerable EquiZip( /// This operator uses deferred execution and streams its results. /// public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7)> EquiZip( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, - IEnumerable seventhSource) + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh) { return EquiZip( - firstSource, - secondSource, - thirdSource, - fourthSource, - fifthSource, - sixthSource, - seventhSource, + first, + second, + third, + fourth, + fifth, + sixth, + seventh, ValueTuple.Create); } @@ -1760,13 +1718,13 @@ public static IEnumerable EquiZip( /// Type of elements in sixth input sequence. /// Type of elements in seventh input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. /// /// Function to apply to each tuple of elements. /// @@ -1776,22 +1734,22 @@ public static IEnumerable EquiZip( /// This operator uses deferred execution and streams its results. /// public static IEnumerable ZipLongest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, - IEnumerable seventhSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, Func resultSelector) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); - if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); - if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); - if (seventhSource == null) throw new ArgumentNullException(nameof(seventhSource)); + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); + if (fifth == null) throw new ArgumentNullException(nameof(fifth)); + if (sixth == null) throw new ArgumentNullException(nameof(sixth)); + if (seventh == null) throw new ArgumentNullException(nameof(seventh)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); return _(); IEnumerable _() @@ -1806,13 +1764,13 @@ public static IEnumerable ZipLongest ZipLongestType of elements in fifth input sequence. /// Type of elements in sixth input sequence. /// Type of elements in seventh input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -1875,22 +1833,22 @@ public static IEnumerable ZipLongest public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7)> ZipLongest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, - IEnumerable seventhSource) + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh) { return ZipLongest( - firstSource, - secondSource, - thirdSource, - fourthSource, - fifthSource, - sixthSource, - seventhSource, + first, + second, + third, + fourth, + fifth, + sixth, + seventh, ValueTuple.Create); } @@ -1907,13 +1865,13 @@ public static IEnumerable ZipLongestType of elements in sixth input sequence. /// Type of elements in seventh input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. /// /// Function to apply to each tuple of elements. /// @@ -1930,33 +1888,33 @@ public static IEnumerable ZipLongest public static IEnumerable ZipShortest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, - IEnumerable seventhSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, Func resultSelector) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); - if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); - if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); - if (seventhSource == null) throw new ArgumentNullException(nameof(seventhSource)); + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); + if (fifth == null) throw new ArgumentNullException(nameof(fifth)); + if (sixth == null) throw new ArgumentNullException(nameof(sixth)); + if (seventh == null) throw new ArgumentNullException(nameof(seventh)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); return _(); IEnumerable _() { - using var e1 = firstSource.GetEnumerator(); - using var e2 = secondSource.GetEnumerator(); - using var e3 = thirdSource.GetEnumerator(); - using var e4 = fourthSource.GetEnumerator(); - using var e5 = fifthSource.GetEnumerator(); - using var e6 = sixthSource.GetEnumerator(); - using var e7 = seventhSource.GetEnumerator(); + using var e1 = first.GetEnumerator(); + using var e2 = second.GetEnumerator(); + using var e3 = third.GetEnumerator(); + using var e4 = fourth.GetEnumerator(); + using var e5 = fifth.GetEnumerator(); + using var e6 = sixth.GetEnumerator(); + using var e7 = seventh.GetEnumerator(); while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext() && e6.MoveNext() && e7.MoveNext()) { @@ -1977,13 +1935,13 @@ public static IEnumerable ZipShortestType of elements in fifth input sequence. /// Type of elements in sixth input sequence. /// Type of elements in seventh input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -1998,22 +1956,22 @@ public static IEnumerable ZipShortest public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7)> ZipShortest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, - IEnumerable seventhSource) + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh) { return ZipShortest( - firstSource, - secondSource, - thirdSource, - fourthSource, - fifthSource, - sixthSource, - seventhSource, + first, + second, + third, + fourth, + fifth, + sixth, + seventh, ValueTuple.Create); } @@ -2031,14 +1989,14 @@ public static IEnumerable ZipShortestType of elements in seventh input sequence. /// Type of elements in eighth input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. - /// The eighth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. /// /// Function to apply to each tuple of elements. /// @@ -2050,61 +2008,54 @@ public static IEnumerable ZipShortest /// This operator uses deferred execution and streams its results. /// + public static IEnumerable EquiZip( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, - IEnumerable seventhSource, - IEnumerable eighthSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, + IEnumerable eighth, Func resultSelector) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); - if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); - if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); - if (seventhSource == null) throw new ArgumentNullException(nameof(seventhSource)); - if (eighthSource == null) throw new ArgumentNullException(nameof(eighthSource)); + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); + if (fifth == null) throw new ArgumentNullException(nameof(fifth)); + if (sixth == null) throw new ArgumentNullException(nameof(sixth)); + if (seventh == null) throw new ArgumentNullException(nameof(seventh)); + if (eighth == null) throw new ArgumentNullException(nameof(eighth)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); return _(); IEnumerable _() { - using var e1 = firstSource.GetEnumerator(); - using var e2 = secondSource.GetEnumerator(); - using var e3 = thirdSource.GetEnumerator(); - using var e4 = fourthSource.GetEnumerator(); - using var e5 = fifthSource.GetEnumerator(); - using var e6 = sixthSource.GetEnumerator(); - using var e7 = seventhSource.GetEnumerator(); - using var e8 = eighthSource.GetEnumerator(); + using var e1 = first.GetEnumerator(); + using var e2 = second.GetEnumerator(); + using var e3 = third.GetEnumerator(); + using var e4 = fourth.GetEnumerator(); + using var e5 = fifth.GetEnumerator(); + using var e6 = sixth.GetEnumerator(); + using var e7 = seventh.GetEnumerator(); + using var e8 = eighth.GetEnumerator(); for (;;) { if (e1.MoveNext()) { if (e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext() && e6.MoveNext() && e7.MoveNext() && e8.MoveNext()) - { yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current, e5.Current, e6.Current, e7.Current, e8.Current); - } else - { break; - } } else { if (e2.MoveNext() || e3.MoveNext() || e4.MoveNext() || e5.MoveNext() || e6.MoveNext() || e7.MoveNext() || e8.MoveNext()) - { break; - } else - { yield break; - } } } @@ -2125,14 +2076,14 @@ public static IEnumerable EquiZipType of elements in sixth input sequence. /// Type of elements in seventh input sequence. /// Type of elements in eighth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. - /// The eighth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -2143,24 +2094,24 @@ public static IEnumerable EquiZip public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7, T8)> EquiZip( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, - IEnumerable seventhSource, - IEnumerable eighthSource) + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, + IEnumerable eighth) { return EquiZip( - firstSource, - secondSource, - thirdSource, - fourthSource, - fifthSource, - sixthSource, - seventhSource, - eighthSource, + first, + second, + third, + fourth, + fifth, + sixth, + seventh, + eighth, ValueTuple.Create); } @@ -2180,14 +2131,14 @@ public static IEnumerable EquiZipType of elements in seventh input sequence. /// Type of elements in eighth input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. - /// The eighth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. /// /// Function to apply to each tuple of elements. /// @@ -2197,24 +2148,24 @@ public static IEnumerable EquiZip public static IEnumerable ZipLongest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, - IEnumerable seventhSource, - IEnumerable eighthSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, + IEnumerable eighth, Func resultSelector) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); - if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); - if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); - if (seventhSource == null) throw new ArgumentNullException(nameof(seventhSource)); - if (eighthSource == null) throw new ArgumentNullException(nameof(eighthSource)); + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); + if (fifth == null) throw new ArgumentNullException(nameof(fifth)); + if (sixth == null) throw new ArgumentNullException(nameof(sixth)); + if (seventh == null) throw new ArgumentNullException(nameof(seventh)); + if (eighth == null) throw new ArgumentNullException(nameof(eighth)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); return _(); IEnumerable _() @@ -2230,14 +2181,14 @@ public static IEnumerable ZipLongest ZipLongestType of elements in sixth input sequence. /// Type of elements in seventh input sequence. /// Type of elements in eighth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. - /// The eighth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -2305,24 +2256,24 @@ public static IEnumerable ZipLongest public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7, T8)> ZipLongest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, - IEnumerable seventhSource, - IEnumerable eighthSource) + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, + IEnumerable eighth) { return ZipLongest( - firstSource, - secondSource, - thirdSource, - fourthSource, - fifthSource, - sixthSource, - seventhSource, - eighthSource, + first, + second, + third, + fourth, + fifth, + sixth, + seventh, + eighth, ValueTuple.Create); } @@ -2340,14 +2291,14 @@ public static IEnumerable ZipLongestType of elements in seventh input sequence. /// Type of elements in eighth input sequence. /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. - /// The eighth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. /// /// Function to apply to each tuple of elements. /// @@ -2364,36 +2315,36 @@ public static IEnumerable ZipLongest public static IEnumerable ZipShortest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, - IEnumerable seventhSource, - IEnumerable eighthSource, + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, + IEnumerable eighth, Func resultSelector) { - if (firstSource == null) throw new ArgumentNullException(nameof(firstSource)); - if (secondSource == null) throw new ArgumentNullException(nameof(secondSource)); - if (thirdSource == null) throw new ArgumentNullException(nameof(thirdSource)); - if (fourthSource == null) throw new ArgumentNullException(nameof(fourthSource)); - if (fifthSource == null) throw new ArgumentNullException(nameof(fifthSource)); - if (sixthSource == null) throw new ArgumentNullException(nameof(sixthSource)); - if (seventhSource == null) throw new ArgumentNullException(nameof(seventhSource)); - if (eighthSource == null) throw new ArgumentNullException(nameof(eighthSource)); + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); + if (fifth == null) throw new ArgumentNullException(nameof(fifth)); + if (sixth == null) throw new ArgumentNullException(nameof(sixth)); + if (seventh == null) throw new ArgumentNullException(nameof(seventh)); + if (eighth == null) throw new ArgumentNullException(nameof(eighth)); if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); return _(); IEnumerable _() { - using var e1 = firstSource.GetEnumerator(); - using var e2 = secondSource.GetEnumerator(); - using var e3 = thirdSource.GetEnumerator(); - using var e4 = fourthSource.GetEnumerator(); - using var e5 = fifthSource.GetEnumerator(); - using var e6 = sixthSource.GetEnumerator(); - using var e7 = seventhSource.GetEnumerator(); - using var e8 = eighthSource.GetEnumerator(); + using var e1 = first.GetEnumerator(); + using var e2 = second.GetEnumerator(); + using var e3 = third.GetEnumerator(); + using var e4 = fourth.GetEnumerator(); + using var e5 = fifth.GetEnumerator(); + using var e6 = sixth.GetEnumerator(); + using var e7 = seventh.GetEnumerator(); + using var e8 = eighth.GetEnumerator(); while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext() && e6.MoveNext() && e7.MoveNext() && e8.MoveNext()) { @@ -2415,14 +2366,14 @@ public static IEnumerable ZipShortestType of elements in sixth input sequence. /// Type of elements in seventh input sequence. /// Type of elements in eighth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. - /// The eighth source sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. /// /// A sequence of tuples, where each tuple contains the N-th element /// from each of the argument sequences. @@ -2437,47 +2388,26 @@ public static IEnumerable ZipShortest public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7, T8)> ZipShortest( - this IEnumerable firstSource, - IEnumerable secondSource, - IEnumerable thirdSource, - IEnumerable fourthSource, - IEnumerable fifthSource, - IEnumerable sixthSource, - IEnumerable seventhSource, - IEnumerable eighthSource) + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, + IEnumerable eighth) { return ZipShortest( - firstSource, - secondSource, - thirdSource, - fourthSource, - fifthSource, - sixthSource, - seventhSource, - eighthSource, + first, + second, + third, + fourth, + fifth, + sixth, + seventh, + eighth, ValueTuple.Create); } - static class ZipHelper - { - public static bool MoveNextOrDefault(ref IEnumerator enumerator, ref T value) - { - if (enumerator == null) - { - return false; - } - - if (enumerator.MoveNext()) - { - value = enumerator.Current; - return true; - } - - enumerator.Dispose(); - enumerator = null; - value = default; - return false; - } - } } } diff --git a/MoreLinq/Zip.g.tt b/MoreLinq/Zip.g.tt index f013e67bb..fba441e95 100644 --- a/MoreLinq/Zip.g.tt +++ b/MoreLinq/Zip.g.tt @@ -77,7 +77,7 @@ namespace MoreLinq <#} #> /// Type of elements in result sequence. <# foreach (var arg in o.Arguments) { #> - /// The <#= arg.Ordinal #> source sequence. + /// The <#= arg.Ordinal #> source sequence. <#} #> /// /// Function to apply to each tuple of elements. @@ -90,21 +90,22 @@ namespace MoreLinq /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable EquiZip<<#= o.Types#>, TResult>( <# foreach (var arg in o.Arguments) { #> - <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #>Source, + <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #>, <#}#> Func<<#= o.Types#>, TResult> resultSelector) { <# foreach (var arg in o.Arguments) { #> - if (<#= arg.Ordinal #>Source == null) throw new ArgumentNullException(nameof(<#= arg.Ordinal #>Source)); + if (<#= arg.Ordinal #> == null) throw new ArgumentNullException(nameof(<#= arg.Ordinal #>)); <#} #> if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); return _(); IEnumerable _() { <# foreach (var arg in o.Arguments) { #> - using var e<#= arg.Number #> = <#= arg.Ordinal #>Source.GetEnumerator(); + using var e<#= arg.Number #> = <#= arg.Ordinal #>.GetEnumerator(); <#} #> for (;;) @@ -112,24 +113,16 @@ namespace MoreLinq if (e<#= o.Arguments.First().Number #>.MoveNext()) { if (<# foreach (var arg in o.Arguments.Skip(1)) { #>e<#= arg.Number #>.MoveNext()<#= arg.Num < o.Count ? " && " : "" #><#}#>) - { yield return resultSelector(<# foreach (var arg in o.Arguments) { #>e<#= arg.Number #>.Current<#= arg.Num < o.Count ? ", " : "" #><#}#>); - } else - { break; - } } else { if (<# foreach (var arg in o.Arguments.Skip(1)) { #>e<#= arg.Number #>.MoveNext()<#= arg.Num < o.Count ? " || " : "" #><#}#>) - { break; - } else - { yield break; - } } } @@ -146,7 +139,7 @@ namespace MoreLinq /// Type of elements in <#= arg.Ordinal #> input sequence. <#} #> <# foreach (var arg in o.Arguments) { #> - /// The <#= arg.Ordinal #> source sequence. + /// The <#= arg.Ordinal #> source sequence. <#} #> /// /// A sequence of tuples, where each tuple contains the N-th element @@ -159,12 +152,12 @@ namespace MoreLinq /// public static IEnumerable<(<#= o.Types#>)> EquiZip<<#= o.Types#>>( <# foreach (var arg in o.Arguments) { #> - <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #>Source<#= arg.Num < o.Count ? "," : ")" #> + <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #><#= arg.Num < o.Count ? "," : ")" #> <#}#> { return EquiZip( <# foreach (var arg in o.Arguments) { #> - <#= arg.Ordinal #>Source, + <#= arg.Ordinal #>, <#}#> ValueTuple.Create); } @@ -181,7 +174,7 @@ namespace MoreLinq <#} #> /// Type of elements in result sequence. <# foreach (var arg in o.Arguments) { #> - /// The <#= arg.Ordinal #> source sequence. + /// The <#= arg.Ordinal #> source sequence. <#} #> /// /// Function to apply to each tuple of elements. @@ -193,12 +186,12 @@ namespace MoreLinq /// public static IEnumerable ZipLongest<<#= o.Types#>, TResult>( <# foreach (var arg in o.Arguments) { #> - <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #>Source, + <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #>, <#}#> Func<<#= o.Types#>, TResult> resultSelector) { <# foreach (var arg in o.Arguments) { #> - if (<#= arg.Ordinal #>Source == null) throw new ArgumentNullException(nameof(<#= arg.Ordinal #>Source)); + if (<#= arg.Ordinal #> == null) throw new ArgumentNullException(nameof(<#= arg.Ordinal #>)); <#} #> if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); @@ -211,7 +204,7 @@ namespace MoreLinq try { <# foreach (var arg in o.Arguments) { #> - e<#= arg.Number #> = <#= arg.Ordinal #>Source.GetEnumerator(); + e<#= arg.Number #> = <#= arg.Ordinal #>.GetEnumerator(); <#} #> <# foreach (var arg in o.Arguments) { #> @@ -246,7 +239,7 @@ namespace MoreLinq /// Type of elements in <#= arg.Ordinal #> input sequence. <#} #> <# foreach (var arg in o.Arguments) { #> - /// The <#= arg.Ordinal #> source sequence. + /// The <#= arg.Ordinal #> source sequence. <#} #> /// /// A sequence of tuples, where each tuple contains the N-th element @@ -256,12 +249,12 @@ namespace MoreLinq /// public static IEnumerable<(<#= o.Types#>)> ZipLongest<<#= o.Types#>>( <# foreach (var arg in o.Arguments) { #> - <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #>Source<#= arg.Num < o.Count ? "," : ")" #> + <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #><#= arg.Num < o.Count ? "," : ")" #> <#}#> { return ZipLongest( <# foreach (var arg in o.Arguments) { #> - <#= arg.Ordinal #>Source, + <#= arg.Ordinal #>, <#}#> ValueTuple.Create); } @@ -276,7 +269,7 @@ namespace MoreLinq <#} #> /// Type of elements in result sequence. <# foreach (var arg in o.Arguments) { #> - /// The <#= arg.Ordinal #> source sequence. + /// The <#= arg.Ordinal #> source sequence. <#} #> /// /// Function to apply to each tuple of elements. @@ -295,19 +288,19 @@ namespace MoreLinq public static IEnumerable ZipShortest<<#= o.Types#>, TResult>( <# foreach (var arg in o.Arguments) { #> - <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #>Source, + <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #>, <#}#> Func<<#= o.Types#>, TResult> resultSelector) { <# foreach (var arg in o.Arguments) { #> - if (<#= arg.Ordinal #>Source == null) throw new ArgumentNullException(nameof(<#= arg.Ordinal #>Source)); + if (<#= arg.Ordinal #> == null) throw new ArgumentNullException(nameof(<#= arg.Ordinal #>)); <#} #> if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); return _(); IEnumerable _() { <# foreach (var arg in o.Arguments) { #> - using var e<#= arg.Number #> = <#= arg.Ordinal #>Source.GetEnumerator(); + using var e<#= arg.Number #> = <#= arg.Ordinal #>.GetEnumerator(); <#} #> while (<# foreach (var arg in o.Arguments) { #>e<#= arg.Number #>.MoveNext()<#= arg.Num < o.Count ? " && " : "" #><#}#>) @@ -326,7 +319,7 @@ namespace MoreLinq /// Type of elements in <#= arg.Ordinal #> input sequence. <#} #> <# foreach (var arg in o.Arguments) { #> - /// The <#= arg.Ordinal #> source sequence. + /// The <#= arg.Ordinal #> source sequence. <#} #> /// /// A sequence of tuples, where each tuple contains the N-th element @@ -343,37 +336,16 @@ namespace MoreLinq public static IEnumerable<(<#= o.Types#>)> ZipShortest<<#= o.Types#>>( <# foreach (var arg in o.Arguments) { #> - <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #>Source<#= arg.Num < o.Count ? "," : ")" #> + <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #><#= arg.Num < o.Count ? "," : ")" #> <#}#> { return ZipShortest( <# foreach (var arg in o.Arguments) { #> - <#= arg.Ordinal #>Source, + <#= arg.Ordinal #>, <#}#> ValueTuple.Create); } <# } #> - static class ZipHelper - { - public static bool MoveNextOrDefault(ref IEnumerator enumerator, ref T value) - { - if (enumerator == null) - { - return false; - } - - if (enumerator.MoveNext()) - { - value = enumerator.Current; - return true; - } - - enumerator.Dispose(); - enumerator = null; - value = default; - return false; - } - } } } From 236123acf83ae53226c4d1b9d2f187d027b25bee Mon Sep 17 00:00:00 2001 From: Orace Date: Wed, 6 Nov 2019 10:39:18 +0100 Subject: [PATCH 07/11] Refactor Zip.g.tt --- MoreLinq/Zip.g.tt | 157 ++++++++++++++++++++++------------------------ 1 file changed, 76 insertions(+), 81 deletions(-) diff --git a/MoreLinq/Zip.g.tt b/MoreLinq/Zip.g.tt index fba441e95..acf41571f 100644 --- a/MoreLinq/Zip.g.tt +++ b/MoreLinq/Zip.g.tt @@ -22,40 +22,35 @@ #endregion <# + var ordinals = new[] + { + "", + "first", "second", "third", "fourth", + "fifth", "sixth", "seventh", "eighth" + }; + var overloads = - from args in new[] - { - new[] - { - new { Ordinal = "first" , Arity = "one" }, - new { Ordinal = "second" , Arity = "two" }, - new { Ordinal = "third" , Arity = "three" }, - new { Ordinal = "fourth" , Arity = "four" }, - new { Ordinal = "fifth" , Arity = "five" }, - new { Ordinal = "sixth" , Arity = "six" }, - new { Ordinal = "seventh", Arity = "seven" }, - new { Ordinal = "eighth" , Arity = "eight" }, - } - } - select args.Select((a, i) => new - { - a.Ordinal, - a.Arity, - Count = i + 1, - Number = (i + 1).ToString(CultureInfo.InvariantCulture), - }) - into args - select args.ToList() into args - from a in args.Skip(1) - select new - { - a.Arity, - a.Count, - Arguments = args.Take(a.Count) - .Select(aa => new { aa.Number, Num = aa.Count, aa.Ordinal }) - .ToList(), - Types = string.Join(", ", Enumerable.Range(1, a.Count).Select(i => $"T{i}")), - }; + Enumerable.Range(2, 7) + .Select(argCount => + Enumerable.Range(1, argCount).Select(argPosition => + new + { + IsFirst = argPosition == 1, + IsLast = argPosition == argCount, + Name = ordinals[argPosition], + Ordinal = ordinals[argPosition], + Type = $"T{argPosition}", + // Objects associated with the argument + Enumerator = $"e{argPosition}", + Value = $"v{argPosition}" + })) + .Select(args => args.ToList()) + .Select(args => + new + { + Arguments = args, + TParams = string.Join(", ", args.Select(arg => arg.Type)) + }); #> namespace MoreLinq { @@ -73,11 +68,11 @@ namespace MoreLinq /// if the input sequences are of different lengths. /// <# foreach (var arg in o.Arguments) { #> - /// Type of elements in <#= arg.Ordinal #> input sequence. + /// Type of elements in <#=arg.Name#> input sequence. <#} #> /// Type of elements in result sequence. <# foreach (var arg in o.Arguments) { #> - /// The <#= arg.Ordinal #> source sequence. + /// The <#=arg.Ordinal#> source sequence. <#} #> /// /// Function to apply to each tuple of elements. @@ -91,35 +86,35 @@ namespace MoreLinq /// This operator uses deferred execution and streams its results. /// - public static IEnumerable EquiZip<<#= o.Types#>, TResult>( + public static IEnumerable EquiZip<<#=o.TParams#>, TResult>( <# foreach (var arg in o.Arguments) { #> - <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #>, -<#}#> - Func<<#= o.Types#>, TResult> resultSelector) + <#= arg.IsFirst ? "this " : "" #>IEnumerable<<#=arg.Type#>> <#=arg.Name#>, +<#} #> + Func<<#=o.TParams#>, TResult> resultSelector) { <# foreach (var arg in o.Arguments) { #> - if (<#= arg.Ordinal #> == null) throw new ArgumentNullException(nameof(<#= arg.Ordinal #>)); + if (<#=arg.Name#> == null) throw new ArgumentNullException(nameof(<#=arg.Name#>)); <#} #> if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); return _(); IEnumerable _() { <# foreach (var arg in o.Arguments) { #> - using var e<#= arg.Number #> = <#= arg.Ordinal #>.GetEnumerator(); + using var <#=arg.Enumerator#> = <#=arg.Name#>.GetEnumerator(); <#} #> for (;;) { - if (e<#= o.Arguments.First().Number #>.MoveNext()) + if (<#=o.Arguments.First().Enumerator#>.MoveNext()) { - if (<# foreach (var arg in o.Arguments.Skip(1)) { #>e<#= arg.Number #>.MoveNext()<#= arg.Num < o.Count ? " && " : "" #><#}#>) - yield return resultSelector(<# foreach (var arg in o.Arguments) { #>e<#= arg.Number #>.Current<#= arg.Num < o.Count ? ", " : "" #><#}#>); + if (<# foreach (var arg in o.Arguments.Skip(1)) { #><#=arg.Enumerator#>.MoveNext()<#= arg.IsLast ? "" : " && " #><#}#>) + yield return resultSelector(<# foreach (var arg in o.Arguments) { #><#=arg.Enumerator#>.Current<#= arg.IsLast ? "" : ", " #><#}#>); else break; } else { - if (<# foreach (var arg in o.Arguments.Skip(1)) { #>e<#= arg.Number #>.MoveNext()<#= arg.Num < o.Count ? " || " : "" #><#}#>) + if (<# foreach (var arg in o.Arguments.Skip(1)) { #><#=arg.Enumerator#>.MoveNext()<#= arg.IsLast ? "" : " || " #><#}#>) break; else yield break; @@ -136,10 +131,10 @@ namespace MoreLinq /// if the input sequences are of different lengths. /// <# foreach (var arg in o.Arguments) { #> - /// Type of elements in <#= arg.Ordinal #> input sequence. + /// Type of elements in <#=arg.Name#> input sequence. <#} #> <# foreach (var arg in o.Arguments) { #> - /// The <#= arg.Ordinal #> source sequence. + /// The <#=arg.Ordinal#> source sequence. <#} #> /// /// A sequence of tuples, where each tuple contains the N-th element @@ -150,14 +145,14 @@ namespace MoreLinq /// /// This operator uses deferred execution and streams its results. /// - public static IEnumerable<(<#= o.Types#>)> EquiZip<<#= o.Types#>>( + public static IEnumerable<(<#=o.TParams#>)> EquiZip<<#=o.TParams#>>( <# foreach (var arg in o.Arguments) { #> - <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #><#= arg.Num < o.Count ? "," : ")" #> + <#= arg.IsFirst ? "this " : "" #>IEnumerable<<#=arg.Type#>> <#=arg.Name#><#= arg.IsLast ? ")" : "," #> <#}#> { return EquiZip( <# foreach (var arg in o.Arguments) { #> - <#= arg.Ordinal #>, + <#=arg.Name#>, <#}#> ValueTuple.Create); } @@ -170,11 +165,11 @@ namespace MoreLinq /// for padding. /// <# foreach (var arg in o.Arguments) { #> - /// Type of elements in <#= arg.Ordinal #> input sequence. + /// Type of elements in <#=arg.Name#> input sequence. <#} #> /// Type of elements in result sequence. <# foreach (var arg in o.Arguments) { #> - /// The <#= arg.Ordinal #> source sequence. + /// The <#=arg.Ordinal#> source sequence. <#} #> /// /// Function to apply to each tuple of elements. @@ -184,45 +179,45 @@ namespace MoreLinq /// /// This operator uses deferred execution and streams its results. /// - public static IEnumerable ZipLongest<<#= o.Types#>, TResult>( + public static IEnumerable ZipLongest<<#=o.TParams#>, TResult>( <# foreach (var arg in o.Arguments) { #> - <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #>, + <#= arg.IsFirst ? "this " : "" #>IEnumerable<<#=arg.Type#>> <#=arg.Name#>, <#}#> - Func<<#= o.Types#>, TResult> resultSelector) + Func<<#=o.TParams#>, TResult> resultSelector) { <# foreach (var arg in o.Arguments) { #> - if (<#= arg.Ordinal #> == null) throw new ArgumentNullException(nameof(<#= arg.Ordinal #>)); + if (<#=arg.Name#> == null) throw new ArgumentNullException(nameof(<#=arg.Name#>)); <#} #> if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); return _(); IEnumerable _() { <# foreach (var arg in o.Arguments) { #> - IEnumerator> e<#= arg.Number #> = null; + IEnumerator<<#=arg.Type#>> <#=arg.Enumerator#> = null; <#} #> try { <# foreach (var arg in o.Arguments) { #> - e<#= arg.Number #> = <#= arg.Ordinal #>.GetEnumerator(); + <#=arg.Enumerator#> = <#=arg.Name#>.GetEnumerator(); <#} #> <# foreach (var arg in o.Arguments) { #> - var v<#= arg.Number #> = default(T<#= arg.Number #>); + var <#=arg.Value#> = default(<#=arg.Type#>); <#} #> while ( <# foreach (var arg in o.Arguments) { #> - ZipHelper.MoveNextOrDefault>(ref e<#= arg.Number #>, ref v<#= arg.Number #>)<#= arg.Num < o.Count ? " |" : ")" #> + ZipHelper.MoveNextOrDefault<<#=arg.Type#>>(ref <#=arg.Enumerator#>, ref <#=arg.Value#>)<#= arg.IsLast ? ")" : " |" #> <#}#> { - yield return resultSelector(<# foreach (var arg in o.Arguments) { #>v<#= arg.Number #><#= arg.Num < o.Count ? ", " : "" #><#}#>); + yield return resultSelector(<# foreach (var arg in o.Arguments) { #><#=arg.Value#><#= arg.IsLast ? "" : ", " #><#}#>); } } finally { <# foreach (var arg in o.Arguments) { #> - e<#= arg.Number #>?.Dispose(); + <#=arg.Enumerator#>?.Dispose(); <#} #> } } @@ -236,10 +231,10 @@ namespace MoreLinq /// for padding. /// <# foreach (var arg in o.Arguments) { #> - /// Type of elements in <#= arg.Ordinal #> input sequence. + /// Type of elements in <#=arg.Name#> input sequence. <#} #> <# foreach (var arg in o.Arguments) { #> - /// The <#= arg.Ordinal #> source sequence. + /// The <#=arg.Ordinal#> source sequence. <#} #> /// /// A sequence of tuples, where each tuple contains the N-th element @@ -247,14 +242,14 @@ namespace MoreLinq /// /// This operator uses deferred execution and streams its results. /// - public static IEnumerable<(<#= o.Types#>)> ZipLongest<<#= o.Types#>>( + public static IEnumerable<(<#=o.TParams#>)> ZipLongest<<#=o.TParams#>>( <# foreach (var arg in o.Arguments) { #> - <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #><#= arg.Num < o.Count ? "," : ")" #> + <#= arg.IsFirst ? "this " : "" #>IEnumerable<<#=arg.Type#>> <#=arg.Name#><#= arg.IsLast ? ")" : "," #> <#}#> { return ZipLongest( <# foreach (var arg in o.Arguments) { #> - <#= arg.Ordinal #>, + <#=arg.Name#>, <#}#> ValueTuple.Create); } @@ -265,11 +260,11 @@ namespace MoreLinq /// is as short as the shortest input sequence. /// <# foreach (var arg in o.Arguments) { #> - /// Type of elements in <#= arg.Ordinal #> input sequence. + /// Type of elements in <#=arg.Name#> input sequence. <#} #> /// Type of elements in result sequence. <# foreach (var arg in o.Arguments) { #> - /// The <#= arg.Ordinal #> source sequence. + /// The <#=arg.Ordinal#> source sequence. <#} #> /// /// Function to apply to each tuple of elements. @@ -286,26 +281,26 @@ namespace MoreLinq /// This operator uses deferred execution and streams its results. /// - public static IEnumerable ZipShortest<<#= o.Types#>, TResult>( + public static IEnumerable ZipShortest<<#=o.TParams#>, TResult>( <# foreach (var arg in o.Arguments) { #> - <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #>, + <#= arg.IsFirst ? "this " : "" #>IEnumerable<<#=arg.Type#>> <#=arg.Name#>, <#}#> - Func<<#= o.Types#>, TResult> resultSelector) + Func<<#=o.TParams#>, TResult> resultSelector) { <# foreach (var arg in o.Arguments) { #> - if (<#= arg.Ordinal #> == null) throw new ArgumentNullException(nameof(<#= arg.Ordinal #>)); + if (<#=arg.Name#> == null) throw new ArgumentNullException(nameof(<#=arg.Name#>)); <#} #> if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); return _(); IEnumerable _() { <# foreach (var arg in o.Arguments) { #> - using var e<#= arg.Number #> = <#= arg.Ordinal #>.GetEnumerator(); + using var <#=arg.Enumerator#> = <#=arg.Name#>.GetEnumerator(); <#} #> - while (<# foreach (var arg in o.Arguments) { #>e<#= arg.Number #>.MoveNext()<#= arg.Num < o.Count ? " && " : "" #><#}#>) + while (<# foreach (var arg in o.Arguments) { #><#=arg.Enumerator#>.MoveNext()<#= arg.IsLast ? "" : " && " #><#}#>) { - yield return resultSelector(<# foreach (var arg in o.Arguments) { #>e<#= arg.Number #>.Current<#= arg.Num < o.Count ? ", " : "" #><#}#>); + yield return resultSelector(<# foreach (var arg in o.Arguments) { #><#=arg.Enumerator#>.Current<#= arg.IsLast ? "" : ", " #><#}#>); } } } @@ -316,10 +311,10 @@ namespace MoreLinq /// is as short as the shortest input sequence. /// <# foreach (var arg in o.Arguments) { #> - /// Type of elements in <#= arg.Ordinal #> input sequence. + /// Type of elements in <#=arg.Name#> input sequence. <#} #> <# foreach (var arg in o.Arguments) { #> - /// The <#= arg.Ordinal #> source sequence. + /// The <#=arg.Ordinal#> source sequence. <#} #> /// /// A sequence of tuples, where each tuple contains the N-th element @@ -334,14 +329,14 @@ namespace MoreLinq /// This operator uses deferred execution and streams its results. /// - public static IEnumerable<(<#= o.Types#>)> ZipShortest<<#= o.Types#>>( + public static IEnumerable<(<#=o.TParams#>)> ZipShortest<<#=o.TParams#>>( <# foreach (var arg in o.Arguments) { #> - <#= arg.Num == 1 ? "this " : "" #>IEnumerable> <#= arg.Ordinal #><#= arg.Num < o.Count ? "," : ")" #> + <#= arg.IsFirst ? "this " : "" #>IEnumerable<<#=arg.Type#>> <#=arg.Name#><#= arg.IsLast ? ")" : "," #> <#}#> { return ZipShortest( <# foreach (var arg in o.Arguments) { #> - <#= arg.Ordinal #>, + <#=arg.Name#>, <#}#> ValueTuple.Create); } From e8925dc2187f5475a1cdf3bdd498645846fac2ed Mon Sep 17 00:00:00 2001 From: Orace Date: Wed, 6 Nov 2019 10:52:24 +0100 Subject: [PATCH 08/11] Split Zip into EquiZip, ZipLongest, ZipShortest --- MoreLinq/EquiZip.g.cs | 824 ++++++++ MoreLinq/EquiZip.g.tt | 163 ++ MoreLinq/Extensions.g.cs | 23 +- MoreLinq/MoreLinq.csproj | 26 +- MoreLinq/Zip.g.cs | 2413 ---------------------- MoreLinq/Zip.g.tt | 346 ---- MoreLinq/ZipLongest.g.cs | 901 ++++++++ MoreLinq/ZipLongest.g.tt | 166 ++ MoreLinq/{Zip.cs => ZipLongestHelper.cs} | 2 +- MoreLinq/ZipShortest.g.cs | 761 +++++++ MoreLinq/ZipShortest.g.tt | 154 ++ 11 files changed, 3013 insertions(+), 2766 deletions(-) create mode 100644 MoreLinq/EquiZip.g.cs create mode 100644 MoreLinq/EquiZip.g.tt delete mode 100644 MoreLinq/Zip.g.cs delete mode 100644 MoreLinq/Zip.g.tt create mode 100644 MoreLinq/ZipLongest.g.cs create mode 100644 MoreLinq/ZipLongest.g.tt rename MoreLinq/{Zip.cs => ZipLongestHelper.cs} (97%) create mode 100644 MoreLinq/ZipShortest.g.cs create mode 100644 MoreLinq/ZipShortest.g.tt diff --git a/MoreLinq/EquiZip.g.cs b/MoreLinq/EquiZip.g.cs new file mode 100644 index 000000000..97f37b883 --- /dev/null +++ b/MoreLinq/EquiZip.g.cs @@ -0,0 +1,824 @@ +#region License and Terms +// MoreLINQ - Extensions to LINQ to Objects +// Copyright (c) 2019 Pierre Lando. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +namespace MoreLinq +{ + using System; + using System.Collections.Generic; + + static partial class MoreEnumerable + { + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable EquiZip( + this IEnumerable first, + IEnumerable second, + Func resultSelector) + { + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return _(); IEnumerable _() + { + using var e1 = first.GetEnumerator(); + using var e2 = second.GetEnumerator(); + + for (;;) + { + if (e1.MoveNext()) + { + if (e2.MoveNext()) + yield return resultSelector(e1.Current, e2.Current); + else + break; + } + else + { + if (e2.MoveNext()) + break; + else + yield break; + } + } + + throw new InvalidOperationException($"Sequences differ in length."); + } + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// The first source sequence. + /// The second source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2)> EquiZip( + this IEnumerable first, + IEnumerable second) + { + return EquiZip( + first, + second, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable EquiZip( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + Func resultSelector) + { + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return _(); IEnumerable _() + { + using var e1 = first.GetEnumerator(); + using var e2 = second.GetEnumerator(); + using var e3 = third.GetEnumerator(); + + for (;;) + { + if (e1.MoveNext()) + { + if (e2.MoveNext() && e3.MoveNext()) + yield return resultSelector(e1.Current, e2.Current, e3.Current); + else + break; + } + else + { + if (e2.MoveNext() || e3.MoveNext()) + break; + else + yield break; + } + } + + throw new InvalidOperationException($"Sequences differ in length."); + } + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3)> EquiZip( + this IEnumerable first, + IEnumerable second, + IEnumerable third) + { + return EquiZip( + first, + second, + third, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable EquiZip( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + Func resultSelector) + { + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return _(); IEnumerable _() + { + using var e1 = first.GetEnumerator(); + using var e2 = second.GetEnumerator(); + using var e3 = third.GetEnumerator(); + using var e4 = fourth.GetEnumerator(); + + for (;;) + { + if (e1.MoveNext()) + { + if (e2.MoveNext() && e3.MoveNext() && e4.MoveNext()) + yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current); + else + break; + } + else + { + if (e2.MoveNext() || e3.MoveNext() || e4.MoveNext()) + break; + else + yield break; + } + } + + throw new InvalidOperationException($"Sequences differ in length."); + } + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3, T4)> EquiZip( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth) + { + return EquiZip( + first, + second, + third, + fourth, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable EquiZip( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + Func resultSelector) + { + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); + if (fifth == null) throw new ArgumentNullException(nameof(fifth)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return _(); IEnumerable _() + { + using var e1 = first.GetEnumerator(); + using var e2 = second.GetEnumerator(); + using var e3 = third.GetEnumerator(); + using var e4 = fourth.GetEnumerator(); + using var e5 = fifth.GetEnumerator(); + + for (;;) + { + if (e1.MoveNext()) + { + if (e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext()) + yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current, e5.Current); + else + break; + } + else + { + if (e2.MoveNext() || e3.MoveNext() || e4.MoveNext() || e5.MoveNext()) + break; + else + yield break; + } + } + + throw new InvalidOperationException($"Sequences differ in length."); + } + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3, T4, T5)> EquiZip( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth) + { + return EquiZip( + first, + second, + third, + fourth, + fifth, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable EquiZip( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + Func resultSelector) + { + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); + if (fifth == null) throw new ArgumentNullException(nameof(fifth)); + if (sixth == null) throw new ArgumentNullException(nameof(sixth)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return _(); IEnumerable _() + { + using var e1 = first.GetEnumerator(); + using var e2 = second.GetEnumerator(); + using var e3 = third.GetEnumerator(); + using var e4 = fourth.GetEnumerator(); + using var e5 = fifth.GetEnumerator(); + using var e6 = sixth.GetEnumerator(); + + for (;;) + { + if (e1.MoveNext()) + { + if (e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext() && e6.MoveNext()) + yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current, e5.Current, e6.Current); + else + break; + } + else + { + if (e2.MoveNext() || e3.MoveNext() || e4.MoveNext() || e5.MoveNext() || e6.MoveNext()) + break; + else + yield break; + } + } + + throw new InvalidOperationException($"Sequences differ in length."); + } + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3, T4, T5, T6)> EquiZip( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth) + { + return EquiZip( + first, + second, + third, + fourth, + fifth, + sixth, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable EquiZip( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, + Func resultSelector) + { + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); + if (fifth == null) throw new ArgumentNullException(nameof(fifth)); + if (sixth == null) throw new ArgumentNullException(nameof(sixth)); + if (seventh == null) throw new ArgumentNullException(nameof(seventh)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return _(); IEnumerable _() + { + using var e1 = first.GetEnumerator(); + using var e2 = second.GetEnumerator(); + using var e3 = third.GetEnumerator(); + using var e4 = fourth.GetEnumerator(); + using var e5 = fifth.GetEnumerator(); + using var e6 = sixth.GetEnumerator(); + using var e7 = seventh.GetEnumerator(); + + for (;;) + { + if (e1.MoveNext()) + { + if (e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext() && e6.MoveNext() && e7.MoveNext()) + yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current, e5.Current, e6.Current, e7.Current); + else + break; + } + else + { + if (e2.MoveNext() || e3.MoveNext() || e4.MoveNext() || e5.MoveNext() || e6.MoveNext() || e7.MoveNext()) + break; + else + yield break; + } + } + + throw new InvalidOperationException($"Sequences differ in length."); + } + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7)> EquiZip( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh) + { + return EquiZip( + first, + second, + third, + fourth, + fifth, + sixth, + seventh, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// Type of elements in eighth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable EquiZip( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, + IEnumerable eighth, + Func resultSelector) + { + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); + if (fifth == null) throw new ArgumentNullException(nameof(fifth)); + if (sixth == null) throw new ArgumentNullException(nameof(sixth)); + if (seventh == null) throw new ArgumentNullException(nameof(seventh)); + if (eighth == null) throw new ArgumentNullException(nameof(eighth)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return _(); IEnumerable _() + { + using var e1 = first.GetEnumerator(); + using var e2 = second.GetEnumerator(); + using var e3 = third.GetEnumerator(); + using var e4 = fourth.GetEnumerator(); + using var e5 = fifth.GetEnumerator(); + using var e6 = sixth.GetEnumerator(); + using var e7 = seventh.GetEnumerator(); + using var e8 = eighth.GetEnumerator(); + + for (;;) + { + if (e1.MoveNext()) + { + if (e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext() && e6.MoveNext() && e7.MoveNext() && e8.MoveNext()) + yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current, e5.Current, e6.Current, e7.Current, e8.Current); + else + break; + } + else + { + if (e2.MoveNext() || e3.MoveNext() || e4.MoveNext() || e5.MoveNext() || e6.MoveNext() || e7.MoveNext() || e8.MoveNext()) + break; + else + yield break; + } + } + + throw new InvalidOperationException($"Sequences differ in length."); + } + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// Type of elements in eighth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7, T8)> EquiZip( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, + IEnumerable eighth) + { + return EquiZip( + first, + second, + third, + fourth, + fifth, + sixth, + seventh, + eighth, + ValueTuple.Create); + } + + } +} diff --git a/MoreLinq/EquiZip.g.tt b/MoreLinq/EquiZip.g.tt new file mode 100644 index 000000000..0a5644995 --- /dev/null +++ b/MoreLinq/EquiZip.g.tt @@ -0,0 +1,163 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ output extension=".cs" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Collections" #> +<#@ import namespace="System.Globalization" #> +<#@ import namespace="System.Linq" #> +#region License and Terms +// MoreLINQ - Extensions to LINQ to Objects +// Copyright (c) 2019 Pierre Lando. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +<# + var ordinals = new[] + { + "", + "first", "second", "third", "fourth", + "fifth", "sixth", "seventh", "eighth" + }; + + var overloads = + Enumerable.Range(2, 7) + .Select(argCount => + Enumerable.Range(1, argCount).Select(argPosition => + new + { + IsFirst = argPosition == 1, + IsLast = argPosition == argCount, + Name = ordinals[argPosition], + Ordinal = ordinals[argPosition], + Type = $"T{argPosition}", + // Objects associated with the argument + Enumerator = $"e{argPosition}", + Value = $"v{argPosition}" + })) + .Select(args => args.ToList()) + .Select(args => + new + { + Arguments = args, + TParams = string.Join(", ", args.Select(arg => arg.Type)) + }); +#> +namespace MoreLinq +{ + using System; + using System.Collections.Generic; + + static partial class MoreEnumerable + { +<# foreach (var o in overloads) + { +#> + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// +<# foreach (var arg in o.Arguments) { #> + /// Type of elements in <#=arg.Name#> input sequence. +<# } #> + /// Type of elements in result sequence. +<# foreach (var arg in o.Arguments) { #> + /// The <#=arg.Ordinal#> source sequence. +<# } #> + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable EquiZip<<#=o.TParams#>, TResult>( +<# foreach (var arg in o.Arguments) { #> + <#= arg.IsFirst ? "this " : "" #>IEnumerable<<#=arg.Type#>> <#=arg.Name#>, +<# } #> + Func<<#=o.TParams#>, TResult> resultSelector) + { +<# foreach (var arg in o.Arguments) { #> + if (<#=arg.Name#> == null) throw new ArgumentNullException(nameof(<#=arg.Name#>)); +<# } #> + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return _(); IEnumerable _() + { +<# foreach (var arg in o.Arguments) { #> + using var <#=arg.Enumerator#> = <#=arg.Name#>.GetEnumerator(); +<# } #> + + for (;;) + { + if (<#=o.Arguments.First().Enumerator#>.MoveNext()) + { + if (<# foreach (var arg in o.Arguments.Skip(1)) { #><#=arg.Enumerator#>.MoveNext()<#= arg.IsLast ? "" : " && " #><#}#>) + yield return resultSelector(<# foreach (var arg in o.Arguments) { #><#=arg.Enumerator#>.Current<#= arg.IsLast ? "" : ", " #><#}#>); + else + break; + } + else + { + if (<# foreach (var arg in o.Arguments.Skip(1)) { #><#=arg.Enumerator#>.MoveNext()<#= arg.IsLast ? "" : " || " #><#}#>) + break; + else + yield break; + } + } + + throw new InvalidOperationException($"Sequences differ in length."); + } + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. An exception is thrown + /// if the input sequences are of different lengths. + /// +<# foreach (var arg in o.Arguments) { #> + /// Type of elements in <#=arg.Name#> input sequence. +<# } #> +<# foreach (var arg in o.Arguments) { #> + /// The <#=arg.Ordinal#> source sequence. +<# } #> + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// The input sequences are of different lengths. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(<#=o.TParams#>)> EquiZip<<#=o.TParams#>>( +<# foreach (var arg in o.Arguments) { #> + <#= arg.IsFirst ? "this " : "" #>IEnumerable<<#=arg.Type#>> <#=arg.Name#><#= arg.IsLast ? ")" : "," #> +<# } #> + { + return EquiZip( +<# foreach (var arg in o.Arguments) { #> + <#=arg.Name#>, +<# } #> + ValueTuple.Create); + } + +<# } #> + } +} diff --git a/MoreLinq/Extensions.g.cs b/MoreLinq/Extensions.g.cs index 4b2a4d2e2..a1499c011 100644 --- a/MoreLinq/Extensions.g.cs +++ b/MoreLinq/Extensions.g.cs @@ -1343,6 +1343,7 @@ public static partial class EquiZipExtension /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable<(T1, T2)> EquiZip( this IEnumerable first, IEnumerable second) @@ -1368,6 +1369,7 @@ public static partial class EquiZipExtension /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable<(T1, T2, T3)> EquiZip( this IEnumerable first, IEnumerable second, @@ -1423,6 +1425,7 @@ public static IEnumerable EquiZip( /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable<(T1, T2, T3, T4)> EquiZip( this IEnumerable first, IEnumerable second, @@ -1485,6 +1488,7 @@ public static IEnumerable EquiZip( /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable<(T1, T2, T3, T4, T5)> EquiZip( this IEnumerable first, IEnumerable second, @@ -1553,6 +1557,7 @@ public static IEnumerable EquiZip( /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable<(T1, T2, T3, T4, T5, T6)> EquiZip( this IEnumerable first, IEnumerable second, @@ -1627,6 +1632,7 @@ public static IEnumerable EquiZip( /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7)> EquiZip( this IEnumerable first, IEnumerable second, @@ -1707,6 +1713,7 @@ public static IEnumerable EquiZip( /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7, T8)> EquiZip( this IEnumerable first, IEnumerable second, @@ -7165,6 +7172,7 @@ public static partial class ZipLongestExtension /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable<(T1, T2)> ZipLongest( this IEnumerable first, IEnumerable second) @@ -7189,12 +7197,12 @@ public static partial class ZipLongestExtension /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable<(T1, T2, T3)> ZipLongest( this IEnumerable first, IEnumerable second, IEnumerable third) => MoreEnumerable.ZipLongest(first, second, third); - /// /// Returns a projection of tuples, where each tuple contains the N-th /// element from each of the input sequences. The resulting sequence @@ -7215,6 +7223,7 @@ public static partial class ZipLongestExtension /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable ZipLongest( this IEnumerable first, IEnumerable second, @@ -7242,6 +7251,7 @@ public static IEnumerable ZipLongest( /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable<(T1, T2, T3, T4)> ZipLongest( this IEnumerable first, IEnumerable second, @@ -7271,6 +7281,7 @@ public static IEnumerable ZipLongest( /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable ZipLongest( this IEnumerable first, IEnumerable second, @@ -7301,6 +7312,7 @@ public static IEnumerable ZipLongest( /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable<(T1, T2, T3, T4, T5)> ZipLongest( this IEnumerable first, IEnumerable second, @@ -7333,6 +7345,7 @@ public static IEnumerable ZipLongest( /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable ZipLongest( this IEnumerable first, IEnumerable second, @@ -7366,6 +7379,7 @@ public static IEnumerable ZipLongest( /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable<(T1, T2, T3, T4, T5, T6)> ZipLongest( this IEnumerable first, IEnumerable second, @@ -7401,6 +7415,7 @@ public static IEnumerable ZipLongest( /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable ZipLongest( this IEnumerable first, IEnumerable second, @@ -7437,6 +7452,7 @@ public static IEnumerable ZipLongest( /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7)> ZipLongest( this IEnumerable first, IEnumerable second, @@ -7475,6 +7491,7 @@ public static IEnumerable ZipLongest( /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable ZipLongest( this IEnumerable first, IEnumerable second, @@ -7514,6 +7531,7 @@ public static IEnumerable ZipLongest( /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7, T8)> ZipLongest( this IEnumerable first, IEnumerable second, @@ -7555,6 +7573,7 @@ public static IEnumerable ZipLongest( /// /// This operator uses deferred execution and streams its results. /// + public static IEnumerable ZipLongest( this IEnumerable first, IEnumerable second, @@ -7598,6 +7617,7 @@ public static IEnumerable ZipLongest /// This operator uses deferred execution and streams its results. /// + public static IEnumerable ZipLongest( this IEnumerable first, IEnumerable second, @@ -7674,7 +7694,6 @@ public static partial class ZipShortestExtension IEnumerable second, IEnumerable third) => MoreEnumerable.ZipShortest(first, second, third); - /// /// Returns a projection of tuples, where each tuple contains the N-th /// element from each of the input sequences. The resulting sequence diff --git a/MoreLinq/MoreLinq.csproj b/MoreLinq/MoreLinq.csproj index db2b6cc08..9c27744f5 100644 --- a/MoreLinq/MoreLinq.csproj +++ b/MoreLinq/MoreLinq.csproj @@ -159,6 +159,10 @@ TextTemplatingFileGenerator Cartesian.g.cs + + TextTemplatingFileGenerator + EquiZip.g.cs + Aggregate.g.cs TextTemplatingFileGenerator @@ -171,9 +175,13 @@ TextTemplatingFileGenerator ToDelimitedString.g.cs - + TextTemplatingFileGenerator - Zip.g.cs + ZipLongest.g.cs + + + TextTemplatingFileGenerator + ZipShortest.g.cs @@ -216,6 +224,11 @@ True Cartesian.g.tt + + True + True + EquiZip.g.tt + True True @@ -239,10 +252,15 @@ True ToDelimitedString.g.tt - + + True + True + ZipLongest.g.tt + + True True - Zip.g.tt + ZipShortest.g.tt diff --git a/MoreLinq/Zip.g.cs b/MoreLinq/Zip.g.cs deleted file mode 100644 index f191db6f6..000000000 --- a/MoreLinq/Zip.g.cs +++ /dev/null @@ -1,2413 +0,0 @@ -#region License and Terms -// MoreLINQ - Extensions to LINQ to Objects -// Copyright (c) 2019 Pierre Lando. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#endregion - -namespace MoreLinq -{ - using System; - using System.Collections.Generic; - - static partial class MoreEnumerable - { - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the input sequences. An exception is thrown - /// if the input sequences are of different lengths. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// - /// Function to apply to each tuple of elements. - /// - /// A projection of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// The input sequences are of different lengths. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable EquiZip( - this IEnumerable first, - IEnumerable second, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return _(); IEnumerable _() - { - using var e1 = first.GetEnumerator(); - using var e2 = second.GetEnumerator(); - - for (;;) - { - if (e1.MoveNext()) - { - if (e2.MoveNext()) - yield return resultSelector(e1.Current, e2.Current); - else - break; - } - else - { - if (e2.MoveNext()) - break; - else - yield break; - } - } - - throw new InvalidOperationException($"Sequences differ in length."); - } - } - - /// - /// Returns a sequence of tuples, where each tuple contains the N-th - /// element from each of the input sequences. An exception is thrown - /// if the input sequences are of different lengths. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// The first source sequence. - /// The second source sequence. - /// - /// A sequence of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// The input sequences are of different lengths. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - public static IEnumerable<(T1, T2)> EquiZip( - this IEnumerable first, - IEnumerable second) - { - return EquiZip( - first, - second, - ValueTuple.Create); - } - - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// - /// Function to apply to each tuple of elements. - /// - /// A projection of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// This operator uses deferred execution and streams its results. - /// - public static IEnumerable ZipLongest( - this IEnumerable first, - IEnumerable second, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return _(); IEnumerable _() - { - IEnumerator e1 = null; - IEnumerator e2 = null; - - try - { - e1 = first.GetEnumerator(); - e2 = second.GetEnumerator(); - - var v1 = default(T1); - var v2 = default(T2); - - while ( - ZipHelper.MoveNextOrDefault(ref e1, ref v1) | - ZipHelper.MoveNextOrDefault(ref e2, ref v2)) - { - yield return resultSelector(v1, v2); - } - } - finally - { - e1?.Dispose(); - e2?.Dispose(); - } - } - } - - /// - /// Returns a sequence of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// The first source sequence. - /// The second source sequence. - /// - /// A sequence of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// This operator uses deferred execution and streams its results. - /// - public static IEnumerable<(T1, T2)> ZipLongest( - this IEnumerable first, - IEnumerable second) - { - return ZipLongest( - first, - second, - ValueTuple.Create); - } - - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// is as short as the shortest input sequence. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// - /// Function to apply to each tuple of elements. - /// - /// A projection of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// - /// If the input sequences are of different lengths, the result sequence - /// is terminated as soon as the shortest input sequence is exhausted - /// and remainder elements from the longer sequences are never consumed. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable ZipShortest( - this IEnumerable first, - IEnumerable second, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return _(); IEnumerable _() - { - using var e1 = first.GetEnumerator(); - using var e2 = second.GetEnumerator(); - - while (e1.MoveNext() && e2.MoveNext()) - { - yield return resultSelector(e1.Current, e2.Current); - } - } - } - - /// - /// Returns a sequence of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// is as short as the shortest input sequence. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// The first source sequence. - /// The second source sequence. - /// - /// A sequence of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// - /// If the input sequences are of different lengths, the result sequence - /// is terminated as soon as the shortest input sequence is exhausted - /// and remainder elements from the longer sequences are never consumed. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable<(T1, T2)> ZipShortest( - this IEnumerable first, - IEnumerable second) - { - return ZipShortest( - first, - second, - ValueTuple.Create); - } - - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the input sequences. An exception is thrown - /// if the input sequences are of different lengths. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// - /// Function to apply to each tuple of elements. - /// - /// A projection of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// The input sequences are of different lengths. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable EquiZip( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (third == null) throw new ArgumentNullException(nameof(third)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return _(); IEnumerable _() - { - using var e1 = first.GetEnumerator(); - using var e2 = second.GetEnumerator(); - using var e3 = third.GetEnumerator(); - - for (;;) - { - if (e1.MoveNext()) - { - if (e2.MoveNext() && e3.MoveNext()) - yield return resultSelector(e1.Current, e2.Current, e3.Current); - else - break; - } - else - { - if (e2.MoveNext() || e3.MoveNext()) - break; - else - yield break; - } - } - - throw new InvalidOperationException($"Sequences differ in length."); - } - } - - /// - /// Returns a sequence of tuples, where each tuple contains the N-th - /// element from each of the input sequences. An exception is thrown - /// if the input sequences are of different lengths. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// - /// A sequence of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// The input sequences are of different lengths. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - public static IEnumerable<(T1, T2, T3)> EquiZip( - this IEnumerable first, - IEnumerable second, - IEnumerable third) - { - return EquiZip( - first, - second, - third, - ValueTuple.Create); - } - - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// - /// Function to apply to each tuple of elements. - /// - /// A projection of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// This operator uses deferred execution and streams its results. - /// - public static IEnumerable ZipLongest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (third == null) throw new ArgumentNullException(nameof(third)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return _(); IEnumerable _() - { - IEnumerator e1 = null; - IEnumerator e2 = null; - IEnumerator e3 = null; - - try - { - e1 = first.GetEnumerator(); - e2 = second.GetEnumerator(); - e3 = third.GetEnumerator(); - - var v1 = default(T1); - var v2 = default(T2); - var v3 = default(T3); - - while ( - ZipHelper.MoveNextOrDefault(ref e1, ref v1) | - ZipHelper.MoveNextOrDefault(ref e2, ref v2) | - ZipHelper.MoveNextOrDefault(ref e3, ref v3)) - { - yield return resultSelector(v1, v2, v3); - } - } - finally - { - e1?.Dispose(); - e2?.Dispose(); - e3?.Dispose(); - } - } - } - - /// - /// Returns a sequence of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// - /// A sequence of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// This operator uses deferred execution and streams its results. - /// - public static IEnumerable<(T1, T2, T3)> ZipLongest( - this IEnumerable first, - IEnumerable second, - IEnumerable third) - { - return ZipLongest( - first, - second, - third, - ValueTuple.Create); - } - - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// is as short as the shortest input sequence. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// - /// Function to apply to each tuple of elements. - /// - /// A projection of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// - /// If the input sequences are of different lengths, the result sequence - /// is terminated as soon as the shortest input sequence is exhausted - /// and remainder elements from the longer sequences are never consumed. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable ZipShortest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (third == null) throw new ArgumentNullException(nameof(third)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return _(); IEnumerable _() - { - using var e1 = first.GetEnumerator(); - using var e2 = second.GetEnumerator(); - using var e3 = third.GetEnumerator(); - - while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext()) - { - yield return resultSelector(e1.Current, e2.Current, e3.Current); - } - } - } - - /// - /// Returns a sequence of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// is as short as the shortest input sequence. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// - /// A sequence of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// - /// If the input sequences are of different lengths, the result sequence - /// is terminated as soon as the shortest input sequence is exhausted - /// and remainder elements from the longer sequences are never consumed. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable<(T1, T2, T3)> ZipShortest( - this IEnumerable first, - IEnumerable second, - IEnumerable third) - { - return ZipShortest( - first, - second, - third, - ValueTuple.Create); - } - - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the input sequences. An exception is thrown - /// if the input sequences are of different lengths. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// - /// Function to apply to each tuple of elements. - /// - /// A projection of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// The input sequences are of different lengths. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable EquiZip( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (third == null) throw new ArgumentNullException(nameof(third)); - if (fourth == null) throw new ArgumentNullException(nameof(fourth)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return _(); IEnumerable _() - { - using var e1 = first.GetEnumerator(); - using var e2 = second.GetEnumerator(); - using var e3 = third.GetEnumerator(); - using var e4 = fourth.GetEnumerator(); - - for (;;) - { - if (e1.MoveNext()) - { - if (e2.MoveNext() && e3.MoveNext() && e4.MoveNext()) - yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current); - else - break; - } - else - { - if (e2.MoveNext() || e3.MoveNext() || e4.MoveNext()) - break; - else - yield break; - } - } - - throw new InvalidOperationException($"Sequences differ in length."); - } - } - - /// - /// Returns a sequence of tuples, where each tuple contains the N-th - /// element from each of the input sequences. An exception is thrown - /// if the input sequences are of different lengths. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// - /// A sequence of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// The input sequences are of different lengths. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - public static IEnumerable<(T1, T2, T3, T4)> EquiZip( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth) - { - return EquiZip( - first, - second, - third, - fourth, - ValueTuple.Create); - } - - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// - /// Function to apply to each tuple of elements. - /// - /// A projection of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// This operator uses deferred execution and streams its results. - /// - public static IEnumerable ZipLongest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (third == null) throw new ArgumentNullException(nameof(third)); - if (fourth == null) throw new ArgumentNullException(nameof(fourth)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return _(); IEnumerable _() - { - IEnumerator e1 = null; - IEnumerator e2 = null; - IEnumerator e3 = null; - IEnumerator e4 = null; - - try - { - e1 = first.GetEnumerator(); - e2 = second.GetEnumerator(); - e3 = third.GetEnumerator(); - e4 = fourth.GetEnumerator(); - - var v1 = default(T1); - var v2 = default(T2); - var v3 = default(T3); - var v4 = default(T4); - - while ( - ZipHelper.MoveNextOrDefault(ref e1, ref v1) | - ZipHelper.MoveNextOrDefault(ref e2, ref v2) | - ZipHelper.MoveNextOrDefault(ref e3, ref v3) | - ZipHelper.MoveNextOrDefault(ref e4, ref v4)) - { - yield return resultSelector(v1, v2, v3, v4); - } - } - finally - { - e1?.Dispose(); - e2?.Dispose(); - e3?.Dispose(); - e4?.Dispose(); - } - } - } - - /// - /// Returns a sequence of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// - /// A sequence of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// This operator uses deferred execution and streams its results. - /// - public static IEnumerable<(T1, T2, T3, T4)> ZipLongest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth) - { - return ZipLongest( - first, - second, - third, - fourth, - ValueTuple.Create); - } - - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// is as short as the shortest input sequence. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// - /// Function to apply to each tuple of elements. - /// - /// A projection of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// - /// If the input sequences are of different lengths, the result sequence - /// is terminated as soon as the shortest input sequence is exhausted - /// and remainder elements from the longer sequences are never consumed. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable ZipShortest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (third == null) throw new ArgumentNullException(nameof(third)); - if (fourth == null) throw new ArgumentNullException(nameof(fourth)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return _(); IEnumerable _() - { - using var e1 = first.GetEnumerator(); - using var e2 = second.GetEnumerator(); - using var e3 = third.GetEnumerator(); - using var e4 = fourth.GetEnumerator(); - - while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext() && e4.MoveNext()) - { - yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current); - } - } - } - - /// - /// Returns a sequence of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// is as short as the shortest input sequence. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// - /// A sequence of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// - /// If the input sequences are of different lengths, the result sequence - /// is terminated as soon as the shortest input sequence is exhausted - /// and remainder elements from the longer sequences are never consumed. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable<(T1, T2, T3, T4)> ZipShortest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth) - { - return ZipShortest( - first, - second, - third, - fourth, - ValueTuple.Create); - } - - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the input sequences. An exception is thrown - /// if the input sequences are of different lengths. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// Type of elements in fifth input sequence. - /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// - /// Function to apply to each tuple of elements. - /// - /// A projection of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// The input sequences are of different lengths. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable EquiZip( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - IEnumerable fifth, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (third == null) throw new ArgumentNullException(nameof(third)); - if (fourth == null) throw new ArgumentNullException(nameof(fourth)); - if (fifth == null) throw new ArgumentNullException(nameof(fifth)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return _(); IEnumerable _() - { - using var e1 = first.GetEnumerator(); - using var e2 = second.GetEnumerator(); - using var e3 = third.GetEnumerator(); - using var e4 = fourth.GetEnumerator(); - using var e5 = fifth.GetEnumerator(); - - for (;;) - { - if (e1.MoveNext()) - { - if (e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext()) - yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current, e5.Current); - else - break; - } - else - { - if (e2.MoveNext() || e3.MoveNext() || e4.MoveNext() || e5.MoveNext()) - break; - else - yield break; - } - } - - throw new InvalidOperationException($"Sequences differ in length."); - } - } - - /// - /// Returns a sequence of tuples, where each tuple contains the N-th - /// element from each of the input sequences. An exception is thrown - /// if the input sequences are of different lengths. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// Type of elements in fifth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// - /// A sequence of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// The input sequences are of different lengths. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - public static IEnumerable<(T1, T2, T3, T4, T5)> EquiZip( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - IEnumerable fifth) - { - return EquiZip( - first, - second, - third, - fourth, - fifth, - ValueTuple.Create); - } - - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// Type of elements in fifth input sequence. - /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// - /// Function to apply to each tuple of elements. - /// - /// A projection of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// This operator uses deferred execution and streams its results. - /// - public static IEnumerable ZipLongest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - IEnumerable fifth, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (third == null) throw new ArgumentNullException(nameof(third)); - if (fourth == null) throw new ArgumentNullException(nameof(fourth)); - if (fifth == null) throw new ArgumentNullException(nameof(fifth)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return _(); IEnumerable _() - { - IEnumerator e1 = null; - IEnumerator e2 = null; - IEnumerator e3 = null; - IEnumerator e4 = null; - IEnumerator e5 = null; - - try - { - e1 = first.GetEnumerator(); - e2 = second.GetEnumerator(); - e3 = third.GetEnumerator(); - e4 = fourth.GetEnumerator(); - e5 = fifth.GetEnumerator(); - - var v1 = default(T1); - var v2 = default(T2); - var v3 = default(T3); - var v4 = default(T4); - var v5 = default(T5); - - while ( - ZipHelper.MoveNextOrDefault(ref e1, ref v1) | - ZipHelper.MoveNextOrDefault(ref e2, ref v2) | - ZipHelper.MoveNextOrDefault(ref e3, ref v3) | - ZipHelper.MoveNextOrDefault(ref e4, ref v4) | - ZipHelper.MoveNextOrDefault(ref e5, ref v5)) - { - yield return resultSelector(v1, v2, v3, v4, v5); - } - } - finally - { - e1?.Dispose(); - e2?.Dispose(); - e3?.Dispose(); - e4?.Dispose(); - e5?.Dispose(); - } - } - } - - /// - /// Returns a sequence of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// Type of elements in fifth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// - /// A sequence of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// This operator uses deferred execution and streams its results. - /// - public static IEnumerable<(T1, T2, T3, T4, T5)> ZipLongest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - IEnumerable fifth) - { - return ZipLongest( - first, - second, - third, - fourth, - fifth, - ValueTuple.Create); - } - - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// is as short as the shortest input sequence. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// Type of elements in fifth input sequence. - /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// - /// Function to apply to each tuple of elements. - /// - /// A projection of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// - /// If the input sequences are of different lengths, the result sequence - /// is terminated as soon as the shortest input sequence is exhausted - /// and remainder elements from the longer sequences are never consumed. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable ZipShortest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - IEnumerable fifth, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (third == null) throw new ArgumentNullException(nameof(third)); - if (fourth == null) throw new ArgumentNullException(nameof(fourth)); - if (fifth == null) throw new ArgumentNullException(nameof(fifth)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return _(); IEnumerable _() - { - using var e1 = first.GetEnumerator(); - using var e2 = second.GetEnumerator(); - using var e3 = third.GetEnumerator(); - using var e4 = fourth.GetEnumerator(); - using var e5 = fifth.GetEnumerator(); - - while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext()) - { - yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current, e5.Current); - } - } - } - - /// - /// Returns a sequence of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// is as short as the shortest input sequence. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// Type of elements in fifth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// - /// A sequence of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// - /// If the input sequences are of different lengths, the result sequence - /// is terminated as soon as the shortest input sequence is exhausted - /// and remainder elements from the longer sequences are never consumed. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable<(T1, T2, T3, T4, T5)> ZipShortest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - IEnumerable fifth) - { - return ZipShortest( - first, - second, - third, - fourth, - fifth, - ValueTuple.Create); - } - - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the input sequences. An exception is thrown - /// if the input sequences are of different lengths. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// Type of elements in fifth input sequence. - /// Type of elements in sixth input sequence. - /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// - /// Function to apply to each tuple of elements. - /// - /// A projection of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// The input sequences are of different lengths. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable EquiZip( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - IEnumerable fifth, - IEnumerable sixth, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (third == null) throw new ArgumentNullException(nameof(third)); - if (fourth == null) throw new ArgumentNullException(nameof(fourth)); - if (fifth == null) throw new ArgumentNullException(nameof(fifth)); - if (sixth == null) throw new ArgumentNullException(nameof(sixth)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return _(); IEnumerable _() - { - using var e1 = first.GetEnumerator(); - using var e2 = second.GetEnumerator(); - using var e3 = third.GetEnumerator(); - using var e4 = fourth.GetEnumerator(); - using var e5 = fifth.GetEnumerator(); - using var e6 = sixth.GetEnumerator(); - - for (;;) - { - if (e1.MoveNext()) - { - if (e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext() && e6.MoveNext()) - yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current, e5.Current, e6.Current); - else - break; - } - else - { - if (e2.MoveNext() || e3.MoveNext() || e4.MoveNext() || e5.MoveNext() || e6.MoveNext()) - break; - else - yield break; - } - } - - throw new InvalidOperationException($"Sequences differ in length."); - } - } - - /// - /// Returns a sequence of tuples, where each tuple contains the N-th - /// element from each of the input sequences. An exception is thrown - /// if the input sequences are of different lengths. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// Type of elements in fifth input sequence. - /// Type of elements in sixth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// - /// A sequence of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// The input sequences are of different lengths. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - public static IEnumerable<(T1, T2, T3, T4, T5, T6)> EquiZip( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - IEnumerable fifth, - IEnumerable sixth) - { - return EquiZip( - first, - second, - third, - fourth, - fifth, - sixth, - ValueTuple.Create); - } - - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// Type of elements in fifth input sequence. - /// Type of elements in sixth input sequence. - /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// - /// Function to apply to each tuple of elements. - /// - /// A projection of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// This operator uses deferred execution and streams its results. - /// - public static IEnumerable ZipLongest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - IEnumerable fifth, - IEnumerable sixth, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (third == null) throw new ArgumentNullException(nameof(third)); - if (fourth == null) throw new ArgumentNullException(nameof(fourth)); - if (fifth == null) throw new ArgumentNullException(nameof(fifth)); - if (sixth == null) throw new ArgumentNullException(nameof(sixth)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return _(); IEnumerable _() - { - IEnumerator e1 = null; - IEnumerator e2 = null; - IEnumerator e3 = null; - IEnumerator e4 = null; - IEnumerator e5 = null; - IEnumerator e6 = null; - - try - { - e1 = first.GetEnumerator(); - e2 = second.GetEnumerator(); - e3 = third.GetEnumerator(); - e4 = fourth.GetEnumerator(); - e5 = fifth.GetEnumerator(); - e6 = sixth.GetEnumerator(); - - var v1 = default(T1); - var v2 = default(T2); - var v3 = default(T3); - var v4 = default(T4); - var v5 = default(T5); - var v6 = default(T6); - - while ( - ZipHelper.MoveNextOrDefault(ref e1, ref v1) | - ZipHelper.MoveNextOrDefault(ref e2, ref v2) | - ZipHelper.MoveNextOrDefault(ref e3, ref v3) | - ZipHelper.MoveNextOrDefault(ref e4, ref v4) | - ZipHelper.MoveNextOrDefault(ref e5, ref v5) | - ZipHelper.MoveNextOrDefault(ref e6, ref v6)) - { - yield return resultSelector(v1, v2, v3, v4, v5, v6); - } - } - finally - { - e1?.Dispose(); - e2?.Dispose(); - e3?.Dispose(); - e4?.Dispose(); - e5?.Dispose(); - e6?.Dispose(); - } - } - } - - /// - /// Returns a sequence of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// Type of elements in fifth input sequence. - /// Type of elements in sixth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// - /// A sequence of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// This operator uses deferred execution and streams its results. - /// - public static IEnumerable<(T1, T2, T3, T4, T5, T6)> ZipLongest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - IEnumerable fifth, - IEnumerable sixth) - { - return ZipLongest( - first, - second, - third, - fourth, - fifth, - sixth, - ValueTuple.Create); - } - - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// is as short as the shortest input sequence. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// Type of elements in fifth input sequence. - /// Type of elements in sixth input sequence. - /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// - /// Function to apply to each tuple of elements. - /// - /// A projection of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// - /// If the input sequences are of different lengths, the result sequence - /// is terminated as soon as the shortest input sequence is exhausted - /// and remainder elements from the longer sequences are never consumed. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable ZipShortest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - IEnumerable fifth, - IEnumerable sixth, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (third == null) throw new ArgumentNullException(nameof(third)); - if (fourth == null) throw new ArgumentNullException(nameof(fourth)); - if (fifth == null) throw new ArgumentNullException(nameof(fifth)); - if (sixth == null) throw new ArgumentNullException(nameof(sixth)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return _(); IEnumerable _() - { - using var e1 = first.GetEnumerator(); - using var e2 = second.GetEnumerator(); - using var e3 = third.GetEnumerator(); - using var e4 = fourth.GetEnumerator(); - using var e5 = fifth.GetEnumerator(); - using var e6 = sixth.GetEnumerator(); - - while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext() && e6.MoveNext()) - { - yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current, e5.Current, e6.Current); - } - } - } - - /// - /// Returns a sequence of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// is as short as the shortest input sequence. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// Type of elements in fifth input sequence. - /// Type of elements in sixth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// - /// A sequence of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// - /// If the input sequences are of different lengths, the result sequence - /// is terminated as soon as the shortest input sequence is exhausted - /// and remainder elements from the longer sequences are never consumed. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable<(T1, T2, T3, T4, T5, T6)> ZipShortest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - IEnumerable fifth, - IEnumerable sixth) - { - return ZipShortest( - first, - second, - third, - fourth, - fifth, - sixth, - ValueTuple.Create); - } - - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the input sequences. An exception is thrown - /// if the input sequences are of different lengths. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// Type of elements in fifth input sequence. - /// Type of elements in sixth input sequence. - /// Type of elements in seventh input sequence. - /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. - /// - /// Function to apply to each tuple of elements. - /// - /// A projection of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// The input sequences are of different lengths. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable EquiZip( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - IEnumerable fifth, - IEnumerable sixth, - IEnumerable seventh, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (third == null) throw new ArgumentNullException(nameof(third)); - if (fourth == null) throw new ArgumentNullException(nameof(fourth)); - if (fifth == null) throw new ArgumentNullException(nameof(fifth)); - if (sixth == null) throw new ArgumentNullException(nameof(sixth)); - if (seventh == null) throw new ArgumentNullException(nameof(seventh)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return _(); IEnumerable _() - { - using var e1 = first.GetEnumerator(); - using var e2 = second.GetEnumerator(); - using var e3 = third.GetEnumerator(); - using var e4 = fourth.GetEnumerator(); - using var e5 = fifth.GetEnumerator(); - using var e6 = sixth.GetEnumerator(); - using var e7 = seventh.GetEnumerator(); - - for (;;) - { - if (e1.MoveNext()) - { - if (e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext() && e6.MoveNext() && e7.MoveNext()) - yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current, e5.Current, e6.Current, e7.Current); - else - break; - } - else - { - if (e2.MoveNext() || e3.MoveNext() || e4.MoveNext() || e5.MoveNext() || e6.MoveNext() || e7.MoveNext()) - break; - else - yield break; - } - } - - throw new InvalidOperationException($"Sequences differ in length."); - } - } - - /// - /// Returns a sequence of tuples, where each tuple contains the N-th - /// element from each of the input sequences. An exception is thrown - /// if the input sequences are of different lengths. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// Type of elements in fifth input sequence. - /// Type of elements in sixth input sequence. - /// Type of elements in seventh input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. - /// - /// A sequence of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// The input sequences are of different lengths. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7)> EquiZip( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - IEnumerable fifth, - IEnumerable sixth, - IEnumerable seventh) - { - return EquiZip( - first, - second, - third, - fourth, - fifth, - sixth, - seventh, - ValueTuple.Create); - } - - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// Type of elements in fifth input sequence. - /// Type of elements in sixth input sequence. - /// Type of elements in seventh input sequence. - /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. - /// - /// Function to apply to each tuple of elements. - /// - /// A projection of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// This operator uses deferred execution and streams its results. - /// - public static IEnumerable ZipLongest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - IEnumerable fifth, - IEnumerable sixth, - IEnumerable seventh, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (third == null) throw new ArgumentNullException(nameof(third)); - if (fourth == null) throw new ArgumentNullException(nameof(fourth)); - if (fifth == null) throw new ArgumentNullException(nameof(fifth)); - if (sixth == null) throw new ArgumentNullException(nameof(sixth)); - if (seventh == null) throw new ArgumentNullException(nameof(seventh)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return _(); IEnumerable _() - { - IEnumerator e1 = null; - IEnumerator e2 = null; - IEnumerator e3 = null; - IEnumerator e4 = null; - IEnumerator e5 = null; - IEnumerator e6 = null; - IEnumerator e7 = null; - - try - { - e1 = first.GetEnumerator(); - e2 = second.GetEnumerator(); - e3 = third.GetEnumerator(); - e4 = fourth.GetEnumerator(); - e5 = fifth.GetEnumerator(); - e6 = sixth.GetEnumerator(); - e7 = seventh.GetEnumerator(); - - var v1 = default(T1); - var v2 = default(T2); - var v3 = default(T3); - var v4 = default(T4); - var v5 = default(T5); - var v6 = default(T6); - var v7 = default(T7); - - while ( - ZipHelper.MoveNextOrDefault(ref e1, ref v1) | - ZipHelper.MoveNextOrDefault(ref e2, ref v2) | - ZipHelper.MoveNextOrDefault(ref e3, ref v3) | - ZipHelper.MoveNextOrDefault(ref e4, ref v4) | - ZipHelper.MoveNextOrDefault(ref e5, ref v5) | - ZipHelper.MoveNextOrDefault(ref e6, ref v6) | - ZipHelper.MoveNextOrDefault(ref e7, ref v7)) - { - yield return resultSelector(v1, v2, v3, v4, v5, v6, v7); - } - } - finally - { - e1?.Dispose(); - e2?.Dispose(); - e3?.Dispose(); - e4?.Dispose(); - e5?.Dispose(); - e6?.Dispose(); - e7?.Dispose(); - } - } - } - - /// - /// Returns a sequence of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// Type of elements in fifth input sequence. - /// Type of elements in sixth input sequence. - /// Type of elements in seventh input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. - /// - /// A sequence of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// This operator uses deferred execution and streams its results. - /// - public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7)> ZipLongest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - IEnumerable fifth, - IEnumerable sixth, - IEnumerable seventh) - { - return ZipLongest( - first, - second, - third, - fourth, - fifth, - sixth, - seventh, - ValueTuple.Create); - } - - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// is as short as the shortest input sequence. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// Type of elements in fifth input sequence. - /// Type of elements in sixth input sequence. - /// Type of elements in seventh input sequence. - /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. - /// - /// Function to apply to each tuple of elements. - /// - /// A projection of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// - /// If the input sequences are of different lengths, the result sequence - /// is terminated as soon as the shortest input sequence is exhausted - /// and remainder elements from the longer sequences are never consumed. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable ZipShortest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - IEnumerable fifth, - IEnumerable sixth, - IEnumerable seventh, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (third == null) throw new ArgumentNullException(nameof(third)); - if (fourth == null) throw new ArgumentNullException(nameof(fourth)); - if (fifth == null) throw new ArgumentNullException(nameof(fifth)); - if (sixth == null) throw new ArgumentNullException(nameof(sixth)); - if (seventh == null) throw new ArgumentNullException(nameof(seventh)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return _(); IEnumerable _() - { - using var e1 = first.GetEnumerator(); - using var e2 = second.GetEnumerator(); - using var e3 = third.GetEnumerator(); - using var e4 = fourth.GetEnumerator(); - using var e5 = fifth.GetEnumerator(); - using var e6 = sixth.GetEnumerator(); - using var e7 = seventh.GetEnumerator(); - - while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext() && e6.MoveNext() && e7.MoveNext()) - { - yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current, e5.Current, e6.Current, e7.Current); - } - } - } - - /// - /// Returns a sequence of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// is as short as the shortest input sequence. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// Type of elements in fifth input sequence. - /// Type of elements in sixth input sequence. - /// Type of elements in seventh input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. - /// - /// A sequence of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// - /// If the input sequences are of different lengths, the result sequence - /// is terminated as soon as the shortest input sequence is exhausted - /// and remainder elements from the longer sequences are never consumed. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7)> ZipShortest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - IEnumerable fifth, - IEnumerable sixth, - IEnumerable seventh) - { - return ZipShortest( - first, - second, - third, - fourth, - fifth, - sixth, - seventh, - ValueTuple.Create); - } - - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the input sequences. An exception is thrown - /// if the input sequences are of different lengths. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// Type of elements in fifth input sequence. - /// Type of elements in sixth input sequence. - /// Type of elements in seventh input sequence. - /// Type of elements in eighth input sequence. - /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. - /// The eighth source sequence. - /// - /// Function to apply to each tuple of elements. - /// - /// A projection of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// The input sequences are of different lengths. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable EquiZip( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - IEnumerable fifth, - IEnumerable sixth, - IEnumerable seventh, - IEnumerable eighth, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (third == null) throw new ArgumentNullException(nameof(third)); - if (fourth == null) throw new ArgumentNullException(nameof(fourth)); - if (fifth == null) throw new ArgumentNullException(nameof(fifth)); - if (sixth == null) throw new ArgumentNullException(nameof(sixth)); - if (seventh == null) throw new ArgumentNullException(nameof(seventh)); - if (eighth == null) throw new ArgumentNullException(nameof(eighth)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return _(); IEnumerable _() - { - using var e1 = first.GetEnumerator(); - using var e2 = second.GetEnumerator(); - using var e3 = third.GetEnumerator(); - using var e4 = fourth.GetEnumerator(); - using var e5 = fifth.GetEnumerator(); - using var e6 = sixth.GetEnumerator(); - using var e7 = seventh.GetEnumerator(); - using var e8 = eighth.GetEnumerator(); - - for (;;) - { - if (e1.MoveNext()) - { - if (e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext() && e6.MoveNext() && e7.MoveNext() && e8.MoveNext()) - yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current, e5.Current, e6.Current, e7.Current, e8.Current); - else - break; - } - else - { - if (e2.MoveNext() || e3.MoveNext() || e4.MoveNext() || e5.MoveNext() || e6.MoveNext() || e7.MoveNext() || e8.MoveNext()) - break; - else - yield break; - } - } - - throw new InvalidOperationException($"Sequences differ in length."); - } - } - - /// - /// Returns a sequence of tuples, where each tuple contains the N-th - /// element from each of the input sequences. An exception is thrown - /// if the input sequences are of different lengths. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// Type of elements in fifth input sequence. - /// Type of elements in sixth input sequence. - /// Type of elements in seventh input sequence. - /// Type of elements in eighth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. - /// The eighth source sequence. - /// - /// A sequence of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// The input sequences are of different lengths. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7, T8)> EquiZip( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - IEnumerable fifth, - IEnumerable sixth, - IEnumerable seventh, - IEnumerable eighth) - { - return EquiZip( - first, - second, - third, - fourth, - fifth, - sixth, - seventh, - eighth, - ValueTuple.Create); - } - - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// Type of elements in fifth input sequence. - /// Type of elements in sixth input sequence. - /// Type of elements in seventh input sequence. - /// Type of elements in eighth input sequence. - /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. - /// The eighth source sequence. - /// - /// Function to apply to each tuple of elements. - /// - /// A projection of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// This operator uses deferred execution and streams its results. - /// - public static IEnumerable ZipLongest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - IEnumerable fifth, - IEnumerable sixth, - IEnumerable seventh, - IEnumerable eighth, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (third == null) throw new ArgumentNullException(nameof(third)); - if (fourth == null) throw new ArgumentNullException(nameof(fourth)); - if (fifth == null) throw new ArgumentNullException(nameof(fifth)); - if (sixth == null) throw new ArgumentNullException(nameof(sixth)); - if (seventh == null) throw new ArgumentNullException(nameof(seventh)); - if (eighth == null) throw new ArgumentNullException(nameof(eighth)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return _(); IEnumerable _() - { - IEnumerator e1 = null; - IEnumerator e2 = null; - IEnumerator e3 = null; - IEnumerator e4 = null; - IEnumerator e5 = null; - IEnumerator e6 = null; - IEnumerator e7 = null; - IEnumerator e8 = null; - - try - { - e1 = first.GetEnumerator(); - e2 = second.GetEnumerator(); - e3 = third.GetEnumerator(); - e4 = fourth.GetEnumerator(); - e5 = fifth.GetEnumerator(); - e6 = sixth.GetEnumerator(); - e7 = seventh.GetEnumerator(); - e8 = eighth.GetEnumerator(); - - var v1 = default(T1); - var v2 = default(T2); - var v3 = default(T3); - var v4 = default(T4); - var v5 = default(T5); - var v6 = default(T6); - var v7 = default(T7); - var v8 = default(T8); - - while ( - ZipHelper.MoveNextOrDefault(ref e1, ref v1) | - ZipHelper.MoveNextOrDefault(ref e2, ref v2) | - ZipHelper.MoveNextOrDefault(ref e3, ref v3) | - ZipHelper.MoveNextOrDefault(ref e4, ref v4) | - ZipHelper.MoveNextOrDefault(ref e5, ref v5) | - ZipHelper.MoveNextOrDefault(ref e6, ref v6) | - ZipHelper.MoveNextOrDefault(ref e7, ref v7) | - ZipHelper.MoveNextOrDefault(ref e8, ref v8)) - { - yield return resultSelector(v1, v2, v3, v4, v5, v6, v7, v8); - } - } - finally - { - e1?.Dispose(); - e2?.Dispose(); - e3?.Dispose(); - e4?.Dispose(); - e5?.Dispose(); - e6?.Dispose(); - e7?.Dispose(); - e8?.Dispose(); - } - } - } - - /// - /// Returns a sequence of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// Type of elements in fifth input sequence. - /// Type of elements in sixth input sequence. - /// Type of elements in seventh input sequence. - /// Type of elements in eighth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. - /// The eighth source sequence. - /// - /// A sequence of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// This operator uses deferred execution and streams its results. - /// - public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7, T8)> ZipLongest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - IEnumerable fifth, - IEnumerable sixth, - IEnumerable seventh, - IEnumerable eighth) - { - return ZipLongest( - first, - second, - third, - fourth, - fifth, - sixth, - seventh, - eighth, - ValueTuple.Create); - } - - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// is as short as the shortest input sequence. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// Type of elements in fifth input sequence. - /// Type of elements in sixth input sequence. - /// Type of elements in seventh input sequence. - /// Type of elements in eighth input sequence. - /// Type of elements in result sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. - /// The eighth source sequence. - /// - /// Function to apply to each tuple of elements. - /// - /// A projection of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// - /// If the input sequences are of different lengths, the result sequence - /// is terminated as soon as the shortest input sequence is exhausted - /// and remainder elements from the longer sequences are never consumed. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable ZipShortest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - IEnumerable fifth, - IEnumerable sixth, - IEnumerable seventh, - IEnumerable eighth, - Func resultSelector) - { - if (first == null) throw new ArgumentNullException(nameof(first)); - if (second == null) throw new ArgumentNullException(nameof(second)); - if (third == null) throw new ArgumentNullException(nameof(third)); - if (fourth == null) throw new ArgumentNullException(nameof(fourth)); - if (fifth == null) throw new ArgumentNullException(nameof(fifth)); - if (sixth == null) throw new ArgumentNullException(nameof(sixth)); - if (seventh == null) throw new ArgumentNullException(nameof(seventh)); - if (eighth == null) throw new ArgumentNullException(nameof(eighth)); - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return _(); IEnumerable _() - { - using var e1 = first.GetEnumerator(); - using var e2 = second.GetEnumerator(); - using var e3 = third.GetEnumerator(); - using var e4 = fourth.GetEnumerator(); - using var e5 = fifth.GetEnumerator(); - using var e6 = sixth.GetEnumerator(); - using var e7 = seventh.GetEnumerator(); - using var e8 = eighth.GetEnumerator(); - - while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext() && e6.MoveNext() && e7.MoveNext() && e8.MoveNext()) - { - yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current, e5.Current, e6.Current, e7.Current, e8.Current); - } - } - } - - /// - /// Returns a sequence of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// is as short as the shortest input sequence. - /// - /// Type of elements in first input sequence. - /// Type of elements in second input sequence. - /// Type of elements in third input sequence. - /// Type of elements in fourth input sequence. - /// Type of elements in fifth input sequence. - /// Type of elements in sixth input sequence. - /// Type of elements in seventh input sequence. - /// Type of elements in eighth input sequence. - /// The first source sequence. - /// The second source sequence. - /// The third source sequence. - /// The fourth source sequence. - /// The fifth source sequence. - /// The sixth source sequence. - /// The seventh source sequence. - /// The eighth source sequence. - /// - /// A sequence of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// - /// If the input sequences are of different lengths, the result sequence - /// is terminated as soon as the shortest input sequence is exhausted - /// and remainder elements from the longer sequences are never consumed. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7, T8)> ZipShortest( - this IEnumerable first, - IEnumerable second, - IEnumerable third, - IEnumerable fourth, - IEnumerable fifth, - IEnumerable sixth, - IEnumerable seventh, - IEnumerable eighth) - { - return ZipShortest( - first, - second, - third, - fourth, - fifth, - sixth, - seventh, - eighth, - ValueTuple.Create); - } - - } -} diff --git a/MoreLinq/Zip.g.tt b/MoreLinq/Zip.g.tt deleted file mode 100644 index acf41571f..000000000 --- a/MoreLinq/Zip.g.tt +++ /dev/null @@ -1,346 +0,0 @@ -<#@ template debug="false" hostspecific="false" language="C#" #> -<#@ output extension=".cs" #> -<#@ assembly name="System.Core" #> -<#@ assembly name="System.Collections" #> -<#@ import namespace="System.Globalization" #> -<#@ import namespace="System.Linq" #> -#region License and Terms -// MoreLINQ - Extensions to LINQ to Objects -// Copyright (c) 2019 Pierre Lando. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#endregion - -<# - var ordinals = new[] - { - "", - "first", "second", "third", "fourth", - "fifth", "sixth", "seventh", "eighth" - }; - - var overloads = - Enumerable.Range(2, 7) - .Select(argCount => - Enumerable.Range(1, argCount).Select(argPosition => - new - { - IsFirst = argPosition == 1, - IsLast = argPosition == argCount, - Name = ordinals[argPosition], - Ordinal = ordinals[argPosition], - Type = $"T{argPosition}", - // Objects associated with the argument - Enumerator = $"e{argPosition}", - Value = $"v{argPosition}" - })) - .Select(args => args.ToList()) - .Select(args => - new - { - Arguments = args, - TParams = string.Join(", ", args.Select(arg => arg.Type)) - }); -#> -namespace MoreLinq -{ - using System; - using System.Collections.Generic; - - static partial class MoreEnumerable - { -<# foreach (var o in overloads) - { -#> - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the input sequences. An exception is thrown - /// if the input sequences are of different lengths. - /// -<# foreach (var arg in o.Arguments) { #> - /// Type of elements in <#=arg.Name#> input sequence. -<#} #> - /// Type of elements in result sequence. -<# foreach (var arg in o.Arguments) { #> - /// The <#=arg.Ordinal#> source sequence. -<#} #> - /// - /// Function to apply to each tuple of elements. - /// - /// A projection of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// The input sequences are of different lengths. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable EquiZip<<#=o.TParams#>, TResult>( -<# foreach (var arg in o.Arguments) { #> - <#= arg.IsFirst ? "this " : "" #>IEnumerable<<#=arg.Type#>> <#=arg.Name#>, -<#} #> - Func<<#=o.TParams#>, TResult> resultSelector) - { -<# foreach (var arg in o.Arguments) { #> - if (<#=arg.Name#> == null) throw new ArgumentNullException(nameof(<#=arg.Name#>)); -<#} #> - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return _(); IEnumerable _() - { -<# foreach (var arg in o.Arguments) { #> - using var <#=arg.Enumerator#> = <#=arg.Name#>.GetEnumerator(); -<#} #> - - for (;;) - { - if (<#=o.Arguments.First().Enumerator#>.MoveNext()) - { - if (<# foreach (var arg in o.Arguments.Skip(1)) { #><#=arg.Enumerator#>.MoveNext()<#= arg.IsLast ? "" : " && " #><#}#>) - yield return resultSelector(<# foreach (var arg in o.Arguments) { #><#=arg.Enumerator#>.Current<#= arg.IsLast ? "" : ", " #><#}#>); - else - break; - } - else - { - if (<# foreach (var arg in o.Arguments.Skip(1)) { #><#=arg.Enumerator#>.MoveNext()<#= arg.IsLast ? "" : " || " #><#}#>) - break; - else - yield break; - } - } - - throw new InvalidOperationException($"Sequences differ in length."); - } - } - - /// - /// Returns a sequence of tuples, where each tuple contains the N-th - /// element from each of the input sequences. An exception is thrown - /// if the input sequences are of different lengths. - /// -<# foreach (var arg in o.Arguments) { #> - /// Type of elements in <#=arg.Name#> input sequence. -<#} #> -<# foreach (var arg in o.Arguments) { #> - /// The <#=arg.Ordinal#> source sequence. -<#} #> - /// - /// A sequence of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// The input sequences are of different lengths. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - public static IEnumerable<(<#=o.TParams#>)> EquiZip<<#=o.TParams#>>( -<# foreach (var arg in o.Arguments) { #> - <#= arg.IsFirst ? "this " : "" #>IEnumerable<<#=arg.Type#>> <#=arg.Name#><#= arg.IsLast ? ")" : "," #> -<#}#> - { - return EquiZip( -<# foreach (var arg in o.Arguments) { #> - <#=arg.Name#>, -<#}#> - ValueTuple.Create); - } - - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. - /// -<# foreach (var arg in o.Arguments) { #> - /// Type of elements in <#=arg.Name#> input sequence. -<#} #> - /// Type of elements in result sequence. -<# foreach (var arg in o.Arguments) { #> - /// The <#=arg.Ordinal#> source sequence. -<#} #> - /// - /// Function to apply to each tuple of elements. - /// - /// A projection of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// This operator uses deferred execution and streams its results. - /// - public static IEnumerable ZipLongest<<#=o.TParams#>, TResult>( -<# foreach (var arg in o.Arguments) { #> - <#= arg.IsFirst ? "this " : "" #>IEnumerable<<#=arg.Type#>> <#=arg.Name#>, -<#}#> - Func<<#=o.TParams#>, TResult> resultSelector) - { -<# foreach (var arg in o.Arguments) { #> - if (<#=arg.Name#> == null) throw new ArgumentNullException(nameof(<#=arg.Name#>)); -<#} #> - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return _(); IEnumerable _() - { -<# foreach (var arg in o.Arguments) { #> - IEnumerator<<#=arg.Type#>> <#=arg.Enumerator#> = null; -<#} #> - - try - { -<# foreach (var arg in o.Arguments) { #> - <#=arg.Enumerator#> = <#=arg.Name#>.GetEnumerator(); -<#} #> - -<# foreach (var arg in o.Arguments) { #> - var <#=arg.Value#> = default(<#=arg.Type#>); -<#} #> - - while ( -<# foreach (var arg in o.Arguments) { #> - ZipHelper.MoveNextOrDefault<<#=arg.Type#>>(ref <#=arg.Enumerator#>, ref <#=arg.Value#>)<#= arg.IsLast ? ")" : " |" #> -<#}#> - { - yield return resultSelector(<# foreach (var arg in o.Arguments) { #><#=arg.Value#><#= arg.IsLast ? "" : ", " #><#}#>); - } - } - finally - { -<# foreach (var arg in o.Arguments) { #> - <#=arg.Enumerator#>?.Dispose(); -<#} #> - } - } - } - - /// - /// Returns a sequence of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// will always be as long as the longest of input sequences where the - /// default value of each of the shorter sequence element types is used - /// for padding. - /// -<# foreach (var arg in o.Arguments) { #> - /// Type of elements in <#=arg.Name#> input sequence. -<#} #> -<# foreach (var arg in o.Arguments) { #> - /// The <#=arg.Ordinal#> source sequence. -<#} #> - /// - /// A sequence of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// This operator uses deferred execution and streams its results. - /// - public static IEnumerable<(<#=o.TParams#>)> ZipLongest<<#=o.TParams#>>( -<# foreach (var arg in o.Arguments) { #> - <#= arg.IsFirst ? "this " : "" #>IEnumerable<<#=arg.Type#>> <#=arg.Name#><#= arg.IsLast ? ")" : "," #> -<#}#> - { - return ZipLongest( -<# foreach (var arg in o.Arguments) { #> - <#=arg.Name#>, -<#}#> - ValueTuple.Create); - } - - /// - /// Returns a projection of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// is as short as the shortest input sequence. - /// -<# foreach (var arg in o.Arguments) { #> - /// Type of elements in <#=arg.Name#> input sequence. -<#} #> - /// Type of elements in result sequence. -<# foreach (var arg in o.Arguments) { #> - /// The <#=arg.Ordinal#> source sequence. -<#} #> - /// - /// Function to apply to each tuple of elements. - /// - /// A projection of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// - /// If the input sequences are of different lengths, the result sequence - /// is terminated as soon as the shortest input sequence is exhausted - /// and remainder elements from the longer sequences are never consumed. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable ZipShortest<<#=o.TParams#>, TResult>( -<# foreach (var arg in o.Arguments) { #> - <#= arg.IsFirst ? "this " : "" #>IEnumerable<<#=arg.Type#>> <#=arg.Name#>, -<#}#> - Func<<#=o.TParams#>, TResult> resultSelector) - { -<# foreach (var arg in o.Arguments) { #> - if (<#=arg.Name#> == null) throw new ArgumentNullException(nameof(<#=arg.Name#>)); -<#} #> - if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); - - return _(); IEnumerable _() - { -<# foreach (var arg in o.Arguments) { #> - using var <#=arg.Enumerator#> = <#=arg.Name#>.GetEnumerator(); -<#} #> - - while (<# foreach (var arg in o.Arguments) { #><#=arg.Enumerator#>.MoveNext()<#= arg.IsLast ? "" : " && " #><#}#>) - { - yield return resultSelector(<# foreach (var arg in o.Arguments) { #><#=arg.Enumerator#>.Current<#= arg.IsLast ? "" : ", " #><#}#>); - } - } - } - - /// - /// Returns a sequence of tuples, where each tuple contains the N-th - /// element from each of the input sequences. The resulting sequence - /// is as short as the shortest input sequence. - /// -<# foreach (var arg in o.Arguments) { #> - /// Type of elements in <#=arg.Name#> input sequence. -<#} #> -<# foreach (var arg in o.Arguments) { #> - /// The <#=arg.Ordinal#> source sequence. -<#} #> - /// - /// A sequence of tuples, where each tuple contains the N-th element - /// from each of the argument sequences. - /// - /// - /// If the input sequences are of different lengths, the result sequence - /// is terminated as soon as the shortest input sequence is exhausted - /// and remainder elements from the longer sequences are never consumed. - /// - /// - /// This operator uses deferred execution and streams its results. - /// - - public static IEnumerable<(<#=o.TParams#>)> ZipShortest<<#=o.TParams#>>( -<# foreach (var arg in o.Arguments) { #> - <#= arg.IsFirst ? "this " : "" #>IEnumerable<<#=arg.Type#>> <#=arg.Name#><#= arg.IsLast ? ")" : "," #> -<#}#> - { - return ZipShortest( -<# foreach (var arg in o.Arguments) { #> - <#=arg.Name#>, -<#}#> - ValueTuple.Create); - } - -<# } #> - } -} diff --git a/MoreLinq/ZipLongest.g.cs b/MoreLinq/ZipLongest.g.cs new file mode 100644 index 000000000..d599fb105 --- /dev/null +++ b/MoreLinq/ZipLongest.g.cs @@ -0,0 +1,901 @@ +#region License and Terms +// MoreLINQ - Extensions to LINQ to Objects +// Copyright (c) 2019 Pierre Lando. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +namespace MoreLinq +{ + using System; + using System.Collections.Generic; + + static partial class MoreEnumerable + { + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipLongest( + this IEnumerable first, + IEnumerable second, + Func resultSelector) + { + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return _(); IEnumerable _() + { + IEnumerator e1 = null; + IEnumerator e2 = null; + + try + { + e1 = first.GetEnumerator(); + e2 = second.GetEnumerator(); + + var v1 = default(T1); + var v2 = default(T2); + + while ( + ZipLongestHelper.MoveNextOrDefault(ref e1, ref v1) | + ZipLongestHelper.MoveNextOrDefault(ref e2, ref v2)) + { + yield return resultSelector(v1, v2); + } + } + finally + { + e1?.Dispose(); + e2?.Dispose(); + } + } + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// The first source sequence. + /// The second source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2)> ZipLongest( + this IEnumerable first, + IEnumerable second) + { + return ZipLongest( + first, + second, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipLongest( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + Func resultSelector) + { + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return _(); IEnumerable _() + { + IEnumerator e1 = null; + IEnumerator e2 = null; + IEnumerator e3 = null; + + try + { + e1 = first.GetEnumerator(); + e2 = second.GetEnumerator(); + e3 = third.GetEnumerator(); + + var v1 = default(T1); + var v2 = default(T2); + var v3 = default(T3); + + while ( + ZipLongestHelper.MoveNextOrDefault(ref e1, ref v1) | + ZipLongestHelper.MoveNextOrDefault(ref e2, ref v2) | + ZipLongestHelper.MoveNextOrDefault(ref e3, ref v3)) + { + yield return resultSelector(v1, v2, v3); + } + } + finally + { + e1?.Dispose(); + e2?.Dispose(); + e3?.Dispose(); + } + } + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3)> ZipLongest( + this IEnumerable first, + IEnumerable second, + IEnumerable third) + { + return ZipLongest( + first, + second, + third, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipLongest( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + Func resultSelector) + { + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return _(); IEnumerable _() + { + IEnumerator e1 = null; + IEnumerator e2 = null; + IEnumerator e3 = null; + IEnumerator e4 = null; + + try + { + e1 = first.GetEnumerator(); + e2 = second.GetEnumerator(); + e3 = third.GetEnumerator(); + e4 = fourth.GetEnumerator(); + + var v1 = default(T1); + var v2 = default(T2); + var v3 = default(T3); + var v4 = default(T4); + + while ( + ZipLongestHelper.MoveNextOrDefault(ref e1, ref v1) | + ZipLongestHelper.MoveNextOrDefault(ref e2, ref v2) | + ZipLongestHelper.MoveNextOrDefault(ref e3, ref v3) | + ZipLongestHelper.MoveNextOrDefault(ref e4, ref v4)) + { + yield return resultSelector(v1, v2, v3, v4); + } + } + finally + { + e1?.Dispose(); + e2?.Dispose(); + e3?.Dispose(); + e4?.Dispose(); + } + } + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3, T4)> ZipLongest( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth) + { + return ZipLongest( + first, + second, + third, + fourth, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipLongest( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + Func resultSelector) + { + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); + if (fifth == null) throw new ArgumentNullException(nameof(fifth)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return _(); IEnumerable _() + { + IEnumerator e1 = null; + IEnumerator e2 = null; + IEnumerator e3 = null; + IEnumerator e4 = null; + IEnumerator e5 = null; + + try + { + e1 = first.GetEnumerator(); + e2 = second.GetEnumerator(); + e3 = third.GetEnumerator(); + e4 = fourth.GetEnumerator(); + e5 = fifth.GetEnumerator(); + + var v1 = default(T1); + var v2 = default(T2); + var v3 = default(T3); + var v4 = default(T4); + var v5 = default(T5); + + while ( + ZipLongestHelper.MoveNextOrDefault(ref e1, ref v1) | + ZipLongestHelper.MoveNextOrDefault(ref e2, ref v2) | + ZipLongestHelper.MoveNextOrDefault(ref e3, ref v3) | + ZipLongestHelper.MoveNextOrDefault(ref e4, ref v4) | + ZipLongestHelper.MoveNextOrDefault(ref e5, ref v5)) + { + yield return resultSelector(v1, v2, v3, v4, v5); + } + } + finally + { + e1?.Dispose(); + e2?.Dispose(); + e3?.Dispose(); + e4?.Dispose(); + e5?.Dispose(); + } + } + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3, T4, T5)> ZipLongest( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth) + { + return ZipLongest( + first, + second, + third, + fourth, + fifth, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipLongest( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + Func resultSelector) + { + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); + if (fifth == null) throw new ArgumentNullException(nameof(fifth)); + if (sixth == null) throw new ArgumentNullException(nameof(sixth)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return _(); IEnumerable _() + { + IEnumerator e1 = null; + IEnumerator e2 = null; + IEnumerator e3 = null; + IEnumerator e4 = null; + IEnumerator e5 = null; + IEnumerator e6 = null; + + try + { + e1 = first.GetEnumerator(); + e2 = second.GetEnumerator(); + e3 = third.GetEnumerator(); + e4 = fourth.GetEnumerator(); + e5 = fifth.GetEnumerator(); + e6 = sixth.GetEnumerator(); + + var v1 = default(T1); + var v2 = default(T2); + var v3 = default(T3); + var v4 = default(T4); + var v5 = default(T5); + var v6 = default(T6); + + while ( + ZipLongestHelper.MoveNextOrDefault(ref e1, ref v1) | + ZipLongestHelper.MoveNextOrDefault(ref e2, ref v2) | + ZipLongestHelper.MoveNextOrDefault(ref e3, ref v3) | + ZipLongestHelper.MoveNextOrDefault(ref e4, ref v4) | + ZipLongestHelper.MoveNextOrDefault(ref e5, ref v5) | + ZipLongestHelper.MoveNextOrDefault(ref e6, ref v6)) + { + yield return resultSelector(v1, v2, v3, v4, v5, v6); + } + } + finally + { + e1?.Dispose(); + e2?.Dispose(); + e3?.Dispose(); + e4?.Dispose(); + e5?.Dispose(); + e6?.Dispose(); + } + } + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3, T4, T5, T6)> ZipLongest( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth) + { + return ZipLongest( + first, + second, + third, + fourth, + fifth, + sixth, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipLongest( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, + Func resultSelector) + { + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); + if (fifth == null) throw new ArgumentNullException(nameof(fifth)); + if (sixth == null) throw new ArgumentNullException(nameof(sixth)); + if (seventh == null) throw new ArgumentNullException(nameof(seventh)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return _(); IEnumerable _() + { + IEnumerator e1 = null; + IEnumerator e2 = null; + IEnumerator e3 = null; + IEnumerator e4 = null; + IEnumerator e5 = null; + IEnumerator e6 = null; + IEnumerator e7 = null; + + try + { + e1 = first.GetEnumerator(); + e2 = second.GetEnumerator(); + e3 = third.GetEnumerator(); + e4 = fourth.GetEnumerator(); + e5 = fifth.GetEnumerator(); + e6 = sixth.GetEnumerator(); + e7 = seventh.GetEnumerator(); + + var v1 = default(T1); + var v2 = default(T2); + var v3 = default(T3); + var v4 = default(T4); + var v5 = default(T5); + var v6 = default(T6); + var v7 = default(T7); + + while ( + ZipLongestHelper.MoveNextOrDefault(ref e1, ref v1) | + ZipLongestHelper.MoveNextOrDefault(ref e2, ref v2) | + ZipLongestHelper.MoveNextOrDefault(ref e3, ref v3) | + ZipLongestHelper.MoveNextOrDefault(ref e4, ref v4) | + ZipLongestHelper.MoveNextOrDefault(ref e5, ref v5) | + ZipLongestHelper.MoveNextOrDefault(ref e6, ref v6) | + ZipLongestHelper.MoveNextOrDefault(ref e7, ref v7)) + { + yield return resultSelector(v1, v2, v3, v4, v5, v6, v7); + } + } + finally + { + e1?.Dispose(); + e2?.Dispose(); + e3?.Dispose(); + e4?.Dispose(); + e5?.Dispose(); + e6?.Dispose(); + e7?.Dispose(); + } + } + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7)> ZipLongest( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh) + { + return ZipLongest( + first, + second, + third, + fourth, + fifth, + sixth, + seventh, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// Type of elements in eighth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipLongest( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, + IEnumerable eighth, + Func resultSelector) + { + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); + if (fifth == null) throw new ArgumentNullException(nameof(fifth)); + if (sixth == null) throw new ArgumentNullException(nameof(sixth)); + if (seventh == null) throw new ArgumentNullException(nameof(seventh)); + if (eighth == null) throw new ArgumentNullException(nameof(eighth)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return _(); IEnumerable _() + { + IEnumerator e1 = null; + IEnumerator e2 = null; + IEnumerator e3 = null; + IEnumerator e4 = null; + IEnumerator e5 = null; + IEnumerator e6 = null; + IEnumerator e7 = null; + IEnumerator e8 = null; + + try + { + e1 = first.GetEnumerator(); + e2 = second.GetEnumerator(); + e3 = third.GetEnumerator(); + e4 = fourth.GetEnumerator(); + e5 = fifth.GetEnumerator(); + e6 = sixth.GetEnumerator(); + e7 = seventh.GetEnumerator(); + e8 = eighth.GetEnumerator(); + + var v1 = default(T1); + var v2 = default(T2); + var v3 = default(T3); + var v4 = default(T4); + var v5 = default(T5); + var v6 = default(T6); + var v7 = default(T7); + var v8 = default(T8); + + while ( + ZipLongestHelper.MoveNextOrDefault(ref e1, ref v1) | + ZipLongestHelper.MoveNextOrDefault(ref e2, ref v2) | + ZipLongestHelper.MoveNextOrDefault(ref e3, ref v3) | + ZipLongestHelper.MoveNextOrDefault(ref e4, ref v4) | + ZipLongestHelper.MoveNextOrDefault(ref e5, ref v5) | + ZipLongestHelper.MoveNextOrDefault(ref e6, ref v6) | + ZipLongestHelper.MoveNextOrDefault(ref e7, ref v7) | + ZipLongestHelper.MoveNextOrDefault(ref e8, ref v8)) + { + yield return resultSelector(v1, v2, v3, v4, v5, v6, v7, v8); + } + } + finally + { + e1?.Dispose(); + e2?.Dispose(); + e3?.Dispose(); + e4?.Dispose(); + e5?.Dispose(); + e6?.Dispose(); + e7?.Dispose(); + e8?.Dispose(); + } + } + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// Type of elements in eighth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7, T8)> ZipLongest( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, + IEnumerable eighth) + { + return ZipLongest( + first, + second, + third, + fourth, + fifth, + sixth, + seventh, + eighth, + ValueTuple.Create); + } + + } +} diff --git a/MoreLinq/ZipLongest.g.tt b/MoreLinq/ZipLongest.g.tt new file mode 100644 index 000000000..cd053a9d5 --- /dev/null +++ b/MoreLinq/ZipLongest.g.tt @@ -0,0 +1,166 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ output extension=".cs" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Collections" #> +<#@ import namespace="System.Globalization" #> +<#@ import namespace="System.Linq" #> +#region License and Terms +// MoreLINQ - Extensions to LINQ to Objects +// Copyright (c) 2019 Pierre Lando. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +<# + var ordinals = new[] + { + "", + "first", "second", "third", "fourth", + "fifth", "sixth", "seventh", "eighth" + }; + + var overloads = + Enumerable.Range(2, 7) + .Select(argCount => + Enumerable.Range(1, argCount).Select(argPosition => + new + { + IsFirst = argPosition == 1, + IsLast = argPosition == argCount, + Name = ordinals[argPosition], + Ordinal = ordinals[argPosition], + Type = $"T{argPosition}", + // Objects associated with the argument + Enumerator = $"e{argPosition}", + Value = $"v{argPosition}" + })) + .Select(args => args.ToList()) + .Select(args => + new + { + Arguments = args, + TParams = string.Join(", ", args.Select(arg => arg.Type)) + }); +#> +namespace MoreLinq +{ + using System; + using System.Collections.Generic; + + static partial class MoreEnumerable + { +<# foreach (var o in overloads) + { +#> + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// +<# foreach (var arg in o.Arguments) { #> + /// Type of elements in <#=arg.Name#> input sequence. +<#} #> + /// Type of elements in result sequence. +<# foreach (var arg in o.Arguments) { #> + /// The <#=arg.Ordinal#> source sequence. +<#} #> + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipLongest<<#=o.TParams#>, TResult>( +<# foreach (var arg in o.Arguments) { #> + <#= arg.IsFirst ? "this " : "" #>IEnumerable<<#=arg.Type#>> <#=arg.Name#>, +<#}#> + Func<<#=o.TParams#>, TResult> resultSelector) + { +<# foreach (var arg in o.Arguments) { #> + if (<#=arg.Name#> == null) throw new ArgumentNullException(nameof(<#=arg.Name#>)); +<#} #> + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return _(); IEnumerable _() + { +<# foreach (var arg in o.Arguments) { #> + IEnumerator<<#=arg.Type#>> <#=arg.Enumerator#> = null; +<#} #> + + try + { +<# foreach (var arg in o.Arguments) { #> + <#=arg.Enumerator#> = <#=arg.Name#>.GetEnumerator(); +<#} #> + +<# foreach (var arg in o.Arguments) { #> + var <#=arg.Value#> = default(<#=arg.Type#>); +<#} #> + + while ( +<# foreach (var arg in o.Arguments) { #> + ZipLongestHelper.MoveNextOrDefault<<#=arg.Type#>>(ref <#=arg.Enumerator#>, ref <#=arg.Value#>)<#= arg.IsLast ? ")" : " |" #> +<#}#> + { + yield return resultSelector(<# foreach (var arg in o.Arguments) { #><#=arg.Value#><#= arg.IsLast ? "" : ", " #><#}#>); + } + } + finally + { +<# foreach (var arg in o.Arguments) { #> + <#=arg.Enumerator#>?.Dispose(); +<#} #> + } + } + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// will always be as long as the longest of input sequences where the + /// default value of each of the shorter sequence element types is used + /// for padding. + /// +<# foreach (var arg in o.Arguments) { #> + /// Type of elements in <#=arg.Name#> input sequence. +<#} #> +<# foreach (var arg in o.Arguments) { #> + /// The <#=arg.Ordinal#> source sequence. +<#} #> + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(<#=o.TParams#>)> ZipLongest<<#=o.TParams#>>( +<# foreach (var arg in o.Arguments) { #> + <#= arg.IsFirst ? "this " : "" #>IEnumerable<<#=arg.Type#>> <#=arg.Name#><#= arg.IsLast ? ")" : "," #> +<#}#> + { + return ZipLongest( +<# foreach (var arg in o.Arguments) { #> + <#=arg.Name#>, +<#}#> + ValueTuple.Create); + } + +<# } #> + } +} diff --git a/MoreLinq/Zip.cs b/MoreLinq/ZipLongestHelper.cs similarity index 97% rename from MoreLinq/Zip.cs rename to MoreLinq/ZipLongestHelper.cs index b03e3c9e0..fd570bd7a 100644 --- a/MoreLinq/Zip.cs +++ b/MoreLinq/ZipLongestHelper.cs @@ -19,7 +19,7 @@ namespace MoreLinq { using System.Collections.Generic; - static class ZipHelper + static class ZipLongestHelper { public static bool MoveNextOrDefault(ref IEnumerator enumerator, ref T value) { diff --git a/MoreLinq/ZipShortest.g.cs b/MoreLinq/ZipShortest.g.cs new file mode 100644 index 000000000..374f28cc2 --- /dev/null +++ b/MoreLinq/ZipShortest.g.cs @@ -0,0 +1,761 @@ +#region License and Terms +// MoreLINQ - Extensions to LINQ to Objects +// Copyright (c) 2019 Pierre Lando. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +namespace MoreLinq +{ + using System; + using System.Collections.Generic; + + static partial class MoreEnumerable + { + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipShortest( + this IEnumerable first, + IEnumerable second, + Func resultSelector) + { + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return _(); IEnumerable _() + { + using var e1 = first.GetEnumerator(); + using var e2 = second.GetEnumerator(); + + while (e1.MoveNext() && e2.MoveNext()) + { + yield return resultSelector(e1.Current, e2.Current); + } + } + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// The first source sequence. + /// The second source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2)> ZipShortest( + this IEnumerable first, + IEnumerable second) + { + return ZipShortest( + first, + second, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipShortest( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + Func resultSelector) + { + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return _(); IEnumerable _() + { + using var e1 = first.GetEnumerator(); + using var e2 = second.GetEnumerator(); + using var e3 = third.GetEnumerator(); + + while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext()) + { + yield return resultSelector(e1.Current, e2.Current, e3.Current); + } + } + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3)> ZipShortest( + this IEnumerable first, + IEnumerable second, + IEnumerable third) + { + return ZipShortest( + first, + second, + third, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipShortest( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + Func resultSelector) + { + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return _(); IEnumerable _() + { + using var e1 = first.GetEnumerator(); + using var e2 = second.GetEnumerator(); + using var e3 = third.GetEnumerator(); + using var e4 = fourth.GetEnumerator(); + + while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext() && e4.MoveNext()) + { + yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current); + } + } + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3, T4)> ZipShortest( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth) + { + return ZipShortest( + first, + second, + third, + fourth, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipShortest( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + Func resultSelector) + { + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); + if (fifth == null) throw new ArgumentNullException(nameof(fifth)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return _(); IEnumerable _() + { + using var e1 = first.GetEnumerator(); + using var e2 = second.GetEnumerator(); + using var e3 = third.GetEnumerator(); + using var e4 = fourth.GetEnumerator(); + using var e5 = fifth.GetEnumerator(); + + while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext()) + { + yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current, e5.Current); + } + } + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3, T4, T5)> ZipShortest( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth) + { + return ZipShortest( + first, + second, + third, + fourth, + fifth, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipShortest( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + Func resultSelector) + { + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); + if (fifth == null) throw new ArgumentNullException(nameof(fifth)); + if (sixth == null) throw new ArgumentNullException(nameof(sixth)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return _(); IEnumerable _() + { + using var e1 = first.GetEnumerator(); + using var e2 = second.GetEnumerator(); + using var e3 = third.GetEnumerator(); + using var e4 = fourth.GetEnumerator(); + using var e5 = fifth.GetEnumerator(); + using var e6 = sixth.GetEnumerator(); + + while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext() && e6.MoveNext()) + { + yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current, e5.Current, e6.Current); + } + } + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3, T4, T5, T6)> ZipShortest( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth) + { + return ZipShortest( + first, + second, + third, + fourth, + fifth, + sixth, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipShortest( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, + Func resultSelector) + { + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); + if (fifth == null) throw new ArgumentNullException(nameof(fifth)); + if (sixth == null) throw new ArgumentNullException(nameof(sixth)); + if (seventh == null) throw new ArgumentNullException(nameof(seventh)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return _(); IEnumerable _() + { + using var e1 = first.GetEnumerator(); + using var e2 = second.GetEnumerator(); + using var e3 = third.GetEnumerator(); + using var e4 = fourth.GetEnumerator(); + using var e5 = fifth.GetEnumerator(); + using var e6 = sixth.GetEnumerator(); + using var e7 = seventh.GetEnumerator(); + + while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext() && e6.MoveNext() && e7.MoveNext()) + { + yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current, e5.Current, e6.Current, e7.Current); + } + } + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7)> ZipShortest( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh) + { + return ZipShortest( + first, + second, + third, + fourth, + fifth, + sixth, + seventh, + ValueTuple.Create); + } + + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// Type of elements in eighth input sequence. + /// Type of elements in result sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipShortest( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, + IEnumerable eighth, + Func resultSelector) + { + if (first == null) throw new ArgumentNullException(nameof(first)); + if (second == null) throw new ArgumentNullException(nameof(second)); + if (third == null) throw new ArgumentNullException(nameof(third)); + if (fourth == null) throw new ArgumentNullException(nameof(fourth)); + if (fifth == null) throw new ArgumentNullException(nameof(fifth)); + if (sixth == null) throw new ArgumentNullException(nameof(sixth)); + if (seventh == null) throw new ArgumentNullException(nameof(seventh)); + if (eighth == null) throw new ArgumentNullException(nameof(eighth)); + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return _(); IEnumerable _() + { + using var e1 = first.GetEnumerator(); + using var e2 = second.GetEnumerator(); + using var e3 = third.GetEnumerator(); + using var e4 = fourth.GetEnumerator(); + using var e5 = fifth.GetEnumerator(); + using var e6 = sixth.GetEnumerator(); + using var e7 = seventh.GetEnumerator(); + using var e8 = eighth.GetEnumerator(); + + while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext() && e4.MoveNext() && e5.MoveNext() && e6.MoveNext() && e7.MoveNext() && e8.MoveNext()) + { + yield return resultSelector(e1.Current, e2.Current, e3.Current, e4.Current, e5.Current, e6.Current, e7.Current, e8.Current); + } + } + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// + /// Type of elements in first input sequence. + /// Type of elements in second input sequence. + /// Type of elements in third input sequence. + /// Type of elements in fourth input sequence. + /// Type of elements in fifth input sequence. + /// Type of elements in sixth input sequence. + /// Type of elements in seventh input sequence. + /// Type of elements in eighth input sequence. + /// The first source sequence. + /// The second source sequence. + /// The third source sequence. + /// The fourth source sequence. + /// The fifth source sequence. + /// The sixth source sequence. + /// The seventh source sequence. + /// The eighth source sequence. + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(T1, T2, T3, T4, T5, T6, T7, T8)> ZipShortest( + this IEnumerable first, + IEnumerable second, + IEnumerable third, + IEnumerable fourth, + IEnumerable fifth, + IEnumerable sixth, + IEnumerable seventh, + IEnumerable eighth) + { + return ZipShortest( + first, + second, + third, + fourth, + fifth, + sixth, + seventh, + eighth, + ValueTuple.Create); + } + + } +} diff --git a/MoreLinq/ZipShortest.g.tt b/MoreLinq/ZipShortest.g.tt new file mode 100644 index 000000000..d23f6cc97 --- /dev/null +++ b/MoreLinq/ZipShortest.g.tt @@ -0,0 +1,154 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ output extension=".cs" #> +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Collections" #> +<#@ import namespace="System.Globalization" #> +<#@ import namespace="System.Linq" #> +#region License and Terms +// MoreLINQ - Extensions to LINQ to Objects +// Copyright (c) 2019 Pierre Lando. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#endregion + +<# + var ordinals = new[] + { + "", + "first", "second", "third", "fourth", + "fifth", "sixth", "seventh", "eighth" + }; + + var overloads = + Enumerable.Range(2, 7) + .Select(argCount => + Enumerable.Range(1, argCount).Select(argPosition => + new + { + IsFirst = argPosition == 1, + IsLast = argPosition == argCount, + Name = ordinals[argPosition], + Ordinal = ordinals[argPosition], + Type = $"T{argPosition}", + // Objects associated with the argument + Enumerator = $"e{argPosition}", + Value = $"v{argPosition}" + })) + .Select(args => args.ToList()) + .Select(args => + new + { + Arguments = args, + TParams = string.Join(", ", args.Select(arg => arg.Type)) + }); +#> +namespace MoreLinq +{ + using System; + using System.Collections.Generic; + + static partial class MoreEnumerable + { +<# foreach (var o in overloads) + { +#> + /// + /// Returns a projection of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// +<# foreach (var arg in o.Arguments) { #> + /// Type of elements in <#=arg.Name#> input sequence. +<#} #> + /// Type of elements in result sequence. +<# foreach (var arg in o.Arguments) { #> + /// The <#=arg.Ordinal#> source sequence. +<#} #> + /// + /// Function to apply to each tuple of elements. + /// + /// A projection of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable ZipShortest<<#=o.TParams#>, TResult>( +<# foreach (var arg in o.Arguments) { #> + <#= arg.IsFirst ? "this " : "" #>IEnumerable<<#=arg.Type#>> <#=arg.Name#>, +<#}#> + Func<<#=o.TParams#>, TResult> resultSelector) + { +<# foreach (var arg in o.Arguments) { #> + if (<#=arg.Name#> == null) throw new ArgumentNullException(nameof(<#=arg.Name#>)); +<#} #> + if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector)); + + return _(); IEnumerable _() + { +<# foreach (var arg in o.Arguments) { #> + using var <#=arg.Enumerator#> = <#=arg.Name#>.GetEnumerator(); +<#} #> + + while (<# foreach (var arg in o.Arguments) { #><#=arg.Enumerator#>.MoveNext()<#= arg.IsLast ? "" : " && " #><#}#>) + { + yield return resultSelector(<# foreach (var arg in o.Arguments) { #><#=arg.Enumerator#>.Current<#= arg.IsLast ? "" : ", " #><#}#>); + } + } + } + + /// + /// Returns a sequence of tuples, where each tuple contains the N-th + /// element from each of the input sequences. The resulting sequence + /// is as short as the shortest input sequence. + /// +<# foreach (var arg in o.Arguments) { #> + /// Type of elements in <#=arg.Name#> input sequence. +<#} #> +<# foreach (var arg in o.Arguments) { #> + /// The <#=arg.Ordinal#> source sequence. +<#} #> + /// + /// A sequence of tuples, where each tuple contains the N-th element + /// from each of the argument sequences. + /// + /// + /// If the input sequences are of different lengths, the result sequence + /// is terminated as soon as the shortest input sequence is exhausted + /// and remainder elements from the longer sequences are never consumed. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + + public static IEnumerable<(<#=o.TParams#>)> ZipShortest<<#=o.TParams#>>( +<# foreach (var arg in o.Arguments) { #> + <#= arg.IsFirst ? "this " : "" #>IEnumerable<<#=arg.Type#>> <#=arg.Name#><#= arg.IsLast ? ")" : "," #> +<#}#> + { + return ZipShortest( +<# foreach (var arg in o.Arguments) { #> + <#=arg.Name#>, +<#}#> + ValueTuple.Create); + } + +<# } #> + } +} From 917a64578ef4cf3eeb3e529f3ee75211aa7a1ed2 Mon Sep 17 00:00:00 2001 From: Orace Date: Wed, 6 Nov 2019 11:08:09 +0100 Subject: [PATCH 09/11] Add comments on ZipLongest implementation. --- MoreLinq/ZipLongest.g.cs | 77 ++++++++++++++++++++---------------- MoreLinq/ZipLongest.g.tt | 1 + MoreLinq/ZipLongestHelper.cs | 22 ++++++++++- 3 files changed, 64 insertions(+), 36 deletions(-) diff --git a/MoreLinq/ZipLongest.g.cs b/MoreLinq/ZipLongest.g.cs index d599fb105..a98be8cd9 100644 --- a/MoreLinq/ZipLongest.g.cs +++ b/MoreLinq/ZipLongest.g.cs @@ -65,9 +65,10 @@ public static IEnumerable ZipLongest( var v1 = default(T1); var v2 = default(T2); + // | is used instead of || in purpose. All operands have to be evaluated. while ( - ZipLongestHelper.MoveNextOrDefault(ref e1, ref v1) | - ZipLongestHelper.MoveNextOrDefault(ref e2, ref v2)) + ZipLongestHelper.MoveNextOrDispose(ref e1, ref v1) | + ZipLongestHelper.MoveNextOrDispose(ref e2, ref v2)) { yield return resultSelector(v1, v2); } @@ -158,10 +159,11 @@ public static IEnumerable ZipLongest( var v2 = default(T2); var v3 = default(T3); + // | is used instead of || in purpose. All operands have to be evaluated. while ( - ZipLongestHelper.MoveNextOrDefault(ref e1, ref v1) | - ZipLongestHelper.MoveNextOrDefault(ref e2, ref v2) | - ZipLongestHelper.MoveNextOrDefault(ref e3, ref v3)) + ZipLongestHelper.MoveNextOrDispose(ref e1, ref v1) | + ZipLongestHelper.MoveNextOrDispose(ref e2, ref v2) | + ZipLongestHelper.MoveNextOrDispose(ref e3, ref v3)) { yield return resultSelector(v1, v2, v3); } @@ -264,11 +266,12 @@ public static IEnumerable ZipLongest( var v3 = default(T3); var v4 = default(T4); + // | is used instead of || in purpose. All operands have to be evaluated. while ( - ZipLongestHelper.MoveNextOrDefault(ref e1, ref v1) | - ZipLongestHelper.MoveNextOrDefault(ref e2, ref v2) | - ZipLongestHelper.MoveNextOrDefault(ref e3, ref v3) | - ZipLongestHelper.MoveNextOrDefault(ref e4, ref v4)) + ZipLongestHelper.MoveNextOrDispose(ref e1, ref v1) | + ZipLongestHelper.MoveNextOrDispose(ref e2, ref v2) | + ZipLongestHelper.MoveNextOrDispose(ref e3, ref v3) | + ZipLongestHelper.MoveNextOrDispose(ref e4, ref v4)) { yield return resultSelector(v1, v2, v3, v4); } @@ -383,12 +386,13 @@ public static IEnumerable ZipLongest( var v4 = default(T4); var v5 = default(T5); + // | is used instead of || in purpose. All operands have to be evaluated. while ( - ZipLongestHelper.MoveNextOrDefault(ref e1, ref v1) | - ZipLongestHelper.MoveNextOrDefault(ref e2, ref v2) | - ZipLongestHelper.MoveNextOrDefault(ref e3, ref v3) | - ZipLongestHelper.MoveNextOrDefault(ref e4, ref v4) | - ZipLongestHelper.MoveNextOrDefault(ref e5, ref v5)) + ZipLongestHelper.MoveNextOrDispose(ref e1, ref v1) | + ZipLongestHelper.MoveNextOrDispose(ref e2, ref v2) | + ZipLongestHelper.MoveNextOrDispose(ref e3, ref v3) | + ZipLongestHelper.MoveNextOrDispose(ref e4, ref v4) | + ZipLongestHelper.MoveNextOrDispose(ref e5, ref v5)) { yield return resultSelector(v1, v2, v3, v4, v5); } @@ -515,13 +519,14 @@ public static IEnumerable ZipLongest( var v5 = default(T5); var v6 = default(T6); + // | is used instead of || in purpose. All operands have to be evaluated. while ( - ZipLongestHelper.MoveNextOrDefault(ref e1, ref v1) | - ZipLongestHelper.MoveNextOrDefault(ref e2, ref v2) | - ZipLongestHelper.MoveNextOrDefault(ref e3, ref v3) | - ZipLongestHelper.MoveNextOrDefault(ref e4, ref v4) | - ZipLongestHelper.MoveNextOrDefault(ref e5, ref v5) | - ZipLongestHelper.MoveNextOrDefault(ref e6, ref v6)) + ZipLongestHelper.MoveNextOrDispose(ref e1, ref v1) | + ZipLongestHelper.MoveNextOrDispose(ref e2, ref v2) | + ZipLongestHelper.MoveNextOrDispose(ref e3, ref v3) | + ZipLongestHelper.MoveNextOrDispose(ref e4, ref v4) | + ZipLongestHelper.MoveNextOrDispose(ref e5, ref v5) | + ZipLongestHelper.MoveNextOrDispose(ref e6, ref v6)) { yield return resultSelector(v1, v2, v3, v4, v5, v6); } @@ -660,14 +665,15 @@ public static IEnumerable ZipLongest(ref e1, ref v1) | - ZipLongestHelper.MoveNextOrDefault(ref e2, ref v2) | - ZipLongestHelper.MoveNextOrDefault(ref e3, ref v3) | - ZipLongestHelper.MoveNextOrDefault(ref e4, ref v4) | - ZipLongestHelper.MoveNextOrDefault(ref e5, ref v5) | - ZipLongestHelper.MoveNextOrDefault(ref e6, ref v6) | - ZipLongestHelper.MoveNextOrDefault(ref e7, ref v7)) + ZipLongestHelper.MoveNextOrDispose(ref e1, ref v1) | + ZipLongestHelper.MoveNextOrDispose(ref e2, ref v2) | + ZipLongestHelper.MoveNextOrDispose(ref e3, ref v3) | + ZipLongestHelper.MoveNextOrDispose(ref e4, ref v4) | + ZipLongestHelper.MoveNextOrDispose(ref e5, ref v5) | + ZipLongestHelper.MoveNextOrDispose(ref e6, ref v6) | + ZipLongestHelper.MoveNextOrDispose(ref e7, ref v7)) { yield return resultSelector(v1, v2, v3, v4, v5, v6, v7); } @@ -818,15 +824,16 @@ public static IEnumerable ZipLongest(ref e1, ref v1) | - ZipLongestHelper.MoveNextOrDefault(ref e2, ref v2) | - ZipLongestHelper.MoveNextOrDefault(ref e3, ref v3) | - ZipLongestHelper.MoveNextOrDefault(ref e4, ref v4) | - ZipLongestHelper.MoveNextOrDefault(ref e5, ref v5) | - ZipLongestHelper.MoveNextOrDefault(ref e6, ref v6) | - ZipLongestHelper.MoveNextOrDefault(ref e7, ref v7) | - ZipLongestHelper.MoveNextOrDefault(ref e8, ref v8)) + ZipLongestHelper.MoveNextOrDispose(ref e1, ref v1) | + ZipLongestHelper.MoveNextOrDispose(ref e2, ref v2) | + ZipLongestHelper.MoveNextOrDispose(ref e3, ref v3) | + ZipLongestHelper.MoveNextOrDispose(ref e4, ref v4) | + ZipLongestHelper.MoveNextOrDispose(ref e5, ref v5) | + ZipLongestHelper.MoveNextOrDispose(ref e6, ref v6) | + ZipLongestHelper.MoveNextOrDispose(ref e7, ref v7) | + ZipLongestHelper.MoveNextOrDispose(ref e8, ref v8)) { yield return resultSelector(v1, v2, v3, v4, v5, v6, v7, v8); } diff --git a/MoreLinq/ZipLongest.g.tt b/MoreLinq/ZipLongest.g.tt index cd053a9d5..8d57d6097 100644 --- a/MoreLinq/ZipLongest.g.tt +++ b/MoreLinq/ZipLongest.g.tt @@ -112,6 +112,7 @@ namespace MoreLinq var <#=arg.Value#> = default(<#=arg.Type#>); <#} #> + // | is used instead of || in purpose. All operands have to be evaluated. while ( <# foreach (var arg in o.Arguments) { #> ZipLongestHelper.MoveNextOrDefault<<#=arg.Type#>>(ref <#=arg.Enumerator#>, ref <#=arg.Value#>)<#= arg.IsLast ? ")" : " |" #> diff --git a/MoreLinq/ZipLongestHelper.cs b/MoreLinq/ZipLongestHelper.cs index fd570bd7a..4a916dc19 100644 --- a/MoreLinq/ZipLongestHelper.cs +++ b/MoreLinq/ZipLongestHelper.cs @@ -21,7 +21,27 @@ namespace MoreLinq static class ZipLongestHelper { - public static bool MoveNextOrDefault(ref IEnumerator enumerator, ref T value) + /// + /// Move the to the next position and put the + /// new current value into . + /// + /// If the has no more element it's disposed and + /// set to null, and is set to default. + /// + /// If the is null the method return immediately + /// and is not modified. + /// + /// The type of element that are enumerated. + /// The enumerator to iterate or dispose. + /// The new current value of or + /// default if has no more element. + /// + /// + /// Because and may both be modified + /// they are both passed by reference. + /// + /// A bool value indicating if the enumerator has moved to the next element. + public static bool MoveNextOrDispose(ref IEnumerator enumerator, ref T value) { if (enumerator == null) { From 43e0bd404a71cf98df7633ed1efd325ac600ed8d Mon Sep 17 00:00:00 2001 From: Orace Date: Wed, 6 Nov 2019 11:20:04 +0100 Subject: [PATCH 10/11] Fix trailing white space --- MoreLinq/ZipLongestHelper.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MoreLinq/ZipLongestHelper.cs b/MoreLinq/ZipLongestHelper.cs index 4a916dc19..09676eb0d 100644 --- a/MoreLinq/ZipLongestHelper.cs +++ b/MoreLinq/ZipLongestHelper.cs @@ -24,10 +24,10 @@ static class ZipLongestHelper /// /// Move the to the next position and put the /// new current value into . - /// + /// /// If the has no more element it's disposed and /// set to null, and is set to default. - /// + /// /// If the is null the method return immediately /// and is not modified. /// From 30d92525ca444eab71dad027722a430e74afa786 Mon Sep 17 00:00:00 2001 From: Orace Date: Wed, 6 Nov 2019 11:25:10 +0100 Subject: [PATCH 11/11] ZipLongestHelper.MoveNextOrDefault => ZipLongestHelper.MoveNextOrDispose --- MoreLinq/ZipLongest.g.tt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MoreLinq/ZipLongest.g.tt b/MoreLinq/ZipLongest.g.tt index 8d57d6097..b45c1bebe 100644 --- a/MoreLinq/ZipLongest.g.tt +++ b/MoreLinq/ZipLongest.g.tt @@ -115,7 +115,7 @@ namespace MoreLinq // | is used instead of || in purpose. All operands have to be evaluated. while ( <# foreach (var arg in o.Arguments) { #> - ZipLongestHelper.MoveNextOrDefault<<#=arg.Type#>>(ref <#=arg.Enumerator#>, ref <#=arg.Value#>)<#= arg.IsLast ? ")" : " |" #> + ZipLongestHelper.MoveNextOrDispose<<#=arg.Type#>>(ref <#=arg.Enumerator#>, ref <#=arg.Value#>)<#= arg.IsLast ? ")" : " |" #> <#}#> { yield return resultSelector(<# foreach (var arg in o.Arguments) { #><#=arg.Value#><#= arg.IsLast ? "" : ", " #><#}#>);