static async ValueTask <IMemoryOwner <TSource> > ToArrayAsync <TEnumerable, TEnumerator, TSource>(this TEnumerable source, AsyncPredicateAt <TSource> predicate, MemoryPool <TSource> pool, CancellationToken cancellationToken) where TEnumerable : notnull, IAsyncValueEnumerable <TSource, TEnumerator> where TEnumerator : struct, IAsyncEnumerator <TSource> => (await ToArrayBuilderAsync <TEnumerable, TEnumerator, TSource>(source, predicate, ArrayPool <TSource> .Shared, cancellationToken).ConfigureAwait(false)).ToArray(pool);
static ValueTask <Option <TSource> > SingleAsync <TEnumerable, TEnumerator, TSource>(this TEnumerable source, AsyncPredicateAt <TSource> predicate, CancellationToken cancellationToken = default) where TEnumerable : notnull, IAsyncValueEnumerable <TSource, TEnumerator> where TEnumerator : struct, IAsyncEnumerator <TSource> => GetSingleAsync <TEnumerable, TEnumerator, TSource>(source, predicate, cancellationToken);
static async ValueTask <List <TSource> > ToListAsync <TEnumerable, TEnumerator, TSource>(this TEnumerable source, AsyncPredicateAt <TSource> predicate, CancellationToken cancellationToken) where TEnumerable : IAsyncValueEnumerable <TSource, TEnumerator> where TEnumerator : struct, IAsyncEnumerator <TSource> { var enumerator = source.GetAsyncEnumerator(cancellationToken); await using (enumerator.ConfigureAwait(false)) { checked { var list = new List <TSource>(); for (var index = 0; await enumerator.MoveNextAsync().ConfigureAwait(false); index++) { var item = enumerator.Current; if (await predicate(item, index, cancellationToken).ConfigureAwait(false)) { list.Add(item); } } return(list); } } }
static async ValueTask <bool> ContainsAsync <TEnumerable, TEnumerator, TSource>(this TEnumerable source, TSource value, IEqualityComparer <TSource>?comparer, AsyncPredicateAt <TSource> predicate, CancellationToken cancellationToken) where TEnumerable : notnull, IAsyncValueEnumerable <TSource, TEnumerator> where TEnumerator : struct, IAsyncEnumerator <TSource> { var enumerator = source.GetAsyncEnumerator(cancellationToken); await using (enumerator.ConfigureAwait(false)) { if (comparer is null) { checked { for (var index = 0; await enumerator.MoveNextAsync().ConfigureAwait(false); index++) { if (await predicate(enumerator.Current, index, cancellationToken).ConfigureAwait(false) && EqualityComparer <TSource> .Default.Equals(enumerator.Current, value)) { return(true); } } } } else { checked { for (var index = 0; await enumerator.MoveNextAsync().ConfigureAwait(false); index++) { if (await predicate(enumerator.Current, index, cancellationToken).ConfigureAwait(false) && comparer.Equals(enumerator.Current, value)) { return(true); } } } } } return(false); }
static async ValueTask <Option <TSource> > GetSingleAsync <TEnumerable, TEnumerator, TSource>(this TEnumerable source, AsyncPredicateAt <TSource> predicate, CancellationToken cancellationToken) where TEnumerable : notnull, IAsyncValueEnumerable <TSource, TEnumerator> where TEnumerator : struct, IAsyncEnumerator <TSource> { var enumerator = source.GetAsyncEnumerator(cancellationToken); await using (enumerator.ConfigureAwait(false)) { checked { for (var index = 0; await enumerator.MoveNextAsync().ConfigureAwait(false); index++) { if (await predicate(enumerator.Current, index, cancellationToken).ConfigureAwait(false)) { var value = enumerator.Current; // found first, keep going until end or find second for (index++; await enumerator.MoveNextAsync().ConfigureAwait(false); index++) { if (await predicate(enumerator.Current, index, cancellationToken).ConfigureAwait(false)) { return(Option.None); } } return(Option.Some(value)); } } } return(Option.None); } }
public async ValueTask AddRangeAsync <TEnumerable, TEnumerator>(TEnumerable items, AsyncPredicateAt <T> predicate, CancellationToken cancellationToken) where TEnumerable : IAsyncValueEnumerable <T, TEnumerator> where TEnumerator : struct, IAsyncEnumerator <T> { Debug.Assert(items is object); var enumerator = items.GetAsyncEnumerator(); await using (enumerator.ConfigureAwait(false)) { var destination = _current; var index = _index; // Continuously read in items from the enumerator, updating _count // and _index when we run out of space. while (await enumerator.MoveNextAsync().ConfigureAwait(false)) { cancellationToken.ThrowIfCancellationRequested(); var item = enumerator.Current; if (await predicate(item, index, cancellationToken).ConfigureAwait(false)) { if ((uint)index >= (uint)destination.Length) { AddWithBufferAllocation(item, ref destination, ref index); } else { destination[index] = item; } index++; } } // Final update to _count and _index. _count += index - _index; _index = index; } }
static async ValueTask <TSource[]> ToArrayAsync <TEnumerable, TEnumerator, TSource>(this TEnumerable source, AsyncPredicateAt <TSource> predicate, CancellationToken cancellationToken) where TEnumerable : IAsyncValueEnumerable <TSource, TEnumerator> where TEnumerator : struct, IAsyncEnumerator <TSource> { var builder = new LargeArrayBuilder <TSource>(initialize: true); await builder.AddRangeAsync <TEnumerable, TEnumerator>(source, predicate, cancellationToken).ConfigureAwait(false); return(builder.ToArray()); }
static async ValueTask <int> CountAsync <TEnumerable, TEnumerator, TSource>(this TEnumerable source, AsyncPredicateAt <TSource> predicate, CancellationToken cancellationToken) where TEnumerable : notnull, IAsyncValueEnumerable <TSource, TEnumerator> where TEnumerator : struct, IAsyncEnumerator <TSource> { var count = 0; var enumerator = source.GetAsyncEnumerator(cancellationToken); await using (enumerator.ConfigureAwait(false)) { checked { for (var index = 0; await enumerator.MoveNextAsync().ConfigureAwait(false); index++) { var result = await predicate(enumerator.Current, index, cancellationToken).ConfigureAwait(false); count += Unsafe.As <bool, byte>(ref result); } } } return(count); }
public static WhereIndexEnumerable <TEnumerable, TEnumerator, TSource> Where <TEnumerable, TEnumerator, TSource>(this TEnumerable source, AsyncPredicateAt <TSource> predicate) where TEnumerable : notnull, IAsyncValueEnumerable <TSource, TEnumerator> where TEnumerator : struct, IAsyncEnumerator <TSource> { if (predicate is null) { Throw.ArgumentNullException(nameof(predicate)); } return(new WhereIndexEnumerable <TEnumerable, TEnumerator, TSource>(in source, predicate)); }
public static AsyncPredicateAt <TSource> Combine <TSource>(AsyncPredicateAt <TSource> first, AsyncPredicateAt <TSource> second) => async(item, index, cancellation) => await first(item, index, cancellation).ConfigureAwait(false) && await second(item, index, cancellation).ConfigureAwait(false);
static async ValueTask <Option <TSource> > FirstAsync <TEnumerable, TEnumerator, TSource>(this TEnumerable source, AsyncPredicateAt <TSource> predicate, CancellationToken cancellationToken) where TEnumerable : notnull, IAsyncValueEnumerable <TSource, TEnumerator> where TEnumerator : struct, IAsyncEnumerator <TSource> { var enumerator = source.GetAsyncEnumerator(cancellationToken); await using (enumerator.ConfigureAwait(false)) { checked { for (var index = 0; await enumerator.MoveNextAsync().ConfigureAwait(false); index++) { var item = enumerator.Current; if (await predicate(item, index, cancellationToken).ConfigureAwait(false)) { return(Option.Some(item)); } } } } return(Option.None); }
static async ValueTask <LargeArrayBuilder <TSource> > ToArrayBuilderAsync <TEnumerable, TEnumerator, TSource>(TEnumerable source, AsyncPredicateAt <TSource> predicate, ArrayPool <TSource> arrayPool, CancellationToken cancellationToken) where TEnumerable : notnull, IAsyncValueEnumerable <TSource, TEnumerator> where TEnumerator : struct, IAsyncEnumerator <TSource> { Debug.Assert(arrayPool is object); var builder = new LargeArrayBuilder <TSource>(arrayPool); var enumerator = source.GetAsyncEnumerator(); await using (enumerator.ConfigureAwait(false)) { checked { for (var index = 0; await enumerator.MoveNextAsync().ConfigureAwait(false); index++) { cancellationToken.ThrowIfCancellationRequested(); var item = enumerator.Current; if (await predicate(item, index, cancellationToken).ConfigureAwait(false)) { builder.Add(item); } } } } return(builder); }