Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2929_PrioritizedGrammarEnumeration/HeuristicLab.ExtLibs/HeuristicLab.AvalonEdit/5.0.1/AvalonEdit-5.0.1/Utils/ImmutableStack.cs @ 16452

Last change on this file since 16452 was 11700, checked in by jkarder, 10 years ago

#2077: created branch and added first version

File size: 4.1 KB
Line 
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}
Note: See TracBrowser for help on using the repository browser.