/// <summary> /// Folds the collection into a single element as described by <paramref name="func"/>. /// </summary> /// <typeparam name="TElement">The type of the elements in the collection.</typeparam> /// <typeparam name="TEnumerator">The type of the enumerator for the collection.</typeparam> /// <param name="collection">This collection.</param> /// <param name="func">The function describing the folding operation. This is a magma.</param> /// <param name="identity">The identity value for <paramref name="func"/>.</param> /// <returns>A single element after folding the entire collection.</returns> /// <remarks> /// <para><paramref name="func"/> is a magma, so associativity like left-fold and right-fold are completely irrelevant.</para> /// <para><paramref name="identity"/> is required as a start point for the fold. It needs to be the identity of the <paramref name="func"/> to function properly. For example, the identity of addition is <c>0</c>, and the identity of multiplication is <c>1</c>. Without an appropriate identity, the results will be wrong.</para> /// </remarks> public static TElement Fold <TElement, TEnumerator>(this IGetEnumerator <TElement, TEnumerator> collection, Func <TElement, TElement, TElement> func, TElement identity) where TEnumerator : notnull, ICurrent <TElement>, IMoveNext { TElement?result = identity; foreach (TElement?item in collection) { result = func(result, item); } return(result); }
/// <summary> /// Determines whether this collection contains any elements described by the <paramref name="predicate"/>. /// </summary> /// <typeparam name="TElement">The type of the elements in the collection.</typeparam> /// <typeparam name="TEnumerator">The type of the enumerator for the collection.</typeparam> /// <param name="collection">This collection.</param> /// <param name="predicate">The predicate describing the element to attempt to find.</param> /// <returns><see langword="true"/> if an element described by the <paramref name="predicate"/> is contained in this collection; otherwise, <see langword="false"/>.</returns> public static Boolean Contains <TElement, TEnumerator>(this IGetEnumerator <TElement, TEnumerator> collection, Predicate <TElement>?predicate) where TEnumerator : notnull, ICurrent <TElement>, IMoveNext { foreach (TElement item in collection) { if (predicate?.Invoke(item) ?? item is null) { return(true); } } return(false); }
/// <summary> /// Determines whether this collection contains all of the specified <paramref name="elements"/>. /// </summary> /// <typeparam name="TElement">The type of the elements in the collection.</typeparam> /// <typeparam name="TEnumerator">The type of the enumerator for the collection.</typeparam> /// <param name="collection">This collection.</param> /// <param name="elements">The elements to attempt to find.</param> /// <returns><see langword="true"/> if all of the <paramref name="elements"/> are contained in this collection; otherwise <see langword="false"/>.</returns> public static Boolean ContainsAll <TElement, TEnumerator>(this IGetEnumerator <TElement, TEnumerator> collection, ReadOnlySpan <TElement> elements) where TEnumerator : notnull, ICurrent <TElement>, IMoveNext { foreach (TElement element in elements) { if (!collection.Contains(element)) { return(false); } } return(true); }
/// <summary> /// Determines whether this collection contains the specified <paramref name="element"/>. /// </summary> /// <typeparam name="TElement">The type of the elements in the collection.</typeparam> /// <typeparam name="TEnumerator">The type of the enumerator for the collection.</typeparam> /// <param name="collection">This collection.</param> /// <param name="element">The element to attempt to find.</param> /// <returns><see langword="true"/> if <paramref name="element"/> is contained in this collection; otherwise, <see langword="false"/>.</returns> public static Boolean Contains <TElement, TEnumerator>(this IGetEnumerator <TElement, TEnumerator> collection, TElement element) where TEnumerator : notnull, ICurrent <TElement>, IMoveNext { foreach (TElement item in collection) { if (Equals(element, item)) { return(true); } } return(false); }
/// <summary> /// Count all occurrences of <paramref name="element"/> in the collection. /// </summary> /// <typeparam name="TElement">The type of the elements in the collection.</typeparam> /// <typeparam name="TEnumerator">The type of the enumerator for the collection.</typeparam> /// <param name="collection">This collection.</param> /// <param name="element">The element to count.</param> /// <returns>The amount of occurrences found.</returns> public static nint Occurrences <TElement, TEnumerator>(this IGetEnumerator <TElement, TEnumerator> collection, TElement element) where TEnumerator : notnull, ICurrent <TElement>, IMoveNext { nint count = 0; foreach (TElement item in collection) { if (Equals(element, item)) { count++; } } return(count); }
/// <summary> /// Determines whether this collection contains the specified <paramref name="element"/>. /// </summary> /// <typeparam name="TElement">The type of the elements in the collection.</typeparam> /// <typeparam name="TEnumerator">The type of the enumerator for the collection.</typeparam> /// <param name="collection">This collection.</param> /// <param name="element">The element to attempt to find.</param> /// <returns><see langword="true"/> if <paramref name="element"/> is contained in this collection; otherwise, <see langword="false"/>.</returns> public static Boolean ContainsOnly <TElement, TEnumerator>(this IGetEnumerator <TElement, TEnumerator> collection, TElement element) where TEnumerator : notnull, ICurrent <TElement>, IMoveNext { TEnumerator enumerator = collection.GetEnumerator(); while (enumerator.MoveNext()) { if (!Equals(enumerator.Current, element)) { return(false); } } return(true); }
/// <summary> /// Count all occurrences of elements that match the provided predicate in the collection. /// </summary> /// <typeparam name="TElement">The type of the elements in the collection.</typeparam> /// <typeparam name="TEnumerator">The type of the enumerator for the collection.</typeparam> /// <param name="collection">This collection.</param> /// <param name="predicate">The <see cref="Predicate{T}"/> describing a match of the elements to count.</param> /// <returns>The amount of occurrences found.</returns> public static nint Occurrences <TElement, TEnumerator>(this IGetEnumerator <TElement, TEnumerator> collection, Predicate <TElement>?predicate) where TEnumerator : notnull, ICurrent <TElement>, IMoveNext { nint count = 0; foreach (TElement item in collection) { if (predicate?.Invoke(item) ?? item is null) { count++; } } return(count); }
/// <summary> /// Applies an accumulator function over a sequence. The specified seed value is used as the initial accumulator value. /// </summary> /// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam> /// <typeparam name="TAccumulate">The type of the accumulator value.</typeparam> /// <typeparam name="TEnumerator">The type of the enumerator of the <paramref name="source"/>.</typeparam> /// <param name="source">An <see cref="IGetEnumerator{TElement, TEnumerator}"/> to aggregate over.</param> /// <param name="seed">The initial accumulator value.</param> /// <param name="func">An accumulator function to be invoked on each element.</param> /// <returns>The final accumulator value.</returns> public static TAccumulate Aggregate <TSource, TAccumulate, TEnumerator>(this IGetEnumerator <TSource, TEnumerator>?source, TAccumulate seed, Func <TAccumulate, TSource, TAccumulate>?func) where TEnumerator : notnull, ICurrent <TSource>, IMoveNext { if (source is null) { throw new ArgumentNullException(nameof(source)); } if (func is null) { throw new ArgumentNullException(nameof(source)); } TAccumulate result = seed; foreach (TSource element in source) { result = func(result, element); } return(result); }
/// <summary> /// Determines whether any element of a sequence satisfies a condition. /// </summary> /// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam> /// <typeparam name="TEnumerator">The type of the enumerator of the <paramref name="source"/>.</typeparam> /// <param name="source">An <see cref="IGetEnumerator{TElement, TEnumerator}"/> whos elements to apply the predicate to.</param> /// <param name="predicate">A function to test each element for a condition.</param> /// <returns><see langword="true"/> if the source sequence is not empty and at least one of its elements passes the test in the specified predicate; otherwise, <see langword="false"/>.</returns> public static Boolean Any <TSource, TEnumerator>(this IGetEnumerator <TSource, TEnumerator>?source, Func <TSource, Boolean> predicate) where TEnumerator : notnull, ICurrent <TSource>, IMoveNext { if (source is null) { throw new ArgumentNullException(nameof(source)); } if (predicate is null) { throw new ArgumentNullException(nameof(predicate)); } foreach (TSource element in source) { if (predicate(element)) { return(true); } } return(false); }
/// <summary> /// Determines whether this collection contains the specified <paramref name="elements"/>. /// </summary> /// <typeparam name="TElement">The type of the elements in the collection.</typeparam> /// <typeparam name="TEnumerator">The type of the enumerator for the collection.</typeparam> /// <param name="collection">This collection.</param> /// <param name="elements">The elements to attempt to find.</param> /// <returns><see langword="true"/> if <paramref name="elements"/> is contained in this collection; otherwise, <see langword="false"/>.</returns> public static Boolean ContainsOnly <TElement, TEnumerator>(this IGetEnumerator <TElement, TEnumerator> collection, ReadOnlySpan <TElement> elements) where TEnumerator : notnull, ICurrent <TElement>, IMoveNext { Boolean[] found = new Boolean[elements.Length]; TEnumerator enumerator = collection.GetEnumerator(); while (enumerator.MoveNext()) { for (Int32 i = 0; i < elements.Length; i++) { if (!Equals(enumerator.Current, elements[i])) { found[i] = true; } } } foreach (Boolean fnd in found) { if (!fnd) { return(false); } } return(true); }
/// <summary> /// Applies an accumulator function over a sequence. /// </summary> /// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam> /// <typeparam name="TEnumerator">The type of the enumerator of the <paramref name="source"/>.</typeparam> /// <param name="source">An <see cref="IGetEnumerator{TElement, TEnumerator}"/> to aggregate over.</param> /// <param name="func">An accumulator function to be invoked on each element.</param> /// <returns>The final accumulator value.</returns> public static TSource Aggregate <TSource, TEnumerator>(this IGetEnumerator <TSource, TEnumerator>?source, Func <TSource, TSource, TSource>?func) where TEnumerator : notnull, ICurrent <TSource>, IMoveNext { if (source is null) { throw new ArgumentNullException(nameof(source)); } if (func is null) { throw new ArgumentNullException(nameof(func)); } TEnumerator e = source.GetEnumerator(); if (!e.MoveNext()) { throw new ArgumentException("The source can not be empty", nameof(source)); } TSource result = e.Current; while (e.MoveNext()) { result = func(result, e.Current); } return(result); }
/// <summary> /// Inserts the elements into the collection at the specified index, one by one. /// </summary> /// <typeparam name="TElement">The type of the elements in the collection.</typeparam> /// <typeparam name="TEnumerator">The type of the enumerator for the collection.</typeparam> /// <param name="collection">This collection.</param> /// <param name="index">The index at which the <paramref name="elements"/> should be inserted.</param> /// <param name="elements">The elements to insert.</param> public static void Insert <TElement, TEnumerator>(this IInsert <Index, TElement> collection, Index index, IGetEnumerator <TElement, TEnumerator>?elements) where TEnumerator : notnull, ICurrent <TElement>, IMoveNext { if (elements is not null) { foreach (TElement element in elements) { collection.Insert(index, element); index = index.Value + 1; } } }
/// <summary> /// Determines whether a sequence contains any elements. /// </summary> /// <typeparam name="TSource">The type of the elements of <paramref name="source"/>.</typeparam> /// <typeparam name="TEnumerator">The type of the enumerator of the <paramref name="source"/>.</typeparam> /// <param name="source">The <see cref="IGetEnumerator{TElement, TEnumerator}"/> to check for emptiness.</param> /// <returns><see langword="true"/> if the source sequence contains any elements; otherwise, <see langword="false"/>.</returns> public static Boolean Any <TSource, TEnumerator>(this IGetEnumerator <TSource, TEnumerator>?source) where TEnumerator : notnull, ICurrent <TSource>, IMoveNext => source?.GetEnumerator().MoveNext() ?? throw new ArgumentNullException(nameof(source));
/// <summary> /// Removes the last instance of the elements from this object. /// </summary> /// <typeparam name="TElement">The type of the elements in the collection.</typeparam> /// <typeparam name="TEnumerator">The type of the enumerator of the <paramref name="elements"/>.</typeparam> /// <param name="collection">This collection.</param> /// <param name="elements">The elements to remove.</param> public static void RemoveLast <TElement, TEnumerator>(this IRemove <TElement> collection, IGetEnumerator <TElement, TEnumerator>?elements) where TEnumerator : notnull, ICurrent <TElement>, IMoveNext { if (elements is not null) { foreach (TElement element in elements) { collection.RemoveLast(element); } } }
/// <summary> /// Postpends the elements onto this object, one by one. /// </summary> /// <typeparam name="TElement">The type of the elements in the collection.</typeparam> /// <typeparam name="TEnumerator">The type of the enumerator for the <paramref name="elements"/>.</typeparam> /// <param name="collection">This collection.</param> /// <param name="elements">The elements to postpend.</param> public static void Postpend <TElement, TEnumerator>(this IPostpend <TElement> collection, IGetEnumerator <TElement, TEnumerator> elements) where TEnumerator : notnull, ICurrent <TElement>, IMoveNext { if (elements is not null) { foreach (TElement element in elements) { collection.Postpend(element); } } }
/// <summary> /// Determines whether this collection contains all of the specified <paramref name="elements"/>. /// </summary> /// <typeparam name="TElement">The type of the elements in the collection.</typeparam> /// <typeparam name="TEnumerator">The type of the enumerator for the collection.</typeparam> /// <param name="collection">This collection.</param> /// <param name="elements">The elements to attempt to find.</param> /// <returns><see langword="true"/> if all of the <paramref name="elements"/> are contained in this collection; otherwise <see langword="false"/>.</returns> public static Boolean ContainsAll <TElement, TEnumerator>(this IGetEnumerator <TElement, TEnumerator> collection, Span <TElement> elements) where TEnumerator : notnull, ICurrent <TElement>, IMoveNext => ContainsAll(collection, (ReadOnlySpan <TElement>)elements);
/// <summary> /// Determines whether this collection contains all of the specified <paramref name="elements"/>. /// </summary> /// <typeparam name="TElement">The type of the elements in the collection.</typeparam> /// <typeparam name="TEnumerator">The type of the enumerator for the collection.</typeparam> /// <param name="collection">This collection.</param> /// <param name="elements">The elements to attempt to find.</param> /// <returns><see langword="true"/> if all of the <paramref name="elements"/> are contained in this collection; otherwise <see langword="false"/>.</returns> public static Boolean ContainsAll <TElement, TEnumerator>(this IGetEnumerator <TElement, TEnumerator> collection, Memory <TElement> elements) where TEnumerator : notnull, ICurrent <TElement>, IMoveNext => ContainsAll(collection, elements.Span);
/// <summary> /// Determines whether this collection contains all of the specified <paramref name="elements"/>. /// </summary> /// <typeparam name="TElement">The type of the elements in the collection.</typeparam> /// <typeparam name="TEnumerator">The type of the enumerator for the collection.</typeparam> /// <param name="collection">This collection.</param> /// <param name="elements">The elements to attempt to find.</param> /// <returns><see langword="true"/> if all of the <paramref name="elements"/> are contained in this collection; otherwise <see langword="false"/>.</returns> public static Boolean ContainsAll <TElement, TEnumerator>(this IGetEnumerator <TElement, TEnumerator> collection, params TElement[]?elements) where TEnumerator : notnull, ICurrent <TElement>, IMoveNext => ContainsAll(collection, elements.AsSpan());
/// <summary> /// Determines whether this collection contains any of the specified <paramref name="elements"/>. /// </summary> /// <typeparam name="TElement">The type of the elements in the collection.</typeparam> /// <typeparam name="TEnumerator">The type of the enumerator for the collection.</typeparam> /// <param name="collection">This collection.</param> /// <param name="elements">The elements to attempt to find.</param> /// <returns><see langword="true"/> if any of the <paramref name="elements"/> are contained in this collection; otherwise <see langword="false"/>.</returns> public static Boolean ContainsAny <TElement, TEnumerator>(this IGetEnumerator <TElement, TEnumerator> collection, ArraySegment <TElement> elements) where TEnumerator : notnull, ICurrent <TElement>, IMoveNext => ContainsAny(collection, elements.AsSpan());