// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT License. // See the LICENSE file in the project root for more information. using System.Threading; using System.Threading.Tasks; namespace System.Linq { public static partial class AsyncEnumerable { private static Func CombinePredicates(Func predicate1, Func predicate2) { if (predicate1.Target is ICombinedPredicates c) { return c.And(predicate2).Invoke; } else { return new CombinedPredicates2(predicate1, predicate2).Invoke; } } private interface ICombinedPredicates { ICombinedPredicates And(Func predicate); bool Invoke(TSource x); } private sealed class CombinedPredicatesN : ICombinedPredicates { private readonly Func[] _predicates; public CombinedPredicatesN(params Func[] predicates) { _predicates = predicates; } public ICombinedPredicates And(Func predicate) { var predicates = new Func[_predicates.Length + 1]; Array.Copy(_predicates, predicates, _predicates.Length); predicates[_predicates.Length] = predicate; return new CombinedPredicatesN(predicates); } public bool Invoke(TSource x) { foreach (var predicate in _predicates) { if (!predicate(x)) { return false; } } return true; } } private static Func> CombinePredicates(Func> predicate1, Func> predicate2) { if (predicate1.Target is ICombinedAsyncPredicates c) { return c.And(predicate2).Invoke; } else { return new CombinedAsyncPredicates2(predicate1, predicate2).Invoke; } } private interface ICombinedAsyncPredicates { ICombinedAsyncPredicates And(Func> predicate); ValueTask Invoke(TSource x); } private sealed class CombinedAsyncPredicatesN : ICombinedAsyncPredicates { private readonly Func>[] _predicates; public CombinedAsyncPredicatesN(params Func>[] predicates) { _predicates = predicates; } public ICombinedAsyncPredicates And(Func> predicate) { var predicates = new Func>[_predicates.Length + 1]; Array.Copy(_predicates, predicates, _predicates.Length); predicates[_predicates.Length] = predicate; return new CombinedAsyncPredicatesN(predicates); } public async ValueTask Invoke(TSource x) { foreach (var predicate in _predicates) { if (!await predicate(x).ConfigureAwait(false)) { return false; } } return true; } } #if !NO_DEEP_CANCELLATION private static Func> CombinePredicates(Func> predicate1, Func> predicate2) { if (predicate1.Target is ICombinedAsyncPredicatesWithCancellation c) { return c.And(predicate2).Invoke; } else { return new CombinedAsyncPredicatesWithCancellation2(predicate1, predicate2).Invoke; } } private interface ICombinedAsyncPredicatesWithCancellation { ICombinedAsyncPredicatesWithCancellation And(Func> predicate); ValueTask Invoke(TSource x, CancellationToken ct); } private sealed class CombinedAsyncPredicatesWithCancellationN : ICombinedAsyncPredicatesWithCancellation { private readonly Func>[] _predicates; public CombinedAsyncPredicatesWithCancellationN(params Func>[] predicates) { _predicates = predicates; } public ICombinedAsyncPredicatesWithCancellation And(Func> predicate) { var predicates = new Func>[_predicates.Length + 1]; Array.Copy(_predicates, predicates, _predicates.Length); predicates[_predicates.Length] = predicate; return new CombinedAsyncPredicatesWithCancellationN(predicates); } public async ValueTask Invoke(TSource x, CancellationToken ct) { foreach (var predicate in _predicates) { if (!await predicate(x, ct).ConfigureAwait(false)) { return false; } } return true; } } #endif } }