// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-#if NET_2_0
using System;
using System.Runtime.InteropServices;
+using System.Diagnostics;
namespace System.Collections.Generic
{
[ComVisible (false)]
- public class Stack <T> : IEnumerable <T>, ICollection, IEnumerable {
-
- T [] data;
- int size;
- int ver;
-
+ [Serializable]
+ [DebuggerDisplay ("Count={Count}")]
+ [DebuggerTypeProxy (typeof (CollectionDebuggerView))]
+ public class Stack <T> : IEnumerable <T>, ICollection, IEnumerable
+ {
+ T [] _array;
+ int _size;
+ int _version;
+
+ private const int INITIAL_SIZE = 16;
+
public Stack ()
{
}
- public Stack (int count)
+ public Stack (int capacity)
{
- if (count < 0)
- throw new ArgumentOutOfRangeException ("count");
-
- data = new T [count];
+ if (capacity < 0)
+ throw new ArgumentOutOfRangeException ("capacity");
+
+ _array = new T [capacity];
}
public Stack (IEnumerable <T> collection)
ICollection <T> col = collection as ICollection <T>;
-
if (col != null) {
- size = col.Count;
- data = new T [size];
- col.CopyTo (data, 0);
+ _size = col.Count;
+ _array = new T [_size];
+ col.CopyTo (_array, 0);
} else {
foreach (T t in collection)
Push (t);
public void Clear ()
{
- if (data != null)
- Array.Clear (data, 0, data.Length);
+ if (_array != null)
+ Array.Clear (_array, 0, _array.Length);
- size = 0;
- ver ++;
+ _size = 0;
+ _version ++;
}
- public bool Contains (T t)
+ public bool Contains (T item)
{
- return data != null && Array.IndexOf (data, t, 0, size) != -1;
+ return _array != null && Array.IndexOf (_array, item, 0, _size) != -1;
}
- public void CopyTo (T [] dest, int idx)
+ public void CopyTo (T [] array, int arrayIndex)
{
+ if (array == null)
+ throw new ArgumentNullException ("array");
+ if (arrayIndex < 0)
+ throw new ArgumentOutOfRangeException ("idx");
+
// this gets copied in the order that it is poped
- if (data != null) {
- Array.Copy (data, 0, dest, idx, size);
- Array.Reverse (dest, idx, size);
+ if (_array != null) {
+ Array.Copy (_array, 0, array, arrayIndex, _size);
+ Array.Reverse (array, arrayIndex, _size);
}
}
public T Peek ()
{
- if (size == 0)
+ if (_size == 0)
throw new InvalidOperationException ();
- ver ++;
-
- return data [size - 1];
+ return _array [_size - 1];
}
public T Pop ()
{
- if (size == 0)
+ if (_size == 0)
throw new InvalidOperationException ();
- ver ++;
-
- return data [-- size];
+ _version ++;
+ T popped = _array [--_size];
+ // clear stuff out to make the GC happy
+ _array [_size] = default(T);
+ return popped;
}
- public void Push (T t)
+ public void Push (T item)
{
- if (size == 0 || size == data.Length)
- Array.Resize <T> (ref data, size == 0 ? 10 : 2 * size);
+ if (_array == null || _size == _array.Length)
+ Array.Resize <T> (ref _array, _size == 0 ? INITIAL_SIZE : 2 * _size);
- ver ++;
+ _version ++;
- data [size++] = t;
+ _array [_size++] = item;
}
public T [] ToArray ()
{
- T [] copy = new T [size];
+ T [] copy = new T [_size];
CopyTo (copy, 0);
return copy;
}
-
- public void TrimToSize ()
+
+ public void TrimExcess ()
{
- // for some broken reason, msft increments the version here
- ver ++;
-
- if (size == 0)
- data = null;
- else
- Array.Resize <T> (ref data, size);
+ if (_array != null && (_size < _array.Length * 0.9))
+ Array.Resize <T> (ref _array, _size);
+ _version ++;
}
public int Count {
- get { return size; }
+ get { return _size; }
}
bool ICollection.IsSynchronized {
void ICollection.CopyTo (Array dest, int idx)
{
try {
- if (data != null) {
- data.CopyTo (dest, idx);
- Array.Reverse (dest, idx, size);
+ if (_array != null) {
+ Array.Copy (_array, 0, dest, idx, _size);
+ Array.Reverse (dest, idx, _size);
}
} catch (ArrayTypeMismatchException) {
throw new ArgumentException ();
return GetEnumerator ();
}
+ [Serializable]
public struct Enumerator : IEnumerator <T>, IEnumerator, IDisposable {
const int NOT_STARTED = -2;
// this MUST be -1, because we depend on it in move next.
- // we just decr the size, so, 0 - 1 == FINISHED
+ // we just decr the _size, so, 0 - 1 == FINISHED
const int FINISHED = -1;
Stack <T> parent;
int idx;
- int ver;
+ int _version;
internal Enumerator (Stack <T> t)
{
parent = t;
idx = NOT_STARTED;
- ver = t.ver;
+ _version = t._version;
}
// for some fucked up reason, MSFT added a useless dispose to this class
// broken.
public void Dispose ()
{
- idx = NOT_STARTED;
+ idx = FINISHED;
}
public bool MoveNext ()
{
- if (ver != parent.ver)
+ if (_version != parent._version)
throw new InvalidOperationException ();
if (idx == -2)
- idx = parent.size;
+ idx = parent._size;
return idx != FINISHED && -- idx != FINISHED;
}
if (idx < 0)
throw new InvalidOperationException ();
- return parent.data [idx];
+ return parent._array [idx];
}
}
void IEnumerator.Reset ()
{
- if (ver != parent.ver)
+ if (_version != parent._version)
throw new InvalidOperationException ();
idx = NOT_STARTED;
}
}
}
-#endif