From dd6a8da96fde31439049dd954b38b58b09b53740 Mon Sep 17 00:00:00 2001 From: neuecc Date: Sat, 9 May 2020 22:06:51 +0900 Subject: [PATCH] generics MinMax and tests --- src/UniTask.NetCore/Linq/Max.cs | 967 +++++---------------- src/UniTask.NetCore/Linq/Min.cs | 967 +++++---------------- src/UniTask.NetCore/Linq/MinMax.cs | 165 ++-- src/UniTask.NetCore/Linq/MinMax.tt | 5 +- src/UniTask.NetCoreSandbox/Program.cs | 15 +- src/UniTask.NetCoreTests/Linq/Aggregate.cs | 227 +++++ 6 files changed, 711 insertions(+), 1635 deletions(-) diff --git a/src/UniTask.NetCore/Linq/Max.cs b/src/UniTask.NetCore/Linq/Max.cs index 08d8450..703226d 100644 --- a/src/UniTask.NetCore/Linq/Max.cs +++ b/src/UniTask.NetCore/Linq/Max.cs @@ -1,775 +1,200 @@ -namespace Cysharp.Threading.Tasks.Linq +using System; +using System.Collections.Generic; +using System.Threading; +using Cysharp.Threading.Tasks.Internal; + +namespace Cysharp.Threading.Tasks.Linq { - internal static partial class Max + public static partial class UniTaskAsyncEnumerable { + public static UniTask MaxAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Max.InvokeAsync(source, cancellationToken); + } + + public static UniTask MaxAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.InvokeAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.InvokeAsync(source, selector, cancellationToken); + } + + public static UniTask MaxAwaitCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Max.InvokeAsync(source, selector, cancellationToken); + } } - -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + internal static partial class Max + { + public static async UniTask InvokeAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + TSource value = default; + var comparer = Comparer.Default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = e.Current; + + goto NEXT_LOOP; + } + + return value; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = e.Current; + if (comparer.Compare(value, x) < 0) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask InvokeAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + TResult value = default; + var comparer = Comparer.Default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = selector(e.Current); + + goto NEXT_LOOP; + } + + return value; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = selector(e.Current); + if (comparer.Compare(value, x) < 0) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask InvokeAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + TResult value = default; + var comparer = Comparer.Default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current); + + goto NEXT_LOOP; + } + + return value; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current); + if (comparer.Compare(value, x) < 0) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask InvokeAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + TResult value = default; + var comparer = Comparer.Default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current, cancellationToken); + + goto NEXT_LOOP; + } + + return value; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current, cancellationToken); + if (comparer.Compare(value, x) < 0) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + } +} \ No newline at end of file diff --git a/src/UniTask.NetCore/Linq/Min.cs b/src/UniTask.NetCore/Linq/Min.cs index e57270b..c54aaf9 100644 --- a/src/UniTask.NetCore/Linq/Min.cs +++ b/src/UniTask.NetCore/Linq/Min.cs @@ -1,775 +1,200 @@ -namespace Cysharp.Threading.Tasks.Linq +using System; +using System.Collections.Generic; +using System.Threading; +using Cysharp.Threading.Tasks.Internal; + +namespace Cysharp.Threading.Tasks.Linq { - internal static partial class Min + public static partial class UniTaskAsyncEnumerable { + public static UniTask MinAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + + return Min.InvokeAsync(source, cancellationToken); + } + + public static UniTask MinAsync(this IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.InvokeAsync(source, selector, cancellationToken); + } + + public static UniTask MinAwaitAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.InvokeAsync(source, selector, cancellationToken); + } + + public static UniTask MinAwaitCancellationAsync(this IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken = default) + { + Error.ThrowArgumentNullException(source, nameof(source)); + Error.ThrowArgumentNullException(source, nameof(selector)); + + return Min.InvokeAsync(source, selector, cancellationToken); + } } - -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + internal static partial class Min + { + public static async UniTask InvokeAsync(IUniTaskAsyncEnumerable source, CancellationToken cancellationToken) + { + TSource value = default; + var comparer = Comparer.Default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = e.Current; + + goto NEXT_LOOP; + } + + return value; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = e.Current; + if (comparer.Compare(value, x) > 0) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask InvokeAsync(IUniTaskAsyncEnumerable source, Func selector, CancellationToken cancellationToken) + { + TResult value = default; + var comparer = Comparer.Default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = selector(e.Current); + + goto NEXT_LOOP; + } + + return value; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = selector(e.Current); + if (comparer.Compare(value, x) > 0) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask InvokeAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + TResult value = default; + var comparer = Comparer.Default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current); + + goto NEXT_LOOP; + } + + return value; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current); + if (comparer.Compare(value, x) > 0) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + + public static async UniTask InvokeAsync(IUniTaskAsyncEnumerable source, Func> selector, CancellationToken cancellationToken) + { + TResult value = default; + var comparer = Comparer.Default; + + var e = source.GetAsyncEnumerator(cancellationToken); + try + { + while (await e.MoveNextAsync()) + { + value = await selector(e.Current, cancellationToken); + + goto NEXT_LOOP; + } + + return value; + + NEXT_LOOP: + + while (await e.MoveNextAsync()) + { + var x = await selector(e.Current, cancellationToken); + if (comparer.Compare(value, x) > 0) + { + value = x; + } + } + } + finally + { + if (e != null) + { + await e.DisposeAsync(); + } + } + + return value; + } + } +} \ No newline at end of file diff --git a/src/UniTask.NetCore/Linq/MinMax.cs b/src/UniTask.NetCore/Linq/MinMax.cs index d0c8102..61f4c7f 100644 --- a/src/UniTask.NetCore/Linq/MinMax.cs +++ b/src/UniTask.NetCore/Linq/MinMax.cs @@ -341,7 +341,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = e.Current; - if (value < x) + if (value > x) { value = x; } @@ -379,7 +379,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = selector(e.Current); - if (value < x) + if (value > x) { value = x; } @@ -417,7 +417,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = await selector(e.Current); - if (value < x) + if (value > x) { value = x; } @@ -455,7 +455,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = await selector(e.Current, cancellationToken); - if (value < x) + if (value > x) { value = x; } @@ -493,7 +493,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = e.Current; - if (value < x) + if (value > x) { value = x; } @@ -531,7 +531,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = selector(e.Current); - if (value < x) + if (value > x) { value = x; } @@ -569,7 +569,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = await selector(e.Current); - if (value < x) + if (value > x) { value = x; } @@ -607,7 +607,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = await selector(e.Current, cancellationToken); - if (value < x) + if (value > x) { value = x; } @@ -645,7 +645,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = e.Current; - if (value < x) + if (value > x) { value = x; } @@ -683,7 +683,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = selector(e.Current); - if (value < x) + if (value > x) { value = x; } @@ -721,7 +721,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = await selector(e.Current); - if (value < x) + if (value > x) { value = x; } @@ -759,7 +759,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = await selector(e.Current, cancellationToken); - if (value < x) + if (value > x) { value = x; } @@ -797,7 +797,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = e.Current; - if (value < x) + if (value > x) { value = x; } @@ -835,7 +835,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = selector(e.Current); - if (value < x) + if (value > x) { value = x; } @@ -873,7 +873,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = await selector(e.Current); - if (value < x) + if (value > x) { value = x; } @@ -911,7 +911,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = await selector(e.Current, cancellationToken); - if (value < x) + if (value > x) { value = x; } @@ -949,7 +949,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = e.Current; - if (value < x) + if (value > x) { value = x; } @@ -987,7 +987,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = selector(e.Current); - if (value < x) + if (value > x) { value = x; } @@ -1025,7 +1025,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = await selector(e.Current); - if (value < x) + if (value > x) { value = x; } @@ -1063,7 +1063,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = await selector(e.Current, cancellationToken); - if (value < x) + if (value > x) { value = x; } @@ -1103,7 +1103,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = e.Current; if( x == null) continue; - if (value < x) + if (value > x) { value = x; } @@ -1143,7 +1143,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = selector(e.Current); if( x == null) continue; - if (value < x) + if (value > x) { value = x; } @@ -1183,7 +1183,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = await selector(e.Current); if( x == null) continue; - if (value < x) + if (value > x) { value = x; } @@ -1223,7 +1223,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = await selector(e.Current, cancellationToken); if( x == null) continue; - if (value < x) + if (value > x) { value = x; } @@ -1263,7 +1263,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = e.Current; if( x == null) continue; - if (value < x) + if (value > x) { value = x; } @@ -1303,7 +1303,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = selector(e.Current); if( x == null) continue; - if (value < x) + if (value > x) { value = x; } @@ -1343,7 +1343,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = await selector(e.Current); if( x == null) continue; - if (value < x) + if (value > x) { value = x; } @@ -1383,7 +1383,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = await selector(e.Current, cancellationToken); if( x == null) continue; - if (value < x) + if (value > x) { value = x; } @@ -1423,7 +1423,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = e.Current; if( x == null) continue; - if (value < x) + if (value > x) { value = x; } @@ -1463,7 +1463,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = selector(e.Current); if( x == null) continue; - if (value < x) + if (value > x) { value = x; } @@ -1503,7 +1503,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = await selector(e.Current); if( x == null) continue; - if (value < x) + if (value > x) { value = x; } @@ -1543,7 +1543,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = await selector(e.Current, cancellationToken); if( x == null) continue; - if (value < x) + if (value > x) { value = x; } @@ -1583,7 +1583,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = e.Current; if( x == null) continue; - if (value < x) + if (value > x) { value = x; } @@ -1623,7 +1623,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = selector(e.Current); if( x == null) continue; - if (value < x) + if (value > x) { value = x; } @@ -1663,7 +1663,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = await selector(e.Current); if( x == null) continue; - if (value < x) + if (value > x) { value = x; } @@ -1703,7 +1703,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = await selector(e.Current, cancellationToken); if( x == null) continue; - if (value < x) + if (value > x) { value = x; } @@ -1743,7 +1743,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = e.Current; if( x == null) continue; - if (value < x) + if (value > x) { value = x; } @@ -1783,7 +1783,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = selector(e.Current); if( x == null) continue; - if (value < x) + if (value > x) { value = x; } @@ -1823,7 +1823,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = await selector(e.Current); if( x == null) continue; - if (value < x) + if (value > x) { value = x; } @@ -1863,7 +1863,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = await selector(e.Current, cancellationToken); if( x == null) continue; - if (value < x) + if (value > x) { value = x; } @@ -1880,6 +1880,10 @@ namespace Cysharp.Threading.Tasks.Linq return value; } + } + + public static partial class UniTaskAsyncEnumerable + { public static UniTask MaxAsync(this IUniTaskAsyncEnumerable source, CancellationToken cancellationToken = default) { Error.ThrowArgumentNullException(source, nameof(source)); @@ -2215,7 +2219,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = e.Current; - if (value > x) + if (value < x) { value = x; } @@ -2253,7 +2257,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = selector(e.Current); - if (value > x) + if (value < x) { value = x; } @@ -2291,7 +2295,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = await selector(e.Current); - if (value > x) + if (value < x) { value = x; } @@ -2329,7 +2333,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = await selector(e.Current, cancellationToken); - if (value > x) + if (value < x) { value = x; } @@ -2367,7 +2371,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = e.Current; - if (value > x) + if (value < x) { value = x; } @@ -2405,7 +2409,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = selector(e.Current); - if (value > x) + if (value < x) { value = x; } @@ -2443,7 +2447,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = await selector(e.Current); - if (value > x) + if (value < x) { value = x; } @@ -2481,7 +2485,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = await selector(e.Current, cancellationToken); - if (value > x) + if (value < x) { value = x; } @@ -2519,7 +2523,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = e.Current; - if (value > x) + if (value < x) { value = x; } @@ -2557,7 +2561,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = selector(e.Current); - if (value > x) + if (value < x) { value = x; } @@ -2595,7 +2599,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = await selector(e.Current); - if (value > x) + if (value < x) { value = x; } @@ -2633,7 +2637,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = await selector(e.Current, cancellationToken); - if (value > x) + if (value < x) { value = x; } @@ -2671,7 +2675,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = e.Current; - if (value > x) + if (value < x) { value = x; } @@ -2709,7 +2713,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = selector(e.Current); - if (value > x) + if (value < x) { value = x; } @@ -2747,7 +2751,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = await selector(e.Current); - if (value > x) + if (value < x) { value = x; } @@ -2785,7 +2789,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = await selector(e.Current, cancellationToken); - if (value > x) + if (value < x) { value = x; } @@ -2823,7 +2827,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = e.Current; - if (value > x) + if (value < x) { value = x; } @@ -2861,7 +2865,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = selector(e.Current); - if (value > x) + if (value < x) { value = x; } @@ -2899,7 +2903,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = await selector(e.Current); - if (value > x) + if (value < x) { value = x; } @@ -2937,7 +2941,7 @@ namespace Cysharp.Threading.Tasks.Linq while (await e.MoveNextAsync()) { var x = await selector(e.Current, cancellationToken); - if (value > x) + if (value < x) { value = x; } @@ -2977,7 +2981,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = e.Current; if( x == null) continue; - if (value > x) + if (value < x) { value = x; } @@ -3017,7 +3021,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = selector(e.Current); if( x == null) continue; - if (value > x) + if (value < x) { value = x; } @@ -3057,7 +3061,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = await selector(e.Current); if( x == null) continue; - if (value > x) + if (value < x) { value = x; } @@ -3097,7 +3101,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = await selector(e.Current, cancellationToken); if( x == null) continue; - if (value > x) + if (value < x) { value = x; } @@ -3137,7 +3141,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = e.Current; if( x == null) continue; - if (value > x) + if (value < x) { value = x; } @@ -3177,7 +3181,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = selector(e.Current); if( x == null) continue; - if (value > x) + if (value < x) { value = x; } @@ -3217,7 +3221,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = await selector(e.Current); if( x == null) continue; - if (value > x) + if (value < x) { value = x; } @@ -3257,7 +3261,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = await selector(e.Current, cancellationToken); if( x == null) continue; - if (value > x) + if (value < x) { value = x; } @@ -3297,7 +3301,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = e.Current; if( x == null) continue; - if (value > x) + if (value < x) { value = x; } @@ -3337,7 +3341,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = selector(e.Current); if( x == null) continue; - if (value > x) + if (value < x) { value = x; } @@ -3377,7 +3381,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = await selector(e.Current); if( x == null) continue; - if (value > x) + if (value < x) { value = x; } @@ -3417,7 +3421,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = await selector(e.Current, cancellationToken); if( x == null) continue; - if (value > x) + if (value < x) { value = x; } @@ -3457,7 +3461,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = e.Current; if( x == null) continue; - if (value > x) + if (value < x) { value = x; } @@ -3497,7 +3501,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = selector(e.Current); if( x == null) continue; - if (value > x) + if (value < x) { value = x; } @@ -3537,7 +3541,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = await selector(e.Current); if( x == null) continue; - if (value > x) + if (value < x) { value = x; } @@ -3577,7 +3581,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = await selector(e.Current, cancellationToken); if( x == null) continue; - if (value > x) + if (value < x) { value = x; } @@ -3617,7 +3621,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = e.Current; if( x == null) continue; - if (value > x) + if (value < x) { value = x; } @@ -3657,7 +3661,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = selector(e.Current); if( x == null) continue; - if (value > x) + if (value < x) { value = x; } @@ -3697,7 +3701,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = await selector(e.Current); if( x == null) continue; - if (value > x) + if (value < x) { value = x; } @@ -3737,7 +3741,7 @@ namespace Cysharp.Threading.Tasks.Linq { var x = await selector(e.Current, cancellationToken); if( x == null) continue; - if (value > x) + if (value < x) { value = x; } @@ -3755,4 +3759,5 @@ namespace Cysharp.Threading.Tasks.Linq } } + } diff --git a/src/UniTask.NetCore/Linq/MinMax.tt b/src/UniTask.NetCore/Linq/MinMax.tt index c79ad3e..ef4f0f8 100644 --- a/src/UniTask.NetCore/Linq/MinMax.tt +++ b/src/UniTask.NetCore/Linq/MinMax.tt @@ -30,9 +30,9 @@ using Cysharp.Threading.Tasks.Internal; namespace Cysharp.Threading.Tasks.Linq { +<# foreach(var (minMax, op) in new[]{("Min",">"), ("Max", "<")}) { #> public static partial class UniTaskAsyncEnumerable { -<# foreach(var (minMax, op) in new[]{("Min","<"), ("Max", ">")}) { #> <# foreach(var t in types) { #> public static UniTask<<#= TypeName(t) #>> <#= minMax #>Async(this IUniTaskAsyncEnumerable<<#= TypeName(t) #>> source, CancellationToken cancellationToken = default) { @@ -255,7 +255,8 @@ namespace Cysharp.Threading.Tasks.Linq return value; } -<# } #> <# } #> } + +<# } #> } diff --git a/src/UniTask.NetCoreSandbox/Program.cs b/src/UniTask.NetCoreSandbox/Program.cs index ca07a99..fe5fb5f 100644 --- a/src/UniTask.NetCoreSandbox/Program.cs +++ b/src/UniTask.NetCoreSandbox/Program.cs @@ -34,18 +34,11 @@ namespace NetCoreSandbox static async Task Main(string[] args) { + var x = await new[] { 110, 50, 200 }.ToUniTaskAsyncEnumerable().MinAsync(); + Console.WriteLine(x); + // new object[] { }.Min( - int? foo = null; - - - if (foo > 100) - { - Console.WriteLine("Under Foo"); - } - else - { - Console.WriteLine("??"); - } + // AsyncEnumerable.MinAwaitAsync( } diff --git a/src/UniTask.NetCoreTests/Linq/Aggregate.cs b/src/UniTask.NetCoreTests/Linq/Aggregate.cs index 0962b2f..53fafb5 100644 --- a/src/UniTask.NetCoreTests/Linq/Aggregate.cs +++ b/src/UniTask.NetCoreTests/Linq/Aggregate.cs @@ -3,6 +3,7 @@ using Cysharp.Threading.Tasks.Linq; using FluentAssertions; using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading.Tasks; using Xunit; @@ -118,5 +119,231 @@ namespace NetCoreTests.Linq break; } } + + + public static IEnumerable array2 = new object[][] + { + new object[]{new int[] { } }, + new object[]{new int[] { 5 } }, + new object[]{new int[] { 5, 10, 100 } }, + new object[]{new int[] { 10, 5,100 } }, + new object[]{new int[] { 100, 10, 5 } }, + + new object[]{new int?[] { } }, + new object[]{new int?[] { 5 } }, + new object[]{new int?[] { null, null, null } }, + new object[]{new int?[] { null, 5, 10, 100 } }, + new object[]{new int?[] { 10, 5,100, null } }, + new object[]{new int?[] { 100, 10, 5 } }, + + new object[]{new X[] { } }, + new object[]{new X[] { new X(5) } }, + new object[]{new X[] { new X(5), new X(10), new X(100) } }, + new object[]{new X[] { new X(10),new X( 5),new X(100) } }, + new object[]{new X[] { new X(100), new X(10),new X(5) } }, + + new object[]{new XX[] { } }, + new object[]{new XX[] { new XX(new X(5)) } }, + new object[]{new XX[] { new XX(new X(5)), new XX(new X(10)), new XX(new X(100)) } }, + new object[]{new XX[] { new XX(new X(10)),new XX(new X( 5)),new XX(new X(100)) } }, + new object[]{new XX[] { new XX(new X(100)), new XX(new X(10)),new XX(new X(5)) } }, + }; + + [Theory] + [MemberData(nameof(array2))] + public async Task Min(T arr) + { + switch (arr) + { + case int[] array: + { + { + if (array.Length == 0) + { + await Assert.ThrowsAsync(async () => await array.ToUniTaskAsyncEnumerable().MinAsync()); + Assert.Throws(() => array.Min()); + } + else + { + var xs = await array.ToUniTaskAsyncEnumerable().MinAsync(); + var ys = array.Min(); + xs.Should().Be(ys); + } + } + { + if (array.Length == 0) + { + await Assert.ThrowsAsync(async () => await array.ToUniTaskAsyncEnumerable().MinAsync(x => x * 2)); + Assert.Throws(() => array.Min(x => x * 2)); + } + else + { + var xs = await array.ToUniTaskAsyncEnumerable().MinAsync(x => x * 2); + var ys = array.Min(x => x * 2); + xs.Should().Be(ys); + } + } + } + break; + case int?[] array: + { + { + var xs = await array.ToUniTaskAsyncEnumerable().MinAsync(); + var ys = array.Min(); + xs.Should().Be(ys); + } + { + var xs = await array.ToUniTaskAsyncEnumerable().MinAsync(x => x); + var ys = array.Min(x => x); + xs.Should().Be(ys); + } + } + break; + case X[] array: + { + { + var xs = await array.ToUniTaskAsyncEnumerable().MinAsync(); + var ys = array.Min(); + xs.Should().Be(ys); + } + { + + if (array.Length == 0) + { + await Assert.ThrowsAsync(async () => await array.ToUniTaskAsyncEnumerable().MinAsync(x => x.Value)); + Assert.Throws(() => array.Min(x => x.Value)); + } + else + { + var xs = await array.ToUniTaskAsyncEnumerable().MinAsync(x => x.Value); + var ys = array.Min(x => x.Value); + xs.Should().Be(ys); + } + } + } + break; + case XX[] array: + { + var xs = await array.ToUniTaskAsyncEnumerable().MinAsync(x => x.Value); + var ys = array.Min(x => x.Value); + xs.Should().Be(ys); + } + break; + default: + break; + } + } + + + + [Theory] + [MemberData(nameof(array2))] + public async Task Max(T arr) + { + switch (arr) + { + case int[] array: + { + { + if (array.Length == 0) + { + await Assert.ThrowsAsync(async () => await array.ToUniTaskAsyncEnumerable().MaxAsync()); + Assert.Throws(() => array.Max()); + } + else + { + var xs = await array.ToUniTaskAsyncEnumerable().MaxAsync(); + var ys = array.Max(); + xs.Should().Be(ys); + } + } + { + if (array.Length == 0) + { + await Assert.ThrowsAsync(async () => await array.ToUniTaskAsyncEnumerable().MaxAsync(x => x * 2)); + Assert.Throws(() => array.Max(x => x * 2)); + } + else + { + var xs = await array.ToUniTaskAsyncEnumerable().MaxAsync(x => x * 2); + var ys = array.Max(x => x * 2); + xs.Should().Be(ys); + } + } + } + break; + case int?[] array: + { + { + var xs = await array.ToUniTaskAsyncEnumerable().MaxAsync(); + var ys = array.Max(); + xs.Should().Be(ys); + } + { + var xs = await array.ToUniTaskAsyncEnumerable().MaxAsync(x => x); + var ys = array.Max(x => x); + xs.Should().Be(ys); + } + } + break; + case X[] array: + { + { + var xs = await array.ToUniTaskAsyncEnumerable().MaxAsync(); + var ys = array.Max(); + xs.Should().Be(ys); + } + { + + if (array.Length == 0) + { + await Assert.ThrowsAsync(async () => await array.ToUniTaskAsyncEnumerable().MaxAsync(x => x.Value)); + Assert.Throws(() => array.Max(x => x.Value)); + } + else + { + var xs = await array.ToUniTaskAsyncEnumerable().MaxAsync(x => x.Value); + var ys = array.Max(x => x.Value); + xs.Should().Be(ys); + } + } + } + break; + case XX[] array: + { + var xs = await array.ToUniTaskAsyncEnumerable().MaxAsync(x => x.Value); + var ys = array.Max(x => x.Value); + xs.Should().Be(ys); + } + break; + default: + break; + } + } + + public class XX + { + public readonly X Value; + + public XX(X value) + { + this.Value = value; + } + } + + public class X : IComparable + { + public readonly int Value; + + public X(int value) + { + Value = value; + } + + public int CompareTo([AllowNull] X other) + { + return Comparer.Default.Compare(Value, other.Value); + } + } } }