mirror of https://github.com/ogoun/Zero.git
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.
126 lines
4.0 KiB
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();
|
|
}
|
|
}
|
|
} |