//----------------------------------------------------------------------- // ----------------------------------------------------------------------- // file="RandomAccessibleStack" // Project: StgSharp // AuthorGroup: Nitload // Copyright (c) Nitload. 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; 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(); } } }