2 // System.Collections.Queue
\r
5 // Ricardo Fernández Pascual
\r
7 // (C) 2001 Ricardo Fernández Pascual
\r
11 using System.Collections;
\r
13 namespace System.Collections {
\r
15 public class Queue : ICollection, IEnumerable, ICloneable {
\r
17 private object[] contents;
\r
18 private int head = 0; // points to the first used slot
\r
19 private int count = 0;
\r
20 private int capacity = 16;
\r
21 private float growFactor = 2.0F;
\r
22 private int modCount = 0;
\r
25 contents = new object[capacity];
\r
28 public Queue (ICollection collection) {
\r
29 capacity = collection.Count;
\r
30 contents = new object[capacity];
\r
32 collection.CopyTo (contents, 0);
\r
35 public Queue (int initialCapacity) {
\r
36 capacity = initialCapacity;
\r
37 contents = new object[capacity];
\r
40 public Queue (int initialCapacity, float growFactor) {
\r
41 capacity = initialCapacity;
\r
42 contents = new object[capacity];
\r
43 // LAMESPEC: The spec says nothing, but I think this
\r
44 // should throw an exception if growFactor <= 1.0
\r
45 this.growFactor = growFactor;
\r
50 public virtual int Count {
\r
51 get { return count; }
\r
54 public virtual bool IsSynchronized {
\r
55 get { return false; }
\r
58 public virtual object SyncRoot {
\r
59 get { return this; }
\r
62 public virtual void CopyTo (Array array, int index) {
\r
63 if (array == null) {
\r
64 throw new ArgumentNullException ();
\r
68 throw new ArgumentOutOfRangeException ();
\r
72 || index >= array.Length
\r
73 || count > array.Length - index) {
\r
74 throw new ArgumentException ();
\r
77 // copy the contents of the circular array
\r
78 Array.Copy (contents, head, array, index,
\r
79 Math.Max (count, capacity - head));
\r
80 if (count > capacity - head)
\r
81 Array.Copy (contents, 0, array,
\r
82 index + capacity - head,
\r
83 count - (capacity - head));
\r
88 public virtual IEnumerator GetEnumerator () {
\r
89 return new QueueEnumerator (this);
\r
94 public virtual object Clone () {
\r
97 newQueue = new Queue (); // FIXME: improve this...
\r
99 newQueue.contents = new object[this.contents.Length];
\r
100 Array.Copy (this.contents, 0, newQueue.contents, 0,
\r
101 this.contents.Length);
\r
102 newQueue.head = this.head;
\r
103 newQueue.count = this.count;
\r
104 newQueue.capacity = this.capacity;
\r
105 newQueue.growFactor = this.growFactor;
\r
110 // FIXME: should override Equals?
\r
114 public virtual bool IsReadOnly {
\r
115 get { return false; }
\r
118 public virtual void Clear () {
\r
122 // FIXME: Should allocate a new contents array?
\r
123 // Should null the current array?
\r
126 public virtual bool Contains (object obj) {
\r
127 int tail = head + count;
\r
129 for (int i = head; i < tail; i++) {
\r
130 if (contents[i % capacity] == null)
\r
134 for (int i = head; i < tail; i++) {
\r
135 if (obj.Equals (contents[i % capacity]))
\r
142 public virtual object Dequeue ()
\r
146 throw new InvalidOperationException ();
\r
147 object result = contents[head];
\r
148 head = (head + 1) % capacity;
\r
153 public virtual void Enqueue (object obj) {
\r
155 if (count == capacity)
\r
157 contents[(head + count) % capacity] = obj;
\r
161 public virtual object Peek () {
\r
163 throw new InvalidOperationException ();
\r
164 return contents[head];
\r
167 public static Queue Synchronized (Queue queue) {
\r
168 if (queue == null) {
\r
169 throw new ArgumentNullException ();
\r
171 return new SyncQueue (queue);
\r
174 public virtual object[] ToArray () {
\r
175 object[] ret = new object[count];
\r
182 private void grow () {
\r
183 int newCapacity = (int) Math.Ceiling
\r
184 (capacity * growFactor);
\r
185 object[] newContents = new object[newCapacity];
\r
186 CopyTo (newContents, 0);
\r
187 contents = newContents;
\r
193 private class SyncQueue : Queue {
\r
196 internal SyncQueue (Queue queue) {
\r
197 this.queue = queue;
\r
200 public override int Count {
\r
203 return queue.count;
\r
208 public override bool IsSynchronized {
\r
211 return queue.IsSynchronized;
\r
216 public override object SyncRoot {
\r
218 return queue.SyncRoot;
\r
222 public override void CopyTo (Array array, int index) {
\r
224 queue.CopyTo (array, index);
\r
228 public override IEnumerator GetEnumerator () {
\r
230 return queue.GetEnumerator ();
\r
234 public override object Clone () {
\r
236 return queue.Clone ();
\r
240 public override bool IsReadOnly {
\r
243 return queue.IsReadOnly;
\r
248 public override void Clear () {
\r
254 public override bool Contains (object obj) {
\r
256 return queue.Contains (obj);
\r
260 public override object Dequeue () {
\r
262 return queue.Dequeue ();
\r
266 public override void Enqueue (object obj) {
\r
268 queue.Enqueue (obj);
\r
272 public override object Peek () {
\r
274 return queue.Peek ();
\r
278 public override object[] ToArray () {
\r
280 return queue.ToArray ();
\r
285 private class QueueEnumerator : IEnumerator {
\r
287 private int modCount;
\r
288 private int current;
\r
290 internal QueueEnumerator (Queue q) {
\r
292 modCount = q.modCount;
\r
293 current = -1; // one element before the head
\r
296 public virtual object Current {
\r
298 if (modCount != queue.modCount
\r
300 || current >= queue.count)
\r
301 throw new InvalidOperationException ();
\r
302 return queue.contents[(queue.head + current) % queue.capacity];
\r
306 public virtual bool MoveNext () {
\r
307 if (modCount != queue.modCount) {
\r
308 throw new InvalidOperationException ();
\r
311 if (current >= queue.count) {
\r
319 public virtual void Reset () {
\r
320 if (modCount != queue.modCount) {
\r
321 throw new InvalidOperationException();
\r