示例#1
0
        public ValueTask <Maybe <TElement> > TryGetElementAtAsync(int index, CancellationToken cancellationToken)
        {
            if (index == 0)
            {
                return(TryGetFirstAsync(cancellationToken));
            }

            if (index > 0)
            {
                return(Core());

                async ValueTask <Maybe <TElement> > Core()
                {
                    var elements = await AsyncEnumerableHelpers.ToArrayWithLength(_source, cancellationToken).ConfigureAwait(false);

                    var count = elements.Length;

                    if (index < count)
                    {
                        var sorter = GetAsyncEnumerableSorter(cancellationToken);

                        var element = await sorter.ElementAt(elements.Array, count, index).ConfigureAwait(false);

                        return(new Maybe <TElement>(element));
                    }

                    return(new Maybe <TElement>());
                }
            }

            return(new ValueTask <Maybe <TElement> >(new Maybe <TElement>()));
        }
示例#2
0
        public async ValueTask <TElement[]> ToArrayAsync(CancellationToken cancellationToken)
        {
            var elements = await AsyncEnumerableHelpers.ToArrayWithLength(_source, cancellationToken).ConfigureAwait(false);

            var count = elements.Length;

            if (count == 0)
            {
#if NO_ARRAY_EMPTY
                return(EmptyArray <TElement> .Value);
#else
                return(Array.Empty <TElement>());
#endif
            }

            var array = elements.Array;

            var map = await SortedMap(array, count, cancellationToken).ConfigureAwait(false);

            var result = new TElement[count];

            for (var i = 0; i < result.Length; i++)
            {
                result[i] = array[map[i]];
            }

            return(result);
        }
示例#3
0
        internal async ValueTask <Maybe <TElement> > TryGetLastAsync(int minIndexInclusive, int maxIndexInclusive, CancellationToken cancellationToken)
        {
            var elements = await AsyncEnumerableHelpers.ToArrayWithLength(_source, cancellationToken).ConfigureAwait(false);

            var count = elements.Length;

            if (minIndexInclusive >= count)
            {
                return(new Maybe <TElement>());
            }

            var array = elements.Array;

            TElement last;

            if (maxIndexInclusive < count - 1)
            {
                var sorter = GetAsyncEnumerableSorter(cancellationToken);

                last = await sorter.ElementAt(array, count, maxIndexInclusive).ConfigureAwait(false);
            }
            else
            {
                last = await Last(array, count, cancellationToken).ConfigureAwait(false);
            }

            return(new Maybe <TElement>(last));
        }
示例#4
0
        /// <summary>
        /// Creates an array from an async-enumerable sequence.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
        /// <param name="source">The source async-enumerable sequence to get an array of elements for.</param>
        /// <param name="cancellationToken">The optional cancellation token to be used for cancelling the sequence at any time.</param>
        /// <returns>An async-enumerable sequence containing a single element with an array containing all the elements of the source sequence.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
        /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
        public static ValueTask <TSource[]> ToArrayAsync <TSource>(this IAsyncEnumerable <TSource> source, CancellationToken cancellationToken = default)
        {
            if (source == null)
            {
                throw Error.ArgumentNull(nameof(source));
            }

            if (source is IAsyncIListProvider <TSource> arrayProvider)
            {
                return(arrayProvider.ToArrayAsync(cancellationToken));
            }

            return(AsyncEnumerableHelpers.ToArray(source, cancellationToken));
        }
示例#5
0
        public static Task <TSource[]> ToArray <TSource>(this IAsyncEnumerable <TSource> source, CancellationToken cancellationToken)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (source is IIListProvider <TSource> arrayProvider)
            {
                return(arrayProvider.ToArrayAsync(cancellationToken));
            }

            return(AsyncEnumerableHelpers.ToArray(source, cancellationToken));
        }
示例#6
0
            public override async Task <TSource[]> ToArrayAsync(CancellationToken cancellationToken)
            {
                var count = await GetCountAsync(onlyIfCheap : true, cancellationToken : cancellationToken).ConfigureAwait(false);

                if (count == -1)
                {
                    return(await AsyncEnumerableHelpers.ToArray(this, cancellationToken).ConfigureAwait(false));
                }

                var array = new TSource[count];
                int index;

                if (appending)
                {
                    index = 0;
                }
                else
                {
                    array[0] = item;
                    index    = 1;
                }

                var sourceCollection = source as ICollection <TSource>;

                if (sourceCollection != null)
                {
                    sourceCollection.CopyTo(array, index);
                }
                else
                {
                    using (var en = source.GetEnumerator())
                    {
                        while (await en.MoveNext(cancellationToken)
                               .ConfigureAwait(false))
                        {
                            array[index] = en.Current;
                            ++index;
                        }
                    }
                }

                if (appending)
                {
                    array[array.Length - 1] = item;
                }

                return(array);
            }
示例#7
0
            public override async ValueTask <TSource[]> ToArrayAsync(CancellationToken cancellationToken)
            {
                var count = await GetCountAsync(onlyIfCheap : true, cancellationToken).ConfigureAwait(false);

                if (count == -1)
                {
                    return(await AsyncEnumerableHelpers.ToArray(this, cancellationToken).ConfigureAwait(false));
                }

                cancellationToken.ThrowIfCancellationRequested();

                var array = new TSource[count];
                int index;

                if (_appending)
                {
                    index = 0;
                }
                else
                {
                    array[0] = _item;
                    index    = 1;
                }

                if (_source is ICollection <TSource> sourceCollection)
                {
                    sourceCollection.CopyTo(array, index);
                }
                else
                {
                    await foreach (var item in _source.WithCancellation(cancellationToken).ConfigureAwait(false))
                    {
                        array[index] = item;
                        ++index;
                    }
                }

                if (_appending)
                {
                    array[array.Length - 1] = _item;
                }

                return(array);
            }
示例#8
0
            public override async Task <TSource[]> ToArrayAsync(CancellationToken cancellationToken)
            {
                var count = await GetCountAsync(onlyIfCheap : true, cancellationToken : cancellationToken).ConfigureAwait(false);

                if (count == -1)
                {
                    return(await AsyncEnumerableHelpers.ToArray(this, cancellationToken).ConfigureAwait(false));
                }

                var array = new TSource[count];
                var index = 0;

                for (var n = prepended; n != null; n = n.Linked)
                {
                    array[index] = n.Item;
                    ++index;
                }

                if (source is ICollection <TSource> sourceCollection)
                {
                    sourceCollection.CopyTo(array, index);
                }
                else
                {
                    using (var en = source.GetEnumerator())
                    {
                        while (await en.MoveNext(cancellationToken)
                               .ConfigureAwait(false))
                        {
                            array[index] = en.Current;
                            ++index;
                        }
                    }
                }

                index = array.Length;
                for (var n = appended; n != null; n = n.Linked)
                {
                    --index;
                    array[index] = n.Item;
                }

                return(array);
            }
示例#9
0
            protected override async ValueTask <bool> MoveNextCore()
            {
                // NB: Earlier implementations of this operator constructed the set for the second source concurrently
                //     with the first MoveNextAsync call on the first source. This resulted in an unexpected source of
                //     concurrency, which isn't a great default behavior because it's very hard to suppress or control
                //     this behavior.

                switch (_state)
                {
                case AsyncIteratorState.Allocated:
                    _set = await AsyncEnumerableHelpers.ToSet(_second, _comparer, _cancellationToken).ConfigureAwait(false);

                    _firstEnumerator = _first.GetAsyncEnumerator(_cancellationToken);

                    _state = AsyncIteratorState.Iterating;
                    goto case AsyncIteratorState.Iterating;

                case AsyncIteratorState.Iterating:

                    bool moveNext;
                    do
                    {
                        moveNext = await _firstEnumerator.MoveNextAsync().ConfigureAwait(false);

                        if (moveNext)
                        {
                            var item = _firstEnumerator.Current;
                            if (_set.Remove(item))
                            {
                                _current = item;
                                return(true);
                            }
                        }
                    } while (moveNext);

                    await DisposeAsync().ConfigureAwait(false);

                    break;
                }

                return(false);
            }
示例#10
0
        internal async ValueTask <TElement[]> ToArrayAsync(int minIndexInclusive, int maxIndexInclusive, CancellationToken cancellationToken)
        {
            var elements = await AsyncEnumerableHelpers.ToArrayWithLength(_source, cancellationToken).ConfigureAwait(false);

            var count = elements.Length;

            if (count <= minIndexInclusive)
            {
#if NO_ARRAY_EMPTY
                return(EmptyArray <TElement> .Value);
#else
                return(Array.Empty <TElement>());
#endif
            }

            if (count <= maxIndexInclusive)
            {
                maxIndexInclusive = count - 1;
            }

            var array = elements.Array;

            if (minIndexInclusive == maxIndexInclusive)
            {
                var sorter = GetAsyncEnumerableSorter(cancellationToken);

                var element = await sorter.ElementAt(array, count, minIndexInclusive).ConfigureAwait(false);

                return(new TElement[] { element });
            }

            var map = await SortedMap(array, count, minIndexInclusive, maxIndexInclusive, cancellationToken).ConfigureAwait(false);

            var result = new TElement[maxIndexInclusive - minIndexInclusive + 1];

            for (var i = 0; minIndexInclusive <= maxIndexInclusive; i++)
            {
                result[i] = array[map[minIndexInclusive++]];
            }

            return(result);
        }
示例#11
0
        internal async ValueTask <List <TElement> > ToListAsync(int minIndexInclusive, int maxIndexInclusive, CancellationToken cancellationToken)
        {
            var elements = await AsyncEnumerableHelpers.ToArrayWithLength(_source, cancellationToken).ConfigureAwait(false);

            var count = elements.Length;

            if (count <= minIndexInclusive)
            {
                return(new List <TElement>(0));
            }

            if (count <= maxIndexInclusive)
            {
                maxIndexInclusive = count - 1;
            }

            var array = elements.Array;

            if (minIndexInclusive == maxIndexInclusive)
            {
                var sorter = GetAsyncEnumerableSorter(cancellationToken);

                var element = await sorter.ElementAt(array, count, minIndexInclusive).ConfigureAwait(false);

                return(new List <TElement>(1)
                {
                    element
                });
            }

            var map = await SortedMap(array, count, minIndexInclusive, maxIndexInclusive, cancellationToken).ConfigureAwait(false);

            var list = new List <TElement>(maxIndexInclusive - minIndexInclusive + 1);

            while (minIndexInclusive <= maxIndexInclusive)
            {
                list.Add(array[map[minIndexInclusive++]]);
            }

            return(list);
        }
示例#12
0
            public override async ValueTask <TSource[]> ToArrayAsync(CancellationToken cancellationToken)
            {
                var count = await GetCountAsync(onlyIfCheap : true, cancellationToken).ConfigureAwait(false);

                if (count == -1)
                {
                    return(await AsyncEnumerableHelpers.ToArray(this, cancellationToken).ConfigureAwait(false));
                }

                var array = new TSource[count];
                var index = 0;

                for (var n = _prepended; n != null; n = n.Linked)
                {
                    array[index] = n.Item;
                    ++index;
                }

                if (_source is ICollection <TSource> sourceCollection)
                {
                    sourceCollection.CopyTo(array, index);
                }
                else
                {
                    await foreach (var item in _source.WithCancellation(cancellationToken).ConfigureAwait(false))
                    {
                        array[index] = item;
                        ++index;
                    }
                }

                index = array.Length;
                for (var n = _appended; n != null; n = n.Linked)
                {
                    --index;
                    array[index] = n.Item;
                }

                return(array);
            }
示例#13
0
        public async ValueTask <List <TElement> > ToListAsync(CancellationToken cancellationToken)
        {
            var elements = await AsyncEnumerableHelpers.ToArrayWithLength(_source, cancellationToken).ConfigureAwait(false);

            var count = elements.Length;

            if (count == 0)
            {
                return(new List <TElement>(capacity: 0));
            }

            var array = elements.Array;

            var map = await SortedMap(array, count, cancellationToken).ConfigureAwait(false);

            var result = new List <TElement>(count);

            for (var i = 0; i < count; i++)
            {
                result.Add(array[map[i]]);
            }

            return(result);
        }
示例#14
0
 private Task <Set <TSource> > FillSetAsync(CancellationToken cancellationToken)
 {
     return(AsyncEnumerableHelpers.ToSet(_source, _comparer, cancellationToken));
 }
示例#15
0
 public Task <TSource[]> ToArrayAsync(CancellationToken cancellationToken)
 {
     return(AsyncEnumerableHelpers.ToArray(this, cancellationToken));
 }