generics MinMax and tests

pull/73/head
neuecc 2020-05-09 22:06:51 +09:00
parent d4511c0f67
commit dd6a8da96f
6 changed files with 711 additions and 1635 deletions

View File

@ -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<TSource> MaxAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, CancellationToken cancellationToken = default)
{
Error.ThrowArgumentNullException(source, nameof(source));
return Max.InvokeAsync(source, cancellationToken);
} }
public static UniTask<TResult> MaxAsync<TSource, TResult>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TResult> selector, CancellationToken cancellationToken = default)
{
Error.ThrowArgumentNullException(source, nameof(source));
Error.ThrowArgumentNullException(source, nameof(selector));
return Max.InvokeAsync(source, selector, cancellationToken);
}
public static UniTask<TResult> MaxAwaitAsync<TSource, TResult>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TResult>> selector, CancellationToken cancellationToken = default)
{
Error.ThrowArgumentNullException(source, nameof(source));
Error.ThrowArgumentNullException(source, nameof(selector));
return Max.InvokeAsync(source, selector, cancellationToken);
}
public static UniTask<TResult> MaxAwaitCancellationAsync<TSource, TResult>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TResult>> 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<TSource> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, CancellationToken cancellationToken)
{
TSource value = default;
var comparer = Comparer<TSource>.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<TResult> InvokeAsync<TSource, TResult>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TResult> selector, CancellationToken cancellationToken)
{
TResult value = default;
var comparer = Comparer<TResult>.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<TResult> InvokeAsync<TSource, TResult>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TResult>> selector, CancellationToken cancellationToken)
{
TResult value = default;
var comparer = Comparer<TResult>.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<TResult> InvokeAsync<TSource, TResult>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TResult>> selector, CancellationToken cancellationToken)
{
TResult value = default;
var comparer = Comparer<TResult>.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;
}
}
} }

View File

@ -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<TSource> MinAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, CancellationToken cancellationToken = default)
{
Error.ThrowArgumentNullException(source, nameof(source));
return Min.InvokeAsync(source, cancellationToken);
} }
public static UniTask<TResult> MinAsync<TSource, TResult>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TResult> selector, CancellationToken cancellationToken = default)
{
Error.ThrowArgumentNullException(source, nameof(source));
Error.ThrowArgumentNullException(source, nameof(selector));
return Min.InvokeAsync(source, selector, cancellationToken);
}
public static UniTask<TResult> MinAwaitAsync<TSource, TResult>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TResult>> selector, CancellationToken cancellationToken = default)
{
Error.ThrowArgumentNullException(source, nameof(source));
Error.ThrowArgumentNullException(source, nameof(selector));
return Min.InvokeAsync(source, selector, cancellationToken);
}
public static UniTask<TResult> MinAwaitCancellationAsync<TSource, TResult>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TResult>> 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<TSource> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, CancellationToken cancellationToken)
{
TSource value = default;
var comparer = Comparer<TSource>.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<TResult> InvokeAsync<TSource, TResult>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, TResult> selector, CancellationToken cancellationToken)
{
TResult value = default;
var comparer = Comparer<TResult>.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<TResult> InvokeAsync<TSource, TResult>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<TResult>> selector, CancellationToken cancellationToken)
{
TResult value = default;
var comparer = Comparer<TResult>.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<TResult> InvokeAsync<TSource, TResult>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<TResult>> selector, CancellationToken cancellationToken)
{
TResult value = default;
var comparer = Comparer<TResult>.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;
}
}
} }

View File

@ -341,7 +341,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = e.Current; var x = e.Current;
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -379,7 +379,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = selector(e.Current); var x = selector(e.Current);
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -417,7 +417,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = await selector(e.Current); var x = await selector(e.Current);
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -455,7 +455,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = await selector(e.Current, cancellationToken); var x = await selector(e.Current, cancellationToken);
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -493,7 +493,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = e.Current; var x = e.Current;
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -531,7 +531,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = selector(e.Current); var x = selector(e.Current);
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -569,7 +569,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = await selector(e.Current); var x = await selector(e.Current);
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -607,7 +607,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = await selector(e.Current, cancellationToken); var x = await selector(e.Current, cancellationToken);
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -645,7 +645,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = e.Current; var x = e.Current;
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -683,7 +683,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = selector(e.Current); var x = selector(e.Current);
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -721,7 +721,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = await selector(e.Current); var x = await selector(e.Current);
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -759,7 +759,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = await selector(e.Current, cancellationToken); var x = await selector(e.Current, cancellationToken);
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -797,7 +797,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = e.Current; var x = e.Current;
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -835,7 +835,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = selector(e.Current); var x = selector(e.Current);
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -873,7 +873,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = await selector(e.Current); var x = await selector(e.Current);
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -911,7 +911,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = await selector(e.Current, cancellationToken); var x = await selector(e.Current, cancellationToken);
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -949,7 +949,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = e.Current; var x = e.Current;
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -987,7 +987,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = selector(e.Current); var x = selector(e.Current);
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -1025,7 +1025,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = await selector(e.Current); var x = await selector(e.Current);
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -1063,7 +1063,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = await selector(e.Current, cancellationToken); var x = await selector(e.Current, cancellationToken);
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -1103,7 +1103,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = e.Current; var x = e.Current;
if( x == null) continue; if( x == null) continue;
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -1143,7 +1143,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = selector(e.Current); var x = selector(e.Current);
if( x == null) continue; if( x == null) continue;
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -1183,7 +1183,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = await selector(e.Current); var x = await selector(e.Current);
if( x == null) continue; if( x == null) continue;
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -1223,7 +1223,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = await selector(e.Current, cancellationToken); var x = await selector(e.Current, cancellationToken);
if( x == null) continue; if( x == null) continue;
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -1263,7 +1263,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = e.Current; var x = e.Current;
if( x == null) continue; if( x == null) continue;
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -1303,7 +1303,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = selector(e.Current); var x = selector(e.Current);
if( x == null) continue; if( x == null) continue;
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -1343,7 +1343,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = await selector(e.Current); var x = await selector(e.Current);
if( x == null) continue; if( x == null) continue;
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -1383,7 +1383,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = await selector(e.Current, cancellationToken); var x = await selector(e.Current, cancellationToken);
if( x == null) continue; if( x == null) continue;
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -1423,7 +1423,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = e.Current; var x = e.Current;
if( x == null) continue; if( x == null) continue;
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -1463,7 +1463,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = selector(e.Current); var x = selector(e.Current);
if( x == null) continue; if( x == null) continue;
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -1503,7 +1503,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = await selector(e.Current); var x = await selector(e.Current);
if( x == null) continue; if( x == null) continue;
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -1543,7 +1543,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = await selector(e.Current, cancellationToken); var x = await selector(e.Current, cancellationToken);
if( x == null) continue; if( x == null) continue;
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -1583,7 +1583,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = e.Current; var x = e.Current;
if( x == null) continue; if( x == null) continue;
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -1623,7 +1623,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = selector(e.Current); var x = selector(e.Current);
if( x == null) continue; if( x == null) continue;
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -1663,7 +1663,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = await selector(e.Current); var x = await selector(e.Current);
if( x == null) continue; if( x == null) continue;
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -1703,7 +1703,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = await selector(e.Current, cancellationToken); var x = await selector(e.Current, cancellationToken);
if( x == null) continue; if( x == null) continue;
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -1743,7 +1743,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = e.Current; var x = e.Current;
if( x == null) continue; if( x == null) continue;
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -1783,7 +1783,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = selector(e.Current); var x = selector(e.Current);
if( x == null) continue; if( x == null) continue;
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -1823,7 +1823,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = await selector(e.Current); var x = await selector(e.Current);
if( x == null) continue; if( x == null) continue;
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -1863,7 +1863,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = await selector(e.Current, cancellationToken); var x = await selector(e.Current, cancellationToken);
if( x == null) continue; if( x == null) continue;
if (value < x) if (value > x)
{ {
value = x; value = x;
} }
@ -1880,6 +1880,10 @@ namespace Cysharp.Threading.Tasks.Linq
return value; return value;
} }
}
public static partial class UniTaskAsyncEnumerable
{
public static UniTask<Int32> MaxAsync(this IUniTaskAsyncEnumerable<Int32> source, CancellationToken cancellationToken = default) public static UniTask<Int32> MaxAsync(this IUniTaskAsyncEnumerable<Int32> source, CancellationToken cancellationToken = default)
{ {
Error.ThrowArgumentNullException(source, nameof(source)); Error.ThrowArgumentNullException(source, nameof(source));
@ -2215,7 +2219,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = e.Current; var x = e.Current;
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -2253,7 +2257,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = selector(e.Current); var x = selector(e.Current);
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -2291,7 +2295,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = await selector(e.Current); var x = await selector(e.Current);
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -2329,7 +2333,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = await selector(e.Current, cancellationToken); var x = await selector(e.Current, cancellationToken);
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -2367,7 +2371,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = e.Current; var x = e.Current;
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -2405,7 +2409,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = selector(e.Current); var x = selector(e.Current);
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -2443,7 +2447,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = await selector(e.Current); var x = await selector(e.Current);
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -2481,7 +2485,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = await selector(e.Current, cancellationToken); var x = await selector(e.Current, cancellationToken);
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -2519,7 +2523,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = e.Current; var x = e.Current;
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -2557,7 +2561,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = selector(e.Current); var x = selector(e.Current);
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -2595,7 +2599,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = await selector(e.Current); var x = await selector(e.Current);
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -2633,7 +2637,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = await selector(e.Current, cancellationToken); var x = await selector(e.Current, cancellationToken);
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -2671,7 +2675,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = e.Current; var x = e.Current;
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -2709,7 +2713,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = selector(e.Current); var x = selector(e.Current);
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -2747,7 +2751,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = await selector(e.Current); var x = await selector(e.Current);
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -2785,7 +2789,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = await selector(e.Current, cancellationToken); var x = await selector(e.Current, cancellationToken);
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -2823,7 +2827,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = e.Current; var x = e.Current;
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -2861,7 +2865,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = selector(e.Current); var x = selector(e.Current);
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -2899,7 +2903,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = await selector(e.Current); var x = await selector(e.Current);
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -2937,7 +2941,7 @@ namespace Cysharp.Threading.Tasks.Linq
while (await e.MoveNextAsync()) while (await e.MoveNextAsync())
{ {
var x = await selector(e.Current, cancellationToken); var x = await selector(e.Current, cancellationToken);
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -2977,7 +2981,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = e.Current; var x = e.Current;
if( x == null) continue; if( x == null) continue;
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -3017,7 +3021,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = selector(e.Current); var x = selector(e.Current);
if( x == null) continue; if( x == null) continue;
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -3057,7 +3061,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = await selector(e.Current); var x = await selector(e.Current);
if( x == null) continue; if( x == null) continue;
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -3097,7 +3101,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = await selector(e.Current, cancellationToken); var x = await selector(e.Current, cancellationToken);
if( x == null) continue; if( x == null) continue;
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -3137,7 +3141,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = e.Current; var x = e.Current;
if( x == null) continue; if( x == null) continue;
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -3177,7 +3181,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = selector(e.Current); var x = selector(e.Current);
if( x == null) continue; if( x == null) continue;
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -3217,7 +3221,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = await selector(e.Current); var x = await selector(e.Current);
if( x == null) continue; if( x == null) continue;
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -3257,7 +3261,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = await selector(e.Current, cancellationToken); var x = await selector(e.Current, cancellationToken);
if( x == null) continue; if( x == null) continue;
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -3297,7 +3301,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = e.Current; var x = e.Current;
if( x == null) continue; if( x == null) continue;
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -3337,7 +3341,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = selector(e.Current); var x = selector(e.Current);
if( x == null) continue; if( x == null) continue;
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -3377,7 +3381,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = await selector(e.Current); var x = await selector(e.Current);
if( x == null) continue; if( x == null) continue;
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -3417,7 +3421,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = await selector(e.Current, cancellationToken); var x = await selector(e.Current, cancellationToken);
if( x == null) continue; if( x == null) continue;
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -3457,7 +3461,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = e.Current; var x = e.Current;
if( x == null) continue; if( x == null) continue;
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -3497,7 +3501,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = selector(e.Current); var x = selector(e.Current);
if( x == null) continue; if( x == null) continue;
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -3537,7 +3541,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = await selector(e.Current); var x = await selector(e.Current);
if( x == null) continue; if( x == null) continue;
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -3577,7 +3581,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = await selector(e.Current, cancellationToken); var x = await selector(e.Current, cancellationToken);
if( x == null) continue; if( x == null) continue;
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -3617,7 +3621,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = e.Current; var x = e.Current;
if( x == null) continue; if( x == null) continue;
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -3657,7 +3661,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = selector(e.Current); var x = selector(e.Current);
if( x == null) continue; if( x == null) continue;
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -3697,7 +3701,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = await selector(e.Current); var x = await selector(e.Current);
if( x == null) continue; if( x == null) continue;
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -3737,7 +3741,7 @@ namespace Cysharp.Threading.Tasks.Linq
{ {
var x = await selector(e.Current, cancellationToken); var x = await selector(e.Current, cancellationToken);
if( x == null) continue; if( x == null) continue;
if (value > x) if (value < x)
{ {
value = x; value = x;
} }
@ -3755,4 +3759,5 @@ namespace Cysharp.Threading.Tasks.Linq
} }
} }
} }

View File

@ -30,9 +30,9 @@ using Cysharp.Threading.Tasks.Internal;
namespace Cysharp.Threading.Tasks.Linq namespace Cysharp.Threading.Tasks.Linq
{ {
<# foreach(var (minMax, op) in new[]{("Min",">"), ("Max", "<")}) { #>
public static partial class UniTaskAsyncEnumerable public static partial class UniTaskAsyncEnumerable
{ {
<# foreach(var (minMax, op) in new[]{("Min","<"), ("Max", ">")}) { #>
<# foreach(var t in types) { #> <# foreach(var t in types) { #>
public static UniTask<<#= TypeName(t) #>> <#= minMax #>Async(this IUniTaskAsyncEnumerable<<#= TypeName(t) #>> source, CancellationToken cancellationToken = default) 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; return value;
} }
<# } #>
<# } #> <# } #>
} }
<# } #>
} }

View File

@ -34,18 +34,11 @@ namespace NetCoreSandbox
static async Task Main(string[] args) static async Task Main(string[] args)
{ {
var x = await new[] { 110, 50, 200 }.ToUniTaskAsyncEnumerable().MinAsync();
Console.WriteLine(x);
// new object[] { }.Min(
int? foo = null; // AsyncEnumerable.MinAwaitAsync(
if (foo > 100)
{
Console.WriteLine("Under Foo");
}
else
{
Console.WriteLine("??");
}
} }

View File

@ -3,6 +3,7 @@ using Cysharp.Threading.Tasks.Linq;
using FluentAssertions; using FluentAssertions;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Xunit; using Xunit;
@ -118,5 +119,231 @@ namespace NetCoreTests.Linq
break; break;
} }
} }
public static IEnumerable<object[]> 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>(T arr)
{
switch (arr)
{
case int[] array:
{
{
if (array.Length == 0)
{
await Assert.ThrowsAsync<InvalidOperationException>(async () => await array.ToUniTaskAsyncEnumerable().MinAsync());
Assert.Throws<InvalidOperationException>(() => array.Min());
}
else
{
var xs = await array.ToUniTaskAsyncEnumerable().MinAsync();
var ys = array.Min();
xs.Should().Be(ys);
}
}
{
if (array.Length == 0)
{
await Assert.ThrowsAsync<InvalidOperationException>(async () => await array.ToUniTaskAsyncEnumerable().MinAsync(x => x * 2));
Assert.Throws<InvalidOperationException>(() => 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<InvalidOperationException>(async () => await array.ToUniTaskAsyncEnumerable().MinAsync(x => x.Value));
Assert.Throws<InvalidOperationException>(() => 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>(T arr)
{
switch (arr)
{
case int[] array:
{
{
if (array.Length == 0)
{
await Assert.ThrowsAsync<InvalidOperationException>(async () => await array.ToUniTaskAsyncEnumerable().MaxAsync());
Assert.Throws<InvalidOperationException>(() => array.Max());
}
else
{
var xs = await array.ToUniTaskAsyncEnumerable().MaxAsync();
var ys = array.Max();
xs.Should().Be(ys);
}
}
{
if (array.Length == 0)
{
await Assert.ThrowsAsync<InvalidOperationException>(async () => await array.ToUniTaskAsyncEnumerable().MaxAsync(x => x * 2));
Assert.Throws<InvalidOperationException>(() => 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<InvalidOperationException>(async () => await array.ToUniTaskAsyncEnumerable().MaxAsync(x => x.Value));
Assert.Throws<InvalidOperationException>(() => 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<X>
{
public readonly int Value;
public X(int value)
{
Value = value;
}
public int CompareTo([AllowNull] X other)
{
return Comparer<int>.Default.Compare(Value, other.Value);
}
}
} }
} }