// 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;
}
}