// ----------------------------------------------------------------------------- // file="RandomAccessibleStack" // Project: StgSharp // Copyright (c) Nitload. // SPDX-License-Identifier: MIT // ----------------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; namespace StgSharp.Collections { public class RandomAccessibleStack : IEnumerable { private const int DefaultCapacity = 4; private T[] _array; private int _size; private int _version; /// /// Initializes a new instance of the RandomAccessStack class that is empty and has the /// default initial capacity. /// public RandomAccessibleStack() { _array = new T[DefaultCapacity]; } /// /// Initializes a new instance of the RandomAccessStack class that is empty and has the /// specified initial capacity. /// public RandomAccessibleStack( int capacity ) { if (capacity < 0) { throw new ArgumentOutOfRangeException( nameof(capacity), "Capacity must be non-negative."); } _array = new T[capacity]; } /// /// Gets or sets the element at the specified index in the stack (0 = bottom, Count-1 = /// top). /// public T this[ int index ] { get { if (index < 0 || index >= _size) { throw new ArgumentOutOfRangeException(nameof(index)); } return _array[index]; } /* set { if( index < 0 || index >= PrimSize ) { throw new ArgumentOutOfRangeException( nameof( index ) ); } _array[ index ] = value; _version++; } /**/ } /// /// Gets the number of elements contained in the stack. /// public int Count => _size; /// /// Removes all objects from the stack. /// public void Clear() { Array.Clear(_array, 0, _size); _size = 0; _version++; } /// /// Returns an enumerator that iterates through the stack from top to bottom. Throws if /// the stack is modified during iteration. /// public IEnumerator GetEnumerator() { int expectedVersion = _version; for (int i = _size - 1; i >= 0; i--) { if (expectedVersion != _version) { throw new InvalidOperationException( "Collection was modified during enumeration."); } yield return _array[i]; } } /// /// Returns the object at the top of the stack without removing it. /// public T Peek() { if (_size == 0) { throw new InvalidOperationException("Stack is empty."); } return _array[_size - 1]; } /// /// Removes and returns the object at the top of the stack. /// public T Pop() { if (_size == 0) { throw new InvalidOperationException("Stack is empty."); } T item = _array[--_size]; _array[_size] = default!; _version++; return item; } /// /// Adds an item to the top of the stack. /// public void Push( T item ) { if (_size == _array.Length) { EnsureCapacity(_size + 1); } _array[_size++] = item; _version++; } private void EnsureCapacity( int min ) { int newCapacity = _array.Length == 0 ? DefaultCapacity : _array.Length * 2; if (newCapacity < min) { newCapacity = min; } Array.Resize(ref _array, newCapacity); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } }