2 // System.Collections.Queue
5 // Ricardo Fernández Pascual
7 // (C) 2001 Ricardo Fernández Pascual
11 using System.Collections;
13 namespace System.Collections {
16 public class Queue : ICollection, IEnumerable, ICloneable {
18 private object[] contents;
19 private int head = 0; // points to the first used slot
20 private int count = 0;
21 private int capacity = 16;
22 private float growFactor = 2.0F;
23 private int modCount = 0;
26 contents = new object[capacity];
29 public Queue (ICollection collection) {
30 capacity = collection.Count;
31 contents = new object[capacity];
33 collection.CopyTo (contents, 0);
36 public Queue (int initialCapacity) {
37 capacity = initialCapacity;
38 contents = new object[capacity];
41 public Queue (int initialCapacity, float growFactor) {
42 capacity = initialCapacity;
43 contents = new object[capacity];
44 // LAMESPEC: The spec says nothing, but I think this
45 // should throw an exception if growFactor <= 1.0
46 this.growFactor = growFactor;
51 public virtual int Count {
55 public virtual bool IsSynchronized {
59 public virtual object SyncRoot {
63 public virtual void CopyTo (Array array, int index) {
65 throw new ArgumentNullException ();
69 throw new ArgumentOutOfRangeException ();
73 || index >= array.Length
74 || count > array.Length - index) {
75 throw new ArgumentException ();
78 int contents_length = contents.Length;
79 int length_from_head = contents_length - head;
80 // copy the contents of the circular array
81 Array.Copy (contents, head, array, index,
82 Math.Min (count, length_from_head));
83 if (count > length_from_head)
84 Array.Copy (contents, 0, array,
85 index + length_from_head,
86 count - length_from_head);
91 public virtual IEnumerator GetEnumerator () {
92 return new QueueEnumerator (this);
97 public virtual object Clone () {
100 newQueue = new Queue (); // FIXME: improve this...
102 newQueue.contents = new object[this.contents.Length];
103 Array.Copy (this.contents, 0, newQueue.contents, 0,
104 this.contents.Length);
105 newQueue.head = this.head;
106 newQueue.count = this.count;
107 newQueue.capacity = this.capacity;
108 newQueue.growFactor = this.growFactor;
113 // FIXME: should override Equals?
118 public virtual bool IsReadOnly {
119 get { return false; }
123 public virtual void Clear () {
127 // FIXME: Should allocate a new contents array?
128 // Should null the current array?
131 public virtual bool Contains (object obj) {
132 int tail = head + count;
134 for (int i = head; i < tail; i++) {
135 if (contents[i % capacity] == null)
139 for (int i = head; i < tail; i++) {
140 if (obj.Equals (contents[i % capacity]))
147 public virtual object Dequeue ()
151 throw new InvalidOperationException ();
152 object result = contents[head];
153 head = (head + 1) % capacity;
158 public virtual void Enqueue (object obj) {
160 if (count == capacity)
162 contents[(head + count) % capacity] = obj;
167 public virtual object Peek () {
169 throw new InvalidOperationException ();
170 return contents[head];
173 public static Queue Synchronized (Queue queue) {
175 throw new ArgumentNullException ();
177 return new SyncQueue (queue);
180 public virtual object[] ToArray () {
181 object[] ret = new object[count];
186 public virtual void TrimToSize() {
187 object[] trimmed = new object [count];
194 private void grow () {
195 int newCapacity = (int) Math.Ceiling
196 (contents.Length * growFactor);
197 object[] newContents = new object[newCapacity];
198 CopyTo (newContents, 0);
199 contents = newContents;
200 capacity = newCapacity;
206 private class SyncQueue : Queue {
209 internal SyncQueue (Queue queue) {
213 public override int Count {
221 public override bool IsSynchronized {
227 public override object SyncRoot {
229 return queue.SyncRoot;
233 public override void CopyTo (Array array, int index) {
235 queue.CopyTo (array, index);
239 public override IEnumerator GetEnumerator () {
241 return queue.GetEnumerator ();
245 public override object Clone () {
247 return queue.Clone ();
252 public override bool IsReadOnly {
255 return queue.IsReadOnly;
261 public override void Clear () {
267 public override bool Contains (object obj) {
269 return queue.Contains (obj);
273 public override object Dequeue () {
275 return queue.Dequeue ();
279 public override void Enqueue (object obj) {
285 public override object Peek () {
287 return queue.Peek ();
291 public override object[] ToArray () {
293 return queue.ToArray ();
299 private class QueueEnumerator : IEnumerator, ICloneable {
301 private int modCount;
304 internal QueueEnumerator (Queue q) {
306 modCount = q.modCount;
307 current = -1; // one element before the head
310 public object Clone ()
312 QueueEnumerator q = new QueueEnumerator (queue);
313 q.modCount = modCount;
318 public virtual object Current {
320 if (modCount != queue.modCount
322 || current >= queue.count)
323 throw new InvalidOperationException ();
324 return queue.contents[(queue.head + current) % queue.contents.Length];
328 public virtual bool MoveNext () {
329 if (modCount != queue.modCount) {
330 throw new InvalidOperationException ();
333 if (current >= queue.count - 1) {
341 public virtual void Reset () {
342 if (modCount != queue.modCount) {
343 throw new InvalidOperationException();