From e93bcbf564a9aae913d463edb27a89a2fc96fa4d Mon Sep 17 00:00:00 2001 From: neuecc Date: Sat, 9 May 2020 23:33:27 +0900 Subject: [PATCH] Count, LongCount --- src/UniTask.NetCore/Linq/Count.cs | 6 +- src/UniTask.NetCore/Linq/LongCount.cs | 911 ++++----------------- src/UniTask.NetCore/Linq/_FileMaker.cs | 28 - src/UniTask.NetCoreTests/Linq/Aggregate.cs | 32 + 4 files changed, 175 insertions(+), 802 deletions(-) diff --git a/src/UniTask.NetCore/Linq/Count.cs b/src/UniTask.NetCore/Linq/Count.cs index 659fee7..a6ec863 100644 --- a/src/UniTask.NetCore/Linq/Count.cs +++ b/src/UniTask.NetCore/Linq/Count.cs @@ -18,7 +18,7 @@ namespace Cysharp.Threading.Tasks.Linq Error.ThrowArgumentNullException(source, nameof(source)); Error.ThrowArgumentNullException(predicate, nameof(predicate)); - return Count.InvokeAsync(source, cancellationToken); + return Count.InvokeAsync(source, predicate, cancellationToken); } public static UniTask CountAwaitAsync(this IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken = default) @@ -26,7 +26,7 @@ namespace Cysharp.Threading.Tasks.Linq Error.ThrowArgumentNullException(source, nameof(source)); Error.ThrowArgumentNullException(predicate, nameof(predicate)); - return Count.InvokeAsync(source, cancellationToken); + return Count.InvokeAsync(source, predicate, cancellationToken); } public static UniTask CountAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken = default) @@ -34,7 +34,7 @@ namespace Cysharp.Threading.Tasks.Linq Error.ThrowArgumentNullException(source, nameof(source)); Error.ThrowArgumentNullException(predicate, nameof(predicate)); - return Count.InvokeAsync(source, cancellationToken); + return Count.InvokeAsync(source, predicate, cancellationToken); } } diff --git a/src/UniTask.NetCore/Linq/LongCount.cs b/src/UniTask.NetCore/Linq/LongCount.cs index 9abb9a2..13b8c0f 100644 --- a/src/UniTask.NetCore/Linq/LongCount.cs +++ b/src/UniTask.NetCore/Linq/LongCount.cs @@ -1,775 +1,144 @@ -namespace Cysharp.Threading.Tasks.Linq +using Cysharp.Threading.Tasks.Internal; +using System; +using System.Threading; + +namespace Cysharp.Threading.Tasks.Linq { - internal sealed class LongCount + public static partial class UniTaskAsyncEnumerable { + public static UniTask LongCountAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return LongCount.InvokeAsync(source, cancellationToken); + } + + public static UniTask LongCountAsync(this IUniTaskAsyncEnumerable source, Func predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return LongCount.InvokeAsync(source, predicate, cancellationToken); + } + + public static UniTask LongCountAwaitAsync(this IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return LongCount.InvokeAsync(source, predicate, cancellationToken); + } + + public static UniTask LongCountAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(predicate, nameof(predicate)); + + return LongCount.InvokeAsync(source, predicate, cancellationToken); + } } - -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + internal static class LongCount + { + internal static async UniTask InvokeAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + long count = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + checked { count++; } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return count; + } + + internal static async UniTask InvokeAsync(IUniTaskAsyncEnumerable source, Func predicate, CancellationToken cancellationToken) + { + long count = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + if (predicate(e.Current)) + { + checked { count++; } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return count; + } + + internal static async UniTask InvokeAsync(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken) + { + long count = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + if (await predicate(e.Current)) + { + checked { count++; } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return count; + } + + internal static async UniTask InvokeAsync(IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken) + { + long count = 0; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + if (await predicate(e.Current, cancellationToken)) + { + checked { count++; } + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return count; + } + } +} \ No newline at end of file diff --git a/src/UniTask.NetCore/Linq/_FileMaker.cs b/src/UniTask.NetCore/Linq/_FileMaker.cs index a432008..7f5d3ea 100644 --- a/src/UniTask.NetCore/Linq/_FileMaker.cs +++ b/src/UniTask.NetCore/Linq/_FileMaker.cs @@ -152,15 +152,6 @@ namespace ___Dummy throw new NotImplementedException(); } - public static UniTask ElementAtAsync(this IUniTaskAsyncEnumerable source, Int32 index, CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } - - public static UniTask ElementAtOrDefaultAsync(this IUniTaskAsyncEnumerable source, Int32 index, CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } public static IUniTaskAsyncEnumerable Except(this IUniTaskAsyncEnumerable first, IUniTaskAsyncEnumerable second) { @@ -366,25 +357,6 @@ namespace ___Dummy } - public static UniTask LongCountAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } - - public static UniTask LongCountAsync(this IUniTaskAsyncEnumerable source, Func predicate, CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } - - public static UniTask LongCountAwaitAsync(this IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } - - public static UniTask LongCountAwaitWithCancellationAsync(this IUniTaskAsyncEnumerable source, Func> predicate, CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } public static IUniTaskAsyncEnumerable OfType(this IUniTaskAsyncEnumerable source) diff --git a/src/UniTask.NetCoreTests/Linq/Aggregate.cs b/src/UniTask.NetCoreTests/Linq/Aggregate.cs index 53fafb5..146bc1a 100644 --- a/src/UniTask.NetCoreTests/Linq/Aggregate.cs +++ b/src/UniTask.NetCoreTests/Linq/Aggregate.cs @@ -345,5 +345,37 @@ namespace NetCoreTests.Linq return Comparer.Default.Compare(Value, other.Value); } } + + + [Theory] + [InlineData(0, 10)] + [InlineData(0, 1)] + [InlineData(10, 0)] + [InlineData(1, 11)] + public async Task Count(int start, int count) + { + { + var xs = await UniTaskAsyncEnumerable.Range(start, count).CountAsync(); + var ys = Enumerable.Range(start, count).Count(); + xs.Should().Be(ys); + } + + { + var xs = await UniTaskAsyncEnumerable.Range(start, count).CountAsync(x => x % 2 == 0); + var ys = Enumerable.Range(start, count).Count(x => x % 2 == 0); + xs.Should().Be(ys); + } + { + var xs = await UniTaskAsyncEnumerable.Range(start, count).LongCountAsync(); + var ys = Enumerable.Range(start, count).LongCount(); + xs.Should().Be(ys); + } + + { + var xs = await UniTaskAsyncEnumerable.Range(start, count).LongCountAsync(x => x % 2 == 0); + var ys = Enumerable.Range(start, count).LongCount(x => x % 2 == 0); + xs.Should().Be(ys); + } + } } }