|
|
|
|
using System;
|
|
|
|
|
|
|
|
|
|
namespace MemoryPools.Collections.Linq
|
|
|
|
|
{
|
|
|
|
|
public static partial class PoolingEnumerable
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets first element from sequence. Complexity = O(1)
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static T First<T>(this IPoolingEnumerable<T> source)
|
|
|
|
|
{
|
|
|
|
|
var enumerator = source.GetEnumerator();
|
|
|
|
|
var hasItems = enumerator.MoveNext();
|
|
|
|
|
if (!hasItems)
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException("Sequence is empty");
|
|
|
|
|
}
|
|
|
|
|
var element = enumerator.Current;
|
|
|
|
|
enumerator.Dispose();
|
|
|
|
|
return element;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets first element from sequence by given <paramref name="condition"/>. Complexity = O(1) - O(N)
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static T First<T>(this IPoolingEnumerable<T> source, Func<T, bool> condition)
|
|
|
|
|
{
|
|
|
|
|
var enumerator = source.GetEnumerator();
|
|
|
|
|
while (enumerator.MoveNext())
|
|
|
|
|
{
|
|
|
|
|
if (condition(enumerator.Current))
|
|
|
|
|
{
|
|
|
|
|
var item = enumerator.Current;
|
|
|
|
|
enumerator.Dispose();
|
|
|
|
|
return item;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
enumerator.Dispose();
|
|
|
|
|
throw new InvalidOperationException("Sequence is empty");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets first element from sequence by given <paramref name="condition"/>. Complexity = O(1) - O(N)
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static T First<T, TContext>(this IPoolingEnumerable<T> source, TContext context, Func<TContext, T, bool> condition)
|
|
|
|
|
{
|
|
|
|
|
var enumerator = source.GetEnumerator();
|
|
|
|
|
while (enumerator.MoveNext())
|
|
|
|
|
{
|
|
|
|
|
if (!condition(context, enumerator.Current)) continue;
|
|
|
|
|
|
|
|
|
|
var item = enumerator.Current;
|
|
|
|
|
enumerator.Dispose();
|
|
|
|
|
return item;
|
|
|
|
|
}
|
|
|
|
|
enumerator.Dispose();
|
|
|
|
|
throw new InvalidOperationException("Sequence is empty");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets first element from sequence. Complexity = O(1)
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static T FirstOrDefault<T>(this IPoolingEnumerable<T> source)
|
|
|
|
|
{
|
|
|
|
|
var enumerator = source.GetEnumerator();
|
|
|
|
|
var hasItem = enumerator.MoveNext();
|
|
|
|
|
|
|
|
|
|
var item = hasItem ? enumerator.Current : default;
|
|
|
|
|
enumerator.Dispose();
|
|
|
|
|
|
|
|
|
|
return item!;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets first element from sequence by given <paramref name="condition"/>. Complexity = O(1) - O(N)
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static T FirstOrDefault<T>(this IPoolingEnumerable<T> source, Func<T, bool> condition)
|
|
|
|
|
{
|
|
|
|
|
var enumerator = source.GetEnumerator();
|
|
|
|
|
while (enumerator.MoveNext())
|
|
|
|
|
{
|
|
|
|
|
if (!condition(enumerator.Current)) continue;
|
|
|
|
|
|
|
|
|
|
var elem = enumerator.Current;
|
|
|
|
|
enumerator.Dispose();
|
|
|
|
|
return elem;
|
|
|
|
|
}
|
|
|
|
|
enumerator.Dispose();
|
|
|
|
|
return default!;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets first element from sequence by given <paramref name="condition"/>. Complexity = O(1) - O(N)
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static T FirstOrDefault<T, TContext>(this IPoolingEnumerable<T> source, TContext context, Func<TContext, T, bool> condition)
|
|
|
|
|
{
|
|
|
|
|
var enumerator = source.GetEnumerator();
|
|
|
|
|
while (enumerator.MoveNext())
|
|
|
|
|
{
|
|
|
|
|
if (!condition(context, enumerator.Current)) continue;
|
|
|
|
|
|
|
|
|
|
var elem = enumerator.Current;
|
|
|
|
|
enumerator.Dispose();
|
|
|
|
|
return elem;
|
|
|
|
|
}
|
|
|
|
|
enumerator.Dispose();
|
|
|
|
|
return default!;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|