UncheckedStack.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. // System.Collections.Generic.Stack<T>
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.Diagnostics;
  6. using System.Runtime.InteropServices;
  7. using System.Threading;
  8. [Serializable]
  9. [DebuggerDisplay("Count = {Count}")]
  10. [ComVisible(false)]
  11. public class UncheckedStack<T> : IEnumerable<T>, IEnumerable, ICollection, IReadOnlyCollection<T>
  12. {
  13. [Serializable]
  14. public struct Enumerator : IEnumerator<T>, IDisposable, IEnumerator
  15. {
  16. private UncheckedStack<T> _stack;
  17. private int _index;
  18. private int _version;
  19. private T currentElement;
  20. public T Current
  21. {
  22. get
  23. {
  24. return currentElement;
  25. }
  26. }
  27. object IEnumerator.Current
  28. {
  29. get
  30. {
  31. return currentElement;
  32. }
  33. }
  34. internal Enumerator(UncheckedStack<T> stack)
  35. {
  36. _stack = stack;
  37. _version = _stack._version;
  38. _index = -2;
  39. currentElement = default(T);
  40. }
  41. public void Dispose()
  42. {
  43. _index = -1;
  44. }
  45. public bool MoveNext()
  46. {
  47. bool flag;
  48. if (_index == -2)
  49. {
  50. _index = _stack._size - 1;
  51. flag = (_index >= 0);
  52. if (flag)
  53. {
  54. currentElement = _stack._array[_index];
  55. }
  56. return flag;
  57. }
  58. if (_index == -1)
  59. {
  60. return false;
  61. }
  62. flag = (--_index >= 0);
  63. if (flag)
  64. {
  65. currentElement = _stack._array[_index];
  66. }
  67. else
  68. {
  69. currentElement = default(T);
  70. }
  71. return flag;
  72. }
  73. void IEnumerator.Reset()
  74. {
  75. _index = -2;
  76. currentElement = default(T);
  77. }
  78. }
  79. private T[] _array;
  80. private int _size;
  81. private int _version;
  82. [NonSerialized]
  83. private object _syncRoot;
  84. private const int _defaultCapacity = 4;
  85. private static T[] _emptyArray = new T[0];
  86. public int Count
  87. {
  88. get
  89. {
  90. return _size;
  91. }
  92. }
  93. bool ICollection.IsSynchronized
  94. {
  95. get
  96. {
  97. return false;
  98. }
  99. }
  100. object ICollection.SyncRoot
  101. {
  102. get
  103. {
  104. if (_syncRoot == null)
  105. {
  106. Interlocked.CompareExchange<object>(ref _syncRoot, new object(), (object)null);
  107. }
  108. return _syncRoot;
  109. }
  110. }
  111. public UncheckedStack()
  112. {
  113. _array = _emptyArray;
  114. _size = 0;
  115. _version = 0;
  116. }
  117. public UncheckedStack(int capacity)
  118. {
  119. _array = new T[capacity];
  120. _size = 0;
  121. _version = 0;
  122. }
  123. public UncheckedStack(IEnumerable<T> collection)
  124. {
  125. ICollection<T> collection2 = collection as ICollection<T>;
  126. if (collection2 != null)
  127. {
  128. int count = collection2.Count;
  129. _array = new T[count];
  130. collection2.CopyTo(_array, 0);
  131. _size = count;
  132. return;
  133. }
  134. _size = 0;
  135. _array = new T[4];
  136. foreach (T item in collection)
  137. {
  138. T local = item;
  139. Push(ref local);
  140. }
  141. }
  142. public void Clear()
  143. {
  144. Array.Clear(_array, 0, _size);
  145. _size = 0;
  146. _version++;
  147. }
  148. public bool Contains(T item)
  149. {
  150. int size = _size;
  151. EqualityComparer<T> @default = EqualityComparer<T>.Default;
  152. while (size-- > 0)
  153. {
  154. if (item == null)
  155. {
  156. if (_array[size] == null)
  157. {
  158. return true;
  159. }
  160. }
  161. else if (_array[size] != null && @default.Equals(_array[size], item))
  162. {
  163. return true;
  164. }
  165. }
  166. return false;
  167. }
  168. public void CopyTo(T[] array, int arrayIndex)
  169. {
  170. Array.Copy(_array, 0, array, arrayIndex, _size);
  171. Array.Reverse(array, arrayIndex, _size);
  172. }
  173. void ICollection.CopyTo(Array array, int arrayIndex)
  174. {
  175. Array.Copy(_array, 0, array, arrayIndex, _size);
  176. Array.Reverse(array, arrayIndex, _size);
  177. }
  178. public Enumerator GetEnumerator()
  179. {
  180. return new Enumerator(this);
  181. }
  182. IEnumerator<T> IEnumerable<T>.GetEnumerator()
  183. {
  184. return new Enumerator(this);
  185. }
  186. IEnumerator IEnumerable.GetEnumerator()
  187. {
  188. return new Enumerator(this);
  189. }
  190. public void TrimExcess()
  191. {
  192. int num = (int)((double)_array.Length * 0.9);
  193. if (_size < num)
  194. {
  195. T[] array = new T[_size];
  196. Array.Copy(_array, 0, array, 0, _size);
  197. _array = array;
  198. _version++;
  199. }
  200. }
  201. public T Peek()
  202. {
  203. return _array[_size - 1];
  204. }
  205. public T Pop()
  206. {
  207. return _array[--_size];
  208. }
  209. public void Push(ref T item)
  210. {
  211. if (_size == _array.Length)
  212. {
  213. T[] array = new T[(_array.Length == 0) ? 4 : (2 * _array.Length)];
  214. Array.Copy(_array, 0, array, 0, _size);
  215. _array = array;
  216. }
  217. _array[_size++] = item;
  218. }
  219. public T[] ToArray()
  220. {
  221. T[] array = new T[_size];
  222. for (int i = 0; i < _size; i++)
  223. {
  224. array[i] = _array[_size - i - 1];
  225. }
  226. return array;
  227. }
  228. }