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[] _array;
19 private int _head = 0; // points to the first used slot
20 private int _size = 0;
21 private int _tail = 0;
22 private int _growFactor;
23 private int _version = 0;
25 public Queue () : this (32, 2.0F) {}
26 public Queue (int initialCapacity) : this (initialCapacity, 2.0F) {}
27 public Queue(ICollection col) : this (col == null ? 32 : col.Count)
30 throw new ArgumentNullException ("col");
32 _size = _array.Length;
34 col.CopyTo (_array, 0);
37 public Queue (int initialCapacity, float growFactor) {
38 if (initialCapacity < 0)
39 throw new ArgumentOutOfRangeException("capacity", "Needs a non-negative number");
40 if (!(growFactor >= 1.0F && growFactor <= 10.0F))
41 throw new ArgumentOutOfRangeException("growFactor", "Queue growth factor must be between 1.0 and 10.0, inclusive");
43 _array = new object[initialCapacity];
45 this._growFactor = (int)(growFactor * 100);
50 public virtual int Count {
54 public virtual bool IsSynchronized {
58 public virtual object SyncRoot {
62 public virtual void CopyTo (Array array, int index)
65 throw new ArgumentNullException ("array");
68 throw new ArgumentOutOfRangeException ("index");
71 || (index != 0 && index >= array.Length)
72 || _size > array.Length - index)
73 throw new ArgumentException ();
75 int contents_length = _array.Length;
76 int length_from_head = contents_length - _head;
77 // copy the _array of the circular array
78 Array.Copy (_array, _head, array, index,
79 Math.Min (_size, length_from_head));
80 if (_size > length_from_head)
81 Array.Copy (_array, 0, array,
82 index + length_from_head,
83 _size - length_from_head);
88 public virtual IEnumerator GetEnumerator () {
89 return new QueueEnumerator (this);
94 public virtual object Clone () {
97 newQueue = new Queue (this._array.Length);
98 newQueue._growFactor = _growFactor;
100 Array.Copy (this._array, 0, newQueue._array, 0,
102 newQueue._head = this._head;
103 newQueue._size = this._size;
104 newQueue._tail = this._tail;
109 public virtual void Clear () {
114 for (int length = _array.Length - 1; length >= 0; length--)
115 _array [length] = null;
118 public virtual bool Contains (object obj) {
119 int tail = _head + _size;
121 for (int i = _head; i < tail; i++) {
122 if (_array[i % _array.Length] == null)
126 for (int i = _head; i < tail; i++) {
127 if (obj.Equals (_array[i % _array.Length]))
134 public virtual object Dequeue ()
138 throw new InvalidOperationException ();
139 object result = _array[_head];
140 _array [_head] = null;
141 _head = (_head + 1) % _array.Length;
146 public virtual void Enqueue (object obj) {
148 if (_size == _array.Length)
151 _tail = (_tail+1) % _array.Length;
156 public virtual object Peek () {
158 throw new InvalidOperationException ();
159 return _array[_head];
162 public static Queue Synchronized (Queue queue) {
164 throw new ArgumentNullException ("queue");
166 return new SyncQueue (queue);
169 public virtual object[] ToArray () {
170 object[] ret = new object[_size];
175 public virtual void TrimToSize() {
177 object[] trimmed = new object [_size];
181 _tail = _head + _size;
186 private void grow () {
187 int newCapacity = (_array.Length * _growFactor) / 100;
188 object[] newContents = new object[newCapacity];
189 CopyTo (newContents, 0);
190 _array = newContents;
192 _tail = _head + _size;
197 private class SyncQueue : Queue {
200 internal SyncQueue (Queue queue) {
204 public override int Count {
212 public override bool IsSynchronized {
218 public override object SyncRoot {
220 return queue.SyncRoot;
224 public override void CopyTo (Array array, int index) {
226 queue.CopyTo (array, index);
230 public override IEnumerator GetEnumerator () {
232 return queue.GetEnumerator ();
236 public override object Clone () {
238 return new SyncQueue((Queue) queue.Clone ());
243 public override bool IsReadOnly {
246 return queue.IsReadOnly;
252 public override void Clear () {
258 public override void TrimToSize () {
264 public override bool Contains (object obj) {
266 return queue.Contains (obj);
270 public override object Dequeue () {
272 return queue.Dequeue ();
276 public override void Enqueue (object obj) {
282 public override object Peek () {
284 return queue.Peek ();
288 public override object[] ToArray () {
290 return queue.ToArray ();
296 private class QueueEnumerator : IEnumerator, ICloneable {
298 private int _version;
301 internal QueueEnumerator (Queue q) {
303 _version = q._version;
304 current = -1; // one element before the _head
307 public object Clone ()
309 QueueEnumerator q = new QueueEnumerator (queue);
310 q._version = _version;
315 public virtual object Current {
317 if (_version != queue._version
319 || current >= queue._size)
320 throw new InvalidOperationException ();
321 return queue._array[(queue._head + current) % queue._array.Length];
325 public virtual bool MoveNext () {
326 if (_version != queue._version) {
327 throw new InvalidOperationException ();
330 if (current >= queue._size - 1) {
338 public virtual void Reset () {
339 if (_version != queue._version) {
340 throw new InvalidOperationException();