// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. using System; using System.Collections.Generic; namespace Flax.Build { /// /// The two-way enumerator interface that can move forward or backwards. /// /// The element type. /// public interface ITwoWayEnumerator : IEnumerator { /// /// Advances the enumerator to the previous element of the collection. /// /// /// if the enumerator was successfully advanced to the previous element; if the enumerator has passed the beginning of the collection. /// The collection was modified after the enumerator was created. bool MovePrevious(); } /// /// The implementation of the that uses a list. /// /// The element type. /// public class TwoWayEnumerator : ITwoWayEnumerator { private IEnumerator _enumerator; private List _buffer; private int _index; /// /// Initializes a new instance of the class. /// /// The enumerator. public TwoWayEnumerator(IEnumerator enumerator) { _enumerator = enumerator ?? throw new ArgumentNullException("enumerator"); _buffer = new List(); _index = -1; } /// /// Advances the enumerator to the previous element of the collection. /// /// if the enumerator was successfully advanced to the previous element; if the enumerator has passed the beginning of the collection. public bool MovePrevious() { if (_index <= 0) { return false; } --_index; return true; } /// /// Advances the enumerator to the next element of the collection. /// /// if the enumerator was successfully advanced to the next element; if the enumerator has passed the end of the collection. public bool MoveNext() { if (_index < _buffer.Count - 1) { ++_index; return true; } if (_enumerator.MoveNext()) { _buffer.Add(_enumerator.Current); ++_index; return true; } return false; } /// /// Gets the element in the collection at the current position of the enumerator. /// public T Current { get { if (_index < 0 || _index >= _buffer.Count) throw new InvalidOperationException(); return _buffer[_index]; } } /// /// Sets the enumerator to its initial position, which is before the first element in the collection. /// public void Reset() { _enumerator.Reset(); _buffer.Clear(); _index = -1; } /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// public void Dispose() { _enumerator.Dispose(); } /// /// Gets the element in the collection at the current position of the enumerator. /// object System.Collections.IEnumerator.Current => Current; } }