You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Zero/ZeroLevel/Services/MemoryPools/Collections/Linq/SelectMany.ExprWithContextE...

126 lines
4.0 KiB

using System;
namespace MemoryPools.Collections.Linq
{
internal class SelectManyExprWithContextEnumerable<T, TR, TContext> : IPoolingEnumerable<TR>
{
private IPoolingEnumerable<T> _src;
private Func<T, TContext, IPoolingEnumerable<TR>> _mutator;
private int _count;
private TContext _context;
public SelectManyExprWithContextEnumerable<T, TR, TContext> Init(
IPoolingEnumerable<T> src,
Func<T, TContext, IPoolingEnumerable<TR>> mutator,
TContext context)
{
_src = src;
_count = 0;
_context = context;
_mutator = mutator;
return this;
}
public IPoolingEnumerator<TR> GetEnumerator()
{
_count++;
return Pool<SelectManyExprWithContextEnumerator>.Get().Init(this, _src.GetEnumerator(), _mutator, _context);
}
private void Dispose()
{
if (_count == 0) return;
_count--;
if (_count == 0)
{
_src = default;
_count = 0;
_context = default;
_mutator = default;
Pool<SelectManyExprWithContextEnumerable<T, TR, TContext>>.Return(this);
}
}
internal class SelectManyExprWithContextEnumerator : IPoolingEnumerator<TR>
{
private TContext _context;
private Func<T, TContext, IPoolingEnumerable<TR>> _mutator;
private SelectManyExprWithContextEnumerable<T, TR, TContext> _parent;
private IPoolingEnumerator<T> _src;
private IPoolingEnumerator<TR> _currentEnumerator;
private bool _finished;
public SelectManyExprWithContextEnumerator Init(
SelectManyExprWithContextEnumerable<T, TR, TContext> parent,
IPoolingEnumerator<T> src,
Func<T, TContext, IPoolingEnumerable<TR>> mutator,
TContext context)
{
_src = src;
_finished = false;
_parent = parent;
_mutator = mutator;
_context = context;
_currentEnumerator = default;
return this;
}
public bool MoveNext()
{
if (_finished) return false;
if (_currentEnumerator == default)
{
if (!_src.MoveNext())
{
_finished = true;
return false;
}
_currentEnumerator = _mutator(_src.Current, _context).GetEnumerator();
}
do
{
var hasValue = _currentEnumerator.MoveNext();
if (hasValue) return true;
if (!_src.MoveNext())
{
_finished = true;
return false;
}
_currentEnumerator?.Dispose();
_currentEnumerator = _mutator(_src.Current, _context).GetEnumerator();
} while (true);
}
public void Reset()
{
_currentEnumerator?.Dispose();
_currentEnumerator = default;
_src.Reset();
}
object IPoolingEnumerator.Current => Current;
public TR Current => _currentEnumerator.Current;
public void Dispose()
{
_currentEnumerator?.Dispose();
_currentEnumerator = default;
_parent?.Dispose();
_parent = default;
_src.Dispose();
_src = default;
Pool<SelectManyExprWithContextEnumerator>.Return(this);
}
}
IPoolingEnumerator IPoolingEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}

Powered by TurnKey Linux.