From 719597a2504866ec6bedae30128f8edbf00767c5 Mon Sep 17 00:00:00 2001 From: Samuel James <507.s94j@gmail.com> Date: Thu, 23 Nov 2023 03:25:10 +0200 Subject: [PATCH 01/11] Move range --- Source/SuperLinq/Move.cs | 28 +++++- .../PublicAPI/net6.0/PublicAPI.Unshipped.txt | 1 + .../PublicAPI/net7.0/PublicAPI.Unshipped.txt | 1 + .../PublicAPI/net8.0/PublicAPI.Unshipped.txt | 1 + .../netcoreapp3.1/PublicAPI.Unshipped.txt | 1 + Tests/SuperLinq.Test/MoveTest.cs | 95 ++++++++++++++++++- 6 files changed, 125 insertions(+), 2 deletions(-) diff --git a/Source/SuperLinq/Move.cs b/Source/SuperLinq/Move.cs index 494d3c73..9df907ad 100644 --- a/Source/SuperLinq/Move.cs +++ b/Source/SuperLinq/Move.cs @@ -67,4 +67,30 @@ static IEnumerable Core(IEnumerable source, int bufferStartIndex, int buff yield return e.Current; } } -} + + /// + /// Returns a sequence with a range of elements in the source sequence + /// moved to a new offset. + /// + /// Type of the source sequence. + /// The source sequence. + /// The range of values to move.> + /// + /// The index where the specified range will be moved. + /// + /// A sequence with the specified range moved to the new position. + /// + /// + /// This operator uses deferred execution and streams its results. + /// + /// + /// + /// The result variable will contain { 3, 4, 0, 1, 2, 5 }. + /// + public static IEnumerable Move(this IEnumerable source, Range range, int toIndex) + { + return source.Move(range.Start.Value, range.End.Value - range.Start.Value, toIndex); + } +} \ No newline at end of file diff --git a/Source/SuperLinq/PublicAPI/net6.0/PublicAPI.Unshipped.txt b/Source/SuperLinq/PublicAPI/net6.0/PublicAPI.Unshipped.txt index e72585ec..ffa1e945 100644 --- a/Source/SuperLinq/PublicAPI/net6.0/PublicAPI.Unshipped.txt +++ b/Source/SuperLinq/PublicAPI/net6.0/PublicAPI.Unshipped.txt @@ -1,5 +1,6 @@ #nullable enable static SuperLinq.SuperEnumerable.AggregateBy(this System.Collections.Generic.IEnumerable! source, System.Func! keySelector, System.Func! seedSelector, System.Func! func, System.Collections.Generic.IEqualityComparer? comparer = null) -> System.Collections.Generic.IEnumerable>! static SuperLinq.SuperEnumerable.AggregateBy(this System.Collections.Generic.IEnumerable! source, System.Func! keySelector, TAccumulate seed, System.Func! func, System.Collections.Generic.IEqualityComparer? comparer = null) -> System.Collections.Generic.IEnumerable>! +static SuperLinq.SuperEnumerable.Move(this System.Collections.Generic.IEnumerable! source, System.Range range, int toIndex) -> System.Collections.Generic.IEnumerable! *REMOVED*static SuperLinq.SuperEnumerable.Publish(this System.Collections.Generic.IEnumerable! source, System.Func!, System.Collections.Generic.IEnumerable!>! selector) -> System.Collections.Generic.IEnumerable! *REMOVED*static SuperLinq.SuperEnumerable.Share(this System.Collections.Generic.IEnumerable! source, System.Func!, System.Collections.Generic.IEnumerable!>! selector) -> System.Collections.Generic.IEnumerable! diff --git a/Source/SuperLinq/PublicAPI/net7.0/PublicAPI.Unshipped.txt b/Source/SuperLinq/PublicAPI/net7.0/PublicAPI.Unshipped.txt index e72585ec..ffa1e945 100644 --- a/Source/SuperLinq/PublicAPI/net7.0/PublicAPI.Unshipped.txt +++ b/Source/SuperLinq/PublicAPI/net7.0/PublicAPI.Unshipped.txt @@ -1,5 +1,6 @@ #nullable enable static SuperLinq.SuperEnumerable.AggregateBy(this System.Collections.Generic.IEnumerable! source, System.Func! keySelector, System.Func! seedSelector, System.Func! func, System.Collections.Generic.IEqualityComparer? comparer = null) -> System.Collections.Generic.IEnumerable>! static SuperLinq.SuperEnumerable.AggregateBy(this System.Collections.Generic.IEnumerable! source, System.Func! keySelector, TAccumulate seed, System.Func! func, System.Collections.Generic.IEqualityComparer? comparer = null) -> System.Collections.Generic.IEnumerable>! +static SuperLinq.SuperEnumerable.Move(this System.Collections.Generic.IEnumerable! source, System.Range range, int toIndex) -> System.Collections.Generic.IEnumerable! *REMOVED*static SuperLinq.SuperEnumerable.Publish(this System.Collections.Generic.IEnumerable! source, System.Func!, System.Collections.Generic.IEnumerable!>! selector) -> System.Collections.Generic.IEnumerable! *REMOVED*static SuperLinq.SuperEnumerable.Share(this System.Collections.Generic.IEnumerable! source, System.Func!, System.Collections.Generic.IEnumerable!>! selector) -> System.Collections.Generic.IEnumerable! diff --git a/Source/SuperLinq/PublicAPI/net8.0/PublicAPI.Unshipped.txt b/Source/SuperLinq/PublicAPI/net8.0/PublicAPI.Unshipped.txt index e72585ec..ffa1e945 100644 --- a/Source/SuperLinq/PublicAPI/net8.0/PublicAPI.Unshipped.txt +++ b/Source/SuperLinq/PublicAPI/net8.0/PublicAPI.Unshipped.txt @@ -1,5 +1,6 @@ #nullable enable static SuperLinq.SuperEnumerable.AggregateBy(this System.Collections.Generic.IEnumerable! source, System.Func! keySelector, System.Func! seedSelector, System.Func! func, System.Collections.Generic.IEqualityComparer? comparer = null) -> System.Collections.Generic.IEnumerable>! static SuperLinq.SuperEnumerable.AggregateBy(this System.Collections.Generic.IEnumerable! source, System.Func! keySelector, TAccumulate seed, System.Func! func, System.Collections.Generic.IEqualityComparer? comparer = null) -> System.Collections.Generic.IEnumerable>! +static SuperLinq.SuperEnumerable.Move(this System.Collections.Generic.IEnumerable! source, System.Range range, int toIndex) -> System.Collections.Generic.IEnumerable! *REMOVED*static SuperLinq.SuperEnumerable.Publish(this System.Collections.Generic.IEnumerable! source, System.Func!, System.Collections.Generic.IEnumerable!>! selector) -> System.Collections.Generic.IEnumerable! *REMOVED*static SuperLinq.SuperEnumerable.Share(this System.Collections.Generic.IEnumerable! source, System.Func!, System.Collections.Generic.IEnumerable!>! selector) -> System.Collections.Generic.IEnumerable! diff --git a/Source/SuperLinq/PublicAPI/netcoreapp3.1/PublicAPI.Unshipped.txt b/Source/SuperLinq/PublicAPI/netcoreapp3.1/PublicAPI.Unshipped.txt index e72585ec..ffa1e945 100644 --- a/Source/SuperLinq/PublicAPI/netcoreapp3.1/PublicAPI.Unshipped.txt +++ b/Source/SuperLinq/PublicAPI/netcoreapp3.1/PublicAPI.Unshipped.txt @@ -1,5 +1,6 @@ #nullable enable static SuperLinq.SuperEnumerable.AggregateBy(this System.Collections.Generic.IEnumerable! source, System.Func! keySelector, System.Func! seedSelector, System.Func! func, System.Collections.Generic.IEqualityComparer? comparer = null) -> System.Collections.Generic.IEnumerable>! static SuperLinq.SuperEnumerable.AggregateBy(this System.Collections.Generic.IEnumerable! source, System.Func! keySelector, TAccumulate seed, System.Func! func, System.Collections.Generic.IEqualityComparer? comparer = null) -> System.Collections.Generic.IEnumerable>! +static SuperLinq.SuperEnumerable.Move(this System.Collections.Generic.IEnumerable! source, System.Range range, int toIndex) -> System.Collections.Generic.IEnumerable! *REMOVED*static SuperLinq.SuperEnumerable.Publish(this System.Collections.Generic.IEnumerable! source, System.Func!, System.Collections.Generic.IEnumerable!>! selector) -> System.Collections.Generic.IEnumerable! *REMOVED*static SuperLinq.SuperEnumerable.Share(this System.Collections.Generic.IEnumerable! source, System.Func!, System.Collections.Generic.IEnumerable!>! selector) -> System.Collections.Generic.IEnumerable! diff --git a/Tests/SuperLinq.Test/MoveTest.cs b/Tests/SuperLinq.Test/MoveTest.cs index 5bb076c1..e6e4cdfa 100644 --- a/Tests/SuperLinq.Test/MoveTest.cs +++ b/Tests/SuperLinq.Test/MoveTest.cs @@ -9,6 +9,12 @@ public void MoveWithNegativeFromIndex() new[] { 1 }.Move(-1, 0, 0)); } + [Fact] + public void MoveRangeWithNegativeStartIndex() + { + _ = Assert.Throws(() => new[] { 1 }.Move(-1..-1, 0)); + } + [Fact] public void MoveWithNegativeCount() { @@ -16,6 +22,13 @@ public void MoveWithNegativeCount() new[] { 1 }.Move(0, -1, 0)); } + [Fact] + public void MoveRangeWithDecendingRange() + { + _ = Assert.Throws(() => + new[] { 1 }.Move(0..-1, 0)); + } + [Fact] public void MoveWithNegativeToIndex() { @@ -23,6 +36,13 @@ public void MoveWithNegativeToIndex() new[] { 1 }.Move(0, 0, -1)); } + [Fact] + public void MoveRangeWithNegativeToIndex() + { + _ = Assert.Throws(() => + new[] { 1 }.Move(0..0, -1)); + } + [Fact] public void MoveIsLazy() { @@ -44,6 +64,21 @@ public void Move(int length, int fromIndex, int count, int toIndex) result.AssertSequenceEqual(expectations); } + [Theory, MemberData(nameof(MoveRangeSource))] + public void MoveRange(int length, Range range, int toIndex) + { + var source = Enumerable.Range(0, length); + + using var test = source.AsTestingSequence(); + + var result = test.Move(range, toIndex); + + var slice = source.Take(range); + var exclude = source.Exclude(range.Start.Value, range.End.Value - range.Start.Value); + var expectations = exclude.Take(toIndex).Concat(slice).Concat(exclude.Skip(toIndex)); + result.AssertSequenceEqual(expectations); + } + public static IEnumerable MoveSource() { const int Length = 10; @@ -58,6 +93,20 @@ from count in Enumerable.Range(0, Length + 1) select tcd; } + public static IEnumerable MoveRangeSource() + { + const int Length = 10; + return + from index in Enumerable.Range(0, Length) + from count in Enumerable.Range(0, Length + 1) + from tcd in new object[][] + { + [Length, index..(index + count), Math.Max(0, index - 1),], + [Length, index..(index + count), index + 1,], + } + select tcd; + } + [Theory, MemberData(nameof(MoveWithSequenceShorterThanToIndexSource))] public void MoveWithSequenceShorterThanToIndex(int length, int fromIndex, int count, int toIndex) { @@ -71,10 +120,27 @@ public void MoveWithSequenceShorterThanToIndex(int length, int fromIndex, int co Assert.Equal(expectations, result); } + [Theory, MemberData(nameof(MoveRangeWithSequenceShorterThanToIndexSource))] + public void MoveRangeWithSequenceShorterThanToIndex(int length, Range range, int toIndex) + { + var source = Enumerable.Range(0, length); + + using var test = source.AsTestingSequence(); + + var result = test.Move(range, toIndex); + + var expectations = source.Exclude(range.Start.Value, range.End.Value - range.Start.Value).Concat(source.Take(range)); + Assert.Equal(expectations, result); + } + public static IEnumerable MoveWithSequenceShorterThanToIndexSource() => Enumerable.Range(10, 10 + 5) .Select(toIndex => new object[] { 10, 5, 2, toIndex, }); + public static IEnumerable MoveRangeWithSequenceShorterThanToIndexSource() => + Enumerable.Range(10, 10 + 5) + .Select(toIndex => new object[] { 10, 5..7, toIndex, }); + [Fact] public void MoveIsRepeatable() { @@ -84,6 +150,15 @@ public void MoveIsRepeatable() Assert.Equal(result, result.ToArray()); } + [Fact] + public void MoveRangeIsRepeatable() + { + using var source = Enumerable.Range(0, 10).AsTestingSequence(maxEnumerations: 2); + + var result = source.Move(0..5, 10); + Assert.Equal(result, result.ToArray()); + } + [Fact] public void MoveWithFromIndexEqualsToIndex() { @@ -93,6 +168,15 @@ public void MoveWithFromIndexEqualsToIndex() result.AssertSequenceEqual(Enumerable.Range(0, 10)); } + [Fact] + public void MoveRangeWithFomrIndexEqualsToIndex() + { + using var source = Enumerable.Range(0, 10).AsTestingSequence(); + + var result = source.Move(5..1004, 5); + result.AssertSequenceEqual(Enumerable.Range(0, 10)); + } + [Fact] public void MoveWithCountEqualsZero() { @@ -101,4 +185,13 @@ public void MoveWithCountEqualsZero() var result = source.Move(5, 0, 999); result.AssertSequenceEqual(Enumerable.Range(0, 10)); } -} + + [Fact] + public void MoveRngeWithCountEqualsZero() + { + using var source = Enumerable.Range(0, 10).AsTestingSequence(); + + var result = source.Move(5..5, 999); + result.AssertSequenceEqual(Enumerable.Range(0, 10)); + } +} \ No newline at end of file From 60fc1de6680ed3dfc79fc4a484193e49dc3efa9f Mon Sep 17 00:00:00 2001 From: Samuel James <507.s94j@gmail.com> Date: Mon, 27 Nov 2023 05:03:56 +0200 Subject: [PATCH 02/11] Update docs. Handle index and from ends --- Source/SuperLinq/Move.cs | 54 ++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/Source/SuperLinq/Move.cs b/Source/SuperLinq/Move.cs index 0f480da8..b0f4ec34 100644 --- a/Source/SuperLinq/Move.cs +++ b/Source/SuperLinq/Move.cs @@ -74,28 +74,50 @@ static IEnumerable Core(IEnumerable source, int bufferStartIndex, int buff } /// - /// Returns a sequence with a range of elements in the source sequence - /// moved to a new offset. + /// Returns a sequence with a range of elements in the source sequence moved to a new offset. /// - /// Type of the source sequence. - /// The source sequence. - /// The range of values to move.> + /// + /// Type of the source sequence. + /// + /// + /// The source sequence. + /// + /// + /// The range of values to move. + /// /// - /// The index where the specified range will be moved. + /// The index where the specified range will be moved. /// - /// A sequence with the specified range moved to the new position. + /// A sequence with the specified range moved to the new position. /// + /// + /// is . + /// + /// + /// 's start is less than 0 or 's end is before start in the sequence. + /// /// - /// This operator uses deferred execution and streams its results. + /// This operator uses deferred executing and streams its results. /// - /// - /// - /// The result variable will contain { 3, 4, 0, 1, 2, 5 }. - /// - public static IEnumerable Move(this IEnumerable source, Range range, int toIndex) + public static IEnumerable Move(this IEnumerable source, Range range, Index toIndex) { - return source.Move(range.Start.Value, range.End.Value - range.Start.Value, toIndex); + int? length = 0; + if (range.Start.IsFromEnd || range.End.IsFromEnd || toIndex.IsFromEnd) + { + length = source.TryGetCollectionCount(); + if (!length.HasValue) + { + length = source.GetCollectionCount(); + } + } + var fromIndex = range.Start.IsFromEnd ? range.Start.GetOffset(length.Value) : range.Start.Value; + var count = (range.End.IsFromEnd ? range.End.GetOffset(length.Value) : range.End.Value) - fromIndex; + var to = toIndex.IsFromEnd ? toIndex.GetOffset(length.Value) : toIndex.Value; + return source.Move + ( + fromIndex, + count, + to + ); } } \ No newline at end of file From 00b5a860fa8ccfd8371aa65491f139934dcecaab Mon Sep 17 00:00:00 2001 From: Samuel James <507.s94j@gmail.com> Date: Mon, 27 Nov 2023 05:10:02 +0200 Subject: [PATCH 03/11] Resolve conflicts --- .../SuperLinq/PublicAPI/net6.0/PublicAPI.Unshipped.txt | 10 +--------- .../SuperLinq/PublicAPI/net7.0/PublicAPI.Unshipped.txt | 10 +--------- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/Source/SuperLinq/PublicAPI/net6.0/PublicAPI.Unshipped.txt b/Source/SuperLinq/PublicAPI/net6.0/PublicAPI.Unshipped.txt index 75c457c3..d5ebddac 100644 --- a/Source/SuperLinq/PublicAPI/net6.0/PublicAPI.Unshipped.txt +++ b/Source/SuperLinq/PublicAPI/net6.0/PublicAPI.Unshipped.txt @@ -1,12 +1,4 @@ #nullable enable -<<<<<<< HEAD -*REMOVED*static SuperLinq.SuperEnumerable.Publish(this System.Collections.Generic.IEnumerable! source, System.Func!, System.Collections.Generic.IEnumerable!>! selector) -> System.Collections.Generic.IEnumerable! -*REMOVED*static SuperLinq.SuperEnumerable.Share(this System.Collections.Generic.IEnumerable! source, System.Func!, System.Collections.Generic.IEnumerable!>! selector) -> System.Collections.Generic.IEnumerable! -static SuperLinq.SuperEnumerable.AggregateBy(this System.Collections.Generic.IEnumerable! source, System.Func! keySelector, System.Func! seedSelector, System.Func! func, System.Collections.Generic.IEqualityComparer? comparer = null) -> System.Collections.Generic.IEnumerable>! -static SuperLinq.SuperEnumerable.AggregateBy(this System.Collections.Generic.IEnumerable! source, System.Func! keySelector, TAccumulate seed, System.Func! func, System.Collections.Generic.IEqualityComparer? comparer = null) -> System.Collections.Generic.IEnumerable>! -static SuperLinq.SuperEnumerable.Take(System.Collections.Generic.IEnumerable! source, System.Range range) -> System.Collections.Generic.IEnumerable! -static SuperLinq.SuperEnumerable.Move(this System.Collections.Generic.IEnumerable! source, System.Range range, int toIndex) -> System.Collections.Generic.IEnumerable! -======= *REMOVED*static SuperLinq.SuperEnumerable.Batch(this System.Collections.Generic.IEnumerable! source, int size, System.Func!, TResult>! resultSelector) -> System.Collections.Generic.IEnumerable! *REMOVED*static SuperLinq.SuperEnumerable.Batch(this System.Collections.Generic.IEnumerable! source, TSource[]! array, int size, System.Func!, TResult>! resultSelector) -> System.Collections.Generic.IEnumerable! *REMOVED*static SuperLinq.SuperEnumerable.Batch(this System.Collections.Generic.IEnumerable! source, TSource[]! array, System.Func!, TResult>! resultSelector) -> System.Collections.Generic.IEnumerable! @@ -24,6 +16,7 @@ static SuperLinq.SuperEnumerable.Move(this System.Collections.Generic.IEnumer static SuperLinq.SuperEnumerable.Batch(this System.Collections.Generic.IEnumerable! source, int size, System.Func, TResult>! resultSelector) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Batch(this System.Collections.Generic.IEnumerable! source, TSource[]! array, int size, System.Func, TResult>! resultSelector) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Batch(this System.Collections.Generic.IEnumerable! source, TSource[]! array, System.Func, TResult>! resultSelector) -> System.Collections.Generic.IEnumerable! +static SuperLinq.SuperEnumerable.Move(this System.Collections.Generic.IEnumerable! source, System.Range range, int toIndex) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Window(this System.Collections.Generic.IEnumerable! source, int size, System.Func, TResult>! selector) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Window(this System.Collections.Generic.IEnumerable! source, TSource[]! array, int size, System.Func, TResult>! selector) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Window(this System.Collections.Generic.IEnumerable! source, TSource[]! array, System.Func, TResult>! selector) -> System.Collections.Generic.IEnumerable! @@ -95,4 +88,3 @@ static SuperLinq.SuperEnumerable.RightOuterHashJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Collections.Generic.IEqualityComparer? comparer = null) -> System.Collections.Generic.IEnumerable<(TLeft? Left, TRight Right)>! static SuperLinq.SuperEnumerable.RightOuterMergeJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Func! rightResultSelector, System.Func! bothResultSelector, System.Collections.Generic.IComparer? comparer = null) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.RightOuterMergeJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Collections.Generic.IComparer? comparer = null) -> System.Collections.Generic.IEnumerable<(TLeft? Left, TRight Right)>! ->>>>>>> master diff --git a/Source/SuperLinq/PublicAPI/net7.0/PublicAPI.Unshipped.txt b/Source/SuperLinq/PublicAPI/net7.0/PublicAPI.Unshipped.txt index 75c457c3..d5ebddac 100644 --- a/Source/SuperLinq/PublicAPI/net7.0/PublicAPI.Unshipped.txt +++ b/Source/SuperLinq/PublicAPI/net7.0/PublicAPI.Unshipped.txt @@ -1,12 +1,4 @@ #nullable enable -<<<<<<< HEAD -*REMOVED*static SuperLinq.SuperEnumerable.Publish(this System.Collections.Generic.IEnumerable! source, System.Func!, System.Collections.Generic.IEnumerable!>! selector) -> System.Collections.Generic.IEnumerable! -*REMOVED*static SuperLinq.SuperEnumerable.Share(this System.Collections.Generic.IEnumerable! source, System.Func!, System.Collections.Generic.IEnumerable!>! selector) -> System.Collections.Generic.IEnumerable! -static SuperLinq.SuperEnumerable.AggregateBy(this System.Collections.Generic.IEnumerable! source, System.Func! keySelector, System.Func! seedSelector, System.Func! func, System.Collections.Generic.IEqualityComparer? comparer = null) -> System.Collections.Generic.IEnumerable>! -static SuperLinq.SuperEnumerable.AggregateBy(this System.Collections.Generic.IEnumerable! source, System.Func! keySelector, TAccumulate seed, System.Func! func, System.Collections.Generic.IEqualityComparer? comparer = null) -> System.Collections.Generic.IEnumerable>! -static SuperLinq.SuperEnumerable.Take(System.Collections.Generic.IEnumerable! source, System.Range range) -> System.Collections.Generic.IEnumerable! -static SuperLinq.SuperEnumerable.Move(this System.Collections.Generic.IEnumerable! source, System.Range range, int toIndex) -> System.Collections.Generic.IEnumerable! -======= *REMOVED*static SuperLinq.SuperEnumerable.Batch(this System.Collections.Generic.IEnumerable! source, int size, System.Func!, TResult>! resultSelector) -> System.Collections.Generic.IEnumerable! *REMOVED*static SuperLinq.SuperEnumerable.Batch(this System.Collections.Generic.IEnumerable! source, TSource[]! array, int size, System.Func!, TResult>! resultSelector) -> System.Collections.Generic.IEnumerable! *REMOVED*static SuperLinq.SuperEnumerable.Batch(this System.Collections.Generic.IEnumerable! source, TSource[]! array, System.Func!, TResult>! resultSelector) -> System.Collections.Generic.IEnumerable! @@ -24,6 +16,7 @@ static SuperLinq.SuperEnumerable.Move(this System.Collections.Generic.IEnumer static SuperLinq.SuperEnumerable.Batch(this System.Collections.Generic.IEnumerable! source, int size, System.Func, TResult>! resultSelector) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Batch(this System.Collections.Generic.IEnumerable! source, TSource[]! array, int size, System.Func, TResult>! resultSelector) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Batch(this System.Collections.Generic.IEnumerable! source, TSource[]! array, System.Func, TResult>! resultSelector) -> System.Collections.Generic.IEnumerable! +static SuperLinq.SuperEnumerable.Move(this System.Collections.Generic.IEnumerable! source, System.Range range, int toIndex) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Window(this System.Collections.Generic.IEnumerable! source, int size, System.Func, TResult>! selector) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Window(this System.Collections.Generic.IEnumerable! source, TSource[]! array, int size, System.Func, TResult>! selector) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Window(this System.Collections.Generic.IEnumerable! source, TSource[]! array, System.Func, TResult>! selector) -> System.Collections.Generic.IEnumerable! @@ -95,4 +88,3 @@ static SuperLinq.SuperEnumerable.RightOuterHashJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Collections.Generic.IEqualityComparer? comparer = null) -> System.Collections.Generic.IEnumerable<(TLeft? Left, TRight Right)>! static SuperLinq.SuperEnumerable.RightOuterMergeJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Func! rightResultSelector, System.Func! bothResultSelector, System.Collections.Generic.IComparer? comparer = null) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.RightOuterMergeJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Collections.Generic.IComparer? comparer = null) -> System.Collections.Generic.IEnumerable<(TLeft? Left, TRight Right)>! ->>>>>>> master From 5752529c0bd1fda233ce833ac518024ffc24d90d Mon Sep 17 00:00:00 2001 From: Samuel James <507.s94j@gmail.com> Date: Mon, 27 Nov 2023 06:01:14 +0200 Subject: [PATCH 04/11] Correct method signature --- Source/SuperLinq/PublicAPI/net6.0/PublicAPI.Unshipped.txt | 2 +- Source/SuperLinq/PublicAPI/net7.0/PublicAPI.Unshipped.txt | 2 +- Source/SuperLinq/PublicAPI/net8.0/PublicAPI.Unshipped.txt | 2 +- .../SuperLinq/PublicAPI/netcoreapp3.1/PublicAPI.Unshipped.txt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Source/SuperLinq/PublicAPI/net6.0/PublicAPI.Unshipped.txt b/Source/SuperLinq/PublicAPI/net6.0/PublicAPI.Unshipped.txt index d5ebddac..5fff6467 100644 --- a/Source/SuperLinq/PublicAPI/net6.0/PublicAPI.Unshipped.txt +++ b/Source/SuperLinq/PublicAPI/net6.0/PublicAPI.Unshipped.txt @@ -16,7 +16,7 @@ static SuperLinq.SuperEnumerable.Batch(this System.Collections.Generic.IEnumerable! source, int size, System.Func, TResult>! resultSelector) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Batch(this System.Collections.Generic.IEnumerable! source, TSource[]! array, int size, System.Func, TResult>! resultSelector) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Batch(this System.Collections.Generic.IEnumerable! source, TSource[]! array, System.Func, TResult>! resultSelector) -> System.Collections.Generic.IEnumerable! -static SuperLinq.SuperEnumerable.Move(this System.Collections.Generic.IEnumerable! source, System.Range range, int toIndex) -> System.Collections.Generic.IEnumerable! +static SuperLinq.SuperEnumerable.Move(this System.Collections.Generic.IEnumerable! source, System.Range range, System.Index toIndex) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Window(this System.Collections.Generic.IEnumerable! source, int size, System.Func, TResult>! selector) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Window(this System.Collections.Generic.IEnumerable! source, TSource[]! array, int size, System.Func, TResult>! selector) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Window(this System.Collections.Generic.IEnumerable! source, TSource[]! array, System.Func, TResult>! selector) -> System.Collections.Generic.IEnumerable! diff --git a/Source/SuperLinq/PublicAPI/net7.0/PublicAPI.Unshipped.txt b/Source/SuperLinq/PublicAPI/net7.0/PublicAPI.Unshipped.txt index d5ebddac..5fff6467 100644 --- a/Source/SuperLinq/PublicAPI/net7.0/PublicAPI.Unshipped.txt +++ b/Source/SuperLinq/PublicAPI/net7.0/PublicAPI.Unshipped.txt @@ -16,7 +16,7 @@ static SuperLinq.SuperEnumerable.Batch(this System.Collections.Generic.IEnumerable! source, int size, System.Func, TResult>! resultSelector) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Batch(this System.Collections.Generic.IEnumerable! source, TSource[]! array, int size, System.Func, TResult>! resultSelector) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Batch(this System.Collections.Generic.IEnumerable! source, TSource[]! array, System.Func, TResult>! resultSelector) -> System.Collections.Generic.IEnumerable! -static SuperLinq.SuperEnumerable.Move(this System.Collections.Generic.IEnumerable! source, System.Range range, int toIndex) -> System.Collections.Generic.IEnumerable! +static SuperLinq.SuperEnumerable.Move(this System.Collections.Generic.IEnumerable! source, System.Range range, System.Index toIndex) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Window(this System.Collections.Generic.IEnumerable! source, int size, System.Func, TResult>! selector) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Window(this System.Collections.Generic.IEnumerable! source, TSource[]! array, int size, System.Func, TResult>! selector) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Window(this System.Collections.Generic.IEnumerable! source, TSource[]! array, System.Func, TResult>! selector) -> System.Collections.Generic.IEnumerable! diff --git a/Source/SuperLinq/PublicAPI/net8.0/PublicAPI.Unshipped.txt b/Source/SuperLinq/PublicAPI/net8.0/PublicAPI.Unshipped.txt index d5ebddac..5fff6467 100644 --- a/Source/SuperLinq/PublicAPI/net8.0/PublicAPI.Unshipped.txt +++ b/Source/SuperLinq/PublicAPI/net8.0/PublicAPI.Unshipped.txt @@ -16,7 +16,7 @@ static SuperLinq.SuperEnumerable.Batch(this System.Collections.Generic.IEnumerable! source, int size, System.Func, TResult>! resultSelector) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Batch(this System.Collections.Generic.IEnumerable! source, TSource[]! array, int size, System.Func, TResult>! resultSelector) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Batch(this System.Collections.Generic.IEnumerable! source, TSource[]! array, System.Func, TResult>! resultSelector) -> System.Collections.Generic.IEnumerable! -static SuperLinq.SuperEnumerable.Move(this System.Collections.Generic.IEnumerable! source, System.Range range, int toIndex) -> System.Collections.Generic.IEnumerable! +static SuperLinq.SuperEnumerable.Move(this System.Collections.Generic.IEnumerable! source, System.Range range, System.Index toIndex) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Window(this System.Collections.Generic.IEnumerable! source, int size, System.Func, TResult>! selector) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Window(this System.Collections.Generic.IEnumerable! source, TSource[]! array, int size, System.Func, TResult>! selector) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Window(this System.Collections.Generic.IEnumerable! source, TSource[]! array, System.Func, TResult>! selector) -> System.Collections.Generic.IEnumerable! diff --git a/Source/SuperLinq/PublicAPI/netcoreapp3.1/PublicAPI.Unshipped.txt b/Source/SuperLinq/PublicAPI/netcoreapp3.1/PublicAPI.Unshipped.txt index d5ebddac..5fff6467 100644 --- a/Source/SuperLinq/PublicAPI/netcoreapp3.1/PublicAPI.Unshipped.txt +++ b/Source/SuperLinq/PublicAPI/netcoreapp3.1/PublicAPI.Unshipped.txt @@ -16,7 +16,7 @@ static SuperLinq.SuperEnumerable.Batch(this System.Collections.Generic.IEnumerable! source, int size, System.Func, TResult>! resultSelector) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Batch(this System.Collections.Generic.IEnumerable! source, TSource[]! array, int size, System.Func, TResult>! resultSelector) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Batch(this System.Collections.Generic.IEnumerable! source, TSource[]! array, System.Func, TResult>! resultSelector) -> System.Collections.Generic.IEnumerable! -static SuperLinq.SuperEnumerable.Move(this System.Collections.Generic.IEnumerable! source, System.Range range, int toIndex) -> System.Collections.Generic.IEnumerable! +static SuperLinq.SuperEnumerable.Move(this System.Collections.Generic.IEnumerable! source, System.Range range, System.Index toIndex) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Window(this System.Collections.Generic.IEnumerable! source, int size, System.Func, TResult>! selector) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Window(this System.Collections.Generic.IEnumerable! source, TSource[]! array, int size, System.Func, TResult>! selector) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.Window(this System.Collections.Generic.IEnumerable! source, TSource[]! array, System.Func, TResult>! selector) -> System.Collections.Generic.IEnumerable! From d0ff98ea9ff1cc74b375ef28fe02fcc3a639b21b Mon Sep 17 00:00:00 2001 From: Scharps <507.s94j@gmail.com> Date: Thu, 1 Feb 2024 20:44:35 +1100 Subject: [PATCH 05/11] Implement try count and enumerate counting --- Source/SuperLinq/Move.cs | 54 +++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/Source/SuperLinq/Move.cs b/Source/SuperLinq/Move.cs index b0f4ec34..c08b831b 100644 --- a/Source/SuperLinq/Move.cs +++ b/Source/SuperLinq/Move.cs @@ -85,7 +85,7 @@ static IEnumerable Core(IEnumerable source, int bufferStartIndex, int buff /// /// The range of values to move. /// - /// + /// /// The index where the specified range will be moved. /// /// A sequence with the specified range moved to the new position. @@ -99,25 +99,45 @@ static IEnumerable Core(IEnumerable source, int bufferStartIndex, int buff /// /// This operator uses deferred executing and streams its results. /// - public static IEnumerable Move(this IEnumerable source, Range range, Index toIndex) + public static IEnumerable Move(this IEnumerable source, Range range, Index to) { - int? length = 0; - if (range.Start.IsFromEnd || range.End.IsFromEnd || toIndex.IsFromEnd) + if (range.Start.IsFromEnd || range.End.IsFromEnd || to.IsFromEnd) { - length = source.TryGetCollectionCount(); - if (!length.HasValue) + int startIndex; + int endIndex; + int toIndex; + + if (source.TryGetCollectionCount() is int count) { - length = source.GetCollectionCount(); + startIndex = range.Start.GetOffset(count); + endIndex = range.End.GetOffset(count); + toIndex = to.GetOffset(count); + } + else + { + using var e = source.GetEnumerator(); + if (!e.MoveNext()) + { + yield break; + } + count = 1; + while (e.MoveNext()) + { + count++; + } + startIndex = range.Start.Value; + endIndex = range.End.Value; + toIndex = to.GetOffset(count); } + foreach (var e in Move(source, startIndex, endIndex - startIndex, toIndex)) + { + yield return e; + } + yield break; + } + foreach (var e in Move(source, range.Start.Value, range.End.Value - range.Start.Value, to.Value)) + { + yield return e; } - var fromIndex = range.Start.IsFromEnd ? range.Start.GetOffset(length.Value) : range.Start.Value; - var count = (range.End.IsFromEnd ? range.End.GetOffset(length.Value) : range.End.Value) - fromIndex; - var to = toIndex.IsFromEnd ? toIndex.GetOffset(length.Value) : toIndex.Value; - return source.Move - ( - fromIndex, - count, - to - ); } -} \ No newline at end of file +} From 555488b0f7a899b33c2636274f8706672fc6bf93 Mon Sep 17 00:00:00 2001 From: Scharps <507.s94j@gmail.com> Date: Thu, 1 Feb 2024 20:51:40 +1100 Subject: [PATCH 06/11] Add Move overload to Unshipped --- Source/SuperLinq/PublicAPI/net6.0/PublicAPI.Unshipped.txt | 1 + Source/SuperLinq/PublicAPI/net7.0/PublicAPI.Unshipped.txt | 1 + Source/SuperLinq/PublicAPI/net8.0/PublicAPI.Unshipped.txt | 1 + Source/SuperLinq/PublicAPI/netcoreapp3.1/PublicAPI.Unshipped.txt | 1 + 4 files changed, 4 insertions(+) diff --git a/Source/SuperLinq/PublicAPI/net6.0/PublicAPI.Unshipped.txt b/Source/SuperLinq/PublicAPI/net6.0/PublicAPI.Unshipped.txt index cf38aa4c..bd7a717e 100644 --- a/Source/SuperLinq/PublicAPI/net6.0/PublicAPI.Unshipped.txt +++ b/Source/SuperLinq/PublicAPI/net6.0/PublicAPI.Unshipped.txt @@ -109,6 +109,7 @@ static SuperLinq.SuperEnumerable.LeftOuterLoopJoin static SuperLinq.SuperEnumerable.LeftOuterLoopJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Collections.Generic.IEqualityComparer? comparer = null) -> System.Collections.Generic.IEnumerable<(TLeft Left, TRight? Right)>! static SuperLinq.SuperEnumerable.LeftOuterMergeJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Func! leftResultSelector, System.Func! bothResultSelector, System.Collections.Generic.IComparer? comparer = null) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.LeftOuterMergeJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Collections.Generic.IComparer? comparer = null) -> System.Collections.Generic.IEnumerable<(TLeft Left, TRight? Right)>! +static SuperLinq.SuperEnumerable.Move(this System.Collections.Generic.IEnumerable! source, System.Range range, System.Index to) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.RightOuterHashJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Func! rightResultSelector, System.Func! bothResultSelector, System.Collections.Generic.IEqualityComparer? comparer = null) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.RightOuterHashJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Collections.Generic.IEqualityComparer? comparer = null) -> System.Collections.Generic.IEnumerable<(TLeft? Left, TRight Right)>! static SuperLinq.SuperEnumerable.RightOuterMergeJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Func! rightResultSelector, System.Func! bothResultSelector, System.Collections.Generic.IComparer? comparer = null) -> System.Collections.Generic.IEnumerable! diff --git a/Source/SuperLinq/PublicAPI/net7.0/PublicAPI.Unshipped.txt b/Source/SuperLinq/PublicAPI/net7.0/PublicAPI.Unshipped.txt index cf38aa4c..bd7a717e 100644 --- a/Source/SuperLinq/PublicAPI/net7.0/PublicAPI.Unshipped.txt +++ b/Source/SuperLinq/PublicAPI/net7.0/PublicAPI.Unshipped.txt @@ -109,6 +109,7 @@ static SuperLinq.SuperEnumerable.LeftOuterLoopJoin static SuperLinq.SuperEnumerable.LeftOuterLoopJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Collections.Generic.IEqualityComparer? comparer = null) -> System.Collections.Generic.IEnumerable<(TLeft Left, TRight? Right)>! static SuperLinq.SuperEnumerable.LeftOuterMergeJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Func! leftResultSelector, System.Func! bothResultSelector, System.Collections.Generic.IComparer? comparer = null) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.LeftOuterMergeJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Collections.Generic.IComparer? comparer = null) -> System.Collections.Generic.IEnumerable<(TLeft Left, TRight? Right)>! +static SuperLinq.SuperEnumerable.Move(this System.Collections.Generic.IEnumerable! source, System.Range range, System.Index to) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.RightOuterHashJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Func! rightResultSelector, System.Func! bothResultSelector, System.Collections.Generic.IEqualityComparer? comparer = null) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.RightOuterHashJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Collections.Generic.IEqualityComparer? comparer = null) -> System.Collections.Generic.IEnumerable<(TLeft? Left, TRight Right)>! static SuperLinq.SuperEnumerable.RightOuterMergeJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Func! rightResultSelector, System.Func! bothResultSelector, System.Collections.Generic.IComparer? comparer = null) -> System.Collections.Generic.IEnumerable! diff --git a/Source/SuperLinq/PublicAPI/net8.0/PublicAPI.Unshipped.txt b/Source/SuperLinq/PublicAPI/net8.0/PublicAPI.Unshipped.txt index cf38aa4c..bd7a717e 100644 --- a/Source/SuperLinq/PublicAPI/net8.0/PublicAPI.Unshipped.txt +++ b/Source/SuperLinq/PublicAPI/net8.0/PublicAPI.Unshipped.txt @@ -109,6 +109,7 @@ static SuperLinq.SuperEnumerable.LeftOuterLoopJoin static SuperLinq.SuperEnumerable.LeftOuterLoopJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Collections.Generic.IEqualityComparer? comparer = null) -> System.Collections.Generic.IEnumerable<(TLeft Left, TRight? Right)>! static SuperLinq.SuperEnumerable.LeftOuterMergeJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Func! leftResultSelector, System.Func! bothResultSelector, System.Collections.Generic.IComparer? comparer = null) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.LeftOuterMergeJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Collections.Generic.IComparer? comparer = null) -> System.Collections.Generic.IEnumerable<(TLeft Left, TRight? Right)>! +static SuperLinq.SuperEnumerable.Move(this System.Collections.Generic.IEnumerable! source, System.Range range, System.Index to) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.RightOuterHashJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Func! rightResultSelector, System.Func! bothResultSelector, System.Collections.Generic.IEqualityComparer? comparer = null) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.RightOuterHashJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Collections.Generic.IEqualityComparer? comparer = null) -> System.Collections.Generic.IEnumerable<(TLeft? Left, TRight Right)>! static SuperLinq.SuperEnumerable.RightOuterMergeJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Func! rightResultSelector, System.Func! bothResultSelector, System.Collections.Generic.IComparer? comparer = null) -> System.Collections.Generic.IEnumerable! diff --git a/Source/SuperLinq/PublicAPI/netcoreapp3.1/PublicAPI.Unshipped.txt b/Source/SuperLinq/PublicAPI/netcoreapp3.1/PublicAPI.Unshipped.txt index cf38aa4c..bd7a717e 100644 --- a/Source/SuperLinq/PublicAPI/netcoreapp3.1/PublicAPI.Unshipped.txt +++ b/Source/SuperLinq/PublicAPI/netcoreapp3.1/PublicAPI.Unshipped.txt @@ -109,6 +109,7 @@ static SuperLinq.SuperEnumerable.LeftOuterLoopJoin static SuperLinq.SuperEnumerable.LeftOuterLoopJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Collections.Generic.IEqualityComparer? comparer = null) -> System.Collections.Generic.IEnumerable<(TLeft Left, TRight? Right)>! static SuperLinq.SuperEnumerable.LeftOuterMergeJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Func! leftResultSelector, System.Func! bothResultSelector, System.Collections.Generic.IComparer? comparer = null) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.LeftOuterMergeJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Collections.Generic.IComparer? comparer = null) -> System.Collections.Generic.IEnumerable<(TLeft Left, TRight? Right)>! +static SuperLinq.SuperEnumerable.Move(this System.Collections.Generic.IEnumerable! source, System.Range range, System.Index to) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.RightOuterHashJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Func! rightResultSelector, System.Func! bothResultSelector, System.Collections.Generic.IEqualityComparer? comparer = null) -> System.Collections.Generic.IEnumerable! static SuperLinq.SuperEnumerable.RightOuterHashJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Collections.Generic.IEqualityComparer? comparer = null) -> System.Collections.Generic.IEnumerable<(TLeft? Left, TRight Right)>! static SuperLinq.SuperEnumerable.RightOuterMergeJoin(this System.Collections.Generic.IEnumerable! left, System.Collections.Generic.IEnumerable! right, System.Func! leftKeySelector, System.Func! rightKeySelector, System.Func! rightResultSelector, System.Func! bothResultSelector, System.Collections.Generic.IComparer? comparer = null) -> System.Collections.Generic.IEnumerable! From 2dc801bfa8bc651c50f142242f3fd8eadf8a07de Mon Sep 17 00:00:00 2001 From: Scharps <507.s94j@gmail.com> Date: Thu, 8 Feb 2024 15:35:36 +1100 Subject: [PATCH 07/11] Handle IsFromEnd 'to' Index --- Source/SuperLinq/Move.cs | 129 ++++++++++++++++++++++++------- Tests/SuperLinq.Test/MoveTest.cs | 52 +++++++------ 2 files changed, 132 insertions(+), 49 deletions(-) diff --git a/Source/SuperLinq/Move.cs b/Source/SuperLinq/Move.cs index c08b831b..49d2a652 100644 --- a/Source/SuperLinq/Move.cs +++ b/Source/SuperLinq/Move.cs @@ -32,21 +32,30 @@ public static partial class SuperEnumerable /// /// This operator uses deferred execution and streams its results. /// - public static IEnumerable Move(this IEnumerable source, int fromIndex, int count, int toIndex) + public static IEnumerable Move( + this IEnumerable source, + int fromIndex, + int count, + int toIndex + ) { ArgumentNullException.ThrowIfNull(source); ArgumentOutOfRangeException.ThrowIfNegative(fromIndex); ArgumentOutOfRangeException.ThrowIfNegative(count); ArgumentOutOfRangeException.ThrowIfNegative(toIndex); - return - toIndex == fromIndex || count == 0 - ? source : - toIndex < fromIndex - ? Core(source, toIndex, fromIndex - toIndex, count) - : Core(source, fromIndex, count, toIndex - fromIndex); + return toIndex == fromIndex || count == 0 + ? source + : toIndex < fromIndex + ? Core(source, toIndex, fromIndex - toIndex, count) + : Core(source, fromIndex, count, toIndex - fromIndex); - static IEnumerable Core(IEnumerable source, int bufferStartIndex, int bufferSize, int bufferYieldIndex) + static IEnumerable Core( + IEnumerable source, + int bufferStartIndex, + int bufferSize, + int bufferYieldIndex + ) { var hasMore = true; bool MoveNext(IEnumerator e) => hasMore && (hasMore = e.MoveNext()); @@ -112,32 +121,98 @@ public static IEnumerable Move(this IEnumerable source, Range range, In startIndex = range.Start.GetOffset(count); endIndex = range.End.GetOffset(count); toIndex = to.GetOffset(count); - } - else + yield return (T)Move(source, startIndex, endIndex - startIndex, toIndex); + } + else { - using var e = source.GetEnumerator(); - if (!e.MoveNext()) - { - yield break; - } - count = 1; - while (e.MoveNext()) + switch ((range.Start.IsFromEnd, range.End.IsFromEnd, to.IsFromEnd)) { - count++; + case (false, false, true): + using (var e = source.GetEnumerator()) + { + if (!e.MoveNext()) + { + yield break; + } + + var bufferCap = to.Value; + var moveCap = range.End.Value - range.Start.Value; + var buffer = new Queue(bufferCap); + var move = new Queue(moveCap); + + buffer.Enqueue(e.Current); + count = 1; + + while (e.MoveNext()) + { + buffer.Enqueue(e.Current); + checked + { + ++count; + } + if (count > to.Value) + { + var idx = count - bufferCap; + if (idx > range.Start.Value && idx <= range.End.Value) + { + move.Enqueue(buffer.Dequeue()); + } + else + { + yield return buffer.Dequeue(); + } + } + } + while (move.TryDequeue(out var element)) + { + yield return element; + } + while (buffer.TryDequeue(out var element)) + { + yield return element; + } + } + yield break; + case (false, true, false): + // [4, 5, 2, 4, 1, §, 5] Move(1..^4, 2) + break; + case (false, true, true): + // [4, 5, 2, 4, 1, §, 5] Move(1..^4, ^2) + break; + case (true, false, false): + // [4, 5, 2, 4, 1, §, 5] Move(^5..4, 2) + break; + case (true, false, true): + // [4, 5, 2, 4, 1, §, 5] Move(^5..4, ^2) + break; + case (true, true, false): + if (range.End.Value > range.Start.Value) + { + yield break; + } + // [4, 5, 2, 4, 1, §, 5] Move(^5..^2, 4) + // Cannot yield any elements until count is known. + // Once count is known, can proceed to yield elements + break; + case (true, true, true): + // [4, 5, 2, 4, 1, §, 5] Move(^5..^3, ^2) + break; } - startIndex = range.Start.Value; - endIndex = range.End.Value; - toIndex = to.GetOffset(count); } - foreach (var e in Move(source, startIndex, endIndex - startIndex, toIndex)) + } + else + { + foreach ( + var e in Move( + source, + range.Start.Value, + range.End.Value - range.Start.Value, + to.Value + ) + ) { yield return e; } - yield break; - } - foreach (var e in Move(source, range.Start.Value, range.End.Value - range.Start.Value, to.Value)) - { - yield return e; } } } diff --git a/Tests/SuperLinq.Test/MoveTest.cs b/Tests/SuperLinq.Test/MoveTest.cs index e6e4cdfa..cbfc4b09 100644 --- a/Tests/SuperLinq.Test/MoveTest.cs +++ b/Tests/SuperLinq.Test/MoveTest.cs @@ -5,8 +5,7 @@ public class MoveTest [Fact] public void MoveWithNegativeFromIndex() { - _ = Assert.Throws(() => - new[] { 1 }.Move(-1, 0, 0)); + _ = Assert.Throws(() => new[] { 1 }.Move(-1, 0, 0)); } [Fact] @@ -18,29 +17,25 @@ public void MoveRangeWithNegativeStartIndex() [Fact] public void MoveWithNegativeCount() { - _ = Assert.Throws(() => - new[] { 1 }.Move(0, -1, 0)); + _ = Assert.Throws(() => new[] { 1 }.Move(0, -1, 0)); } [Fact] public void MoveRangeWithDecendingRange() { - _ = Assert.Throws(() => - new[] { 1 }.Move(0..-1, 0)); + _ = Assert.Throws(() => new[] { 1 }.Move(0..-1, 0)); } [Fact] public void MoveWithNegativeToIndex() { - _ = Assert.Throws(() => - new[] { 1 }.Move(0, 0, -1)); + _ = Assert.Throws(() => new[] { 1 }.Move(0, 0, -1)); } [Fact] public void MoveRangeWithNegativeToIndex() { - _ = Assert.Throws(() => - new[] { 1 }.Move(0..0, -1)); + _ = Assert.Throws(() => new[] { 1 }.Move(0..0, -1)); } [Fact] @@ -82,8 +77,7 @@ public void MoveRange(int length, Range range, int toIndex) public static IEnumerable MoveSource() { const int Length = 10; - return - from index in Enumerable.Range(0, Length) + return from index in Enumerable.Range(0, Length) from count in Enumerable.Range(0, Length + 1) from tcd in new object[][] { @@ -96,8 +90,7 @@ from count in Enumerable.Range(0, Length + 1) public static IEnumerable MoveRangeSource() { const int Length = 10; - return - from index in Enumerable.Range(0, Length) + return from index in Enumerable.Range(0, Length) from count in Enumerable.Range(0, Length + 1) from tcd in new object[][] { @@ -108,7 +101,12 @@ from count in Enumerable.Range(0, Length + 1) } [Theory, MemberData(nameof(MoveWithSequenceShorterThanToIndexSource))] - public void MoveWithSequenceShorterThanToIndex(int length, int fromIndex, int count, int toIndex) + public void MoveWithSequenceShorterThanToIndex( + int length, + int fromIndex, + int count, + int toIndex + ) { var source = Enumerable.Range(0, length); @@ -116,7 +114,9 @@ public void MoveWithSequenceShorterThanToIndex(int length, int fromIndex, int co var result = test.Move(fromIndex, count, toIndex); - var expectations = source.Exclude(fromIndex, count).Concat(source.Take(fromIndex..(fromIndex + count))); + var expectations = source + .Exclude(fromIndex, count) + .Concat(source.Take(fromIndex..(fromIndex + count))); Assert.Equal(expectations, result); } @@ -129,17 +129,17 @@ public void MoveRangeWithSequenceShorterThanToIndex(int length, Range range, int var result = test.Move(range, toIndex); - var expectations = source.Exclude(range.Start.Value, range.End.Value - range.Start.Value).Concat(source.Take(range)); + var expectations = source + .Exclude(range.Start.Value, range.End.Value - range.Start.Value) + .Concat(source.Take(range)); Assert.Equal(expectations, result); } public static IEnumerable MoveWithSequenceShorterThanToIndexSource() => - Enumerable.Range(10, 10 + 5) - .Select(toIndex => new object[] { 10, 5, 2, toIndex, }); + Enumerable.Range(10, 10 + 5).Select(toIndex => new object[] { 10, 5, 2, toIndex, }); public static IEnumerable MoveRangeWithSequenceShorterThanToIndexSource() => - Enumerable.Range(10, 10 + 5) - .Select(toIndex => new object[] { 10, 5..7, toIndex, }); + Enumerable.Range(10, 10 + 5).Select(toIndex => new object[] { 10, 5..7, toIndex, }); [Fact] public void MoveIsRepeatable() @@ -194,4 +194,12 @@ public void MoveRngeWithCountEqualsZero() var result = source.Move(5..5, 999); result.AssertSequenceEqual(Enumerable.Range(0, 10)); } -} \ No newline at end of file + + [Fact] + public void MoveRangeFromEndIndex() + { + using var source = Enumerable.Range(0, 8).AsTestingSequence(); + var result = source.Move(1..4, ^3); + result.AssertSequenceEqual([0, 4, 1, 2, 3, 5, 6, 7]); + } +} From 192276991a236f1551b52f3a2470e86348cf80d2 Mon Sep 17 00:00:00 2001 From: Scharps <507.s94j@gmail.com> Date: Fri, 9 Feb 2024 20:51:42 +1100 Subject: [PATCH 08/11] Invert if statement --- Source/SuperLinq/Move.cs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/Source/SuperLinq/Move.cs b/Source/SuperLinq/Move.cs index 49d2a652..272c2a06 100644 --- a/Source/SuperLinq/Move.cs +++ b/Source/SuperLinq/Move.cs @@ -110,7 +110,21 @@ int bufferYieldIndex /// public static IEnumerable Move(this IEnumerable source, Range range, Index to) { - if (range.Start.IsFromEnd || range.End.IsFromEnd || to.IsFromEnd) + if (!range.Start.IsFromEnd && !range.End.IsFromEnd && !to.IsFromEnd) + { + foreach ( + var e in Move( + source, + range.Start.Value, + range.End.Value - range.Start.Value, + to.Value + ) + ) + { + yield return e; + } + } + else { int startIndex; int endIndex; @@ -200,19 +214,5 @@ public static IEnumerable Move(this IEnumerable source, Range range, In } } } - else - { - foreach ( - var e in Move( - source, - range.Start.Value, - range.End.Value - range.Start.Value, - to.Value - ) - ) - { - yield return e; - } - } } } From d006520f5729ab227e803f1559028addc8f03b51 Mon Sep 17 00:00:00 2001 From: Scharps <507.s94j@gmail.com> Date: Tue, 13 Feb 2024 19:08:21 +1100 Subject: [PATCH 09/11] Add handler for where range end IsFromEnd --- Source/SuperLinq/Move.cs | 70 +++++++++++++++++++++++++++----- Tests/SuperLinq.Test/MoveTest.cs | 16 ++++++++ 2 files changed, 76 insertions(+), 10 deletions(-) diff --git a/Source/SuperLinq/Move.cs b/Source/SuperLinq/Move.cs index 272c2a06..6444254b 100644 --- a/Source/SuperLinq/Move.cs +++ b/Source/SuperLinq/Move.cs @@ -126,15 +126,11 @@ var e in Move( } else { - int startIndex; - int endIndex; - int toIndex; - if (source.TryGetCollectionCount() is int count) { - startIndex = range.Start.GetOffset(count); - endIndex = range.End.GetOffset(count); - toIndex = to.GetOffset(count); + var startIndex = range.Start.GetOffset(count); + var endIndex = range.End.GetOffset(count); + var toIndex = to.GetOffset(count); yield return (T)Move(source, startIndex, endIndex - startIndex, toIndex); } else @@ -142,6 +138,7 @@ var e in Move( switch ((range.Start.IsFromEnd, range.End.IsFromEnd, to.IsFromEnd)) { case (false, false, true): + // TODO: Does not work for moving ranges to an earlier position using (var e = source.GetEnumerator()) { if (!e.MoveNext()) @@ -189,12 +186,67 @@ var e in Move( yield break; case (false, true, false): // [4, 5, 2, 4, 1, §, 5] Move(1..^4, 2) + using (var e = source.GetEnumerator()) + { + // TODO: Does not work for moving ranges to an earlier position + if (!e.MoveNext()) + { + yield break; + } + count = 1; + // [a0, a2, a3, a4, a5, a6][b0, b1, b2, b3] + var toMove = new Queue(); + var b = new Queue(range.End.Value); + var min = Math.Min(range.Start.Value, to.Value); + b.Enqueue(e.Current); + + while (e.MoveNext()) + { + if (count <= min) + { + yield return b.Dequeue(); + } + else + { + if (count - min >= range.End.Value) + { + toMove.Enqueue(b.Dequeue()); + } + } + b.Enqueue(e.Current); + checked + { + ++count; + } + } + + var dir = range.Start.Value - to.Value; + for (; dir < 0; dir++) + yield return b.Dequeue(); + + var tmpQ = new Queue(dir); + for (; dir > 0; dir--) + { + tmpQ.Enqueue(toMove.Dequeue()); + } + + while (toMove.TryDequeue(out var el)) + yield return el; + + while (tmpQ.TryDequeue(out var el)) + yield return el; + + while (b.TryDequeue(out var el)) + yield return el; + } break; case (false, true, true): // [4, 5, 2, 4, 1, §, 5] Move(1..^4, ^2) + // Optimisitc approach - yield elements until start. break; case (true, false, false): // [4, 5, 2, 4, 1, §, 5] Move(^5..4, 2) + break; case (true, false, true): // [4, 5, 2, 4, 1, §, 5] Move(^5..4, ^2) @@ -202,11 +254,9 @@ var e in Move( case (true, true, false): if (range.End.Value > range.Start.Value) { + // Invalid range provided yield break; } - // [4, 5, 2, 4, 1, §, 5] Move(^5..^2, 4) - // Cannot yield any elements until count is known. - // Once count is known, can proceed to yield elements break; case (true, true, true): // [4, 5, 2, 4, 1, §, 5] Move(^5..^3, ^2) diff --git a/Tests/SuperLinq.Test/MoveTest.cs b/Tests/SuperLinq.Test/MoveTest.cs index cbfc4b09..951966c6 100644 --- a/Tests/SuperLinq.Test/MoveTest.cs +++ b/Tests/SuperLinq.Test/MoveTest.cs @@ -202,4 +202,20 @@ public void MoveRangeFromEndIndex() var result = source.Move(1..4, ^3); result.AssertSequenceEqual([0, 4, 1, 2, 3, 5, 6, 7]); } + + [Fact] + public void MoveRangeWithRangeEndFromEnd_Forward() + { + using var source = Enumerable.Range(0, 8).AsTestingSequence(); + var result = source.Move(1..^4, 2); + result.AssertSequenceEqual([0, 4, 1, 2, 3, 5, 6, 7]); + } + + [Fact] + public void MoveRangeWithRangeEndFromEnd_Backward() + { + using var source = Enumerable.Range(0, 8).AsTestingSequence(); + var result = source.Move(1..^4, 0); + result.AssertSequenceEqual([1, 2, 3, 0, 4, 5, 6, 7]); + } } From f22b599e636916b00c8ef062b8b327cf5655096f Mon Sep 17 00:00:00 2001 From: Scharps <507.s94j@gmail.com> Date: Wed, 14 Feb 2024 15:09:21 +1100 Subject: [PATCH 10/11] Remove comments --- Source/SuperLinq/Move.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Source/SuperLinq/Move.cs b/Source/SuperLinq/Move.cs index 6444254b..74eb676b 100644 --- a/Source/SuperLinq/Move.cs +++ b/Source/SuperLinq/Move.cs @@ -185,16 +185,14 @@ var e in Move( } yield break; case (false, true, false): - // [4, 5, 2, 4, 1, §, 5] Move(1..^4, 2) using (var e = source.GetEnumerator()) { - // TODO: Does not work for moving ranges to an earlier position if (!e.MoveNext()) { yield break; } + count = 1; - // [a0, a2, a3, a4, a5, a6][b0, b1, b2, b3] var toMove = new Queue(); var b = new Queue(range.End.Value); var min = Math.Min(range.Start.Value, to.Value); @@ -224,7 +222,7 @@ var e in Move( for (; dir < 0; dir++) yield return b.Dequeue(); - var tmpQ = new Queue(dir); + var tmpQ = new Queue(Math.Abs(dir)); for (; dir > 0; dir--) { tmpQ.Enqueue(toMove.Dequeue()); From 3f48c9a8e9ba9359b416ae7ddfd73e2314a90d34 Mon Sep 17 00:00:00 2001 From: Scharps <507.s94j@gmail.com> Date: Wed, 14 Feb 2024 17:03:40 +1100 Subject: [PATCH 11/11] Can now move range backwards --- Source/SuperLinq/Move.cs | 23 ++++++++++++++++++----- Tests/SuperLinq.Test/MoveTest.cs | 10 +++++++++- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/Source/SuperLinq/Move.cs b/Source/SuperLinq/Move.cs index 74eb676b..066dadc2 100644 --- a/Source/SuperLinq/Move.cs +++ b/Source/SuperLinq/Move.cs @@ -138,7 +138,6 @@ var e in Move( switch ((range.Start.IsFromEnd, range.End.IsFromEnd, to.IsFromEnd)) { case (false, false, true): - // TODO: Does not work for moving ranges to an earlier position using (var e = source.GetEnumerator()) { if (!e.MoveNext()) @@ -174,14 +173,28 @@ var e in Move( } } } - while (move.TryDequeue(out var element)) + + var preQSize = range.Start.Value - to.GetOffset(count); + var preQ = new Queue(Math.Abs(preQSize)); + for (var i = 0; i < preQSize; i++) + preQ.Enqueue(buffer.Dequeue()); + + if (move.Count == 0) { - yield return element; + for (var i = 0; i < moveCap && buffer.TryDequeue(out var el); i++) + yield return el; } - while (buffer.TryDequeue(out var element)) + else { - yield return element; + while (move.TryDequeue(out var element)) + yield return element; } + + while (preQ.TryDequeue(out var el)) + yield return el; + + while (buffer.TryDequeue(out var element)) + yield return element; } yield break; case (false, true, false): diff --git a/Tests/SuperLinq.Test/MoveTest.cs b/Tests/SuperLinq.Test/MoveTest.cs index 951966c6..1d8af375 100644 --- a/Tests/SuperLinq.Test/MoveTest.cs +++ b/Tests/SuperLinq.Test/MoveTest.cs @@ -196,13 +196,21 @@ public void MoveRngeWithCountEqualsZero() } [Fact] - public void MoveRangeFromEndIndex() + public void MoveRangeFromEndIndex_Forward() { using var source = Enumerable.Range(0, 8).AsTestingSequence(); var result = source.Move(1..4, ^3); result.AssertSequenceEqual([0, 4, 1, 2, 3, 5, 6, 7]); } + [Fact] + public void MoveRangeFromEndIndex_Backward() + { + using var source = Enumerable.Range(0, 10).AsTestingSequence(); + var result = source.Move(3..4, ^9); + result.AssertSequenceEqual([0, 3, 1, 2, 4, 5, 6, 7, 8, 9]); + } + [Fact] public void MoveRangeWithRangeEndFromEnd_Forward() {