56 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			56 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			C#
		
	
	
using System;
 | 
						|
using System.Collections.Generic;
 | 
						|
 | 
						|
namespace ProtoBuf.Reflection
 | 
						|
{
 | 
						|
    internal sealed class Peekable<T> : IDisposable
 | 
						|
    {
 | 
						|
        public override string ToString()
 | 
						|
        {
 | 
						|
            T val;
 | 
						|
            return Peek(out val) ? (val?.ToString() ?? "(null)") : "(EOF)";
 | 
						|
        }
 | 
						|
        private readonly IEnumerator<T> _iter;
 | 
						|
        private T _peek, _prev;
 | 
						|
        private bool _havePeek, _eof;
 | 
						|
        public Peekable(IEnumerable<T> sequence)
 | 
						|
        {
 | 
						|
            _iter = sequence.GetEnumerator();
 | 
						|
        }
 | 
						|
        public T Previous => _prev;
 | 
						|
        public bool Consume()
 | 
						|
        {
 | 
						|
            T val;
 | 
						|
            bool haveData = _havePeek || Peek(out val);
 | 
						|
            _prev = _peek;
 | 
						|
            _havePeek = false;            
 | 
						|
            return haveData;
 | 
						|
        }
 | 
						|
        public bool Peek(out T next)
 | 
						|
        {
 | 
						|
            if (!_havePeek)
 | 
						|
            {
 | 
						|
                if (_iter.MoveNext())
 | 
						|
                {
 | 
						|
                    _prev = _peek;
 | 
						|
                    _peek = _iter.Current;
 | 
						|
                    _havePeek = true;
 | 
						|
                }
 | 
						|
                else
 | 
						|
                {
 | 
						|
                    _eof = true;
 | 
						|
                    _havePeek = false;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            if (_eof)
 | 
						|
            {
 | 
						|
                next = default(T);
 | 
						|
                return false;
 | 
						|
            }
 | 
						|
            next = _peek;
 | 
						|
            return true;
 | 
						|
        }
 | 
						|
        public void Dispose() => _iter?.Dispose();
 | 
						|
    }
 | 
						|
}
 |