< Summary

Line coverage
95%
Covered lines: 342
Uncovered lines: 18
Coverable lines: 360
Total lines: 790
Line coverage: 95%
Branch coverage
84%
Covered branches: 110
Total branches: 130
Branch coverage: 84.6%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
File 1: .cctor()100%11100%
File 2: .cctor()100%11100%
File 2: .ctor()100%11100%
File 2: .ctor(...)100%44100%
File 2: .ctor(...)83.33%66100%
File 2: .ctor(...)100%11100%
File 2: get_InnerArray()100%11100%
File 2: get_Count()100%11100%
File 2: get_Capacity()100%11100%
File 2: get_IsSynchronized()100%11100%
File 2: System.Collections.ICollection.get_SyncRoot()100%22100%
File 2: get_IsReadOnly()100%11100%
File 2: get_Item(...)50%22100%
File 2: set_Item(...)50%22100%
File 2: get_State()100%22100%
File 2: set_State(...)66.66%66100%
File 2: System.Collections.Generic.ICollection<T>.Add(...)100%11100%
File 2: Enqueue(...)100%22100%
File 2: EnqueueRange(...)75%4485.71%
File 2: EnqueueRange(...)100%11100%
File 2: EnqueueRange(...)100%4491.66%
File 2: Dequeue()100%44100%
File 2: TryDequeue(...)100%44100%
File 2: System.Collections.Generic.ICollection<T>.Remove(...)100%11100%
File 2: Peek()100%22100%
File 2: TryPeek(...)100%22100%
File 2: PeekTail()100%22100%
File 2: Contains(...)83.33%66100%
File 2: Exists(...)100%44100%
File 2: Find(...)100%44100%
File 2: Clear()100%66100%
File 2: FastClear()100%11100%
File 2: EnsureCapacity(...)100%22100%
File 2: Resize(...)83.33%6684.21%
File 2: TrimExcessCapacity()75%8880.95%
File 2: ToArray()50%5458.33%
File 2: GetSegments(...)100%44100%
File 2: CopyTo(...)80%101093.33%
File 2: CopyTo(...)70%1010100%
File 2: CopyTo(...)100%44100%
File 2: CopyToInternal(...)100%2290.9%
File 2: CloneTo(...)100%22100%
File 2: GetEnumerator()100%11100%
File 2: System.Collections.Generic.IEnumerable<T>.GetEnumerator()100%11100%
File 2: System.Collections.IEnumerable.GetEnumerator()100%11100%
File 2: .ctor(...)100%11100%
File 2: get_Current()100%11100%
File 2: System.Collections.IEnumerator.get_Current()100%22100%
File 2: MoveNext()66.66%6690%
File 2: Reset()50%2285.71%
File 2: Dispose()100%11100%

File(s)

/_/src/SwiftCollections/obj/Debug/net8.0/MemoryPack.Generator/MemoryPack.Generator.MemoryPackGenerator/SwiftCollections.SwiftQueue_T_.MemoryPackFormatter.g.cs

File '/_/src/SwiftCollections/obj/Debug/net8.0/MemoryPack.Generator/MemoryPack.Generator.MemoryPackGenerator/SwiftCollections.SwiftQueue_T_.MemoryPackFormatter.g.cs' does not exist (any more).

/home/runner/work/SwiftCollections/SwiftCollections/src/SwiftCollections/Collection/SwiftQueue.cs

#LineLine coverage
 1using MemoryPack;
 2using System;
 3using System.Collections;
 4using System.Collections.Generic;
 5using System.Runtime.CompilerServices;
 6using System.Text.Json.Serialization;
 7
 8namespace SwiftCollections;
 9
 10/// <summary>
 11/// <c>SwiftQueue&lt;T&gt;</c> is a high-performance, circular buffer-based queue designed for ultra-low-latency enqueue
 12/// <para>
 13/// It leverages power-of-two capacities and bitwise arithmetic to eliminate expensive modulo operations, enhancing perf
 14/// By managing memory efficiently with a wrap-around technique and custom capacity growth strategies, SwiftQueue minimi
 15/// Aggressive inlining and optimized exception handling further reduce overhead, making SwiftQueue outperform tradition
 16/// especially in scenarios with high-frequency additions and removals.
 17/// </para>
 18/// </summary>
 19/// <typeparam name="T">Specifies the type of elements in the queue.</typeparam>
 20[Serializable]
 21[JsonConverter(typeof(SwiftStateJsonConverterFactory))]
 22[MemoryPackable]
 23public sealed partial class SwiftQueue<T> : ISwiftCloneable<T>, IEnumerable<T>, IEnumerable, ICollection<T>, ICollection
 24{
 25    #region Constants
 26
 27    /// <summary>
 28    /// The default initial capacity of the SwiftQueue if none is specified.
 29    /// Used to allocate a reasonable starting size to minimize resizing operations.
 30    /// </summary>
 31    public const int DefaultCapacity = 8;
 32
 233    private static readonly T[] _emptyArray = Array.Empty<T>();
 234    private static readonly bool _clearReleasedSlots = RuntimeHelpers.IsReferenceOrContainsReferences<T>();
 35
 36    #endregion
 37
 38    #region Fields
 39
 40    /// <summary>
 41    /// The internal array that stores elements of the SwiftQueue. Resized as needed to
 42    /// accommodate additional elements. Not directly exposed outside the queue.
 43    /// </summary>
 44    private T[] _innerArray;
 45
 46    /// <summary>
 47    /// The current number of elements in the SwiftQueue. Represents the total count of
 48    /// valid elements stored in the queue, also indicating the arrayIndex of the next insertion point.
 49    /// </summary>
 50    private int _count;
 51
 52    /// <summary>
 53    /// The arrayIndex of the first element in the queue. Adjusts as elements are dequeued.
 54    /// </summary>
 55    private int _head;
 56
 57    /// <summary>
 58    /// The arrayIndex at which the next element will be enqueued, wrapping around as needed.
 59    /// </summary>
 60    private int _tail;
 61
 62    /// <summary>
 63    /// A bitmask used for efficient modulo operations, derived from the capacity of the internal array.
 64    /// </summary>
 65    private int _mask;
 66
 67    /// <summary>
 68    /// A version number used to track modifications to the SwiftQueue to help detect changes during enumeration and ens
 69    /// </summary>
 70    [NonSerialized]
 71    private uint _version;
 72
 73    /// <summary>
 74    /// An object used to synchronize access to the SwiftQueue, ensuring thread safety.
 75    /// </summary>
 76    [NonSerialized]
 77    private object _syncRoot;
 78
 79    #endregion
 80
 81    #region Constructors
 82
 83    /// <summary>
 84    /// Initializes a new, empty instance of SwiftQueue.
 85    /// </summary>
 10886    public SwiftQueue() : this(0) { }
 87
 88    /// <summary>
 89    /// Initializes a new, empty instance of SwiftQueue with the specified initial capacity.
 90    /// </summary>
 5191    public SwiftQueue(int capacity)
 5192    {
 5193        if (capacity == 0)
 3694        {
 3695            _innerArray = _emptyArray;
 3696            _mask = 0;
 3697        }
 98        else
 1599        {
 15100            capacity = capacity < DefaultCapacity ? DefaultCapacity : SwiftHashTools.NextPowerOfTwo(capacity);
 15101            _innerArray = new T[capacity];
 15102            _mask = _innerArray.Length - 1;
 15103        }
 51104    }
 105
 106    /// <summary>
 107    /// Initializes a new instance of SwiftQueue that contains elements copied from the provided items.
 108    /// </summary>
 2109    public SwiftQueue(IEnumerable<T> items)
 2110    {
 2111        SwiftThrowHelper.ThrowIfNull(items, nameof(items));
 2112        if (items is ICollection<T> collection)
 1113        {
 1114            int capacity = collection.Count < DefaultCapacity ? DefaultCapacity : SwiftHashTools.NextPowerOfTwo(collecti
 1115            _innerArray = new T[capacity];
 1116        }
 117        else
 1118            _innerArray = new T[DefaultCapacity];
 119
 2120        _mask = _innerArray.Length - 1;
 18121        foreach (T item in items)
 6122            Enqueue(item);
 2123    }
 124
 125    ///  <summary>
 126    ///  Initializes a new instance of the <see cref="SwiftQueue{T}"/> class with the specified <see cref="SwiftArraySta
 127    ///  </summary>
 128    ///  <param name="state">The state containing the internal array, count, offset, and version for initialization.</pa
 129    [MemoryPackConstructor]
 3130    public SwiftQueue(SwiftArrayState<T> state)
 3131    {
 3132        State = state;
 3133    }
 134
 135    #endregion
 136
 137    #region Properties
 138
 139    /// <inheritdoc cref="_innerArray"/>
 140    [JsonIgnore]
 141    [MemoryPackIgnore]
 5142    public T[] InnerArray => _innerArray;
 143
 144    /// <inheritdoc cref="_count"/>
 145    [JsonIgnore]
 146    [MemoryPackIgnore]
 127147    public int Count => _count;
 148
 149    /// <summary>
 150    /// Gets the total number of elements the SwiftQueue can hold without resizing.
 151    /// Reflects the current allocated size of the internal array.
 152    /// </summary>
 153    [JsonIgnore]
 154    [MemoryPackIgnore]
 7155    public int Capacity => _innerArray.Length;
 156
 157    [JsonIgnore]
 158    [MemoryPackIgnore]
 1159    public bool IsSynchronized => false;
 160
 161    [JsonIgnore]
 162    [MemoryPackIgnore]
 1163    object ICollection.SyncRoot => _syncRoot ??= new object();
 164
 165    /// <inheritdoc/>
 166    [JsonIgnore]
 167    [MemoryPackIgnore]
 1168    public bool IsReadOnly => false;
 169
 170    /// <summary>
 171    /// Gets the element at the specified arrayIndex.
 172    /// </summary>
 173    [JsonIgnore]
 174    [MemoryPackIgnore]
 175    public T this[int index]
 176    {
 177        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 178        get
 200179        {
 200180            if ((uint)index >= (uint)_count) throw new ArgumentOutOfRangeException(nameof(index));
 200181            return _innerArray[(_head + index) & _mask];
 200182        }
 183        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 184        set
 1185        {
 1186            if ((uint)index >= (uint)_count) throw new ArgumentOutOfRangeException(nameof(index));
 1187            _innerArray[(_head + index) & _mask] = value;
 1188        }
 189    }
 190
 191    [JsonInclude]
 192    [MemoryPackInclude]
 193    public SwiftArrayState<T> State
 194    {
 195        get
 2196        {
 2197            var items = new T[_count];
 198
 404199            for (int i = 0; i < _count; i++)
 200200                items[i] = _innerArray[(_head + i) & _mask];
 201
 2202            return new SwiftArrayState<T>(items);
 2203        }
 204        internal set
 3205        {
 3206            int count = value.Items?.Length ?? 0;
 207
 3208            if (count == 0)
 1209            {
 1210                _innerArray = _emptyArray;
 1211                _count = 0;
 1212                _head = 0;
 1213                _tail = 0;
 1214                _mask = 0;
 1215                _version = 0;
 1216                return;
 217            }
 218
 2219            int capacity = SwiftHashTools.NextPowerOfTwo(count <= DefaultCapacity ? DefaultCapacity : count);
 220
 2221            _innerArray = new T[capacity];
 2222            Array.Copy(value.Items, 0, _innerArray, 0, count);
 223
 2224            _count = count;
 2225            _head = 0;
 2226            _tail = count;
 2227            _mask = capacity - 1;
 228
 2229            _version = 0;
 3230        }
 231    }
 232
 233    #endregion
 234
 235    #region Collection Management
 236
 237    /// <inheritdoc/>
 1238    void ICollection<T>.Add(T item) => Enqueue(item);
 239
 240    /// <summary>
 241    /// Adds an item to the end of the queue. Automatically resizes the queue if the capacity is exceeded.
 242    /// </summary>
 243    /// <param name="item">The item to add to the queue.</param>
 244    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 245    public void Enqueue(T item)
 319246    {
 319247        if ((uint)_count >= (uint)_innerArray.Length)
 33248            Resize(_innerArray.Length * 2);
 319249        _innerArray[_tail] = item;
 319250        _tail = (_tail + 1) & _mask;
 319251        _count++;
 319252        _version++;
 319253    }
 254
 255    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 256    public void EnqueueRange(IEnumerable<T> items)
 2257    {
 2258        SwiftThrowHelper.ThrowIfNull(items, nameof(items));
 259
 2260        if (items is ICollection<T> collection)
 0261            EnsureCapacity(_count + collection.Count);
 262
 18263        foreach (T item in items)
 6264            Enqueue(item);
 2265    }
 266
 267    /// <summary>
 268    /// Adds the elements of the specified array to the end of the queue in queue order.
 269    /// </summary>
 270    /// <param name="items">The array whose elements should be enqueued.</param>
 271    public void EnqueueRange(T[] items)
 6272    {
 6273        SwiftThrowHelper.ThrowIfNull(items, nameof(items));
 6274        EnqueueRange(items.AsSpan());
 6275    }
 276
 277    /// <summary>
 278    /// Adds the elements of the specified span to the end of the queue in queue order.
 279    /// </summary>
 280    /// <param name="items">The span whose elements should be enqueued.</param>
 281    public void EnqueueRange(ReadOnlySpan<T> items)
 22282    {
 22283        if (items.Length == 0)
 0284            return;
 285
 22286        EnsureCapacity(_count + items.Length);
 287
 226288        for (int i = 0; i < items.Length; i++)
 91289        {
 91290            _innerArray[_tail] = items[i];
 91291            _tail = (_tail + 1) & _mask;
 91292        }
 293
 22294        _count += items.Length;
 22295        _version++;
 22296    }
 297
 298    /// <summary>
 299    /// Removes and returns the item at the front of the queue.
 300    /// Throws an InvalidOperationException if the queue is empty.
 301    /// </summary>
 302    /// <returns>The item at the front of the queue.</returns>
 303    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 304    public T Dequeue()
 69305    {
 70306        if ((uint)_count == 0) throw new InvalidOperationException("Queue is Empty");
 68307        T item = _innerArray[_head];
 68308        if (_clearReleasedSlots)
 5309            _innerArray[_head] = default;
 68310        _head = (_head + 1) & _mask;
 68311        _count--;
 68312        _version++;
 68313        return item;
 68314    }
 315
 316    /// <summary>
 317    /// Tries to remove and return the item at the front of the queue.
 318    /// </summary>
 319    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 320    public bool TryDequeue(out T item)
 3321    {
 3322        if ((uint)_count == 0)
 1323        {
 1324            item = default;
 1325            return false;
 326        }
 327
 2328        item = _innerArray[_head];
 2329        if (_clearReleasedSlots)
 1330            _innerArray[_head] = default;
 2331        _head = (_head + 1) & _mask;
 2332        _count--;
 2333        _version++;
 2334        return true;
 3335    }
 336
 1337    bool ICollection<T>.Remove(T item) => throw new NotSupportedException("Remove is not supported for SwiftQueue.");
 338
 339    /// <summary>
 340    /// Returns the item at the front of the queue without removing it.
 341    /// Throws an InvalidOperationException if the queue is empty.
 342    /// </summary>
 343    /// <returns>The item at the front of the queue.</returns>
 344    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 345    public T Peek()
 5346    {
 7347        if ((uint)_count == 0) throw new InvalidOperationException("Queue is Empty");
 3348        return _innerArray[_head];
 3349    }
 350
 351    /// <summary>
 352    /// Tries to return the item at the front of the queue without removing it.
 353    /// </summary>
 354    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 355    public bool TryPeek(out T item)
 2356    {
 2357        if ((uint)_count == 0)
 1358        {
 1359            item = default;
 1360            return false;
 361        }
 362
 1363        item = _innerArray[_head];
 1364        return true;
 2365    }
 366
 367    /// <summary>
 368    /// Returns the item at the end of the queue without removing it.
 369    /// Throws an InvalidOperationException if the queue is empty.
 370    /// </summary>
 371    /// <returns>The item at the end of the queue.</returns>
 372    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 373    public T PeekTail()
 4374    {
 5375        if ((uint)_count == 0) throw new InvalidOperationException("Queue is Empty");
 3376        int tailIndex = (_tail - 1) & _mask;
 3377        return _innerArray[tailIndex];
 3378    }
 379
 380    /// <inheritdoc/>
 381    public bool Contains(T item)
 2382    {
 2383        if ((uint)_count == 0) return false;
 384
 2385        int index = _head;
 20386        for (int i = 0; i < _count; i++)
 9387        {
 9388            if (Equals(_innerArray[index], item))
 1389                return true;
 390
 8391            index = (index + 1) & _mask;
 8392        }
 393
 1394        return false;
 2395    }
 396
 397    /// <summary>
 398    /// Determines whether the <see cref="SwiftQueue{T}"/> contains an element that matches the conditions defined by th
 399    /// </summary>
 400    /// <param name="match">The predicate that defines the conditions of the element to search for.</param>
 401    /// <returns><c>true</c> if the <see cref="SwiftQueue{T}"/> contains one or more elements that match the specified p
 402    public bool Exists(Predicate<T> match)
 3403    {
 3404        SwiftThrowHelper.ThrowIfNull(match, nameof(match));
 405
 2406        int index = _head;
 20407        for (int i = 0; i < _count; i++)
 9408        {
 9409            if (match(_innerArray[index]))
 1410                return true;
 411
 8412            index = (index + 1) & _mask;
 8413        }
 414
 1415        return false;
 2416    }
 417
 418    /// <summary>
 419    /// Searches for an element that matches the conditions defined by the specified predicate, and returns the first ma
 420    /// </summary>
 421    /// <param name="match">The predicate that defines the conditions of the element to search for.</param>
 422    /// <returns>The first element that matches the conditions defined by the specified predicate, if found; otherwise, 
 423    public T Find(Predicate<T> match)
 2424    {
 2425        SwiftThrowHelper.ThrowIfNull(match, nameof(match));
 426
 2427        int index = _head;
 22428        for (int i = 0; i < _count; i++)
 10429        {
 10430            T item = _innerArray[index];
 10431            if (match(item))
 1432                return item;
 433
 9434            index = (index + 1) & _mask;
 9435        }
 436
 1437        return default;
 2438    }
 439
 440    /// <summary>
 441    /// Removes all elements from the SwiftQueue, resetting its count to zero.
 442    /// </summary>
 443    public void Clear()
 6444    {
 8445        if (_count == 0) return;
 446
 4447        if (_clearReleasedSlots)
 2448        {
 2449            if ((uint)_head < (uint)_tail)
 1450                Array.Clear(_innerArray, _head, _count);
 451            else
 1452            {
 1453                Array.Clear(_innerArray, _head, _innerArray.Length - _head);
 1454                Array.Clear(_innerArray, 0, _tail);
 1455            }
 2456        }
 457
 4458        _count = 0;
 4459        _head = 0;
 4460        _tail = 0;
 4461        _version++;
 6462    }
 463
 464    /// <summary>
 465    /// Clears the SwiftQueue without releasing the reference to the stored elements.
 466    /// Use FastClear() when you want to quickly reset the list without reallocating memory.
 467    /// </summary>
 468    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 469    public void FastClear()
 1470    {
 1471        _count = 0;
 1472        _tail = 0;
 1473        _head = 0;
 1474        _version++;
 1475    }
 476
 477    #endregion
 478
 479    #region Capacity Management
 480
 481    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 482    public void EnsureCapacity(int capacity)
 23483    {
 23484        capacity = SwiftHashTools.NextPowerOfTwo(capacity);  // Capacity must be a power of 2 for proper masking
 23485        if (capacity > _innerArray.Length)
 5486            Resize(capacity);
 23487    }
 488
 489    /// <summary>
 490    /// Ensures that the capacity of the queue is sufficient to accommodate the specified number of elements.
 491    /// The capacity increases to the next power of two greater than or equal to the required minimum capacity.
 492    /// </summary>
 493    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 494    private void Resize(int newSize)
 38495    {
 38496        var newArray = new T[newSize <= DefaultCapacity ? DefaultCapacity : newSize];
 38497        if ((uint)_count > 0)
 9498        {
 499            // If we are not wrapped around...
 9500            if ((uint)_head < (uint)_tail)
 0501            {
 502                // ...copy from head to tail into new array starting at arrayIndex 0
 0503                Array.Copy(_innerArray, _head, newArray, 0, _count);
 0504            }
 505            // Else if we are wrapped around...
 506            else
 9507            {
 508                // ...copy from head to end of old array to beginning of new array
 9509                Array.Copy(_innerArray, _head, newArray, 0, _innerArray.Length - _head);
 510                // ...copy from start of old array to tail into new array
 9511                Array.Copy(_innerArray, 0, newArray, _innerArray.Length - _head, _tail);
 9512            }
 9513        }
 514
 38515        _innerArray = newArray;
 38516        _mask = _innerArray.Length - 1;
 38517        _head = 0;
 38518        _tail = _count & _mask;
 38519        _version++;
 38520    }
 521
 522    /// <summary>
 523    /// Reduces the capacity of the SwiftQueue if the element count is significantly less than the current capacity.
 524    /// This method resizes the internal array to the next power of two greater than or equal to the current count,
 525    /// optimizing memory usage.
 526    /// </summary>
 527    public void TrimExcessCapacity()
 2528    {
 2529        int newSize = _count < DefaultCapacity ? DefaultCapacity : SwiftHashTools.NextPowerOfTwo(_count);
 2530        if (newSize >= _innerArray.Length) return;
 531
 2532        var newArray = new T[newSize];
 533
 2534        if ((uint)_count != 0)
 1535        {
 1536            if ((uint)_head < (uint)_tail)
 1537            {
 538                // No wrap-around, simple copy
 1539                Array.Copy(_innerArray, _head, newArray, 0, _count);
 1540            }
 541            else
 0542            {
 543                // Wrap-around, copy in two parts
 0544                Array.Copy(_innerArray, _head, newArray, 0, _innerArray.Length - _head);
 0545                Array.Copy(_innerArray, 0, newArray, _innerArray.Length - _head, _tail);
 0546            }
 1547        }
 548
 2549        _innerArray = newArray;
 2550        _mask = _innerArray.Length - 1;
 2551        _head = 0;
 2552        _tail = _count & _mask;
 2553        _version++;
 2554    }
 555
 556    #endregion
 557
 558    #region Utility Methods
 559
 560    /// <summary>
 561    /// Copies the elements of the SwiftQueue to a new array.
 562    /// </summary>
 563    public T[] ToArray()
 10564    {
 10565        var result = new T[_count];
 10566        if ((uint)_count == 0) return result;
 10567        if ((uint)_head < (uint)_tail)
 10568            Array.Copy(_innerArray, _head, result, 0, _count);
 569        else
 0570        {
 0571            int firstPartLength = _innerArray.Length - _head;
 0572            Array.Copy(_innerArray, _head, result, 0, firstPartLength);
 0573            Array.Copy(_innerArray, 0, result, firstPartLength, _tail);
 0574        }
 10575        return result;
 10576    }
 577
 578    /// <summary>
 579    /// Returns the current queue contents as up to two read-only spans.
 580    /// </summary>
 581    /// <param name="first">The first contiguous queue segment.</param>
 582    /// <param name="second">The wrapped tail segment, if any.</param>
 583    public void GetSegments(out ReadOnlySpan<T> first, out ReadOnlySpan<T> second)
 4584    {
 4585        if ((uint)_count == 0)
 1586        {
 1587            first = ReadOnlySpan<T>.Empty;
 1588            second = ReadOnlySpan<T>.Empty;
 1589            return;
 590        }
 591
 3592        if ((uint)_head < (uint)_tail)
 1593        {
 1594            first = _innerArray.AsSpan(_head, _count);
 1595            second = ReadOnlySpan<T>.Empty;
 1596            return;
 597        }
 598
 2599        int firstPartLength = _innerArray.Length - _head;
 2600        first = _innerArray.AsSpan(_head, firstPartLength);
 2601        second = _innerArray.AsSpan(0, _tail);
 4602    }
 603
 604    /// <inheritdoc/>
 605    public void CopyTo(Array array, int arrayIndex)
 4606    {
 4607        SwiftThrowHelper.ThrowIfNull(array, nameof(array));
 5608        if ((uint)array.Rank != 1) throw new ArgumentException("Array must be single dimensional.", nameof(array));
 4609        if ((uint)array.GetLowerBound(0) != 0) throw new ArgumentException("Array must have zero-based indexing.", nameo
 2610        if ((uint)arrayIndex > array.Length) throw new ArgumentOutOfRangeException(nameof(arrayIndex));
 2611        if ((uint)(array.Length - arrayIndex) < _count) throw new ArgumentException("Destination array is not long enoug
 612
 2613        if ((uint)_count == 0)
 0614            return;
 615
 616        try
 2617        {
 2618            CopyToInternal(array, arrayIndex);
 1619        }
 1620        catch (ArrayTypeMismatchException)
 1621        {
 1622            throw new ArgumentException("Invalid array type.", nameof(array));
 623        }
 1624    }
 625
 626    /// <inheritdoc/>
 627    public void CopyTo(T[] array, int arrayIndex)
 2628    {
 2629        SwiftThrowHelper.ThrowIfNull(array, nameof(array));
 2630        if ((uint)array.Rank != 1) throw new ArgumentException("Array must be single dimensional.", nameof(array));
 2631        if ((uint)array.GetLowerBound(0) != 0) throw new ArgumentException("Array must have zero-based indexing.", nameo
 2632        if ((uint)arrayIndex > array.Length) throw new ArgumentOutOfRangeException(nameof(arrayIndex));
 3633        if ((uint)(array.Length - arrayIndex) < _count) throw new ArgumentException("Destination array is not long enoug
 634
 1635        if ((uint)_count == 0) return;
 636
 1637        CopyToInternal(array, arrayIndex);
 1638    }
 639
 640    /// <summary>
 641    /// Copies the elements of the SwiftQueue into the specified destination span.
 642    /// </summary>
 643    /// <param name="destination">The destination span.</param>
 644    public void CopyTo(Span<T> destination)
 2645    {
 2646        if (destination.Length < _count)
 1647            throw new ArgumentException("Destination span is not long enough.", nameof(destination));
 648
 1649        GetSegments(out ReadOnlySpan<T> first, out ReadOnlySpan<T> second);
 1650        first.CopyTo(destination);
 651
 1652        if (second.Length > 0)
 1653            second.CopyTo(destination.Slice(first.Length));
 1654    }
 655
 656    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 657    private void CopyToInternal(Array destination, int arrayIndex)
 3658    {
 3659        if ((uint)_head < (uint)_tail)
 1660        {
 1661            Array.Copy(_innerArray, _head, destination, arrayIndex, _count);
 0662        }
 663        else
 2664        {
 2665            int firstPartLength = _innerArray.Length - _head;
 2666            Array.Copy(_innerArray, _head, destination, arrayIndex, firstPartLength);
 2667            Array.Copy(_innerArray, 0, destination, arrayIndex + firstPartLength, _tail);
 2668        }
 2669    }
 670
 671    public void CloneTo(ICollection<T> output)
 1672    {
 1673        SwiftThrowHelper.ThrowIfNull(output, nameof(output));
 1674        output.Clear();
 13675        foreach (var item in this)
 5676            output.Add(item);
 1677    }
 678
 679    #endregion
 680
 681    #region Enumerators
 682
 683    /// <summary>
 684    /// Returns an enumerator that iterates through the SwiftList.
 685    /// </summary>
 13686    public SwiftQueueEnumerator GetEnumerator() => new SwiftQueueEnumerator(this);
 8687    IEnumerator<T> IEnumerable<T>.GetEnumerator() => GetEnumerator();
 2688    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
 689
 690    public struct SwiftQueueEnumerator : IEnumerator<T>, IEnumerator, IDisposable
 691    {
 692        private readonly SwiftQueue<T> _queue;
 693        private readonly T[] _array;
 694        private readonly uint _version;
 695        private uint _index;
 696        private uint _currentIndex;
 697
 698        private T _current;
 699
 700        public SwiftQueueEnumerator(SwiftQueue<T> queue)
 13701        {
 13702            _queue = queue;
 13703            _array = queue._innerArray;
 13704            _version = queue._version;
 13705            _index = 0;
 13706            _currentIndex = (uint)queue._head - 1;
 13707            _current = default;
 13708        }
 709
 413710        public readonly T Current => _current;
 711
 712        readonly object IEnumerator.Current
 713        {
 714            [MethodImpl(MethodImplOptions.AggressiveInlining)]
 715            get
 3716            {
 4717                if (_index >= (uint)_queue._count) throw new InvalidOperationException("Bad enumeration");
 2718                return _current;
 2719            }
 720        }
 721
 722        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 723        public bool MoveNext()
 229724        {
 229725            if (_version != _queue._version)
 0726                throw new InvalidOperationException("Collection was modified during enumeration.");
 229727            _index++;
 240728            if (_index > (uint)_queue._count) return false;
 218729            _currentIndex++;
 218730            if (_currentIndex == _array.Length) _currentIndex = 0;
 218731            _current = _array[_currentIndex];
 218732            return true;
 229733        }
 734
 735        public void Reset()
 2736        {
 2737            if (_version != _queue._version)
 0738                throw new InvalidOperationException("Collection was modified during enumeration.");
 739
 2740            _index = 0;
 2741            _currentIndex = (uint)_queue._head - 1;
 2742            _current = default;
 2743        }
 744
 20745        public void Dispose() { }
 746    }
 747
 748    #endregion
 749}