< Summary

Information
Class: SwiftCollections.SwiftStack<T>
Assembly: SwiftCollections
File(s): /home/runner/work/SwiftCollections/SwiftCollections/src/SwiftCollections/Collection/SwiftStack.cs
Line coverage
100%
Covered lines: 174
Uncovered lines: 0
Coverable lines: 174
Total lines: 605
Line coverage: 100%
Branch coverage
96%
Covered branches: 60
Total branches: 62
Branch coverage: 96.7%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
.ctor()100%11100%
.ctor(...)100%44100%
.ctor(...)100%88100%
.ctor(...)100%11100%
get_InnerArray()100%11100%
get_Count()100%11100%
get_Capacity()100%11100%
System.Collections.Generic.ICollection<T>.get_IsReadOnly()100%11100%
get_IsSynchronized()100%11100%
System.Collections.ICollection.get_SyncRoot()50%22100%
get_Item(...)100%11100%
set_Item(...)100%11100%
get_State()100%11100%
set_State(...)100%44100%
System.Collections.Generic.ICollection<T>.Add(...)100%11100%
Push(...)100%22100%
PushRange(...)100%44100%
System.Collections.Generic.ICollection<T>.Remove(...)100%11100%
Pop()100%22100%
Clear()100%44100%
FastClear()100%11100%
EnsureCapacity(...)50%22100%
Resize(...)100%44100%
TrimCapacity()100%44100%
Peek()100%11100%
ToString()100%22100%
AsSpan()100%11100%
AsReadOnlySpan()100%11100%
CopyTo(...)100%11100%
CopyTo(...)100%11100%
CopyTo(...)100%22100%
CloneTo(...)100%22100%
Contains(...)100%44100%
Exists(...)100%44100%
Find(...)100%44100%
GetEnumerator()100%11100%
System.Collections.Generic.IEnumerable<T>.GetEnumerator()100%11100%
System.Collections.IEnumerable.GetEnumerator()100%11100%
.ctor(...)100%11100%
get_Current()100%11100%
System.Collections.IEnumerator.get_Current()100%11100%
MoveNext()100%44100%
Reset()100%11100%
Dispose()100%11100%

File(s)

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

#LineLine coverage
 1//=======================================================================
 2// SwiftStack.cs
 3//=======================================================================
 4// MIT License, Copyright (c) 2024–present David Oravsky (mrdav30)
 5// See LICENSE file in the project root for full license information.
 6//=======================================================================
 7
 8using Chronicler;
 9using MemoryPack;
 10using SwiftCollections.Diagnostics;
 11using SwiftCollections.Utility;
 12using System;
 13using System.Collections;
 14using System.Collections.Generic;
 15using System.Runtime.CompilerServices;
 16using System.Text.Json.Serialization;
 17
 18namespace SwiftCollections;
 19
 20/// <summary>
 21/// Represents a fast, array-based stack (LIFO - Last-In-First-Out) collection of objects.
 22/// <para>
 23/// The <c>SwiftStack&lt;T&gt;</c> class provides O(1) time complexity for <c>Push</c> and <c>Pop</c> operations,
 24/// making it highly efficient for scenarios where performance is critical.
 25/// It minimizes memory allocations by reusing internal arrays and offers methods
 26/// like <c>FastClear</c> to quickly reset the stack without deallocating memory.
 27/// </para>
 28/// <para>
 29/// This implementation is optimized for performance and does not perform versioning checks.
 30/// Modifying the stack during enumeration may result in undefined behavior.
 31/// </para>
 32/// </summary>
 33/// <typeparam name="T">Specifies the type of elements in the stack.</typeparam>
 34[Serializable]
 35[JsonConverter(typeof(StateJsonConverterFactory))]
 36[MemoryPackable]
 37public sealed partial class SwiftStack<T> : IStateBacked<SwiftArrayState<T>>, ISwiftCloneable<T>, IEnumerable<T>, IEnume
 38{
 39    #region Constants
 40
 41    /// <summary>
 42    /// The default initial capacity of the SwiftStack if none is specified.
 43    /// Used to allocate a reasonable starting size to minimize resizing operations.
 44    /// </summary>
 45    public const int DefaultCapacity = 8;
 46
 347    private static readonly T[] _emptyArray = Array.Empty<T>();
 348    private static readonly bool _clearReleasedSlots = RuntimeHelpers.IsReferenceOrContainsReferences<T>();
 49
 50    #endregion
 51
 52    #region Fields
 53
 54    /// <summary>
 55    /// The internal array that stores elements of the SwiftStack. Resized as needed to
 56    /// accommodate additional elements. Not directly exposed outside the stack.
 57    /// </summary>
 58    private T[] _innerArray;
 59
 60    /// <summary>
 61    /// The current number of elements in the SwiftStack. Represents the total count of
 62    /// valid elements stored in the stack, also indicating the arrayIndex of the next insertion point.
 63    /// </summary>
 64    private int _count;
 65
 66    [NonSerialized]
 67    private uint _version;
 68
 69    [NonSerialized]
 70    private object? _syncRoot;
 71
 72    #endregion
 73
 74    #region Constructors
 75
 76    /// <summary>
 77    /// Initializes a new, empty instance of SwiftStack.
 78    /// </summary>
 9879    public SwiftStack() : this(0) { }
 80
 81    /// <summary>
 82    /// Initializes a new, empty instance of SwiftStack with the specified initial capacity.
 83    /// </summary>
 5584    public SwiftStack(int capacity)
 85    {
 5586        if (capacity == 0)
 4987            _innerArray = _emptyArray;
 88        else
 89        {
 690            capacity = capacity <= DefaultCapacity ? DefaultCapacity : SwiftHashTools.NextPowerOfTwo(capacity);
 691            _innerArray = new T[capacity];
 92        }
 693    }
 94
 95    /// <summary>
 96    /// Initializes a new instance of the <see cref="SwiftStack{T}"/> class that contains elements copied from the speci
 97    /// </summary>
 98    /// <remarks>
 99    /// The elements are copied onto the stack in the order they are returned by the enumerator of the collection,
 100    /// so that the last element in the collection becomes the top of the stack.
 101    /// </remarks>
 102    /// <param name="items">The collection whose elements are copied to the new stack. Cannot be null.</param>
 4103    public SwiftStack(IEnumerable<T> items)
 104    {
 4105        SwiftThrowHelper.ThrowIfNull(items, nameof(items));
 106
 4107        if (items is ICollection<T> collection)
 108        {
 3109            int count = collection.Count;
 3110            if (count == 0)
 1111                _innerArray = _emptyArray;
 112            else
 113            {
 2114                int capacity = SwiftHashTools.NextPowerOfTwo(count <= DefaultCapacity ? DefaultCapacity : count);
 2115                _innerArray = new T[capacity];
 2116                collection.CopyTo(_innerArray, 0);
 2117                _count = count;
 118            }
 119        }
 120        else
 121        {
 1122            _innerArray = new T[DefaultCapacity];
 8123            foreach (T item in items)
 3124                Push(item);
 125        }
 1126    }
 127
 128    ///  <summary>
 129    ///  Initializes a new instance of the <see cref="SwiftStack{T}"/> class with the specified <see cref="SwiftArraySta
 130    ///  </summary>
 131    ///  <param name="state">The state containing the internal array, count, offset, and version for initialization.</pa
 132    [MemoryPackConstructor]
 5133    public SwiftStack(SwiftArrayState<T> state)
 134    {
 5135        State = state;
 5136        SwiftThrowHelper.ThrowIfNull(_innerArray, nameof(_innerArray));
 5137    }
 138
 139    #endregion
 140
 141    #region Properties
 142
 143    /// <inheritdoc cref="_innerArray"/>
 144    [JsonIgnore]
 145    [MemoryPackIgnore]
 3146    public T[] InnerArray => _innerArray;
 147
 148    /// <inheritdoc cref="_count"/>
 149    [JsonIgnore]
 150    [MemoryPackIgnore]
 123151    public int Count => _count;
 152
 153    /// <summary>
 154    /// Gets the total number of elements the SwiftQueue can hold without resizing.
 155    /// Reflects the current allocated size of the internal array.
 156    /// </summary>
 157    [JsonIgnore]
 158    [MemoryPackIgnore]
 16159    public int Capacity => _innerArray.Length;
 160
 161    [JsonIgnore]
 162    [MemoryPackIgnore]
 1163    bool ICollection<T>.IsReadOnly => false;
 164
 165    /// <inheritdoc/>
 166    [JsonIgnore]
 167    [MemoryPackIgnore]
 1168    public bool IsSynchronized => false;
 169
 170    [JsonIgnore]
 171    [MemoryPackIgnore]
 1172    object ICollection.SyncRoot => _syncRoot ??= new object();
 173
 174    /// <summary>
 175    /// Gets the element at the specified arrayIndex.
 176    /// </summary>
 177    [JsonIgnore]
 178    [MemoryPackIgnore]
 179    public T this[int index]
 180    {
 181        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 182        get
 183        {
 205184            SwiftThrowHelper.ThrowIfListIndexInvalid(index, _count);
 203185            return _innerArray[index];
 186        }
 187        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 188        set
 189        {
 2190            SwiftThrowHelper.ThrowIfListIndexInvalid(index, _count);
 1191            _innerArray[index] = value;
 1192        }
 193    }
 194
 195    /// <summary>
 196    /// Gets or sets the current state of the array, including its items and count.
 197    /// </summary>
 198    /// <remarks>
 199    /// Setting this property replaces the entire contents of the array with the items from the specified state.
 200    /// The setter is intended for internal use and may reset the array's version and capacity.
 201    /// </remarks>
 202    [JsonInclude]
 203    [MemoryPackInclude]
 204    public SwiftArrayState<T> State
 205    {
 206        get
 207        {
 2208            var items = new T[_count];
 2209            Array.Copy(_innerArray, 0, items, 0, _count);
 2210            return new SwiftArrayState<T>(items);
 211        }
 212        internal set
 213        {
 5214            SwiftThrowHelper.ThrowIfNull(value.Items, nameof(value.Items));
 215
 5216            int count = value.Items.Length;
 217
 5218            if (count == 0)
 219            {
 1220                _innerArray = _emptyArray;
 1221                _count = 0;
 1222                _version = 0;
 1223                return;
 224            }
 225
 4226            int capacity = SwiftHashTools.NextPowerOfTwo(count <= DefaultCapacity ? DefaultCapacity : count);
 227
 4228            _innerArray = new T[capacity];
 4229            Array.Copy(value.Items, 0, _innerArray, 0, count);
 230
 4231            _count = count;
 4232            _version = 0;
 4233        }
 234    }
 235
 236    #endregion
 237
 238    #region Collection Manipulation
 239
 240    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 2241    void ICollection<T>.Add(T item) => Push(item);
 242
 243    /// <summary>
 244    /// Inserts an object at the top of the SwiftStack.
 245    /// </summary>
 246    /// <param name="item"></param>
 247    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 248    public void Push(T item)
 249    {
 290250        if ((uint)_count == (uint)_innerArray.Length)
 42251            Resize(_innerArray.Length * 2);
 290252        _innerArray[_count++] = item;
 290253        _version++;
 290254    }
 255
 256    /// <summary>
 257    /// Pushes the elements of the specified span onto the stack in order.
 258    /// </summary>
 259    /// <param name="items">The span whose elements should be pushed.</param>
 260    public void PushRange(ReadOnlySpan<T> items)
 261    {
 6262        if (items.Length == 0)
 1263            return;
 264
 5265        if (_count + items.Length > _innerArray.Length)
 266        {
 4267            int newCapacity = SwiftHashTools.NextPowerOfTwo(_count + items.Length);
 4268            Resize(newCapacity);
 269        }
 270
 5271        items.CopyTo(_innerArray.AsSpan(_count, items.Length));
 5272        _count += items.Length;
 5273        _version++;
 5274    }
 275
 276    bool ICollection<T>.Remove(T item)
 277    {
 1278        throw new NotSupportedException("Remove is not supported on Stack.");
 279    }
 280
 281    /// <summary>
 282    /// Removes and returns the object at the top of the SwiftStack.
 283    /// </summary>
 284    /// <returns></returns>
 285    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 286    public T Pop()
 287    {
 3288        SwiftThrowHelper.ThrowIfTrue((uint)_count == 0, message: "Stack is empty.");
 2289        T item = _innerArray[--_count];
 2290        if (_clearReleasedSlots)
 1291            _innerArray[_count] = default!;
 2292        _version++;
 2293        return item;
 294    }
 295
 296    /// <summary>
 297    /// Removes all elements from the SwiftStack, resetting its count to zero.
 298    /// </summary>
 299    public void Clear()
 300    {
 6301        if (_count == 0) return;
 4302        if (_clearReleasedSlots)
 1303            Array.Clear(_innerArray, 0, _count);
 4304        _count = 0;
 4305        _version++;
 4306    }
 307
 308    /// <summary>
 309    /// Clears the SwiftStack without releasing the reference to the stored elements.
 310    /// Use FastClear() when you want to quickly reset the list without reallocating memory.
 311    /// </summary>
 312    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 313    public void FastClear()
 314    {
 1315        _count = 0;
 1316        _version++;
 1317    }
 318
 319    #endregion
 320
 321    #region Capacity Management
 322
 323    /// <summary>
 324    /// Ensures that the internal storage has at least the specified capacity, resizing if necessary.
 325    /// </summary>
 326    /// <remarks>
 327    /// If the current capacity is less than the specified value, the internal storage is increased to
 328    /// the next power of two greater than or equal to <paramref name="capacity"/>.
 329    /// No action is taken if the current capacity is sufficient.
 330    /// </remarks>
 331    /// <param name="capacity">The minimum number of elements that the internal storage should be able to hold. Must be 
 332    public void EnsureCapacity(int capacity)
 333    {
 1334        capacity = SwiftHashTools.NextPowerOfTwo(capacity);
 1335        if (capacity > _innerArray.Length)
 1336            Resize(capacity);
 1337    }
 338
 339    /// <summary>
 340    /// Ensures that the capacity of the stack is sufficient to accommodate the specified number of elements.
 341    /// The stack capacity can increase by double to balance memory allocation efficiency and space.
 342    /// </summary>
 343    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 344    private void Resize(int newSize)
 345    {
 47346        int newCapacity = newSize <= DefaultCapacity ? DefaultCapacity : newSize;
 47347        T[] newArray = new T[newCapacity];
 47348        if ((uint)_count > 0)
 8349            Array.Copy(_innerArray, 0, newArray, 0, _count);
 47350        _innerArray = newArray;
 47351        _version++;
 47352    }
 353
 354
 355    /// <summary>
 356    /// Sets the capacity of a <see cref="SwiftStack{T}"/> to the actual
 357    /// number of elements it contains, rounded up to a nearby next power of 2 value.
 358    /// </summary>
 359    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 360    public void TrimCapacity()
 361    {
 3362        int newCapacity = _count <= DefaultCapacity ? DefaultCapacity : SwiftHashTools.NextPowerOfTwo(_count);
 3363        T[] newArray = new T[newCapacity];
 3364        if ((uint)_count > 0)
 2365            Array.Copy(_innerArray, 0, newArray, 0, _count);
 3366        _innerArray = newArray;
 3367        _version++;
 3368    }
 369
 370    #endregion
 371
 372    #region Utility Methods
 373
 374    /// <summary>
 375    /// Returns the object at the top of the SwiftStack without removing it.
 376    /// </summary>
 377    /// <returns></returns>
 378    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 379    public T Peek()
 380    {
 7381        SwiftThrowHelper.ThrowIfTrue((uint)_count == 0, message: "Stack is empty.");
 6382        return _innerArray[_count - 1];
 383    }
 384
 385    /// <summary>
 386    /// Returns a string that represents the current stack, including its type and the number of elements it contains.
 387    /// </summary>
 388    /// <returns>
 389    /// A string containing the type name and the current element count if the stack is not empty;
 390    /// otherwise, a string indicating that the stack is empty.
 391    /// </returns>
 392    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 2393    public override string ToString() => (uint)_count == 0 ? $"{typeof(SwiftStack<T>)}: Empty" : $"{typeof(SwiftStack<T>
 394
 395    /// <summary>
 396    /// Returns a mutable span over the populated portion of the stack.
 397    /// </summary>
 398    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 2399    public Span<T> AsSpan() => _innerArray.AsSpan(0, _count);
 400
 401    /// <summary>
 402    /// Returns a read-only span over the populated portion of the stack.
 403    /// </summary>
 404    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 8405    public ReadOnlySpan<T> AsReadOnlySpan() => _innerArray.AsSpan(0, _count);
 406
 407    /// <summary>
 408    /// Copies the elements of the collection to the specified array, starting at the specified array index.
 409    /// </summary>
 410    /// <param name="array">
 411    /// The one-dimensional array that is the destination of the elements copied from the collection.
 412    /// The array must have zero-based indexing.</param>
 413    /// <param name="arrayIndex">The zero-based index in the destination array at which copying begins.</param>
 414    /// <exception cref="ArgumentOutOfRangeException">
 415    /// Thrown when <paramref name="arrayIndex"/> is less than 0 or greater than the length of <paramref name="array"/>.
 416    /// </exception>
 417    /// <exception cref="ArgumentException">
 418    /// Thrown when the number of elements in the source collection is greater than
 419    /// the available space from <paramref name="arrayIndex"/> to the end of <paramref name="array"/>.
 420    /// </exception>
 421    public void CopyTo(T[] array, int arrayIndex)
 422    {
 4423        SwiftThrowHelper.ThrowIfNull(array, nameof(array));
 3424        SwiftThrowHelper.ThrowIfArrayIndexInvalid(arrayIndex, array.Length);
 2425        SwiftThrowHelper.ThrowIfArgument((uint)(array.Length - arrayIndex) < (uint)_count, nameof(array), "Destination a
 426
 1427        Array.Copy(_innerArray, 0, array, arrayIndex, _count);
 1428    }
 429
 430    /// <summary>
 431    /// Copies the populated elements of the SwiftStack into the specified destination span.
 432    /// </summary>
 433    /// <param name="destination">The destination span.</param>
 434    public void CopyTo(Span<T> destination)
 435    {
 2436        SwiftThrowHelper.ThrowIfArgument(destination.Length < _count, nameof(destination), "Destination span is not long
 437
 1438        AsSpan().CopyTo(destination);
 1439    }
 440
 441    /// <inheritdoc/>
 442    public void CopyTo(Array array, int arrayIndex)
 443    {
 4444        SwiftThrowHelper.ThrowIfNull(array, nameof(array));
 4445        SwiftThrowHelper.ThrowIfArgument(array.Rank != 1, nameof(array), "Array must be single dimensional.");
 3446        SwiftThrowHelper.ThrowIfArgument(array.GetLowerBound(0) != 0, nameof(array), "Array must have zero-based indexin
 2447        SwiftThrowHelper.ThrowIfArrayIndexInvalid(arrayIndex, array.Length);
 2448        SwiftThrowHelper.ThrowIfArgument((uint)(array.Length - arrayIndex) < (uint)_count, nameof(array), "Destination a
 449
 450        try
 451        {
 10452            for (int i = 0; (uint)i < (uint)_count; i++)
 4453                array.SetValue(_innerArray[i], arrayIndex++);
 1454        }
 1455        catch (InvalidCastException)
 456        {
 1457            throw new ArgumentException("Invalid array type.");
 458        }
 1459    }
 460
 461    /// <inheritdoc/>
 462    public void CloneTo(ICollection<T> output)
 463    {
 1464        output.Clear();
 6465        for (int i = 0; (uint)i < (uint)_count; i++)
 2466            output.Add(_innerArray[i]);
 1467    }
 468
 469    /// <inheritdoc/>
 470    public bool Contains(T item)
 471    {
 2472        EqualityComparer<T> comparer = EqualityComparer<T>.Default;
 10473        for (int i = 0; i < _count; i++)
 474        {
 4475            if (comparer.Equals(_innerArray[i], item))
 1476                return true;
 477        }
 1478        return false;
 479    }
 480
 481    /// <summary>
 482    /// Determines whether the <see cref="SwiftStack{T}"/> contains an element that matches the conditions defined by th
 483    /// </summary>
 484    /// <param name="match">The predicate that defines the conditions of the element to search for.</param>
 485    /// <returns><c>true</c> if the <see cref="SwiftStack{T}"/> contains one or more elements that match the specified p
 486    public bool Exists(Predicate<T> match)
 487    {
 3488        SwiftThrowHelper.ThrowIfNull(match, nameof(match));
 489
 12490        for (int i = _count - 1; i >= 0; i--)
 491        {
 5492            if (match(_innerArray[i]))
 1493                return true;
 494        }
 495
 1496        return false;
 497    }
 498
 499    /// <summary>
 500    /// Searches for an element that matches the conditions defined by the specified predicate, and returns the first ma
 501    /// </summary>
 502    /// <param name="match">The predicate that defines the conditions of the element to search for.</param>
 503    /// <returns>The first element that matches the conditions defined by the specified predicate, if found; otherwise, 
 504    public T Find(Predicate<T> match)
 505    {
 2506        SwiftThrowHelper.ThrowIfNull(match, nameof(match));
 507
 8508        for (int i = _count - 1; i >= 0; i--)
 509        {
 3510            if (match(_innerArray[i]))
 1511                return _innerArray[i];
 512        }
 513
 1514        return default!;
 515    }
 516
 517    #endregion
 518
 519    #region Enumerators
 520
 521    /// <inheritdoc cref="IEnumerable.GetEnumerator()"/>
 20522    public SwiftStackEnumerator GetEnumerator() => new(this);
 9523    IEnumerator<T> IEnumerable<T>.GetEnumerator() => GetEnumerator();
 3524    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
 525
 526    /// <summary>
 527    /// Supports simple iteration over the elements of a <see cref="SwiftStack{T}"/> in last-in, first-out (LIFO) order.
 528    /// </summary>
 529    /// <remarks>
 530    /// The enumerator is invalidated if the collection is modified after the enumerator is created.
 531    /// This type is not thread-safe.
 532    /// </remarks>
 533    public struct SwiftStackEnumerator : IEnumerator<T>, IEnumerator, IDisposable
 534    {
 535        private readonly SwiftStack<T> _stack;
 536        private readonly T[] _array;
 537        private readonly uint _version;
 538        private readonly int _count;
 539        private int _index;
 540
 541        private T _current;
 542
 543        internal SwiftStackEnumerator(SwiftStack<T> stack)
 544        {
 20545            _stack = stack;
 20546            _array = stack._innerArray;
 20547            _count = stack._count;
 20548            _version = stack._version;
 20549            _index = -2; // Enumerator not started
 20550            _current = default!;
 20551        }
 552
 553        /// <inheritdoc/>
 430554        public T Current => _current;
 555
 556        object IEnumerator.Current
 557        {
 558            get
 559            {
 2560                SwiftThrowHelper.ThrowIfTrue((uint)_index > _count, message: "Bad enumeration");
 1561                return _current!;
 562            }
 563        }
 564
 565        /// <inheritdoc/>
 566        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 567        public bool MoveNext()
 568        {
 251569            SwiftThrowHelper.ThrowIfTrue(_version != _stack._version, message: "Enumerator modified outside of enumerati
 570
 250571            if (_index == -2)
 572            {
 22573                _index = _count - 1;
 574            }
 575            else
 576            {
 228577                _index--;
 578            }
 579
 250580            if (_index >= 0)
 581            {
 232582                _current = _array[_index];
 232583                return true;
 584            }
 585
 18586            _index = -1;
 18587            _current = default!;
 18588            return false;
 589        }
 590
 591        /// <inheritdoc/>
 592        public void Reset()
 593        {
 4594            SwiftThrowHelper.ThrowIfTrue(_version != _stack._version, message: "Enumerator modified outside of enumerati
 595
 3596            _index = -2;
 3597            _current = default!;
 3598        }
 599
 600        /// <inheritdoc/>
 11601        public void Dispose() => _index = -1;
 602    }
 603
 604    #endregion
 605}