MinMax.tt 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. <#@ template debug="false" hostspecific="false" language="C#" #>
  2. <#@ assembly name="System.Core" #>
  3. <#@ import namespace="System.Linq" #>
  4. <#@ import namespace="System.Text" #>
  5. <#@ import namespace="System.Collections.Generic" #>
  6. <#@ output extension=".cs" #>
  7. <#
  8. var types = new[]
  9. {
  10. typeof(int),
  11. typeof(long),
  12. typeof(float),
  13. typeof(double),
  14. typeof(decimal),
  15. typeof(int?),
  16. typeof(long?),
  17. typeof(float?),
  18. typeof(double?),
  19. typeof(decimal?),
  20. };
  21. Func<Type, bool> IsNullable = x => x.IsGenericType;
  22. Func<Type, string> TypeName = x => IsNullable(x) ? x.GetGenericArguments()[0].Name + "?" : x.Name;
  23. Func<Type, string> WithSuffix = x => IsNullable(x) ? ".GetValueOrDefault()" : "";
  24. #>
  25. using System;
  26. using System.Threading;
  27. using Cysharp.Threading.Tasks.Internal;
  28. namespace Cysharp.Threading.Tasks.Linq
  29. {
  30. <# foreach(var (minMax, op) in new[]{("Min",">"), ("Max", "<")}) { #>
  31. public static partial class UniTaskAsyncEnumerable
  32. {
  33. <# foreach(var t in types) { #>
  34. public static UniTask<<#= TypeName(t) #>> <#= minMax #>Async(this IUniTaskAsyncEnumerable<<#= TypeName(t) #>> source, CancellationToken cancellationToken = default)
  35. {
  36. Error.ThrowArgumentNullException(source, nameof(source));
  37. return <#= minMax #>.<#= minMax #>Async(source, cancellationToken);
  38. }
  39. public static UniTask<<#= TypeName(t) #>> <#= minMax #>Async<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, <#= TypeName(t) #>> selector, CancellationToken cancellationToken = default)
  40. {
  41. Error.ThrowArgumentNullException(source, nameof(source));
  42. Error.ThrowArgumentNullException(source, nameof(selector));
  43. return <#= minMax #>.<#= minMax #>Async(source, selector, cancellationToken);
  44. }
  45. public static UniTask<<#= TypeName(t) #>> <#= minMax #>AwaitAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<<#= TypeName(t) #>>> selector, CancellationToken cancellationToken = default)
  46. {
  47. Error.ThrowArgumentNullException(source, nameof(source));
  48. Error.ThrowArgumentNullException(source, nameof(selector));
  49. return <#= minMax #>.<#= minMax #>AwaitAsync(source, selector, cancellationToken);
  50. }
  51. public static UniTask<<#= TypeName(t) #>> <#= minMax #>AwaitWithCancellationAsync<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<<#= TypeName(t) #>>> selector, CancellationToken cancellationToken = default)
  52. {
  53. Error.ThrowArgumentNullException(source, nameof(source));
  54. Error.ThrowArgumentNullException(source, nameof(selector));
  55. return <#= minMax #>.<#= minMax #>AwaitWithCancellationAsync(source, selector, cancellationToken);
  56. }
  57. <# } #>
  58. }
  59. internal static partial class <#= minMax #>
  60. {
  61. <# foreach(var t in types) { #>
  62. public static async UniTask<<#= TypeName(t) #>> <#= minMax #>Async(IUniTaskAsyncEnumerable<<#= TypeName(t) #>> source, CancellationToken cancellationToken)
  63. {
  64. <#= TypeName(t) #> value = default;
  65. var e = source.GetAsyncEnumerator(cancellationToken);
  66. try
  67. {
  68. while (await e.MoveNextAsync())
  69. {
  70. value = e.Current;
  71. <# if (IsNullable(t)) { #>
  72. if(value == null) continue;
  73. <# } #>
  74. goto NEXT_LOOP;
  75. }
  76. <# if (IsNullable(t)) { #>
  77. return default;
  78. <# } else { #>
  79. throw Error.NoElements();
  80. <# } #>
  81. NEXT_LOOP:
  82. while (await e.MoveNextAsync())
  83. {
  84. var x = e.Current;
  85. <# if (IsNullable(t)) { #>
  86. if( x == null) continue;
  87. <# } #>
  88. if (value <#= op #> x)
  89. {
  90. value = x;
  91. }
  92. }
  93. }
  94. finally
  95. {
  96. if (e != null)
  97. {
  98. await e.DisposeAsync();
  99. }
  100. }
  101. return value;
  102. }
  103. public static async UniTask<<#= TypeName(t) #>> <#= minMax #>Async<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, <#= TypeName(t) #>> selector, CancellationToken cancellationToken)
  104. {
  105. <#= TypeName(t) #> value = default;
  106. var e = source.GetAsyncEnumerator(cancellationToken);
  107. try
  108. {
  109. while (await e.MoveNextAsync())
  110. {
  111. value = selector(e.Current);
  112. <# if (IsNullable(t)) { #>
  113. if(value == null) continue;
  114. <# } #>
  115. goto NEXT_LOOP;
  116. }
  117. <# if (IsNullable(t)) { #>
  118. return default;
  119. <# } else { #>
  120. throw Error.NoElements();
  121. <# } #>
  122. NEXT_LOOP:
  123. while (await e.MoveNextAsync())
  124. {
  125. var x = selector(e.Current);
  126. <# if (IsNullable(t)) { #>
  127. if( x == null) continue;
  128. <# } #>
  129. if (value <#= op #> x)
  130. {
  131. value = x;
  132. }
  133. }
  134. }
  135. finally
  136. {
  137. if (e != null)
  138. {
  139. await e.DisposeAsync();
  140. }
  141. }
  142. return value;
  143. }
  144. public static async UniTask<<#= TypeName(t) #>> <#= minMax #>AwaitAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<<#= TypeName(t) #>>> selector, CancellationToken cancellationToken)
  145. {
  146. <#= TypeName(t) #> value = default;
  147. var e = source.GetAsyncEnumerator(cancellationToken);
  148. try
  149. {
  150. while (await e.MoveNextAsync())
  151. {
  152. value = await selector(e.Current);
  153. <# if (IsNullable(t)) { #>
  154. if(value == null) continue;
  155. <# } #>
  156. goto NEXT_LOOP;
  157. }
  158. <# if (IsNullable(t)) { #>
  159. return default;
  160. <# } else { #>
  161. throw Error.NoElements();
  162. <# } #>
  163. NEXT_LOOP:
  164. while (await e.MoveNextAsync())
  165. {
  166. var x = await selector(e.Current);
  167. <# if (IsNullable(t)) { #>
  168. if( x == null) continue;
  169. <# } #>
  170. if (value <#= op #> x)
  171. {
  172. value = x;
  173. }
  174. }
  175. }
  176. finally
  177. {
  178. if (e != null)
  179. {
  180. await e.DisposeAsync();
  181. }
  182. }
  183. return value;
  184. }
  185. public static async UniTask<<#= TypeName(t) #>> <#= minMax #>AwaitWithCancellationAsync<TSource>(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<<#= TypeName(t) #>>> selector, CancellationToken cancellationToken)
  186. {
  187. <#= TypeName(t) #> value = default;
  188. var e = source.GetAsyncEnumerator(cancellationToken);
  189. try
  190. {
  191. while (await e.MoveNextAsync())
  192. {
  193. value = await selector(e.Current, cancellationToken);
  194. <# if (IsNullable(t)) { #>
  195. if(value == null) continue;
  196. <# } #>
  197. goto NEXT_LOOP;
  198. }
  199. <# if (IsNullable(t)) { #>
  200. return default;
  201. <# } else { #>
  202. throw Error.NoElements();
  203. <# } #>
  204. NEXT_LOOP:
  205. while (await e.MoveNextAsync())
  206. {
  207. var x = await selector(e.Current, cancellationToken);
  208. <# if (IsNullable(t)) { #>
  209. if( x == null) continue;
  210. <# } #>
  211. if (value <#= op #> x)
  212. {
  213. value = x;
  214. }
  215. }
  216. }
  217. finally
  218. {
  219. if (e != null)
  220. {
  221. await e.DisposeAsync();
  222. }
  223. }
  224. return value;
  225. }
  226. <# } #>
  227. }
  228. <# } #>
  229. }