// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. // https://github.com/CommunityToolkit/dotnet/blob/main/CommunityToolkit.HighPerformance/Enumerables/ReadOnlySpanEnumerable%7BT%7D.cs using System.ComponentModel; using System.Runtime.CompilerServices; using JetBrains.Annotations; namespace FisheryLib; /// /// A that enumerates the items in a given instance. /// /// The type of items to enumerate. [EditorBrowsable(EditorBrowsableState.Never)] [PublicAPI] public ref struct ReadOnlySpanEnumerable { /// /// The source instance. /// private readonly ReadOnlySpan _span; /// /// The current index within . /// private int _index; /// /// Initializes a new instance of the struct. /// /// The source instance. [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlySpanEnumerable(ReadOnlySpan span) { _span = span; _index = -1; } /// /// Implements the duck-typed method. /// /// An instance targeting the current value. [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly ReadOnlySpanEnumerable GetEnumerator() => this; /// /// Implements the duck-typed method. /// /// whether a new element is available, otherwise [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool MoveNext() => ++_index < _span.Length; /// /// Gets the duck-typed property. /// public readonly Item Current { [MethodImpl(MethodImplOptions.AggressiveInlining)] get // See comment in SpanEnumerable about this => new(ref Unsafe.Add(ref _span.DangerousGetPinnableReference(), (nint)(uint)_index), _index); } /// /// An item from a source instance. /// [EditorBrowsable(EditorBrowsableState.Never)] public readonly ref struct Item { /// /// The source instance. /// private readonly ReadOnlySpan _span; /// /// Initializes a new instance of the struct. /// /// A reference to the target value. /// The index of the target value. [MethodImpl(MethodImplOptions.AggressiveInlining)] public Item(ref T value, int index) => _span = MemoryMarshal.CreateReadOnlySpan(ref value, index); /// /// Gets the reference to the current value. /// public ref readonly T Value { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => ref _span.DangerousGetPinnableReference(); } /// /// Gets the current index. /// public int Index { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => _span.Length; } } }