using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace MySystem.Collections.Generic
{
public class MyQueue<T> : ICollection, IEnumerable<T>
{
#region Konstanten
private const int DefaultCapacity = 4;
#endregion
#region Nesty
public struct Enumerator : IEnumerator<T>, IDisposable
{
#region Felder
private MyQueue<T> _queue;
private int _index;
private int _version;
private T _currentElement;
#endregion
#region Eigenschaften
#endregion
#region Konstruktoren
internal Enumerator(MyQueue<T> queue)
{
this._queue = queue;
this._version = queue._version;
this._index = -1;
this._currentElement = default(T);
}
#endregion
#region Funktionen
#endregion
#region IEnumerator<T> Member
public T Current
{
get { return this._currentElement; }
}
#endregion
#region IDisposable Member
public void Dispose()
{
this._index = -2;
this._currentElement = default(T);
}
#endregion
#region IEnumerator Member
object IEnumerator.Current
{
get { return this._currentElement; }
}
public bool MoveNext()
{
if (this._version != this._queue._version)
throw new InvalidOperationException("Die Auflistung hat sich geändert.");
else
{
if (this._index < -1)
return false;
else
{
this._index++;
if (this._index >= this._queue.Count)
{
this.Dispose();
return false;
}
else
{
this._currentElement = this._queue.GetElement(this._index);
return true;
}
}
}
}
public void Reset()
{
if (this._version != this._queue._version)
throw new InvalidOperationException("Die Auflistung hat sich geändert.");
else
{
this._index = -1;
this._currentElement = default(T);
}
}
#endregion
}
#endregion
#region Felder
protected T[] _data;
protected int _head = 0;
protected int _size;
protected int _tail = 0;
protected int _version = 0;
#endregion
#region Eigenschaften
#endregion
#region Konstruktoren
public MyQueue(IEnumerable<T> collection)
{
if (collection == null) throw new ArgumentNullException("collection");
this._data = new T[4];
this._size = 0;
foreach (T fValue in collection)
{
this.Enqueue(fValue);
}
}
public MyQueue(int capacity)
{
if (capacity < 0) throw new ArgumentOutOfRangeException("capacity");
this._data = new T[capacity];
this._size = 0;
}
public MyQueue() : this (DefaultCapacity)
{
}
#endregion
#region Funktionen
public void Enqueue(T value)
{
if (this._size >= this._data.Length)
{
int capacity = this._data.Length * 2;
if (capacity < this._data.Length + DefaultCapacity) capacity += DefaultCapacity;
this.SetCapacity(capacity);
}
this._data[this._tail] = value;
this._tail = (this._tail + 1) % this._data.Length;
this._size++;
this._version++;
}
public void EnqueueBulk(T[] values)
{
this.EnqueueBulk(values, 0, values.Length);
}
public void EnqueueBulk(T[] values, int offset, int length)
{
if (values == null) throw new ArgumentNullException("values");
if (offset < 0) throw new ArgumentOutOfRangeException("offset");
if (length < 0) throw new ArgumentOutOfRangeException("length");
if (offset + length > values.Length) throw new ArgumentOutOfRangeException("length");
int size = this._size + length;
if (size >= this._data.Length)
{
size = size * 2;
if (size < this._data.Length + DefaultCapacity) size += DefaultCapacity;
this.SetCapacity(size);
}
if (this._tail + length > this._data.Length)
{
int tmp = this._data.Length - this._tail;
Array.Copy(values, offset, this._data, this._tail, tmp);
this._tail = length - tmp;
Array.Copy(values, offset + tmp, this._data, 0, this._tail - 1);
}
else
{
Array.Copy(values, offset, this._data, this._tail, length);
this._tail = (this._tail + length) % this._data.Length;
}
this._size += length;
this._version++;
}
public T Dequeue()
{
if (this._size == 0) throw new InvalidOperationException("Es sind keine Elemente in der Liste vorhanden");
T current = this._data[this._head];
this._data[this._head] = default(T);
this._head = (this._head + 1) % this._data.Length;
this._size--;
this._version++;
return current;
}
public int DequeueBulk(T[] buffer, int offset, int length)
{
if (buffer == null) throw new ArgumentNullException("buffer");
if (offset < 0) throw new ArgumentOutOfRangeException("offset");
if (length < 0) throw new ArgumentOutOfRangeException("length");
if (offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length");
int count = Math.Min(length, this._size);
int tHead = this._head;
if (count == 0)
return 0;
else
{
for (int fi = 0; fi < count; fi++)
{
buffer[offset + fi] = this._data[tHead];
tHead = (tHead + 1) % this._data.Length;
}
this._size -= count;
this._head = tHead;
this._version++;
return count;
}
}
public T Peek()
{
if (this._size == 0) throw new InvalidOperationException("Es sind keine Elemente in der Liste vorhanden");
return this._data[this._head];
}
public int PeekBulk(T[] buffer, int offset, int length)
{
if (buffer == null) throw new ArgumentNullException("buffer");
if (offset < 0) throw new ArgumentOutOfRangeException("offset");
if (length < 0) throw new ArgumentOutOfRangeException("length");
if (offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length");
int count = Math.Max(length, this._size);
int tHead = this._head;
if (count == 0)
return 0;
else
{
for (int fi = 0; fi < count; fi++)
{
buffer[offset + fi] = this._data[tHead];
tHead = (tHead + 1) % this._data.Length;
}
this._size -= count;
this._version++;
return count;
}
}
private void SetCapacity(int capacity)
{
T[] newData = new T[capacity];
if (this._size > 0)
{
if (this._head < this._tail)
{
Array.Copy(this._data, this._head, newData, 0, this._size);
}
else
{
Array.Copy(this._data, this._head, newData, 0, this._data.Length - this._head);
Array.Copy(this._data, 0, newData, this._data.Length - this._head, this._tail);
}
this._data = newData;
this._head = 0;
this._tail = this._size;
this._version++;
}
}
public T[] ToArray()
{
T[] destArray = new T[this._size];
if (this._size > 0)
{
if (this._head < this._tail)
{
Array.Copy(this._data, this._head, destArray, 0, this._size);
}
else
{
Array.Copy(this._data, this._head, destArray, 0, this._data.Length - this._head);
Array.Copy(this._data, 0, destArray, this._data.Length - this._head, this._tail);
}
}
return destArray;
}
public void TrimExcess()
{
int newCapacity = (int)(this._data.Length * 0.9F);
if (this._size < newCapacity)
this.SetCapacity(this._size);
}
internal T GetElement(int index)
{
return this._data[(this._head + index) % this._data.Length];
}
public void Clear()
{
if (this._size > 0)
{
if (this._head < this._tail)
{
for (int fi = this._head; fi < this._size; fi++)
{
this._data[fi] = default(T);
}
}
else
{
for (int fi = this._head; fi < this._data.Length; fi++)
{
this._data[fi] = default(T);
}
for (int fi = 0; fi < this._tail; fi++)
{
this._data[fi] = default(T);
}
}
this._size = 0;
this._head = 0;
this._tail = 0;
this._version++;
}
}
#endregion
#region IEnumerable<T> Member
public IEnumerator<T> GetEnumerator()
{
return new Enumerator(this);
}
#endregion
#region IEnumerable Member
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<T>)this).GetEnumerator();
}
#endregion
#region ICollection Member
public void CopyTo(Array array, int index)
{
if (array == null) throw new ArgumentNullException("array");
if (index < 0) throw new ArgumentOutOfRangeException("index");
if (array.Length + index < this._size) throw new ArgumentOutOfRangeException("array", "Die Länge des übergebenen Arrays ist zu kurz");
if (this._size > 0)
{
if (this._head < this._tail)
{
Array.Copy(this._data, this._head, array, index, this._size);
}
else
{
Array.Copy(this._data, this._head, array, 0, this._data.Length - this._head);
Array.Copy(this._data, 0, array, this._data.Length - this._head + index, this._tail);
}
}
}
public int Count
{
get { return this._size; }
}
public bool IsSynchronized
{
get { return false; }
}
public object SyncRoot
{
get { return null; }
}
#endregion
}
}
|