Where.Opt.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT License.
  3. // See the LICENSE file in the project root for more information.
  4. using System.Threading;
  5. using System.Threading.Tasks;
  6. namespace System.Linq
  7. {
  8. #if REFERENCE_ASSEMBLY
  9. public static partial class AsyncEnumerableDeprecated
  10. #else
  11. public static partial class AsyncEnumerable
  12. #endif
  13. {
  14. private static Func<TSource, bool> CombinePredicates<TSource>(Func<TSource, bool> predicate1, Func<TSource, bool> predicate2)
  15. {
  16. if (predicate1.Target is ICombinedPredicates<TSource> c)
  17. {
  18. return c.And(predicate2).Invoke;
  19. }
  20. else
  21. {
  22. return new CombinedPredicates2<TSource>(predicate1, predicate2).Invoke;
  23. }
  24. }
  25. private interface ICombinedPredicates<TSource>
  26. {
  27. ICombinedPredicates<TSource> And(Func<TSource, bool> predicate);
  28. bool Invoke(TSource x);
  29. }
  30. private sealed class CombinedPredicatesN<TSource> : ICombinedPredicates<TSource>
  31. {
  32. private readonly Func<TSource, bool>[] _predicates;
  33. public CombinedPredicatesN(params Func<TSource, bool>[] predicates)
  34. {
  35. _predicates = predicates;
  36. }
  37. public ICombinedPredicates<TSource> And(Func<TSource, bool> predicate)
  38. {
  39. var predicates = new Func<TSource, bool>[_predicates.Length + 1];
  40. Array.Copy(_predicates, predicates, _predicates.Length);
  41. predicates[_predicates.Length] = predicate;
  42. return new CombinedPredicatesN<TSource>(predicates);
  43. }
  44. public bool Invoke(TSource x)
  45. {
  46. foreach (var predicate in _predicates)
  47. {
  48. if (!predicate(x))
  49. {
  50. return false;
  51. }
  52. }
  53. return true;
  54. }
  55. }
  56. private static Func<TSource, ValueTask<bool>> CombinePredicates<TSource>(Func<TSource, ValueTask<bool>> predicate1, Func<TSource, ValueTask<bool>> predicate2)
  57. {
  58. if (predicate1.Target is ICombinedAsyncPredicates<TSource> c)
  59. {
  60. return c.And(predicate2).Invoke;
  61. }
  62. else
  63. {
  64. return new CombinedAsyncPredicates2<TSource>(predicate1, predicate2).Invoke;
  65. }
  66. }
  67. private interface ICombinedAsyncPredicates<TSource>
  68. {
  69. ICombinedAsyncPredicates<TSource> And(Func<TSource, ValueTask<bool>> predicate);
  70. ValueTask<bool> Invoke(TSource x);
  71. }
  72. private sealed class CombinedAsyncPredicatesN<TSource> : ICombinedAsyncPredicates<TSource>
  73. {
  74. private readonly Func<TSource, ValueTask<bool>>[] _predicates;
  75. public CombinedAsyncPredicatesN(params Func<TSource, ValueTask<bool>>[] predicates)
  76. {
  77. _predicates = predicates;
  78. }
  79. public ICombinedAsyncPredicates<TSource> And(Func<TSource, ValueTask<bool>> predicate)
  80. {
  81. var predicates = new Func<TSource, ValueTask<bool>>[_predicates.Length + 1];
  82. Array.Copy(_predicates, predicates, _predicates.Length);
  83. predicates[_predicates.Length] = predicate;
  84. return new CombinedAsyncPredicatesN<TSource>(predicates);
  85. }
  86. public async ValueTask<bool> Invoke(TSource x)
  87. {
  88. foreach (var predicate in _predicates)
  89. {
  90. if (!await predicate(x).ConfigureAwait(false))
  91. {
  92. return false;
  93. }
  94. }
  95. return true;
  96. }
  97. }
  98. #if !NO_DEEP_CANCELLATION
  99. private static Func<TSource, CancellationToken, ValueTask<bool>> CombinePredicates<TSource>(Func<TSource, CancellationToken, ValueTask<bool>> predicate1, Func<TSource, CancellationToken, ValueTask<bool>> predicate2)
  100. {
  101. if (predicate1.Target is ICombinedAsyncPredicatesWithCancellation<TSource> c)
  102. {
  103. return c.And(predicate2).Invoke;
  104. }
  105. else
  106. {
  107. return new CombinedAsyncPredicatesWithCancellation2<TSource>(predicate1, predicate2).Invoke;
  108. }
  109. }
  110. private interface ICombinedAsyncPredicatesWithCancellation<TSource>
  111. {
  112. ICombinedAsyncPredicatesWithCancellation<TSource> And(Func<TSource, CancellationToken, ValueTask<bool>> predicate);
  113. ValueTask<bool> Invoke(TSource x, CancellationToken ct);
  114. }
  115. private sealed class CombinedAsyncPredicatesWithCancellationN<TSource> : ICombinedAsyncPredicatesWithCancellation<TSource>
  116. {
  117. private readonly Func<TSource, CancellationToken, ValueTask<bool>>[] _predicates;
  118. public CombinedAsyncPredicatesWithCancellationN(params Func<TSource, CancellationToken, ValueTask<bool>>[] predicates)
  119. {
  120. _predicates = predicates;
  121. }
  122. public ICombinedAsyncPredicatesWithCancellation<TSource> And(Func<TSource, CancellationToken, ValueTask<bool>> predicate)
  123. {
  124. var predicates = new Func<TSource, CancellationToken, ValueTask<bool>>[_predicates.Length + 1];
  125. Array.Copy(_predicates, predicates, _predicates.Length);
  126. predicates[_predicates.Length] = predicate;
  127. return new CombinedAsyncPredicatesWithCancellationN<TSource>(predicates);
  128. }
  129. public async ValueTask<bool> Invoke(TSource x, CancellationToken ct)
  130. {
  131. foreach (var predicate in _predicates)
  132. {
  133. if (!await predicate(x, ct).ConfigureAwait(false))
  134. {
  135. return false;
  136. }
  137. }
  138. return true;
  139. }
  140. }
  141. #endif
  142. }
  143. }