PageRenderTime 19ms CodeModel.GetById 7ms app.highlight 6ms RepoModel.GetById 2ms app.codeStats 0ms

/AvalonEdit/ICSharpCode.AvalonEdit/Utils/ImmutableStack.cs

http://github.com/icsharpcode/ILSpy
C# | 132 lines | 71 code | 13 blank | 48 comment | 4 complexity | 52876920a9ce8283727e3d01f7014827 MD5 | raw file
  1// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
  2// 
  3// Permission is hereby granted, free of charge, to any person obtaining a copy of this
  4// software and associated documentation files (the "Software"), to deal in the Software
  5// without restriction, including without limitation the rights to use, copy, modify, merge,
  6// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
  7// to whom the Software is furnished to do so, subject to the following conditions:
  8// 
  9// The above copyright notice and this permission notice shall be included in all copies or
 10// substantial portions of the Software.
 11// 
 12// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 13// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 14// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
 15// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 16// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 17// DEALINGS IN THE SOFTWARE.
 18
 19using System;
 20using System.Collections.Generic;
 21using System.Diagnostics;
 22using System.Text;
 23
 24namespace ICSharpCode.AvalonEdit.Utils
 25{
 26	/// <summary>
 27	/// An immutable stack.
 28	/// 
 29	/// Using 'foreach' on the stack will return the items from top to bottom (in the order they would be popped).
 30	/// </summary>
 31	[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
 32	[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix")]
 33	[Serializable]
 34	public sealed class ImmutableStack<T> : IEnumerable<T>
 35	{
 36		/// <summary>
 37		/// Gets the empty stack instance.
 38		/// </summary>
 39		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "ImmutableStack is immutable")]
 40		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")]
 41		public static readonly ImmutableStack<T> Empty = new ImmutableStack<T>();
 42		
 43		readonly T value;
 44		readonly ImmutableStack<T> next;
 45		
 46		private ImmutableStack()
 47		{
 48		}
 49		
 50		private ImmutableStack(T value, ImmutableStack<T> next)
 51		{
 52			this.value = value;
 53			this.next = next;
 54		}
 55		
 56		/// <summary>
 57		/// Pushes an item on the stack. This does not modify the stack itself, but returns a new
 58		/// one with the value pushed.
 59		/// </summary>
 60		public ImmutableStack<T> Push(T item)
 61		{
 62			return new ImmutableStack<T>(item, this);
 63		}
 64		
 65		/// <summary>
 66		/// Gets the item on the top of the stack.
 67		/// </summary>
 68		/// <exception cref="InvalidOperationException">The stack is empty.</exception>
 69		public T Peek()
 70		{
 71			if (IsEmpty)
 72				throw new InvalidOperationException("Operation not valid on empty stack.");
 73			return value;
 74		}
 75		
 76		/// <summary>
 77		/// Gets the item on the top of the stack.
 78		/// Returns <c>default(T)</c> if the stack is empty.
 79		/// </summary>
 80		public T PeekOrDefault()
 81		{
 82			return value;
 83		}
 84		
 85		/// <summary>
 86		/// Gets the stack with the top item removed.
 87		/// </summary>
 88		/// <exception cref="InvalidOperationException">The stack is empty.</exception>
 89		public ImmutableStack<T> Pop()
 90		{
 91			if (IsEmpty)
 92				throw new InvalidOperationException("Operation not valid on empty stack.");
 93			return next;
 94		}
 95		
 96		/// <summary>
 97		/// Gets if this stack is empty.
 98		/// </summary>
 99		public bool IsEmpty {
100			get { return next == null; }
101		}
102		
103		/// <summary>
104		/// Gets an enumerator that iterates through the stack top-to-bottom.
105		/// </summary>
106		public IEnumerator<T> GetEnumerator()
107		{
108			ImmutableStack<T> t = this;
109			while (!t.IsEmpty) {
110				yield return t.value;
111				t = t.next;
112			}
113		}
114		
115		System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
116		{
117			return this.GetEnumerator();
118		}
119		
120		/// <inheritdoc/>
121		public override string ToString()
122		{
123			StringBuilder b = new StringBuilder("[Stack");
124			foreach (T val in this) {
125				b.Append(' ');
126				b.Append(val);
127			}
128			b.Append(']');
129			return b.ToString();
130		}
131	}
132}