[Test] Cleaned up how a bunch of tests were ignored
[mono.git] / mcs / class / corlib / System.Collections / Queue.cs
index f9c800f8652f189daa2a2bd3e05d3da602c27343..5e359e821f4d5f1bf85e94360afa20587d2f0422 100644 (file)
@@ -1,54 +1,90 @@
-//
+//
 // System.Collections.Queue
 //
 // Author:
-//    Ricardo Fernández Pascual
+//    Ricardo Fernández Pascual
+//
+// (C) 2001 Ricardo Fernández Pascual
+//
+
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
 //
-// (C) 2001 Ricardo Fernández Pascual
+// 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.Collections;
+using System.Runtime.InteropServices;
 
 namespace System.Collections {
 
+       [ComVisible(true)]
+       [System.Diagnostics.DebuggerDisplay ("Count={Count}")]
+       [System.Diagnostics.DebuggerTypeProxy (typeof (CollectionDebuggerView))]
        [Serializable]
-       public class Queue : ICollection, IEnumerable, ICloneable {
-
-               private object[] contents;
-               private int head = 0;   // points to the first used slot
-               private int count = 0;
-               private int capacity;
-               private float growFactor;
-               private int modCount = 0;
+#if INSIDE_CORLIB
+       public
+#else
+       internal
+#endif
+       class Queue : ICollection, IEnumerable, ICloneable {
+
+               private object[] _array;
+               private int _head = 0;   // points to the first used slot
+               private int _size = 0;
+               private int _tail = 0;
+               private int _growFactor;
+               private int _version = 0;
 
                public Queue () : this (32, 2.0F) {}
-               public Queue (int initialCapacity) : this (initialCapacity, 2.0F) {}
+
+               public Queue (int capacity) : this (capacity, 2.0F) {}
+
                public Queue(ICollection col) : this (col == null ? 32 : col.Count)
                {
                        if (col == null)
                                throw new ArgumentNullException ("col");
                        
-                       count = capacity;
-                       col.CopyTo (contents, 0);
+                       // We have to do this because msft seems to call the
+                       // enumerator rather than CopyTo. This affects classes
+                       // like bitarray.
+                       foreach (object o in col)
+                               Enqueue (o);    
                }
                        
-               public Queue (int initialCapacity, float growFactor) {
-                       if (initialCapacity < 0)
+               public Queue (int capacity, float growFactor) {
+                       if (capacity < 0)
                                throw new ArgumentOutOfRangeException("capacity", "Needs a non-negative number");
                        if (!(growFactor >= 1.0F && growFactor <= 10.0F))
                                throw new ArgumentOutOfRangeException("growFactor", "Queue growth factor must be between 1.0 and 10.0, inclusive");
            
-                       capacity = initialCapacity;
-                       contents = new object[capacity];
+                       _array = new object[capacity];
 
-                       this.growFactor = growFactor;
+                       this._growFactor = (int)(growFactor * 100);
                }
-
+               
                // from ICollection
 
                public virtual int Count {
-                       get { return count; }
+                       get { return _size; }
                }
 
                public virtual bool IsSynchronized {
@@ -69,18 +105,18 @@ namespace System.Collections {
 
                        if (array.Rank > 1 
                            || (index != 0 && index >= array.Length)
-                           || count > array.Length - index)
+                           || _size > array.Length - index)
                                throw new ArgumentException ();
                        
-                       int contents_length = contents.Length;
-                       int length_from_head = contents_length - head;
-                       // copy the contents of the circular array
-                       Array.Copy (contents, head, array, index,
-                                   Math.Min (count, length_from_head));
-                       if (count >  length_from_head)
-                               Array.Copy (contents, 0, array, 
+                       int contents_length = _array.Length;
+                       int length_from_head = contents_length - _head;
+                       // copy the _array of the circular array
+                       Array.Copy (_array, _head, array, index,
+                                   Math.Min (_size, length_from_head));
+                       if (_size >  length_from_head)
+                               Array.Copy (_array, 0, array, 
                                            index + length_from_head,
-                                           count - length_from_head);
+                                           _size - length_from_head);
                }
 
                // from IEnumerable
@@ -94,47 +130,37 @@ namespace System.Collections {
                public virtual object Clone () {
                        Queue newQueue;
                        
-                       newQueue = new Queue (); // FIXME: improve this...
+                       newQueue = new Queue (this._array.Length);
+                       newQueue._growFactor = _growFactor;
                        
-                       newQueue.contents = new object[this.contents.Length];
-                       Array.Copy (this.contents, 0, newQueue.contents, 0,
-                                   this.contents.Length);
-                       newQueue.head = this.head;
-                       newQueue.count = this.count;
-                       newQueue.capacity = this.capacity;
-                       newQueue.growFactor = this.growFactor;
+                       Array.Copy (this._array, 0, newQueue._array, 0,
+                                   this._array.Length);
+                       newQueue._head = this._head;
+                       newQueue._size = this._size;
+                       newQueue._tail = this._tail;
 
                        return newQueue;
                }
 
-               // FIXME: should override Equals?
-
-               // from Queue spec
-
-/*
-               public virtual bool IsReadOnly {
-                       get { return false; }
-               }
-*/
-
                public virtual void Clear () {
-                       modCount++;
-                       head = 0;
-                       count = 0;
-                       // FIXME: Should allocate a new contents array? 
-                       //        Should null the current array?
+                       _version++;
+                       _head = 0;
+                       _size = 0;
+                       _tail = 0;
+                       for (int length = _array.Length - 1; length >= 0; length--)
+                               _array [length] = null;
                }
 
                public virtual bool Contains (object obj) {
-                       int tail = head + count;
+                       int tail = _head + _size;
                        if (obj == null) {
-                               for (int i = head; i < tail; i++) {
-                                       if (contents[i % capacity] == null) 
+                               for (int i = _head; i < tail; i++) {
+                                       if (_array[i % _array.Length] == null) 
                                                return true;
                                }
                        } else {
-                               for (int i = head; i < tail; i++) {
-                                       if (obj.Equals (contents[i % capacity]))
+                               for (int i = _head; i < tail; i++) {
+                                       if (obj.Equals (_array[i % _array.Length]))
                                                return true;
                                }
                        }
@@ -143,59 +169,65 @@ namespace System.Collections {
                
                public virtual object Dequeue ()
                {
-                       modCount++;
-                       if (count < 1)
+                       _version++;
+                       if (_size < 1)
                                throw new InvalidOperationException ();
-                       object result = contents[head];
-                       head = (head + 1) % capacity;
-                       count--;
+                       object result = _array[_head];
+                       _array [_head] = null;
+                       _head = (_head + 1) % _array.Length;
+                       _size--;
                        return result;
                }
 
                public virtual void Enqueue (object obj) {
-                       modCount++;
-                       if (count == capacity
+                       _version++;
+                       if (_size == _array.Length
                                grow ();
-                       contents[(head + count) % capacity] = obj;
-                       count++;
+                       _array[_tail] = obj;
+                       _tail = (_tail+1) % _array.Length;
+                       _size++;
 
                }
 
                public virtual object Peek () {
-                       if (count < 1)
+                       if (_size < 1)
                                throw new InvalidOperationException ();
-                       return contents[head];
+                       return _array[_head];
                }
 
                public static Queue Synchronized (Queue queue) {
                        if (queue == null) {
-                               throw new ArgumentNullException ();
+                               throw new ArgumentNullException ("queue");
                        }
                        return new SyncQueue (queue);
                }
 
                public virtual object[] ToArray () {
-                       object[] ret = new object[count];
+                       object[] ret = new object[_size];
                        CopyTo (ret, 0);
                        return ret;
                }
 
                public virtual void TrimToSize() {
-                       object[] trimmed = new object [count];
+                       _version++;
+                       object[] trimmed = new object [_size];
                        CopyTo (trimmed, 0);
-                       contents = trimmed;
+                       _array = trimmed;
+                       _head = 0;
+                       _tail = 0;
                }
 
                // private methods
 
                private void grow () {
-                       int newCapacity = (int) Math.Ceiling
-                               (contents.Length * growFactor);
+                       int newCapacity = (_array.Length * _growFactor) / 100;
+                       if (newCapacity < _array.Length + 1)
+                               newCapacity = _array.Length + 1;
                        object[] newContents = new object[newCapacity];
                        CopyTo (newContents, 0);
-                       contents = newContents;
-                        capacity = newCapacity;
-                        head = 0;
+                       _array = newContents;
+                       _head = 0;
+                       _tail = _head + _size;
                }
 
                // private classes
@@ -210,7 +242,7 @@ namespace System.Collections {
                        public override int Count {
                                get { 
                                        lock (queue) {
-                                               return queue.count; 
+                                               return queue.Count; 
                                        }
                                }
                        }
@@ -241,7 +273,7 @@ namespace System.Collections {
                        
                        public override object Clone () {
                                lock (queue) {
-                                       return queue.Clone ();
+                                       return new SyncQueue((Queue) queue.Clone ());
                                }
                        }
                        
@@ -261,6 +293,12 @@ namespace System.Collections {
                                }
                        }
 
+                       public override void TrimToSize () {
+                               lock (queue) {
+                                       queue.TrimToSize ();
+                               }
+                       }
+
                        public override bool Contains (object obj) {
                                lock (queue) {
                                        return queue.Contains (obj);
@@ -295,39 +333,40 @@ namespace System.Collections {
                [Serializable]
                private class QueueEnumerator : IEnumerator, ICloneable {
                        Queue queue;
-                       private int modCount;
+                       private int _version;
                        private int current;
 
                        internal QueueEnumerator (Queue q) {
                                queue = q;
-                               modCount = q.modCount;
-                               current = -1;  // one element before the head
+                               _version = q._version;
+                               current = -1;  // one element before the _head
                        }
 
                        public object Clone ()
                        {
                                QueueEnumerator q = new QueueEnumerator (queue);
-                               q.modCount = modCount;
+                               q._version = _version;
                                q.current = current;
                                return q;
                        }
 
                        public virtual object Current {
                                get {
-                                       if (modCount != queue.modCount 
+                                       if (_version != queue._version 
                                            || current < 0
-                                           || current >= queue.count)
+                                           || current >= queue._size)
                                                throw new InvalidOperationException ();
-                                       return queue.contents[(queue.head + current) % queue.contents.Length];
+                                       return queue._array[(queue._head + current) % queue._array.Length];
                                }
                        }
 
                        public virtual bool MoveNext () {
-                               if (modCount != queue.modCount) {
+                               if (_version != queue._version) {
                                        throw new InvalidOperationException ();
                                }
 
-                               if (current >= queue.count - 1) {
+                               if (current >= queue._size - 1) {
+                                       current = Int32.MaxValue; // to late!
                                        return false;
                                } else {
                                        current++;
@@ -336,7 +375,7 @@ namespace System.Collections {
                        }
 
                        public virtual void Reset () {
-                               if (modCount != queue.modCount) {
+                               if (_version != queue._version) {
                                        throw new InvalidOperationException();
                                }
                                current = -1;