generator and tests

This commit is contained in:
neuecc
2020-05-08 12:08:15 +09:00
parent 856a049dd0
commit ed0990e402
13 changed files with 1763 additions and 2586 deletions

View File

@@ -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 Count
public static partial class UniTaskAsyncEnumerable
{
public static UniTask<Int32> CountAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, CancellationToken cancellationToken = default)
{
Error.ThrowArgumentNullException(source, nameof(source));
return Count<TSource>.InvokeAsync(source, cancellationToken);
}
public static UniTask<Int32> CountAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Boolean> predicate, CancellationToken cancellationToken = default)
{
Error.ThrowArgumentNullException(source, nameof(source));
Error.ThrowArgumentNullException(predicate, nameof(predicate));
return Count<TSource>.InvokeAsync(source, cancellationToken);
}
public static UniTask<Int32> CountAwaitAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Boolean>> predicate, CancellationToken cancellationToken = default)
{
Error.ThrowArgumentNullException(source, nameof(source));
Error.ThrowArgumentNullException(predicate, nameof(predicate));
return Count<TSource>.InvokeAsync(source, cancellationToken);
}
public static UniTask<Int32> CountAwaitWithCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Boolean>> predicate, CancellationToken cancellationToken = default)
{
Error.ThrowArgumentNullException(source, nameof(source));
Error.ThrowArgumentNullException(predicate, nameof(predicate));
return Count<TSource>.InvokeAsync(source, cancellationToken);
}
}
}
internal static class Count<TSource>
{
internal static async UniTask<int> InvokeAsync(IUniTaskAsyncEnumerable<TSource> source, CancellationToken cancellationToken)
{
var 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<int> InvokeAsync(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Boolean> predicate, CancellationToken cancellationToken)
{
var 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<int> InvokeAsync(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Boolean>> predicate, CancellationToken cancellationToken)
{
var 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<int> InvokeAsync(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Boolean>> predicate, CancellationToken cancellationToken)
{
var 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;
}
}
}

View File

@@ -48,7 +48,7 @@ namespace Cysharp.Threading.Tasks.Linq
this.end = end;
this.cancellationToken = cancellationToken;
this.current = 0;
this.current = start - 1;
}
public int Current => current;

View File

@@ -5,39 +5,39 @@ namespace Cysharp.Threading.Tasks.Linq
{
public static partial class UniTaskAsyncEnumerable
{
public static IUniTaskAsyncEnumerable<TResult> Repeat<TResult>(TResult element, int count)
public static IUniTaskAsyncEnumerable<TElement> Repeat<TElement>(TElement element, int count)
{
if (count < 0) throw Error.ArgumentOutOfRange(nameof(count));
return new Repeat<TResult>(element, count);
return new Repeat<TElement>(element, count);
}
}
internal class Repeat<TResult> : IUniTaskAsyncEnumerable<TResult>
internal class Repeat<TElement> : IUniTaskAsyncEnumerable<TElement>
{
readonly TResult element;
readonly TElement element;
readonly int count;
public Repeat(TResult element, int count)
public Repeat(TElement element, int count)
{
this.element = element;
this.count = count;
}
public IUniTaskAsyncEnumerator<TResult> GetAsyncEnumerator(CancellationToken cancellationToken = default)
public IUniTaskAsyncEnumerator<TElement> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
return new Enumerator(element, count, cancellationToken);
}
class Enumerator : IUniTaskAsyncEnumerator<TResult>
class Enumerator : IUniTaskAsyncEnumerator<TElement>
{
readonly TResult element;
readonly TElement element;
readonly int count;
int remaining;
CancellationToken cancellationToken;
public Enumerator(TResult element, int count, CancellationToken cancellationToken)
public Enumerator(TElement element, int count, CancellationToken cancellationToken)
{
this.element = element;
this.count = count;
@@ -46,7 +46,7 @@ namespace Cysharp.Threading.Tasks.Linq
this.remaining = count;
}
public TResult Current => element;
public TElement Current => element;
public UniTask<bool> MoveNextAsync()
{

View File

@@ -0,0 +1,64 @@
using Cysharp.Threading.Tasks.Internal;
using System.Threading;
namespace Cysharp.Threading.Tasks.Linq
{
public static partial class UniTaskAsyncEnumerable
{
public static IUniTaskAsyncEnumerable<TValue> Return<TValue>(TValue value)
{
return new Return<TValue>(value);
}
}
internal class Return<TValue> : IUniTaskAsyncEnumerable<TValue>
{
readonly TValue value;
public Return(TValue value)
{
this.value = value;
}
public IUniTaskAsyncEnumerator<TValue> GetAsyncEnumerator(CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
return new Enumerator(value, cancellationToken);
}
class Enumerator : IUniTaskAsyncEnumerator<TValue>
{
readonly TValue value;
CancellationToken cancellationToken;
bool called;
public Enumerator(TValue value, CancellationToken cancellationToken)
{
this.value = value;
this.cancellationToken = cancellationToken;
this.called = false;
}
public TValue Current => value;
public UniTask<bool> MoveNextAsync()
{
cancellationToken.ThrowIfCancellationRequested();
if (!called)
{
called = true;
return CompletedTasks.True;
}
return CompletedTasks.False;
}
public UniTask DisposeAsync()
{
return default;
}
}
}
}

View File

@@ -1,6 +1,7 @@
namespace Cysharp.Threading.Tasks.Linq
{
internal sealed class Single
// avoid conflicts with System.Single
internal sealed class SingleOperator
{
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,167 @@
<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".cs" #>
<#
var types = new[]
{
typeof(int),
typeof(long),
typeof(float),
typeof(double),
typeof(decimal),
typeof(int?),
typeof(long?),
typeof(float?),
typeof(double?),
typeof(decimal?),
};
Func<Type, bool> IsNullable = x => x.IsGenericType;
Func<Type, string> TypeName = x => IsNullable(x) ? x.GetGenericArguments()[0].Name + "?" : x.Name;
Func<Type, string> WithSuffix = x => IsNullable(x) ? ".GetValueOrDefault()" : "";
#>
using System;
using System.Threading;
using Cysharp.Threading.Tasks.Internal;
namespace Cysharp.Threading.Tasks.Linq
{
public static partial class UniTaskAsyncEnumerable
{
<# foreach(var t in types) { #>
public static UniTask<<#= TypeName(t) #>> SumAsync(this IUniTaskAsyncEnumerable<<#= TypeName(t) #>> source, CancellationToken cancellationToken = default)
{
Error.ThrowArgumentNullException(source, nameof(source));
return Sum.InvokeAsync(source, cancellationToken);
}
public static UniTask<<#= TypeName(t) #>> SumAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, <#= TypeName(t) #>> selector, CancellationToken cancellationToken = default)
{
Error.ThrowArgumentNullException(source, nameof(source));
Error.ThrowArgumentNullException(source, nameof(selector));
return Sum.InvokeAsync(source, selector, cancellationToken);
}
public static UniTask<<#= TypeName(t) #>> SumAwaitAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<<#= TypeName(t) #>>> selector, CancellationToken cancellationToken = default)
{
Error.ThrowArgumentNullException(source, nameof(source));
Error.ThrowArgumentNullException(source, nameof(selector));
return Sum.InvokeAsync(source, selector, cancellationToken);
}
public static UniTask<<#= TypeName(t) #>> SumAwaitCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<<#= TypeName(t) #>>> selector, CancellationToken cancellationToken = default)
{
Error.ThrowArgumentNullException(source, nameof(source));
Error.ThrowArgumentNullException(source, nameof(selector));
return Sum.InvokeAsync(source, selector, cancellationToken);
}
<# } #>
}
internal static class Sum
{
<# foreach(var t in types) { #>
public static async UniTask<<#= TypeName(t) #>> InvokeAsync(IUniTaskAsyncEnumerable<<#= TypeName(t) #>> source, CancellationToken cancellationToken)
{
<#= TypeName(t) #> sum = default;
var e = source.GetAsyncEnumerator(cancellationToken);
try
{
while (await e.MoveNextAsync())
{
sum += e.Current<#= WithSuffix(t) #>;
}
}
finally
{
if (e != null)
{
await e.DisposeAsync();
}
}
return sum;
}
public static async UniTask<<#= TypeName(t) #>> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, <#= TypeName(t) #>> selector, CancellationToken cancellationToken)
{
<#= TypeName(t) #> sum = default;
var e = source.GetAsyncEnumerator(cancellationToken);
try
{
while (await e.MoveNextAsync())
{
sum += selector(e.Current)<#= WithSuffix(t) #>;
}
}
finally
{
if (e != null)
{
await e.DisposeAsync();
}
}
return sum;
}
public static async UniTask<<#= TypeName(t) #>> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<<#= TypeName(t) #>>> selector, CancellationToken cancellationToken)
{
<#= TypeName(t) #> sum = default;
var e = source.GetAsyncEnumerator(cancellationToken);
try
{
while (await e.MoveNextAsync())
{
sum += (await selector(e.Current))<#= WithSuffix(t) #>;
}
}
finally
{
if (e != null)
{
await e.DisposeAsync();
}
}
return sum;
}
public static async UniTask<<#= TypeName(t) #>> InvokeAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<<#= TypeName(t) #>>> selector, CancellationToken cancellationToken)
{
<#= TypeName(t) #> sum = default;
var e = source.GetAsyncEnumerator(cancellationToken);
try
{
while (await e.MoveNextAsync())
{
sum += (await selector(e.Current, cancellationToken))<#= WithSuffix(t) #>;
}
}
finally
{
if (e != null)
{
await e.DisposeAsync();
}
}
return sum;
}
<# } #>
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -10,4 +10,31 @@
<Compile Include="..\UniTask\Assets\Plugins\UniTask\**\*.cs" Exclude="..\UniTask\Assets\Plugins\UniTask\Triggers\*.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\Editor\*.cs;&#xD;&#xA; &#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\Internal\UnityEqualityComparer.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\Internal\DiagnosticsExtensions.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\Internal\PlayerLoopRunner.cs;&#xD;&#xA; &#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\CancellationTokenSourceExtensions.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\EnumeratorAsyncExtensions.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\PlayerLoopHelper.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\UniTask.Delay.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\UniTask.Run.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\UniTask.Bridge.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\UniTask.WaitUntil.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\UnityAsyncExtensions.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\UnityAsyncExtensions.uGUI.cs;&#xD;&#xA; ..\UniTask\Assets\Plugins\UniTask\UnityAsyncExtensions.MonoBehaviour.cs;&#xD;&#xA; " />
</ItemGroup>
<ItemGroup>
<None Include="Linq\Sum.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Sum.tt</DependentUpon>
</None>
</ItemGroup>
<ItemGroup>
<None Update="Linq\Sum.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>Sum.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup>
<ItemGroup>
<Compile Update="Linq\Sum.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Sum.tt</DependentUpon>
</Compile>
</ItemGroup>
</Project>