C#Queue源码
2023-07-27 本文已影响0人
好怕怕
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
namespace System.Collections.Generic
{
/// <summary>Represents a first-in, first-out collection of objects.</summary>
/// <typeparam name="T">Specifies the type of elements in the queue.</typeparam>
// Token: 0x020003C4 RID: 964
[DebuggerTypeProxy(typeof(System_QueueDebugView<>))]
[DebuggerDisplay("Count = {Count}")]
[ComVisible(false)]
[__DynamicallyInvokable]
[Serializable]
public class Queue<T> : IEnumerable<!0>, IEnumerable, ICollection, IReadOnlyCollection<T>
{
/// <summary>Initializes a new instance of the <see cref="T:System.Collections.Generic.Queue`1" /> class that is empty and has the default initial capacity.</summary>
// Token: 0x06002441 RID: 9281 RVA: 0x000A97EB File Offset: 0x000A79EB
[__DynamicallyInvokable]
public Queue()
{
this._array = Queue<T>._emptyArray;
}
/// <summary>Initializes a new instance of the <see cref="T:System.Collections.Generic.Queue`1" /> class that is empty and has the specified initial capacity.</summary>
/// <param name="capacity">The initial number of elements that the <see cref="T:System.Collections.Generic.Queue`1" /> can contain.</param>
/// <exception cref="T:System.ArgumentOutOfRangeException">
/// <paramref name="capacity" /> is less than zero.</exception>
// Token: 0x06002442 RID: 9282 RVA: 0x000A97FE File Offset: 0x000A79FE
[__DynamicallyInvokable]
public Queue(int capacity)
{
if (capacity < 0)
{
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.capacity, ExceptionResource.ArgumentOutOfRange_NeedNonNegNumRequired);
}
this._array = new T[capacity];
this._head = 0;
this._tail = 0;
this._size = 0;
}
/// <summary>Initializes a new instance of the <see cref="T:System.Collections.Generic.Queue`1" /> class that contains elements copied from the specified collection and has sufficient capacity to accommodate the number of elements copied.</summary>
/// <param name="collection">The collection whose elements are copied to the new <see cref="T:System.Collections.Generic.Queue`1" />.</param>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="collection" /> is <see langword="null" />.</exception>
// Token: 0x06002443 RID: 9283 RVA: 0x000A9834 File Offset: 0x000A7A34
[__DynamicallyInvokable]
public Queue(IEnumerable<T> collection)
{
if (collection == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
}
this._array = new T[4];
this._size = 0;
this._version = 0;
foreach (T item in collection)
{
this.Enqueue(item);
}
}
/// <summary>Gets the number of elements contained in the <see cref="T:System.Collections.Generic.Queue`1" />.</summary>
/// <returns>The number of elements contained in the <see cref="T:System.Collections.Generic.Queue`1" />.</returns>
// Token: 0x17000922 RID: 2338
// (get) Token: 0x06002444 RID: 9284 RVA: 0x000A98A4 File Offset: 0x000A7AA4
[__DynamicallyInvokable]
public int Count
{
[__DynamicallyInvokable]
get
{
return this._size;
}
}
/// <summary>Gets a value indicating whether access to the <see cref="T:System.Collections.ICollection" /> is synchronized (thread safe).</summary>
/// <returns>
/// <see langword="true" /> if access to the <see cref="T:System.Collections.ICollection" /> is synchronized (thread safe); otherwise, <see langword="false" />. In the default implementation of <see cref="T:System.Collections.Generic.Queue`1" />, this property always returns <see langword="false" />.</returns>
// Token: 0x17000923 RID: 2339
// (get) Token: 0x06002445 RID: 9285 RVA: 0x000A98AC File Offset: 0x000A7AAC
[__DynamicallyInvokable]
bool ICollection.IsSynchronized
{
[__DynamicallyInvokable]
get
{
return false;
}
}
/// <summary>Gets an object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection" />.</summary>
/// <returns>An object that can be used to synchronize access to the <see cref="T:System.Collections.ICollection" />. In the default implementation of <see cref="T:System.Collections.Generic.Queue`1" />, this property always returns the current instance.</returns>
// Token: 0x17000924 RID: 2340
// (get) Token: 0x06002446 RID: 9286 RVA: 0x000A98AF File Offset: 0x000A7AAF
[__DynamicallyInvokable]
object ICollection.SyncRoot
{
[__DynamicallyInvokable]
get
{
if (this._syncRoot == null)
{
Interlocked.CompareExchange<object>(ref this._syncRoot, new object(), null);
}
return this._syncRoot;
}
}
/// <summary>Removes all objects from the <see cref="T:System.Collections.Generic.Queue`1" />.</summary>
// Token: 0x06002447 RID: 9287 RVA: 0x000A98D4 File Offset: 0x000A7AD4
[__DynamicallyInvokable]
public void Clear()
{
if (this._head < this._tail)
{
Array.Clear(this._array, this._head, this._size);
}
else
{
Array.Clear(this._array, this._head, this._array.Length - this._head);
Array.Clear(this._array, 0, this._tail);
}
this._head = 0;
this._tail = 0;
this._size = 0;
this._version++;
}
/// <summary>Copies the <see cref="T:System.Collections.Generic.Queue`1" /> elements to an existing one-dimensional <see cref="T:System.Array" />, starting at the specified array index.</summary>
/// <param name="array">The one-dimensional <see cref="T:System.Array" /> that is the destination of the elements copied from <see cref="T:System.Collections.Generic.Queue`1" />. The <see cref="T:System.Array" /> must have zero-based indexing.</param>
/// <param name="arrayIndex">The zero-based index in <paramref name="array" /> at which copying begins.</param>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="array" /> is <see langword="null" />.</exception>
/// <exception cref="T:System.ArgumentOutOfRangeException">
/// <paramref name="arrayIndex" /> is less than zero.</exception>
/// <exception cref="T:System.ArgumentException">The number of elements in the source <see cref="T:System.Collections.Generic.Queue`1" /> is greater than the available space from <paramref name="arrayIndex" /> to the end of the destination <paramref name="array" />.</exception>
// Token: 0x06002448 RID: 9288 RVA: 0x000A9960 File Offset: 0x000A7B60
[__DynamicallyInvokable]
public void CopyTo(T[] array, int arrayIndex)
{
if (array == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
if (arrayIndex < 0 || arrayIndex > array.Length)
{
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.arrayIndex, ExceptionResource.ArgumentOutOfRange_Index);
}
int num = array.Length;
if (num - arrayIndex < this._size)
{
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
}
int num2 = (num - arrayIndex < this._size) ? (num - arrayIndex) : this._size;
if (num2 == 0)
{
return;
}
int num3 = (this._array.Length - this._head < num2) ? (this._array.Length - this._head) : num2;
Array.Copy(this._array, this._head, array, arrayIndex, num3);
num2 -= num3;
if (num2 > 0)
{
Array.Copy(this._array, 0, array, arrayIndex + this._array.Length - this._head, num2);
}
}
/// <summary>Copies the elements of the <see cref="T:System.Collections.ICollection" /> to an <see cref="T:System.Array" />, starting at a particular <see cref="T:System.Array" /> index.</summary>
/// <param name="array">The one-dimensional <see cref="T:System.Array" /> that is the destination of the elements copied from <see cref="T:System.Collections.ICollection" />. The <see cref="T:System.Array" /> must have zero-based indexing.</param>
/// <param name="index">The zero-based index in <paramref name="array" /> at which copying begins.</param>
/// <exception cref="T:System.ArgumentNullException">
/// <paramref name="array" /> is <see langword="null" />.</exception>
/// <exception cref="T:System.ArgumentOutOfRangeException">
/// <paramref name="index" /> is less than zero.</exception>
/// <exception cref="T:System.ArgumentException">
/// <paramref name="array" /> is multidimensional.
/// -or-
/// <paramref name="array" /> does not have zero-based indexing.
/// -or-
/// The number of elements in the source <see cref="T:System.Collections.ICollection" /> is greater than the available space from <paramref name="index" /> to the end of the destination <paramref name="array" />.
/// -or-
/// The type of the source <see cref="T:System.Collections.ICollection" /> cannot be cast automatically to the type of the destination <paramref name="array" />.</exception>
// Token: 0x06002449 RID: 9289 RVA: 0x000A9A1C File Offset: 0x000A7C1C
[__DynamicallyInvokable]
void ICollection.CopyTo(Array array, int index)
{
if (array == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.array);
}
if (array.Rank != 1)
{
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_RankMultiDimNotSupported);
}
if (array.GetLowerBound(0) != 0)
{
ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_NonZeroLowerBound);
}
int length = array.Length;
if (index < 0 || index > length)
{
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_Index);
}
if (length - index < this._size)
{
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
}
int num = (length - index < this._size) ? (length - index) : this._size;
if (num == 0)
{
return;
}
try
{
int num2 = (this._array.Length - this._head < num) ? (this._array.Length - this._head) : num;
Array.Copy(this._array, this._head, array, index, num2);
num -= num2;
if (num > 0)
{
Array.Copy(this._array, 0, array, index + this._array.Length - this._head, num);
}
}
catch (ArrayTypeMismatchException)
{
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidArrayType);
}
}
/// <summary>Adds an object to the end of the <see cref="T:System.Collections.Generic.Queue`1" />.</summary>
/// <param name="item">The object to add to the <see cref="T:System.Collections.Generic.Queue`1" />. The value can be <see langword="null" /> for reference types.</param>
// Token: 0x0600244A RID: 9290 RVA: 0x000A9B14 File Offset: 0x000A7D14
[__DynamicallyInvokable]
public void Enqueue(T item)
{
if (this._size == this._array.Length)
{
int num = (int)((long)this._array.Length * 200L / 100L);
if (num < this._array.Length + 4)
{
num = this._array.Length + 4;
}
this.SetCapacity(num);
}
this._array[this._tail] = item;
this._tail = (this._tail + 1) % this._array.Length;
this._size++;
this._version++;
}
/// <summary>Returns an enumerator that iterates through the <see cref="T:System.Collections.Generic.Queue`1" />.</summary>
/// <returns>An <see cref="T:System.Collections.Generic.Queue`1.Enumerator" /> for the <see cref="T:System.Collections.Generic.Queue`1" />.</returns>
// Token: 0x0600244B RID: 9291 RVA: 0x000A9BAB File Offset: 0x000A7DAB
[__DynamicallyInvokable]
public Queue<T>.Enumerator GetEnumerator()
{
return new Queue<T>.Enumerator(this);
}
// Token: 0x0600244C RID: 9292 RVA: 0x000A9BB3 File Offset: 0x000A7DB3
[__DynamicallyInvokable]
IEnumerator<T> IEnumerable<!0>.GetEnumerator()
{
return new Queue<T>.Enumerator(this);
}
/// <summary>Returns an enumerator that iterates through a collection.</summary>
/// <returns>An <see cref="T:System.Collections.IEnumerator" /> that can be used to iterate through the collection.</returns>
// Token: 0x0600244D RID: 9293 RVA: 0x000A9BC0 File Offset: 0x000A7DC0
[__DynamicallyInvokable]
IEnumerator IEnumerable.GetEnumerator()
{
return new Queue<T>.Enumerator(this);
}
/// <summary>Removes and returns the object at the beginning of the <see cref="T:System.Collections.Generic.Queue`1" />.</summary>
/// <returns>The object that is removed from the beginning of the <see cref="T:System.Collections.Generic.Queue`1" />.</returns>
/// <exception cref="T:System.InvalidOperationException">The <see cref="T:System.Collections.Generic.Queue`1" /> is empty.</exception>
// Token: 0x0600244E RID: 9294 RVA: 0x000A9BD0 File Offset: 0x000A7DD0
[__DynamicallyInvokable]
public T Dequeue()
{
if (this._size == 0)
{
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EmptyQueue);
}
T result = this._array[this._head];
this._array[this._head] = default(T);
this._head = (this._head + 1) % this._array.Length;
this._size--;
this._version++;
return result;
}
/// <summary>Returns the object at the beginning of the <see cref="T:System.Collections.Generic.Queue`1" /> without removing it.</summary>
/// <returns>The object at the beginning of the <see cref="T:System.Collections.Generic.Queue`1" />.</returns>
/// <exception cref="T:System.InvalidOperationException">The <see cref="T:System.Collections.Generic.Queue`1" /> is empty.</exception>
// Token: 0x0600244F RID: 9295 RVA: 0x000A9C4C File Offset: 0x000A7E4C
[__DynamicallyInvokable]
public T Peek()
{
if (this._size == 0)
{
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EmptyQueue);
}
return this._array[this._head];
}
/// <summary>Determines whether an element is in the <see cref="T:System.Collections.Generic.Queue`1" />.</summary>
/// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.Queue`1" />. The value can be <see langword="null" /> for reference types.</param>
/// <returns>
/// <see langword="true" /> if <paramref name="item" /> is found in the <see cref="T:System.Collections.Generic.Queue`1" />; otherwise, <see langword="false" />.</returns>
// Token: 0x06002450 RID: 9296 RVA: 0x000A9C70 File Offset: 0x000A7E70
[__DynamicallyInvokable]
public bool Contains(T item)
{
int num = this._head;
int size = this._size;
EqualityComparer<T> @default = EqualityComparer<T>.Default;
while (size-- > 0)
{
if (item == null)
{
if (this._array[num] == null)
{
return true;
}
}
else if (this._array[num] != null && @default.Equals(this._array[num], item))
{
return true;
}
num = (num + 1) % this._array.Length;
}
return false;
}
// Token: 0x06002451 RID: 9297 RVA: 0x000A9CF0 File Offset: 0x000A7EF0
internal T GetElement(int i)
{
return this._array[(this._head + i) % this._array.Length];
}
/// <summary>Copies the <see cref="T:System.Collections.Generic.Queue`1" /> elements to a new array.</summary>
/// <returns>A new array containing elements copied from the <see cref="T:System.Collections.Generic.Queue`1" />.</returns>
// Token: 0x06002452 RID: 9298 RVA: 0x000A9D10 File Offset: 0x000A7F10
[__DynamicallyInvokable]
public T[] ToArray()
{
T[] array = new T[this._size];
if (this._size == 0)
{
return array;
}
if (this._head < this._tail)
{
Array.Copy(this._array, this._head, array, 0, this._size);
}
else
{
Array.Copy(this._array, this._head, array, 0, this._array.Length - this._head);
Array.Copy(this._array, 0, array, this._array.Length - this._head, this._tail);
}
return array;
}
// Token: 0x06002453 RID: 9299 RVA: 0x000A9DA4 File Offset: 0x000A7FA4
private void SetCapacity(int capacity)
{
T[] array = new T[capacity];
if (this._size > 0)
{
if (this._head < this._tail)
{
Array.Copy(this._array, this._head, array, 0, this._size);
}
else
{
Array.Copy(this._array, this._head, array, 0, this._array.Length - this._head);
Array.Copy(this._array, 0, array, this._array.Length - this._head, this._tail);
}
}
this._array = array;
this._head = 0;
this._tail = ((this._size == capacity) ? 0 : this._size);
this._version++;
}
/// <summary>Sets the capacity to the actual number of elements in the <see cref="T:System.Collections.Generic.Queue`1" />, if that number is less than 90 percent of current capacity.</summary>
// Token: 0x06002454 RID: 9300 RVA: 0x000A9E64 File Offset: 0x000A8064
[__DynamicallyInvokable]
public void TrimExcess()
{
int num = (int)((double)this._array.Length * 0.9);
if (this._size < num)
{
this.SetCapacity(this._size);
}
}
// Token: 0x04001FF1 RID: 8177
private T[] _array;
// Token: 0x04001FF2 RID: 8178
private int _head;
// Token: 0x04001FF3 RID: 8179
private int _tail;
// Token: 0x04001FF4 RID: 8180
private int _size;
// Token: 0x04001FF5 RID: 8181
private int _version;
// Token: 0x04001FF6 RID: 8182
[NonSerialized]
private object _syncRoot;
// Token: 0x04001FF7 RID: 8183
private const int _MinimumGrow = 4;
// Token: 0x04001FF8 RID: 8184
private const int _ShrinkThreshold = 32;
// Token: 0x04001FF9 RID: 8185
private const int _GrowFactor = 200;
// Token: 0x04001FFA RID: 8186
private const int _DefaultCapacity = 4;
// Token: 0x04001FFB RID: 8187
private static T[] _emptyArray = new T[0];
/// <summary>Enumerates the elements of a <see cref="T:System.Collections.Generic.Queue`1" />.</summary>
/// <typeparam name="T" />
// Token: 0x020007F2 RID: 2034
[__DynamicallyInvokable]
[Serializable]
public struct Enumerator : IEnumerator<T>, IDisposable, IEnumerator
{
// Token: 0x06004414 RID: 17428 RVA: 0x0011D9C3 File Offset: 0x0011BBC3
internal Enumerator(Queue<T> q)
{
this._q = q;
this._version = this._q._version;
this._index = -1;
this._currentElement = default(T);
}
/// <summary>Releases all resources used by the <see cref="T:System.Collections.Generic.Queue`1.Enumerator" />.</summary>
// Token: 0x06004415 RID: 17429 RVA: 0x0011D9F0 File Offset: 0x0011BBF0
[__DynamicallyInvokable]
public void Dispose()
{
this._index = -2;
this._currentElement = default(T);
}
/// <summary>Advances the enumerator to the next element of the <see cref="T:System.Collections.Generic.Queue`1" />.</summary>
/// <returns>
/// <see langword="true" /> if the enumerator was successfully advanced to the next element; <see langword="false" /> if the enumerator has passed the end of the collection.</returns>
/// <exception cref="T:System.InvalidOperationException">The collection was modified after the enumerator was created.</exception>
// Token: 0x06004416 RID: 17430 RVA: 0x0011DA08 File Offset: 0x0011BC08
[__DynamicallyInvokable]
public bool MoveNext()
{
if (this._version != this._q._version)
{
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
}
if (this._index == -2)
{
return false;
}
this._index++;
if (this._index == this._q._size)
{
this._index = -2;
this._currentElement = default(T);
return false;
}
this._currentElement = this._q.GetElement(this._index);
return true;
}
/// <summary>Gets the element at the current position of the enumerator.</summary>
/// <returns>The element in the <see cref="T:System.Collections.Generic.Queue`1" /> at the current position of the enumerator.</returns>
/// <exception cref="T:System.InvalidOperationException">The enumerator is positioned before the first element of the collection or after the last element.</exception>
// Token: 0x17000F6C RID: 3948
// (get) Token: 0x06004417 RID: 17431 RVA: 0x0011DA8A File Offset: 0x0011BC8A
[__DynamicallyInvokable]
public T Current
{
[__DynamicallyInvokable]
get
{
if (this._index < 0)
{
if (this._index == -1)
{
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumNotStarted);
}
else
{
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumEnded);
}
}
return this._currentElement;
}
}
/// <summary>Gets the element at the current position of the enumerator.</summary>
/// <returns>The element in the collection at the current position of the enumerator.</returns>
/// <exception cref="T:System.InvalidOperationException">The enumerator is positioned before the first element of the collection or after the last element.</exception>
// Token: 0x17000F6D RID: 3949
// (get) Token: 0x06004418 RID: 17432 RVA: 0x0011DAB4 File Offset: 0x0011BCB4
[__DynamicallyInvokable]
object IEnumerator.Current
{
[__DynamicallyInvokable]
get
{
if (this._index < 0)
{
if (this._index == -1)
{
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumNotStarted);
}
else
{
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumEnded);
}
}
return this._currentElement;
}
}
/// <summary>Sets the enumerator to its initial position, which is before the first element in the collection.</summary>
/// <exception cref="T:System.InvalidOperationException">The collection was modified after the enumerator was created.</exception>
// Token: 0x06004419 RID: 17433 RVA: 0x0011DAE3 File Offset: 0x0011BCE3
[__DynamicallyInvokable]
void IEnumerator.Reset()
{
if (this._version != this._q._version)
{
ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
}
this._index = -1;
this._currentElement = default(T);
}
// Token: 0x040034FD RID: 13565
private Queue<T> _q;
// Token: 0x040034FE RID: 13566
private int _index;
// Token: 0x040034FF RID: 13567
private int _version;
// Token: 0x04003500 RID: 13568
private T _currentElement;
}
}
}