UncheckedStack.cs 4.2 KB

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