< Summary

Information
Class: SwiftCollections.SwiftList<T>
Assembly: SwiftCollections
File(s): /home/runner/work/SwiftCollections/SwiftCollections/src/SwiftCollections/Collection/SwiftList.cs
Line coverage
99%
Covered lines: 262
Uncovered lines: 2
Coverable lines: 264
Total lines: 855
Line coverage: 99.2%
Branch coverage
95%
Covered branches: 76
Total branches: 80
Branch coverage: 95%
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%44100%
.ctor(...)100%11100%
get_InnerArray()100%11100%
get_Capacity()100%11100%
get_Count()100%11100%
get_IsReadOnly()100%11100%
get_IsSynchronized()100%11100%
get_SyncRoot()50%22100%
get_IsFixedSize()100%11100%
System.Collections.IList.get_Item(...)100%22100%
System.Collections.IList.set_Item(...)100%11100%
get_Item(...)100%11100%
set_Item(...)100%11100%
get_State()100%11100%
set_State(...)100%44100%
Add(...)100%22100%
System.Collections.IList.Add(...)100%11100%
AddRange(...)87.5%8893.75%
AddKnownCountRange(...)75%4485.71%
AddRange(...)100%11100%
AddRange(...)100%22100%
EnsureAdditionalCapacity(...)100%11100%
Remove(...)100%22100%
System.Collections.IList.Remove(...)100%11100%
RemoveAt(...)100%22100%
RemoveAll(...)100%22100%
IndexOfFirstMatch(...)100%44100%
CompactUnmatchedItems(...)100%44100%
ClearReleasedSlots(...)75%44100%
Insert(...)100%44100%
System.Collections.IList.Insert(...)100%11100%
Reverse()100%11100%
SortInPlace(...)100%11100%
SortInPlace(...)100%11100%
Clear()100%22100%
FastClear()100%11100%
EnsureCapacity(...)100%22100%
Resize(...)100%44100%
TrimExcessCapacity()100%22100%
IndexOf(...)100%11100%
System.Collections.IList.IndexOf(...)100%11100%
ToArray()100%11100%
AsSpan()100%11100%
AsReadOnlySpan()100%11100%
ToString()100%22100%
Contains(...)100%11100%
Exists(...)100%44100%
Find(...)100%44100%
System.Collections.IList.Contains(...)100%11100%
Swap(...)100%11100%
CopyTo(...)100%22100%
CopyTo(...)100%11100%
CopyTo(...)100%11100%
CopyTo(...)100%11100%
CloneTo(...)100%22100%
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%22100%
Reset()100%11100%
Dispose()100%11100%

File(s)

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

#LineLine coverage
 1//=======================================================================
 2// SwiftList.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/// <c>SwiftList&lt;T&gt;</c> is a high-performance, memory-efficient dynamic list designed to outperform
 22/// traditional generic lists in speed-critical applications.
 23/// <para>
 24/// By utilizing custom growth and
 25/// shrink strategies, SwiftList optimizes memory allocation and minimizes resizing overhead,
 26/// all while maintaining compact storage. With aggressive inlining and optimized algorithms,
 27/// SwiftList delivers faster iteration, insertion, and overall memory management compared to
 28/// standard List. It is ideal for scenarios where predictable performance and minimal
 29/// memory allocations are essential.
 30/// </para>
 31/// <para>
 32/// This implementation is optimized for performance and does not perform versioning checks.
 33/// Modifying the list during enumeration may result in undefined behavior.
 34/// </para>
 35/// </summary>
 36/// <typeparam name="T">Specifies the type of elements in the list.</typeparam>
 37[Serializable]
 38[JsonConverter(typeof(StateJsonConverterFactory))]
 39[MemoryPackable]
 40public partial class SwiftList<T> : IStateBacked<SwiftArrayState<T>>, ISwiftCloneable<T>, IEnumerable<T>, IEnumerable, I
 41{
 42    #region Constants
 43
 44    /// <summary>
 45    /// The default initial capacity of the <see cref="SwiftList{T}"/> if none is specified.
 46    /// Used to allocate a reasonable starting size to minimize resizing operations.
 47    /// </summary>
 48    public const int DefaultCapacity = 8;
 49
 250    private static readonly T[] _emptyArray = Array.Empty<T>();
 251    private static readonly bool _clearReleasedSlots = RuntimeHelpers.IsReferenceOrContainsReferences<T>();
 52
 53    #endregion
 54
 55    #region Fields
 56
 57    /// <summary>
 58    /// The internal array that stores elements of the SwiftList. Resized as needed to
 59    /// accommodate additional elements. Not directly exposed outside the list.
 60    /// </summary>
 61    protected T[] _innerArray;
 62
 63    /// <summary>
 64    /// The current number of elements in the SwiftList. Represents the total count of
 65    /// valid elements stored in the list, also indicating the arrayIndex of the next insertion point.
 66    /// </summary>
 67    protected int _count;
 68
 69    /// <summary>
 70    /// The version of the SwiftList, used to track modifications.
 71    /// </summary>
 72    [NonSerialized]
 73    protected uint _version;
 74
 75    /// <summary>
 76    /// An object that can be used to synchronize access to the SwiftList.
 77    /// </summary>
 78    [NonSerialized]
 79    private object? _syncRoot;
 80
 81    #endregion
 82
 83    #region Constructors
 84
 85    /// <summary>
 86    /// Initializes a new instance of the SwiftList class that is empty and has the default initial capacity.
 87    /// </summary>
 74088    public SwiftList() : this(0) { }
 89
 90    /// <summary>
 91    /// Initializes a new, empty instance of <see cref="SwiftList{T}"/> with the specified initial capacity.
 92    /// </summary>
 68193    public SwiftList(int capacity)
 94    {
 68195        if (capacity == 0)
 37096            _innerArray = _emptyArray;
 97        else
 98        {
 31199            capacity = SwiftHashTools.NextPowerOfTwo(capacity <= DefaultCapacity ? DefaultCapacity : capacity);
 311100            _innerArray = new T[capacity];
 101        }
 311102    }
 103
 104    /// <summary>
 105    /// Initializes a new instance of the <see cref="SwiftList{T}"/> class with elements from the specified collection.
 106    /// The collection must have a known count for optimized memory allocation.
 107    /// </summary>
 108    /// <exception cref="ArgumentException">Thrown if the input collection does not have a known count.</exception>
 13109    public SwiftList(IEnumerable<T> items)
 110    {
 13111        SwiftThrowHelper.ThrowIfNull(items, nameof(items));
 112
 13113        if (items is ICollection<T> collection)
 114        {
 10115            int count = collection.Count;
 10116            if (count == 0)
 1117                _innerArray = _emptyArray;
 118            else
 119            {
 9120                _innerArray = new T[count];
 9121                collection.CopyTo(_innerArray, 0);
 9122                _count = count;
 123            }
 124        }
 125        else
 126        {
 3127            _innerArray = new T[DefaultCapacity];
 3128            AddRange(items); // Will handle capacity increases as needed
 129        }
 3130    }
 131
 132    ///  <summary>
 133    ///  Initializes a new instance of the <see cref="SwiftList{T}"/> class with the specified <see cref="SwiftArrayStat
 134    ///  </summary>
 135    ///  <param name="state">The state containing the internal array, count, offset, and version for initialization.</pa
 136    [MemoryPackConstructor]
 10137    public SwiftList(SwiftArrayState<T> state)
 138    {
 10139        State = state;
 140
 141        // Validate that the internal array is not null after deserialization
 10142        SwiftThrowHelper.ThrowIfNull(_innerArray, nameof(_innerArray));
 10143    }
 144
 145    #endregion
 146
 147    #region Properties
 148
 149    /// <summary>
 150    /// Gets the underlying array that stores the elements of the collection.
 151    /// </summary>
 152    [JsonIgnore]
 153    [MemoryPackIgnore]
 8154    public T[] InnerArray => _innerArray;
 155
 156    /// <summary>
 157    /// Gets the total number of elements the SwiftList can hold without resizing.
 158    /// Reflects the current allocated size of the internal array.
 159    /// </summary>
 160    [JsonIgnore]
 161    [MemoryPackIgnore]
 22162    public int Capacity => _innerArray.Length;
 163
 164    /// <inheritdoc cref="_count"/>
 165    [JsonIgnore]
 166    [MemoryPackIgnore]
 6164167    public int Count => _count;
 168
 169    /// <inheritdoc/>
 170    [JsonIgnore]
 171    [MemoryPackIgnore]
 1172    public bool IsReadOnly => false;
 173
 174    /// <inheritdoc/>
 175    [JsonIgnore]
 176    [MemoryPackIgnore]
 1177    public bool IsSynchronized => false;
 178
 179    /// <inheritdoc/>
 180    [JsonIgnore]
 181    [MemoryPackIgnore]
 1182    public object SyncRoot => _syncRoot ??= new object();
 183
 184    /// <inheritdoc/>
 185    [JsonIgnore]
 186    [MemoryPackIgnore]
 1187    public bool IsFixedSize => false;
 188
 189    [JsonIgnore]
 190    [MemoryPackIgnore]
 191    object? IList.this[int index]
 192    {
 2193        get => this[index] ?? default!;
 194        set
 195        {
 196            try
 197            {
 2198                this[index] = (T)value!;
 1199            }
 1200            catch
 201            {
 1202                throw new NotSupportedException($"Unsupported value type for {value}");
 203            }
 1204        }
 205    }
 206
 207    /// <summary>
 208    /// Gets the element at the specified arrayIndex.
 209    /// </summary>
 210    [JsonIgnore]
 211    [MemoryPackIgnore]
 212    public T this[int index]
 213    {
 214        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 215        get
 216        {
 5614217            SwiftThrowHelper.ThrowIfListIndexInvalid(index, _count);
 5610218            return _innerArray[index];
 219        }
 220        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 221        set
 222        {
 1514223            SwiftThrowHelper.ThrowIfListIndexInvalid(index, _count);
 1514224            _innerArray[index] = value;
 1514225        }
 226    }
 227
 228    /// <summary>
 229    /// Gets or sets the current state of the array, including its items and count.
 230    /// </summary>
 231    /// <remarks>
 232    /// Setting this property replaces the entire contents of the array with the items from the specified state.
 233    /// The previous contents are discarded.
 234    /// The version is reset when the state is set.
 235    /// </remarks>
 236    [JsonInclude]
 237    [MemoryPackInclude]
 238    public SwiftArrayState<T> State
 239    {
 240        get
 241        {
 9242            var items = new T[_count];
 9243            Array.Copy(_innerArray, 0, items, 0, _count);
 9244            return new SwiftArrayState<T>(items);
 245        }
 246        internal set
 247        {
 10248            SwiftThrowHelper.ThrowIfNull(value.Items, nameof(value.Items));
 249
 10250            int count = value.Items.Length;
 251
 10252            if (count == 0)
 253            {
 1254                _innerArray = _emptyArray;
 1255                _count = 0;
 256            }
 257            else
 258            {
 9259                _innerArray = new T[count <= DefaultCapacity ? DefaultCapacity : count];
 9260                Array.Copy(value.Items, 0, _innerArray, 0, count);
 9261                _count = count;
 262            }
 263
 10264            _version = 0;
 10265        }
 266    }
 267
 268    #endregion
 269
 270    #region Collection Manipulation
 271
 272    /// <summary>
 273    /// Adds an object to the end of the SwiftList.
 274    /// </summary>
 275    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 276    public virtual void Add(T item)
 277    {
 111967278        if ((uint)_count == (uint)_innerArray.Length)
 223279            Resize(_innerArray.Length * 2);
 111967280        _innerArray[_count++] = item;
 111967281        _version++;
 111967282    }
 283
 284    int IList.Add(object? value)
 285    {
 286        try
 287        {
 2288            Add((T)value!);
 1289        }
 1290        catch (InvalidCastException)
 291        {
 1292            throw new NotSupportedException($"Wrong value type for {value}");
 293        }
 294
 1295        return _count - 1;
 296    }
 297
 298    /// <summary>
 299    /// Adds the elements of the specified collection to the end of the SwiftList.
 300    /// </summary>
 301    /// <remarks>
 302    /// Known-count sources reserve capacity before enumeration to avoid repeated growth.
 303    /// </remarks>
 304    public virtual void AddRange(IEnumerable<T> items)
 305    {
 8306        SwiftThrowHelper.ThrowIfNull(items, nameof(items));
 307
 8308        if (items is ICollection<T> collection)
 309        {
 3310            int count = collection.Count;
 3311            if (count == 0)
 0312                return;
 313
 3314            EnsureAdditionalCapacity(count);
 3315            collection.CopyTo(_innerArray, _count);
 3316            _count += count;
 3317            _version++;
 318
 3319            return;
 320        }
 321
 5322        if (items is IReadOnlyCollection<T> readOnlyCollection)
 323        {
 4324            AddKnownCountRange(readOnlyCollection, readOnlyCollection.Count);
 4325            return;
 326        }
 327
 8328        foreach (T item in items)
 3329            Add(item);
 1330    }
 331
 332    private void AddKnownCountRange(IEnumerable<T> items, int count)
 333    {
 4334        if (count == 0)
 0335            return;
 336
 4337        EnsureAdditionalCapacity(count);
 338
 50339        foreach (T item in items)
 21340            _innerArray[_count++] = item;
 341
 4342        _version++;
 4343    }
 344
 345    /// <summary>
 346    /// Adds the elements of the specified array to the end of the SwiftList.
 347    /// </summary>
 348    /// <param name="items">The array whose elements should be appended.</param>
 349    public virtual void AddRange(T[] items)
 350    {
 2351        SwiftThrowHelper.ThrowIfNull(items, nameof(items));
 2352        AddRange(items.AsSpan());
 2353    }
 354
 355    /// <summary>
 356    /// Adds the elements of the specified span to the end of the SwiftList.
 357    /// </summary>
 358    /// <param name="items">The span whose elements should be appended.</param>
 359    public virtual void AddRange(ReadOnlySpan<T> items)
 360    {
 20361        if (items.Length == 0)
 1362            return;
 363
 19364        EnsureAdditionalCapacity(items.Length);
 365
 19366        items.CopyTo(_innerArray.AsSpan(_count, items.Length));
 19367        _count += items.Length;
 19368        _version++;
 19369    }
 370
 371    private void EnsureAdditionalCapacity(int additionalCount)
 372    {
 26373        long requiredCount = (long)_count + additionalCount;
 26374        SwiftThrowHelper.ThrowIfTrue(requiredCount > int.MaxValue, message: "The collection is too large.");
 26375        EnsureCapacity((int)requiredCount);
 26376    }
 377
 378    /// <summary>
 379    /// Removes the first occurrence of a specific object from the SwiftList.
 380    /// </summary>
 381    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 382    public virtual bool Remove(T item)
 383    {
 3384        int index = IndexOf(item);
 4385        if (index < 0) return false; // Item not found return false;
 2386        RemoveAt(index);
 2387        return true;
 388    }
 389
 390    void IList.Remove(object? value)
 391    {
 392        try
 393        {
 2394            Remove((T)value!);
 1395        }
 1396        catch (InvalidCastException)
 397        {
 1398            throw new NotSupportedException($"Wrong value type for {value}");
 399        }
 1400    }
 401
 402    /// <summary>
 403    /// Removes the element at the specified arrayIndex of the SwiftList.
 404    /// </summary>
 405    public virtual void RemoveAt(int index)
 406    {
 638407        SwiftThrowHelper.ThrowIfListIndexInvalid(index, _count);
 637408        Array.Copy(_innerArray, index + 1, _innerArray, index, _count - index - 1);
 637409        _count--;
 637410        if (_clearReleasedSlots)
 2411            _innerArray[_count] = default!;
 637412        _version++;
 637413    }
 414
 415    /// <summary>
 416    /// Removes all the elements that match the conditions defined by the specified predicate.
 417    /// </summary>
 418    public virtual int RemoveAll(Predicate<T> match)
 419    {
 11420        SwiftThrowHelper.ThrowIfNull(match, nameof(match));
 421
 10422        int firstMatchIndex = IndexOfFirstMatch(match);
 10423        if (firstMatchIndex >= _count)
 3424            return 0;
 425
 7426        int newCount = CompactUnmatchedItems(firstMatchIndex, match);
 7427        int removedCount = _count - newCount;
 7428        ClearReleasedSlots(newCount, removedCount);
 7429        _count = newCount;
 7430        _version++;
 431
 7432        return removedCount;
 433    }
 434
 435    private int IndexOfFirstMatch(Predicate<T> match)
 436    {
 10437        int index = 0;
 25438        while (index < _count && !match(_innerArray[index]))
 15439            index++;
 440
 10441        return index;
 442    }
 443
 444    private int CompactUnmatchedItems(int writeIndex, Predicate<T> match)
 445    {
 200042446        for (int readIndex = writeIndex + 1; readIndex < _count; readIndex++)
 447        {
 100014448            if (!match(_innerArray[readIndex]))
 50006449                _innerArray[writeIndex++] = _innerArray[readIndex];
 450        }
 451
 7452        return writeIndex;
 453    }
 454
 455    private void ClearReleasedSlots(int startIndex, int count)
 456    {
 7457        if (_clearReleasedSlots && count > 0)
 2458            Array.Clear(_innerArray, startIndex, count);
 7459    }
 460
 461    /// <summary>
 462    /// Inserts an element into the SwiftList at the specified arrayIndex.
 463    /// </summary>
 464    public virtual void Insert(int index, T item)
 465    {
 7466        SwiftThrowHelper.ThrowIfArrayIndexInvalid(index, _count);
 6467        if ((uint)_count == (uint)_innerArray.Length)
 1468            Resize(_innerArray.Length * 2);
 6469        if ((uint)index < (uint)_count)
 4470            Array.Copy(_innerArray, index, _innerArray, index + 1, _count - index);
 6471        _innerArray[index] = item;
 6472        _count++;
 6473        _version++;
 6474    }
 475
 476    void IList.Insert(int index, object? value)
 477    {
 478        try
 479        {
 2480            Insert(index, (T)value!);
 1481        }
 1482        catch (InvalidCastException)
 483        {
 1484            throw new NotSupportedException($"Wrong value type for {value}");
 485        }
 1486    }
 487
 488    /// <summary>
 489    /// Reverses the order of the elements in the entire <see cref="SwiftList{T}"/>.
 490    /// </summary>
 491    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 492    public void Reverse()
 493    {
 1494        Array.Reverse(_innerArray, 0, _count);
 1495        _version++;
 1496    }
 497
 498    /// <summary>
 499    /// Sorts the populated elements of the <see cref="SwiftList{T}"/> in place.
 500    /// </summary>
 501    /// <remarks>
 502    /// The sort is performed over the active <c>[0..Count)</c> range of the backing array and does not
 503    /// allocate additional collection storage. Pass a comparer to define a custom order; otherwise the
 504    /// default comparer for <typeparamref name="T"/> is used.
 505    /// </remarks>
 506    /// <param name="comparer">The comparer to use, or <c>null</c> to use the default comparer.</param>
 507    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 508    public void SortInPlace(IComparer<T>? comparer = null)
 509    {
 11510        SwiftArraySortHelper.Sort(_innerArray, 0, _count, comparer);
 11511        _version++;
 11512    }
 513
 514    /// <summary>
 515    /// Sorts the populated elements of the <see cref="SwiftList{T}"/> in place using a struct comparer.
 516    /// </summary>
 517    /// <remarks>
 518    /// This overload avoids boxing struct comparers and lets the JIT devirtualize comparer calls in hot paths.
 519    /// </remarks>
 520    /// <param name="comparer">The comparer to use.</param>
 521    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 522    public void SortInPlace<TComparer>(TComparer comparer)
 523        where TComparer : struct, IComparer<T>
 524    {
 9525        SwiftArraySortHelper.Sort(_innerArray, 0, _count, comparer);
 9526        _version++;
 9527    }
 528
 529    /// <summary>
 530    /// Removes all elements from the <see cref="SwiftList{T}"/>, resetting its count to zero.
 531    /// </summary>
 532    public virtual void Clear()
 533    {
 9534        if (_clearReleasedSlots)
 1535            Array.Clear(_innerArray, 0, _count);
 9536        _count = 0;
 9537        _version++;
 9538    }
 539
 540    /// <summary>
 541    /// Clears the <see cref="SwiftList{T}"/> without releasing the reference to the stored elements.
 542    /// Use FastClear() when you want to quickly reset the list without reallocating memory.
 543    /// </summary>
 544    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 545    public void FastClear()
 546    {
 17547        _count = 0;
 17548        _version++;
 17549    }
 550
 551    #endregion
 552
 553    #region Capacity Management
 554
 555    /// <summary>
 556    /// Ensures that the capacity of <see cref="SwiftList{T}"/> is sufficient to accommodate the specified number of ele
 557    /// The capacity can increase by double to balance memory allocation efficiency and space.
 558    /// </summary>
 559    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 560    public void EnsureCapacity(int capacity)
 561    {
 32562        capacity = SwiftHashTools.NextPowerOfTwo(capacity);
 32563        if (capacity > _innerArray.Length)
 8564            Resize(capacity);
 32565    }
 566
 567    /// <summary>
 568    /// Resizes the internal array to accommodate the specified number of elements.
 569    /// </summary>
 570    /// <remarks>
 571    /// If the specified size is less than or equal to the default capacity, the internal array is
 572    /// set to the default capacity.
 573    /// Existing elements are preserved up to the current count.
 574    /// </remarks>
 575    /// <param name="newSize">The desired new size of the internal array. Must be greater than or equal to zero.</param>
 576    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 577    protected void Resize(int newSize)
 578    {
 233579        int newCapacity = newSize <= DefaultCapacity ? DefaultCapacity : newSize;
 580
 233581        T[] newArray = new T[newCapacity];
 233582        if (_count > 0)
 45583            Array.Copy(_innerArray, 0, newArray, 0, _count);
 233584        _innerArray = newArray;
 233585        _version++;
 233586    }
 587
 588    /// <summary>
 589    /// Reduces the capacity of the SwiftList if the element count falls below 50% of the current capacity.
 590    /// Ensures efficient memory usage by resizing the internal array to match the current count when necessary.
 591    /// </summary>
 592    public void TrimExcessCapacity()
 593    {
 2594        int newCapacity = _count < DefaultCapacity ? DefaultCapacity : SwiftHashTools.NextPowerOfTwo(_count);
 2595        Array.Resize(ref _innerArray, newCapacity);
 2596        _version++;
 2597    }
 598
 599    #endregion
 600
 601    #region Utility Methods
 602
 603    /// <summary>
 604    /// Searches for the specified object and returns the zero-based arrayIndex of the first occurrence within the Swift
 605    /// </summary>
 606    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 573607    public int IndexOf(T item) => Array.IndexOf(_innerArray, item, 0, _count);
 608
 609    int IList.IndexOf(object? value)
 610    {
 611        int index;
 612        try
 613        {
 2614            index = Array.IndexOf(_innerArray, (T)value!, 0, _count);
 1615        }
 1616        catch
 617        {
 1618            throw new NotSupportedException($"Unsupported value type for {value}");
 619        }
 1620        return index;
 621    }
 622
 623    /// <summary>
 624    /// Copies the elements of the SwiftList to a new array.
 625    /// </summary>
 626    public T[] ToArray()
 627    {
 38628        T[] result = new T[_count];
 38629        Array.Copy(_innerArray, result, _count);
 38630        return result;
 631    }
 632
 633    /// <summary>
 634    /// Returns a mutable span over the populated portion of the list.
 635    /// </summary>
 636    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 2637    public Span<T> AsSpan() => _innerArray.AsSpan(0, _count);
 638
 639    /// <summary>
 640    /// Returns a read-only span over the populated portion of the list.
 641    /// </summary>
 642    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1643    public ReadOnlySpan<T> AsReadOnlySpan() => _innerArray.AsSpan(0, _count);
 644
 645    /// <summary>
 646    /// Returns a string that represents the current collection.
 647    /// </summary>
 648    /// <remarks>
 649    /// This method provides a human-readable representation of the collection's contents,
 650    /// which can be useful for debugging or logging purposes.
 651    /// </remarks>
 652    /// <returns>A comma-separated list of the collection's elements, or the default string representation if the collec
 653    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 2654    public override string ToString() => _count == 0
 2655        ? base.ToString()!
 2656        : string.Join(", ", this);
 657
 658    /// <summary>
 659    /// Determines whether an element is in the SwiftList.
 660    /// </summary>
 661    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 3662    public bool Contains(T item) => IndexOf(item) != -1;
 663
 664    /// <summary>
 665    /// Determines whether the <see cref="SwiftList{T}"/> contains an element that matches the conditions defined by the
 666    /// </summary>
 667    /// <param name="match">The predicate that defines the conditions of the element to search for.</param>
 668    /// <returns><c>true</c> if the <see cref="SwiftList{T}"/> contains one or more elements that match the specified pr
 669    public bool Exists(Predicate<T> match)
 670    {
 3671        SwiftThrowHelper.ThrowIfNull(match, nameof(match));
 672
 14673        for (int i = 0; i < _count; i++)
 674        {
 6675            if (match(_innerArray[i]))
 1676                return true;
 677        }
 678
 1679        return false;
 680    }
 681
 682    /// <summary>
 683    /// Searches for an element that matches the conditions defined by the specified predicate, and returns the first oc
 684    /// </summary>
 685    /// <param name="match">The predicate that defines the conditions of the element to search for.</param>
 686    /// <returns>The first element that matches the conditions defined by the specified predicate, if found; otherwise, 
 687    public T Find(Predicate<T> match)
 688    {
 4689        SwiftThrowHelper.ThrowIfNull(match, nameof(match));
 690
 20691        for (int i = 0; i < _count; i++)
 692        {
 8693            if (match(_innerArray[i]))
 1694                return _innerArray[i];
 695        }
 696
 2697        return default!;
 698    }
 699
 700    bool IList.Contains(object? value)
 701    {
 702        int index;
 703        try
 704        {
 2705            index = IndexOf((T)value!);
 1706        }
 1707        catch
 708        {
 1709            throw new NotSupportedException($"Unsupported value type for {value}");
 710        }
 1711        return index != -1;
 712    }
 713
 714    /// <summary>
 715    /// Swaps the values of two elements in the SwiftList.
 716    /// This method exchanges the values referenced by two variables.
 717    /// </summary>
 718    /// <param name="indexA">The first element to swap.</param>
 719    /// <param name="indexB">The second element to swap.</param>
 720    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1721    public void Swap(int indexA, int indexB) => (_innerArray[indexB], _innerArray[indexA]) = (_innerArray[indexA], _inne
 722
 723    /// <summary>
 724    /// Copies the elements of the SwiftList to the specified target SwiftList.
 725    /// The target list will resize if it lacks sufficient capacity,
 726    /// but retains any existing elements beyond the copied range.
 727    /// </summary>
 728    public void CopyTo(SwiftList<T> target)
 729    {
 2730        if (_count + 1 > target._innerArray.Length)
 1731            target.Resize(target._innerArray.Length * 2);
 2732        Array.Copy(_innerArray, 0, target._innerArray, 0, _count);
 2733        target._count = _count;
 2734        target._version++;
 2735    }
 736
 737    /// <inheritdoc/>
 738    public void CopyTo(T[] array, int arrayIndex)
 739    {
 4740        SwiftThrowHelper.ThrowIfNull(array, nameof(array));
 4741        SwiftThrowHelper.ThrowIfArrayIndexInvalid(arrayIndex, array.Length);
 4742        SwiftThrowHelper.ThrowIfArgument(array.Length - arrayIndex < _count, nameof(array), "Destination array is not lo
 743
 2744        Array.Copy(_innerArray, 0, array, arrayIndex, _count);
 2745    }
 746
 747    /// <summary>
 748    /// Copies the populated elements of the SwiftList into the specified destination span.
 749    /// </summary>
 750    /// <param name="destination">The destination span.</param>
 751    public void CopyTo(Span<T> destination)
 752    {
 2753        SwiftThrowHelper.ThrowIfArgument(destination.Length < _count, nameof(destination), "Destination span is not long
 754
 1755        AsSpan().CopyTo(destination);
 1756    }
 757
 758    /// <inheritdoc/>
 759    public void CopyTo(Array array, int arrayIndex)
 760    {
 3761        SwiftThrowHelper.ThrowIfNull(array, nameof(array));
 3762        SwiftThrowHelper.ThrowIfArgument(array.Rank != 1, nameof(array), "Array must be single dimensional.");
 2763        SwiftThrowHelper.ThrowIfArgument(array.GetLowerBound(0) != 0, nameof(array), "Array must have zero-based indexin
 1764        SwiftThrowHelper.ThrowIfArrayIndexInvalid(arrayIndex, array.Length);
 1765        SwiftThrowHelper.ThrowIfArgument(array.Length - arrayIndex < _count, nameof(array), "Destination array is not lo
 766
 1767        Array.Copy(_innerArray, 0, array, arrayIndex, _count);
 1768    }
 769
 770    /// <inheritdoc/>
 771    public void CloneTo(ICollection<T> output)
 772    {
 1773        output.Clear();
 8774        foreach (var item in this)
 3775            output.Add(item);
 1776    }
 777
 778    #endregion
 779
 780    #region Enumerators
 781
 782    /// <summary>
 783    /// Returns an enumerator that iterates through the <see cref="SwiftList{T}"/>.
 784    /// </summary>
 27785    public SwiftListEnumerator GetEnumerator() => new(this);
 21786    IEnumerator<T> IEnumerable<T>.GetEnumerator() => GetEnumerator();
 2787    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
 788
 789    /// <summary>
 790    /// Enumerates the elements of a <see cref="SwiftList{T}"/> collection.
 791    /// </summary>
 792    /// <remarks>
 793    /// The enumerator provides read-only, forward-only iteration over the collection.
 794    /// The enumerator is invalidated if the collection is modified after the enumerator is created.
 795    /// In such cases, calling MoveNext or Reset will throw an InvalidOperationException.
 796    /// </remarks>
 797    public struct SwiftListEnumerator : IEnumerator<T>, IEnumerator, IDisposable
 798    {
 799        private readonly SwiftList<T> _list;
 800        private readonly T[] _array;
 801        private readonly uint _count;
 802        private readonly uint _version;
 803        private uint _index;
 804
 805        private T _current;
 806
 807        internal SwiftListEnumerator(SwiftList<T> list)
 808        {
 27809            _list = list;
 27810            _array = list._innerArray;
 27811            _count = (uint)list._count;
 27812            _version = list._version;
 27813            _index = 0;
 27814            _current = default!;
 27815        }
 816
 817        /// <inheritdoc/>
 436818        public T Current => _current;
 819
 820        object IEnumerator.Current
 821        {
 822            [MethodImpl(MethodImplOptions.AggressiveInlining)]
 823            get
 824            {
 3825                SwiftThrowHelper.ThrowIfTrue(_index >= _count, message: "Enumeration has either not started or has alrea
 2826                return _current!;
 827            }
 828        }
 829
 830        /// <inheritdoc/>
 831        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 832        public bool MoveNext()
 833        {
 250834            SwiftThrowHelper.ThrowIfTrue(_version != _list._version, message: "Collection was modified during enumeratio
 835
 270836            if (_index >= _count) return false;
 226837            _current = _array[_index++];
 226838            return true;
 839        }
 840
 841        /// <inheritdoc/>
 842        public void Reset()
 843        {
 2844            SwiftThrowHelper.ThrowIfTrue(_version != _list._version, message: "Collection was modified during enumeratio
 845
 1846            _index = 0;
 1847            _current = default!;
 1848        }
 849
 850        /// <inheritdoc/>
 22851        public void Dispose() => _index = 0;
 852    }
 853
 854    #endregion
 855}

Methods/Properties

.cctor()
.ctor()
.ctor(System.Int32)
.ctor(System.Collections.Generic.IEnumerable`1<T>)
.ctor(SwiftCollections.SwiftArrayState`1<T>)
get_InnerArray()
get_Capacity()
get_Count()
get_IsReadOnly()
get_IsSynchronized()
get_SyncRoot()
get_IsFixedSize()
System.Collections.IList.get_Item(System.Int32)
System.Collections.IList.set_Item(System.Int32,System.Object)
get_Item(System.Int32)
set_Item(System.Int32,T)
get_State()
set_State(SwiftCollections.SwiftArrayState`1<T>)
Add(T)
System.Collections.IList.Add(System.Object)
AddRange(System.Collections.Generic.IEnumerable`1<T>)
AddKnownCountRange(System.Collections.Generic.IEnumerable`1<T>,System.Int32)
AddRange(T[])
AddRange(System.ReadOnlySpan`1<T>)
EnsureAdditionalCapacity(System.Int32)
Remove(T)
System.Collections.IList.Remove(System.Object)
RemoveAt(System.Int32)
RemoveAll(System.Predicate`1<T>)
IndexOfFirstMatch(System.Predicate`1<T>)
CompactUnmatchedItems(System.Int32,System.Predicate`1<T>)
ClearReleasedSlots(System.Int32,System.Int32)
Insert(System.Int32,T)
System.Collections.IList.Insert(System.Int32,System.Object)
Reverse()
SortInPlace(System.Collections.Generic.IComparer`1<T>)
SortInPlace(TComparer)
Clear()
FastClear()
EnsureCapacity(System.Int32)
Resize(System.Int32)
TrimExcessCapacity()
IndexOf(T)
System.Collections.IList.IndexOf(System.Object)
ToArray()
AsSpan()
AsReadOnlySpan()
ToString()
Contains(T)
Exists(System.Predicate`1<T>)
Find(System.Predicate`1<T>)
System.Collections.IList.Contains(System.Object)
Swap(System.Int32,System.Int32)
CopyTo(SwiftCollections.SwiftList`1<T>)
CopyTo(T[],System.Int32)
CopyTo(System.Span`1<T>)
CopyTo(System.Array,System.Int32)
CloneTo(System.Collections.Generic.ICollection`1<T>)
GetEnumerator()
System.Collections.Generic.IEnumerable<T>.GetEnumerator()
System.Collections.IEnumerable.GetEnumerator()
.ctor(SwiftCollections.SwiftList`1<T>)
get_Current()
System.Collections.IEnumerator.get_Current()
MoveNext()
Reset()
Dispose()