Imported Upstream version 3.6.0

Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
This commit is contained in:
Jo Shields
2014-08-13 10:39:27 +01:00
commit a575963da9
50588 changed files with 8155799 additions and 0 deletions

View File

@@ -0,0 +1,304 @@
2010-04-09 Raja R Harinath <harinath@hurrynot.org>
Don't maintain state in the view
* SortedSet.cs (SortedSubSet.count): Remove.
(SortedSubSet..ctor): Move counting loop ...
(SortedSubSet.Count): ... here.
(SortedSubSet.TryAdd, SortedSubSet.TryRemove): Update to changes.
(SortedSubSet.GetMin, SortedSubSet.GetMax): Likewise. Use bounds
to determine if the view is empty, rather than the count.
2010-04-07 Raja R Harinath <harinath@hurrynot.org>
Enable set comparision operations on views, and improve performance
* RBTree.cs (Bound): New. Returns the greatest lower bound and
least upper bound of the given key.
(GetSuffixEnumerator): New. Returns an enumerator that starts at
the given key.
(NodeEnumerator): Provide suffix enumerator functionality.
* SortedSet.cs (GetEnumerator): Delegate to ...
(TryGetEnumerator): ... this. New virtual function.
(Enumerator): Provide subset enumeration using RBTree's suffix enumerators.
(SortedSubSet.count): New.
(SortedSubSet.GetCount): Use it.
(SortedSubSet.TryAdd, SortedSubSet.TryRemove): Update count.
(SortedSubSet.GetMin, SortedSubSet.GetMax): Use RBTree.Bound().
(SortedSubSet.GetEnumerator): Remove.
(SortedSubSet.TryGetEnumerator): New. Use ranged enumerators.
2010-04-06 Jb Evain <jbevain@novell.com>
* SortedSet.cs: implement Count for SortedSubSet.
2010-04-05 Raja R Harinath <harinath@hurrynot.org>
* SortedSet.cs (IsProperSubsetOf, IsSubsetOf): Implement using ...
(is_subset_of): ... new helper.
(IsProperSupersetOf, IsSupersetOf): Implement using ...
(is_superset_of): ... new helper.
(covers, nodups, overlaps): New helpers.
(SetEquals): Implement.
(Overlaps): Implement using overlaps().
(SymmetricExceptWith): Use nodups() helper.
2010-04-04 Raja R Harinath <harinath@hurrynot.org>
* SortedSet.cs (CheckArgumentNotNull): New helper.
(IntersectWith, UnionWith): Implement.
(ExceptWith, SymmetricExceptWith): Likewise.
(SortedSubSet.IntersectWith): Implement override.
* RBTree.cs (do_remove): Ensure the node returned is suitable for
re-insertion.
2010-04-02 Jb Evain <jbevain@novell.com>
* SortedSet.cs: implement Mix and Max for subsets.
2010-04-02 Jb Evain <jbevain@novell.com>
* SortedSet.cs: implement GetViewBetween.
2010-04-02 Jb Evain <jbevain@novell.com>
* SortedSet.cs: optimize Reverse. Add a virtual TryAdd and TryRemove
to override in sub trees.
2010-04-02 Jb Evain <jbevain@novell.com>
* SortedSet.cs: implement Min and Max.
2010-04-02 Jb Evain <jbevain@novell.com>
* SortedSet.cs: implement RemoveWhere.
2010-04-02 Jb Evain <jbevain@novell.com>
* SortedSet.cs: implement Reverse.
2010-04-01 Jb Evain <jbevain@novell.com>
* SortedSet.cs: fix API.
2010-04-01 Jb Evain <jbevain@novell.com>
* SortedSet.cs: add new SortedSet type in .net 4.0
2010-03-03 Miguel de Icaza <miguel@novell.com>
* RBTree.cs: Make these serializable, should fix the serialization
across appdomains of SortedDictionaries
2010-03-11 Sebastien Pouliot <sebastien@ximian.com>
* ISet.cs: Add NET_2_1 since this is part of SL4
2009-12-01 Jb Evain <jbevain@novell.com>
* Stack.cs (Enumerator.Dispose): tag the enumerator as finished
upon Dispose.
2009-11-26 Marek Safar <marek.safar@gmail.com>
* LinkedList.cs: Allocate less.
2009-11-25 Jb Evain <jbevain@novell.com>
* Queue.cs (Enqueue): deal with the case where the tail
is off the array when deciding to enlarge the capacity.
2009-11-25 Jb Evain <jbevain@novell.com>
* Queue.cs (ICollection.CopyTo): fix typo, remove code duplication.
2009-11-02 Miguel de Icaza <miguel@novell.com>
* ISet.cs: Added new interface.
2009-10-20 Marek Safar <marek.safar@gmail.com>
* SortedList.cs, LinkedList.cs, Queue.cs, Stack.cs,
SortedDictionary.cs: Improve debugging experience.
2009-07-31 Raja R Harinath <harinath@hurrynot.org>
* RBTree.cs (NodeEnumerator.check_current): New helper.
(NodeEnumerator.Current): Don't check invariants.
* SortedDictionary.cs (Enumerator.Current): Likewise.
(ValueCollection.Enumerator.Current): Likewise.
(KeyCollection.Enumerator.Current): Likewise.
2009-07-26 Miguel de Icaza <miguel@novell.com>
* Stack.cs: Check arguments.
2009-07-14 Gonzalo Paniagua Javier <gonzalo@novell.com>
* SortedList.cs: the IComparar.Compare arguments were reversed.
Fixes bug #521750. Patch by Kevin Fitzgerald.
2009-05-10 Andy Hume <andyhume32@yahoo.co.uk>
* LinkedList.cs: Add null check. Fixes #481621.
2009-03-11 Zoltan Varga <vargaz@gmail.com>
* SortedList.cs: Add version checking to the Key/Value enumerators +
implement support for Reset (). Fixes #483985.
2009-05-06 Pia Eriksson <pe@hallerud.se>
* SortedList.cs: Handle Count == 0 in CopyTo correcly
* SortedDictionary.cs: Handle Count == 0 in CopyTo correcly
2007-11-15 Roei Erez <roeie@mainsoft.com>
* Stack.cs: Performance improvement in the case where the stack is popped
until empty. Changed the condition for resizing the array, and instead of
check for zero size, check if the inner array is null.
2007-11-15 Jb Evain <jbevain@novell.com>
* LinkedList.cs: ifdef out manually the Serialization part of the
LinkedList.Enumerator. As it is a struct, the field SerializationInfo
have to be assigned in the default constructor, and the tuner cannot
remove that. Fixes #341938 for real.
2007-10-09 Raja R Harinath <rharinath@novell.com>
* RBTree.cs (get_Item, do_remove): Remove redundant code.
2007-08-20 Jb Evain <jbevain@novell.com>
* SortedList.cs: don't crash in ListKeys and ListValues
when CopyTo targets an empty array, and that the
sorted list is empty. Fixes #82492.
2007-05-08 Raja R Harinath <rharinath@novell.com>
Avoid unnecessary allocation on indexer access
* SortedDictionary.cs (NodeHelper): Rename from NodeComparer.
(NodeHelper.CreateNode): New.
(Item.set): Move responsibility of creating new nodes to
RBTree.Intern.
* RBTree.cs (INodeHelper): Rename from INodeComparer.
(INodeHelper.CreateNode): New.
(Intern): Use it to create a new node if no node is passed in.
2007-05-08 Igor Zelmanovich <igorz@mainsoft.com>
* RBTree.cs: for TARGET_JVM used Thread Local Storage
istead Thread-Relative Static Fields
2007-05-02 Raja R Harinath <rharinath@novell.com>
* RBTree.cs (Enumerator.Current): Remove nullref.
* SortedDictionary.cs (ICollection.Contains): Use EqualityComparer
for comparing the value field.
* RBTree.cs (do_remove): Remove some redundant assignments/checks.
(NodeEnumerator): Simplify. Keep track of a list of
right-pennants that need to be traversed next, rather than
comparing parent pointers.
2007-05-02 Raja R Harinath <harinath@gmail.com>
Make add and remove operations O(log n).
* SortedDictionary.cs: Rewrite to use the red-black tree
implementation from RBTree.cs.
* RBTree.cs: Some more refactoring. Rename Insert() to Intern(),
and modify semantics slightly. Replace Contains() with Lookup().
2007-04-30 Raja R Harinath <rharinath@novell.com>
* RBTree.cs: Refactor to reduce generics code.
2007-04-30 Raja R Harinath <harinath@gmail.com>
* RBTree.cs: New red-black tree implementation for use with
SortedDictionary.
2007-04-19 Gert Driesen <drieseng@users.sourceforge.net>
* Queue.cs: Fixed binary serialization, based on patch provided by
Lionel Cuir. Fixes TrimExcess to use SetCapacity, before it was not
updating _head which could lead to IndexOutOfRangeException.
* Stack.cs: Fixed binary serialization, based on patch provided by
Lionel Cuir. In Pop, clear entry from array to help GC.
2007-03-27 Alan McGovern <alan.mcgovern@gmail.com>
* Queue.cs: Removed wrong call to version++
* Stack.cs: Removed wrong call to version++
2006-09-30 Gert Driesen <drieseng@users.sourceforge.net>
* SortedList.cs: Count property, indexer and Clear method should not
be virtual. Removed unnecessary explicit interface implementation of
Add (TKey, TValue) and Remove (TKey, TValue).
* Queue.cs: Marked Enumerator as Serializable.
* Stack.cs: Marked Stack <T> and Enumerator as serializable.
2006-09-28 Andrew Skiba <andrews@mainsoft.com>
* Stack.cs: TARGET_JVM
2006-04-05 Atsushi Enomoto <atsushi@ximian.com>
* SortedDictionary.cs : new file. The original code is mostly
from Kazuki Oikawa.
2006-03-11 Miguel de Icaza <miguel@novell.com>
* Queue.cs: Flag as serializable.
* LinkedList.cs (OnDeserialization): Fix signature.
* SortedList.cs: Implement explicitly a few methods that were
flagged by corcompare.
2005-11-10 Zoltan Varga <vargaz@gmail.com>
* SortedList.cs Queue.cs Stack.cs: Implement TrimExcess methods.
* SortedList.cs: Fix build.
* Stack.cs SortedList.cs LinkedList.cs: Update to net 2.0 RTM.
2005-11-09 Zoltan Varga <vargaz@gmail.com>
* SortedList.cs: New file.
2005-09-04 David Waite <mass@akuma.org>
* LinkedList.cs, LinkedListNode.cs: added implementation of LinkedList<T>
2005-08-08 Kamil Skalski <nazgul@nemerle.org>
* Queue.cs, Stack.cs: remove implementation of ICollection<T>,
since it is no longer in b2 API
2005-06-20 David Waite <mass@akuma.org>
* Collection.cs, ReadOnlyCollection.cs: removed as they are no longer in the b2 API
2005-05-13 Atsushi Enomoto <atsushi@ximian.com>
* Queue.cs, Stack.cs: moved from mscorlib.dll
2005-02-35 Carlos Alberto Cortez <calberto.cortez@gmail.com>
* Collections.cs: Changed the code inside IndexOf, for
the use of Array.IndexOf<>, to keep clean the code.
2004-11-17 Carlos Alberto Cortez Guevara <carlos@unixmexico.org>
* Collections.cs: Avoid the call to Array.Clear () in RemoveItem (),
now we only assign the last element (the deleted one) to its default
value.
2004-09-20 Gert Driesen <drieseng@users.sourceforge.net>
* ReadOnlyCollection.cs: Moved over from corlib
* Collection.cs: Moved over from corlib

View File

@@ -0,0 +1,46 @@
//
// System.Collections.Generic.ISet.cs
//
// Author:
// Miguel de Icaza (miguel@gnome.org)
//
// Copyright (C) 2009 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
#if NET_4_0
namespace System.Collections.Generic {
public interface ISet<T> : ICollection<T>
{
new bool Add (T item);
void ExceptWith (IEnumerable<T> other);
void IntersectWith (IEnumerable<T> other);
bool IsProperSubsetOf (IEnumerable<T> other);
bool IsProperSupersetOf (IEnumerable<T> other);
bool IsSubsetOf (IEnumerable<T> other);
bool IsSupersetOf (IEnumerable<T> other);
bool Overlaps (IEnumerable<T> other);
bool SetEquals (IEnumerable<T> other);
void SymmetricExceptWith (IEnumerable<T> other);
void UnionWith (IEnumerable<T> other);
}
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,110 @@
//
// System.Collections.Generic.LinkedListNode
//
// Author:
// David Waite
//
// (C) 2005 David Waite (mass@akuma.org)
//
//
// Copyright (C) 2005 David Waite
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Runtime.InteropServices;
namespace System.Collections.Generic
{
[ComVisible (false)]
public sealed class LinkedListNode <T>
{
T item;
LinkedList <T> container;
internal LinkedListNode <T> forward, back;
public LinkedListNode (T value)
{
item = value;
}
internal LinkedListNode (LinkedList <T> list, T value)
{
container = list;
item = value;
this.back = this.forward = this;
}
internal LinkedListNode (LinkedList <T> list, T value, LinkedListNode <T> previousNode, LinkedListNode <T> nextNode)
{
container = list;
item = value;
this.back = previousNode;
this.forward = nextNode;
previousNode.forward = this;
nextNode.back = this;
}
internal void Detach ()
{
back.forward = forward;
forward.back = back;
forward = back = null;
container = null;
}
internal void SelfReference (LinkedList <T> list)
{
forward = this;
back = this;
container = list;
}
internal void InsertBetween (LinkedListNode <T> previousNode, LinkedListNode <T> nextNode, LinkedList <T> list)
{
previousNode.forward = this;
nextNode.back = this;
this.forward = nextNode;
this.back = previousNode;
this.container = list;
}
public LinkedList <T> List {
get { return container; }
}
public LinkedListNode <T> Next {
get { return (container != null && forward != container.first) ? forward : null; }
}
public LinkedListNode <T> Previous {
get { return (container != null && this != container.first) ? back : null ; }
}
public T Value {
get { return item; }
set { item = value; }
}
}
}

View File

@@ -0,0 +1,293 @@
//
// System.Collections.Generic.Queue
//
// Author:
// Martin Baulig (martin@ximian.com)
// Ben Maurer (bmaurer@ximian.com)
//
// (C) 2003, 2004 Novell, Inc.
//
//
// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace System.Collections.Generic
{
[ComVisible(false)]
[Serializable]
[DebuggerDisplay ("Count={Count}")]
[DebuggerTypeProxy (typeof (CollectionDebuggerView))]
public class Queue<T> : IEnumerable <T>, ICollection, IEnumerable
{
T [] _array;
int _head;
int _tail;
int _size;
int _version;
public Queue ()
{
_array = new T [0];
}
public Queue (int capacity)
{
if (capacity < 0)
throw new ArgumentOutOfRangeException ("capacity");
_array = new T [capacity];
}
public Queue (IEnumerable <T> collection)
{
if (collection == null)
throw new ArgumentNullException ("collection");
var icoll = collection as ICollection<T>;
var size = icoll != null ? icoll.Count : 0;
_array = new T [size];
foreach (T t in collection)
Enqueue (t);
}
public void Clear ()
{
Array.Clear (_array, 0, _array.Length);
_head = _tail = _size = 0;
_version++;
}
public bool Contains (T item)
{
if (item == null) {
foreach (T t in this)
if (t == null)
return true;
} else {
foreach (T t in this)
if (item.Equals (t))
return true;
}
return false;
}
public void CopyTo (T [] array, int arrayIndex)
{
if (array == null)
throw new ArgumentNullException ();
((ICollection) this).CopyTo (array, arrayIndex);
}
void ICollection.CopyTo (Array array, int idx)
{
if (array == null)
throw new ArgumentNullException ();
if ((uint) idx > (uint) array.Length)
throw new ArgumentOutOfRangeException ();
if (array.Length - idx < _size)
throw new ArgumentOutOfRangeException ();
if (_size == 0)
return;
try {
int contents_length = _array.Length;
int length_from_head = contents_length - _head;
Array.Copy (_array, _head, array, idx, Math.Min (_size, length_from_head));
if (_size > length_from_head)
Array.Copy (_array, 0, array,
idx + length_from_head,
_size - length_from_head);
} catch (ArrayTypeMismatchException) {
throw new ArgumentException ();
}
}
public T Dequeue ()
{
T ret = Peek ();
// clear stuff out to make the GC happy
_array [_head] = default (T);
if (++_head == _array.Length)
_head = 0;
_size --;
_version ++;
return ret;
}
public T Peek ()
{
if (_size == 0)
throw new InvalidOperationException ();
return _array [_head];
}
public void Enqueue (T item)
{
if (_size == _array.Length || _tail == _array.Length)
SetCapacity (Math.Max (Math.Max (_size, _tail) * 2, 4));
_array [_tail] = item;
if (++_tail == _array.Length)
_tail = 0;
_size ++;
_version ++;
}
public T [] ToArray ()
{
T [] t = new T [_size];
CopyTo (t, 0);
return t;
}
public void TrimExcess ()
{
if (_size < _array.Length * 0.9)
SetCapacity (_size);
}
void SetCapacity (int new_size)
{
if (new_size == _array.Length)
return;
if (new_size < _size)
throw new InvalidOperationException ("shouldnt happen");
T [] new_data = new T [new_size];
if (_size > 0)
CopyTo (new_data, 0);
_array = new_data;
_tail = _size;
_head = 0;
_version ++;
}
public int Count {
get { return _size; }
}
bool ICollection.IsSynchronized {
get { return false; }
}
object ICollection.SyncRoot {
get { return this; }
}
public Enumerator GetEnumerator ()
{
return new Enumerator (this);
}
IEnumerator <T> IEnumerable<T>.GetEnumerator ()
{
return GetEnumerator ();
}
IEnumerator IEnumerable.GetEnumerator ()
{
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
const int FINISHED = -1;
Queue <T> q;
int idx;
int ver;
internal Enumerator (Queue <T> q)
{
this.q = q;
idx = NOT_STARTED;
ver = q._version;
}
// for some reason, MSFT added a dispose to this class
// It means that in foreach, we must still do a try/finally. Broken?
public void Dispose ()
{
idx = NOT_STARTED;
}
public bool MoveNext ()
{
if (ver != q._version)
throw new InvalidOperationException ();
if (idx == NOT_STARTED)
idx = q._size;
return idx != FINISHED && -- idx != FINISHED;
}
public T Current {
get {
if (idx < 0)
throw new InvalidOperationException ();
return q._array [(q._size - 1 - idx + q._head) % q._array.Length];
}
}
void IEnumerator.Reset ()
{
if (ver != q._version)
throw new InvalidOperationException ();
idx = NOT_STARTED;
}
object IEnumerator.Current {
get { return Current; }
}
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,252 @@
//
// System.Collections.Generic.Stack
//
// Authors:
// Martin Baulig (martin@ximian.com)
// Ben Maurer (bmaurer@ximian.com)
//
// (C) 2003, 2004 Novell, Inc.
//
//
// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace System.Collections.Generic
{
[ComVisible (false)]
[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 capacity)
{
if (capacity < 0)
throw new ArgumentOutOfRangeException ("capacity");
_array = new T [capacity];
}
public Stack (IEnumerable <T> collection)
{
if (collection == null)
throw new ArgumentNullException ("collection");
ICollection <T> col = collection as ICollection <T>;
if (col != null) {
_size = col.Count;
_array = new T [_size];
col.CopyTo (_array, 0);
} else {
foreach (T t in collection)
Push (t);
}
}
public void Clear ()
{
if (_array != null)
Array.Clear (_array, 0, _array.Length);
_size = 0;
_version ++;
}
public bool Contains (T item)
{
return _array != null && Array.IndexOf (_array, item, 0, _size) != -1;
}
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 (_array != null) {
Array.Copy (_array, 0, array, arrayIndex, _size);
Array.Reverse (array, arrayIndex, _size);
}
}
public T Peek ()
{
if (_size == 0)
throw new InvalidOperationException ();
return _array [_size - 1];
}
public T Pop ()
{
if (_size == 0)
throw new InvalidOperationException ();
_version ++;
T popped = _array [--_size];
// clear stuff out to make the GC happy
_array [_size] = default(T);
return popped;
}
public void Push (T item)
{
if (_array == null || _size == _array.Length)
Array.Resize <T> (ref _array, _size == 0 ? INITIAL_SIZE : 2 * _size);
_version ++;
_array [_size++] = item;
}
public T [] ToArray ()
{
T [] copy = new T [_size];
CopyTo (copy, 0);
return copy;
}
public void TrimExcess ()
{
if (_array != null && (_size < _array.Length * 0.9))
Array.Resize <T> (ref _array, _size);
_version ++;
}
public int Count {
get { return _size; }
}
bool ICollection.IsSynchronized {
get { return false; }
}
object ICollection.SyncRoot {
get { return this; }
}
void ICollection.CopyTo (Array dest, int idx)
{
try {
if (_array != null) {
Array.Copy (_array, 0, dest, idx, _size);
Array.Reverse (dest, idx, _size);
}
} catch (ArrayTypeMismatchException) {
throw new ArgumentException ();
}
}
public Enumerator GetEnumerator ()
{
return new Enumerator (this);
}
IEnumerator <T> IEnumerable<T>.GetEnumerator ()
{
return GetEnumerator ();
}
IEnumerator IEnumerable.GetEnumerator ()
{
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
const int FINISHED = -1;
Stack <T> parent;
int idx;
int _version;
internal Enumerator (Stack <T> t)
{
parent = t;
idx = NOT_STARTED;
_version = t._version;
}
// for some reason, MSFT added a dispose to this class
// It means that in foreach, we must still do a try/finally. broken?
public void Dispose ()
{
idx = FINISHED;
}
public bool MoveNext ()
{
if (_version != parent._version)
throw new InvalidOperationException ();
if (idx == -2)
idx = parent._size;
return idx != FINISHED && -- idx != FINISHED;
}
public T Current {
get {
if (idx < 0)
throw new InvalidOperationException ();
return parent._array [idx];
}
}
void IEnumerator.Reset ()
{
if (_version != parent._version)
throw new InvalidOperationException ();
idx = NOT_STARTED;
}
object IEnumerator.Current {
get { return Current; }
}
}
}
}