Stack.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / CompMod / System / Collections / Generic / Stack.cs / 1 / Stack.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
/*==============================================================================
** 
** Class: Stack 
**
** Purpose: An array implementation of a generic stack. 
**
** Date: January 28, 2003
**
=============================================================================*/ 
namespace System.Collections.Generic {
    using System; 
    using System.Security.Permissions; 
    using System.Diagnostics;
 
    // A simple stack of objects.  Internally it is implemented as an array,
    // so Push can be O(n).  Pop is O(1).
    [DebuggerTypeProxy(typeof(System_StackDebugView<>))]
    [DebuggerDisplay("Count = {Count}")] 
    [Serializable()]
    [System.Runtime.InteropServices.ComVisible(false)] 
    public class Stack : IEnumerable, 
        System.Collections.ICollection {
        private T[] _array;     // Storage for stack elements 
        private int _size;           // Number of items in the stack.
        private int _version;        // Used to keep enumerator in [....] w/ collection.
        [NonSerialized]
        private Object _syncRoot; 

        private const int _defaultCapacity = 4; 
        static T[] _emptyArray = new T[0]; 

        ///  
        public Stack() {
            _array = _emptyArray;
            _size = 0;
            _version = 0; 
        }
 
        // Create a stack with a specific initial capacity.  The initial capacity 
        // must be a non-negative number.
        ///  
        public Stack(int capacity) {
            if (capacity < 0)
                ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.capacity, ExceptionResource.ArgumentOutOfRange_NeedNonNegNumRequired);
            _array = new T[capacity]; 
            _size = 0;
            _version = 0; 
        } 

        // Fills a Stack with the contents of a particular collection.  The items are 
        // pushed onto the stack in the same order they are read by the enumerator.
        //
        /// 
        public Stack(IEnumerable collection) 
        {
            if (collection==null) 
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection); 

            ICollection c = collection as ICollection; 
            if( c != null) {
                int count = c.Count;
                _array = new T[count];
                c.CopyTo(_array, 0); 
                _size = count;
            } 
            else { 
                _size = 0;
                _array = new T[_defaultCapacity]; 

                using(IEnumerator en = collection.GetEnumerator()) {
                    while(en.MoveNext()) {
                        Push(en.Current); 
                    }
                } 
            } 
        }
 
        /// 
        public int Count {
            get { return _size; }
        } 

        ///  
        bool System.Collections.ICollection.IsSynchronized { 
            get { return false; }
        } 

        /// 
        Object System.Collections.ICollection.SyncRoot {
            get { 
                if( _syncRoot == null) {
                    System.Threading.Interlocked.CompareExchange(ref _syncRoot, new Object(), null); 
                } 
                return _syncRoot;
            } 
        }

        // Removes all Objects from the Stack.
        ///  
        public void Clear() {
            Array.Clear(_array, 0, _size); // Don't need to doc this but we clear the elements so that the gc can reclaim the references. 
            _size = 0; 
            _version++;
        } 

        /// 
        public bool Contains(T item) {
            int count = _size; 

            EqualityComparer c = EqualityComparer.Default; 
            while (count-- > 0) { 
                if (((Object) item) == null) {
                    if (((Object) _array[count]) == null) 
                        return true;
                }
                else if (_array[count] != null && c.Equals(_array[count], item) ) {
                    return true; 
                }
            } 
            return false; 
        }
 
        // Copies the stack into an array.
        /// 
        public void CopyTo(T[] array, int arrayIndex) {
            if (array==null) { 
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
            } 
 
            if (arrayIndex < 0 || arrayIndex > array.Length) {
                ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.arrayIndex, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); 
            }

            if (array.Length - arrayIndex < _size) {
                ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen); 
            }
 
            Array.Copy(_array, 0, array, arrayIndex, _size); 
            Array.Reverse(array, arrayIndex, _size);
        } 

        void System.Collections.ICollection.CopyTo(Array array, int arrayIndex) {
            if (array==null) {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array); 
            }
 
            if (array.Rank != 1) { 
                ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
            } 

            if( array.GetLowerBound(0) != 0 ) {
                ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
            } 

            if (arrayIndex < 0 || arrayIndex > array.Length) { 
                ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.arrayIndex, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); 
            }
 
            if (array.Length - arrayIndex < _size) {
                ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
            }
 
            try {
                Array.Copy(_array, 0, array, arrayIndex, _size); 
                Array.Reverse(array, arrayIndex, _size); 
            }
            catch(ArrayTypeMismatchException){ 
                ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
            }
        }
 
        // Returns an IEnumerator for this Stack.
        ///  
        public Enumerator GetEnumerator() { 
            return new Enumerator(this);
        } 

        /// 
        /// 
        IEnumerator IEnumerable.GetEnumerator() { 
            return new Enumerator(this);
        } 
 
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
            return new Enumerator(this); 
        }

        public void TrimExcess() {
            int threshold = (int)(((double)_array.Length) * 0.9); 
            if( _size < threshold ) {
                T[] newarray = new T[_size]; 
                Array.Copy(_array, 0, newarray, 0, _size); 
                _array = newarray;
                _version++; 
            }
        }

        // Returns the top object on the stack without removing it.  If the stack 
        // is empty, Peek throws an InvalidOperationException.
        ///  
        public T Peek() { 
            if (_size==0)
                ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EmptyStack); 
            return _array[_size-1];
        }

        // Pops an item from the top of the stack.  If the stack is empty, Pop 
        // throws an InvalidOperationException.
        ///  
        public T Pop() { 
            if (_size == 0)
                ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EmptyStack); 
            _version++;
            T item = _array[--_size];
            _array[_size] = default(T);     // Free memory quicker.
            return item; 
        }
 
        // Pushes an item to the top of the stack. 
        //
        ///  
        public void Push(T item) {
            if (_size == _array.Length) {
                T[] newArray = new T[(_array.Length == 0) ? _defaultCapacity : 2*_array.Length];
                Array.Copy(_array, 0, newArray, 0, _size); 
                _array = newArray;
            } 
            _array[_size++] = item; 
            _version++;
        } 

        // Copies the Stack to an array, in the same order Pop would return the items.
        public T[] ToArray()
        { 
            T[] objArray = new T[_size];
            int i = 0; 
            while(i < _size) { 
                objArray[i] = _array[_size-i-1];
                i++; 
            }
            return objArray;
        }
 
        /// 
        [Serializable()] 
        public struct Enumerator : IEnumerator, 
            System.Collections.IEnumerator
        { 
            private Stack _stack;
            private int _index;
            private int _version;
            private T currentElement; 

            internal Enumerator(Stack stack) { 
                _stack = stack; 
                _version = _stack._version;
                _index = -2; 
                currentElement = default(T);
            }

            ///  
            public void Dispose()
            { 
                _index = -1; 
            }
 
            /// 
            public bool MoveNext() {
                bool retval;
                if (_version != _stack._version) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion); 
                if (_index == -2) {  // First call to enumerator.
                    _index = _stack._size-1; 
                    retval = ( _index >= 0); 
                    if (retval)
                        currentElement = _stack._array[_index]; 
                    return retval;
                }
                if (_index == -1) {  // End of enumeration.
                    return false; 
                }
 
                retval = (--_index >= 0); 
                if (retval)
                    currentElement = _stack._array[_index]; 
                else
                    currentElement = default(T);
                return retval;
            } 

            ///  
            public T Current { 
                get {
                    if (_index == -2) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumNotStarted); 
                    if (_index == -1) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumEnded);
                    return currentElement;
                }
            } 

            Object System.Collections.IEnumerator.Current { 
                get { 
                    if (_index == -2) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumNotStarted);
                    if (_index == -1) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumEnded); 
                    return currentElement;
                }
            }
 
            void System.Collections.IEnumerator.Reset() {
                if (_version != _stack._version) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion); 
                _index = -2; 
                currentElement = default(T);
            } 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
/*==============================================================================
** 
** Class: Stack 
**
** Purpose: An array implementation of a generic stack. 
**
** Date: January 28, 2003
**
=============================================================================*/ 
namespace System.Collections.Generic {
    using System; 
    using System.Security.Permissions; 
    using System.Diagnostics;
 
    // A simple stack of objects.  Internally it is implemented as an array,
    // so Push can be O(n).  Pop is O(1).
    [DebuggerTypeProxy(typeof(System_StackDebugView<>))]
    [DebuggerDisplay("Count = {Count}")] 
    [Serializable()]
    [System.Runtime.InteropServices.ComVisible(false)] 
    public class Stack : IEnumerable, 
        System.Collections.ICollection {
        private T[] _array;     // Storage for stack elements 
        private int _size;           // Number of items in the stack.
        private int _version;        // Used to keep enumerator in [....] w/ collection.
        [NonSerialized]
        private Object _syncRoot; 

        private const int _defaultCapacity = 4; 
        static T[] _emptyArray = new T[0]; 

        ///  
        public Stack() {
            _array = _emptyArray;
            _size = 0;
            _version = 0; 
        }
 
        // Create a stack with a specific initial capacity.  The initial capacity 
        // must be a non-negative number.
        ///  
        public Stack(int capacity) {
            if (capacity < 0)
                ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.capacity, ExceptionResource.ArgumentOutOfRange_NeedNonNegNumRequired);
            _array = new T[capacity]; 
            _size = 0;
            _version = 0; 
        } 

        // Fills a Stack with the contents of a particular collection.  The items are 
        // pushed onto the stack in the same order they are read by the enumerator.
        //
        /// 
        public Stack(IEnumerable collection) 
        {
            if (collection==null) 
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection); 

            ICollection c = collection as ICollection; 
            if( c != null) {
                int count = c.Count;
                _array = new T[count];
                c.CopyTo(_array, 0); 
                _size = count;
            } 
            else { 
                _size = 0;
                _array = new T[_defaultCapacity]; 

                using(IEnumerator en = collection.GetEnumerator()) {
                    while(en.MoveNext()) {
                        Push(en.Current); 
                    }
                } 
            } 
        }
 
        /// 
        public int Count {
            get { return _size; }
        } 

        ///  
        bool System.Collections.ICollection.IsSynchronized { 
            get { return false; }
        } 

        /// 
        Object System.Collections.ICollection.SyncRoot {
            get { 
                if( _syncRoot == null) {
                    System.Threading.Interlocked.CompareExchange(ref _syncRoot, new Object(), null); 
                } 
                return _syncRoot;
            } 
        }

        // Removes all Objects from the Stack.
        ///  
        public void Clear() {
            Array.Clear(_array, 0, _size); // Don't need to doc this but we clear the elements so that the gc can reclaim the references. 
            _size = 0; 
            _version++;
        } 

        /// 
        public bool Contains(T item) {
            int count = _size; 

            EqualityComparer c = EqualityComparer.Default; 
            while (count-- > 0) { 
                if (((Object) item) == null) {
                    if (((Object) _array[count]) == null) 
                        return true;
                }
                else if (_array[count] != null && c.Equals(_array[count], item) ) {
                    return true; 
                }
            } 
            return false; 
        }
 
        // Copies the stack into an array.
        /// 
        public void CopyTo(T[] array, int arrayIndex) {
            if (array==null) { 
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
            } 
 
            if (arrayIndex < 0 || arrayIndex > array.Length) {
                ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.arrayIndex, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); 
            }

            if (array.Length - arrayIndex < _size) {
                ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen); 
            }
 
            Array.Copy(_array, 0, array, arrayIndex, _size); 
            Array.Reverse(array, arrayIndex, _size);
        } 

        void System.Collections.ICollection.CopyTo(Array array, int arrayIndex) {
            if (array==null) {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array); 
            }
 
            if (array.Rank != 1) { 
                ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
            } 

            if( array.GetLowerBound(0) != 0 ) {
                ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
            } 

            if (arrayIndex < 0 || arrayIndex > array.Length) { 
                ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.arrayIndex, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum); 
            }
 
            if (array.Length - arrayIndex < _size) {
                ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
            }
 
            try {
                Array.Copy(_array, 0, array, arrayIndex, _size); 
                Array.Reverse(array, arrayIndex, _size); 
            }
            catch(ArrayTypeMismatchException){ 
                ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
            }
        }
 
        // Returns an IEnumerator for this Stack.
        ///  
        public Enumerator GetEnumerator() { 
            return new Enumerator(this);
        } 

        /// 
        /// 
        IEnumerator IEnumerable.GetEnumerator() { 
            return new Enumerator(this);
        } 
 
        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
            return new Enumerator(this); 
        }

        public void TrimExcess() {
            int threshold = (int)(((double)_array.Length) * 0.9); 
            if( _size < threshold ) {
                T[] newarray = new T[_size]; 
                Array.Copy(_array, 0, newarray, 0, _size); 
                _array = newarray;
                _version++; 
            }
        }

        // Returns the top object on the stack without removing it.  If the stack 
        // is empty, Peek throws an InvalidOperationException.
        ///  
        public T Peek() { 
            if (_size==0)
                ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EmptyStack); 
            return _array[_size-1];
        }

        // Pops an item from the top of the stack.  If the stack is empty, Pop 
        // throws an InvalidOperationException.
        ///  
        public T Pop() { 
            if (_size == 0)
                ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EmptyStack); 
            _version++;
            T item = _array[--_size];
            _array[_size] = default(T);     // Free memory quicker.
            return item; 
        }
 
        // Pushes an item to the top of the stack. 
        //
        ///  
        public void Push(T item) {
            if (_size == _array.Length) {
                T[] newArray = new T[(_array.Length == 0) ? _defaultCapacity : 2*_array.Length];
                Array.Copy(_array, 0, newArray, 0, _size); 
                _array = newArray;
            } 
            _array[_size++] = item; 
            _version++;
        } 

        // Copies the Stack to an array, in the same order Pop would return the items.
        public T[] ToArray()
        { 
            T[] objArray = new T[_size];
            int i = 0; 
            while(i < _size) { 
                objArray[i] = _array[_size-i-1];
                i++; 
            }
            return objArray;
        }
 
        /// 
        [Serializable()] 
        public struct Enumerator : IEnumerator, 
            System.Collections.IEnumerator
        { 
            private Stack _stack;
            private int _index;
            private int _version;
            private T currentElement; 

            internal Enumerator(Stack stack) { 
                _stack = stack; 
                _version = _stack._version;
                _index = -2; 
                currentElement = default(T);
            }

            ///  
            public void Dispose()
            { 
                _index = -1; 
            }
 
            /// 
            public bool MoveNext() {
                bool retval;
                if (_version != _stack._version) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion); 
                if (_index == -2) {  // First call to enumerator.
                    _index = _stack._size-1; 
                    retval = ( _index >= 0); 
                    if (retval)
                        currentElement = _stack._array[_index]; 
                    return retval;
                }
                if (_index == -1) {  // End of enumeration.
                    return false; 
                }
 
                retval = (--_index >= 0); 
                if (retval)
                    currentElement = _stack._array[_index]; 
                else
                    currentElement = default(T);
                return retval;
            } 

            ///  
            public T Current { 
                get {
                    if (_index == -2) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumNotStarted); 
                    if (_index == -1) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumEnded);
                    return currentElement;
                }
            } 

            Object System.Collections.IEnumerator.Current { 
                get { 
                    if (_index == -2) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumNotStarted);
                    if (_index == -1) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumEnded); 
                    return currentElement;
                }
            }
 
            void System.Collections.IEnumerator.Reset() {
                if (_version != _stack._version) ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion); 
                _index = -2; 
                currentElement = default(T);
            } 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK