// 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;
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;
}
}
}