//----------------------------------------------------------------------- // ----------------------------------------------------------------------- // file="RandomAccessibleStack.cs" // Project: StgSharp // AuthorGroup: Nitload Space // Copyright (c) Nitload Space. All rights reserved. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the “Software”), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and // this permission notice shall be included in all copies // or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED “AS IS”, // WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, // ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; 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() => GetEnumerator(); } }