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();
 | |
|         }
 | |
|     }
 | |
| } |