// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // Taken from https://github.com/CommunityToolkit/dotnet/blob/ecd1711b740f4f88d2bb943ce292ae4fc90df1bc/src/CommunityToolkit.Mvvm.SourceGenerators/Helpers/EquatableArray%7BT%7D.cs using System.Collections; using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; namespace Robust.Roslyn.Shared.Helpers; #nullable enable /// /// Extensions for . /// public static class EquatableArray { /// /// Creates an instance from a given . /// /// The type of items in the input array. /// The input instance. /// An instance from a given . public static EquatableArray AsEquatableArray(this ImmutableArray array) where T : IEquatable { return new(array); } } /// /// An immutable, equatable array. This is equivalent to but with value equality support. /// /// The type of values in the array. public readonly struct EquatableArray : IEquatable>, IEnumerable where T : IEquatable { /// /// The underlying array. /// private readonly T[]? array; /// /// Creates a new instance. /// /// The input to wrap. public EquatableArray(ImmutableArray array) { this.array = Unsafe.As, T[]?>(ref array); } /// /// Gets a reference to an item at a specified position within the array. /// /// The index of the item to retrieve a reference to. /// A reference to an item at a specified position within the array. public ref readonly T this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => ref AsImmutableArray().ItemRef(index); } /// /// Gets a value indicating whether the current array is empty. /// public bool IsEmpty { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => AsImmutableArray().IsEmpty; } /// public bool Equals(EquatableArray array) { return AsSpan().SequenceEqual(array.AsSpan()); } /// public override bool Equals([NotNullWhen(true)] object? obj) { return obj is EquatableArray array && Equals(this, array); } /// public override int GetHashCode() { if (this.array is not T[] array) { return 0; } HashCode hashCode = default; foreach (T item in array) { hashCode.Add(item); } return hashCode.ToHashCode(); } /// /// Gets an instance from the current . /// /// The from the current . [MethodImpl(MethodImplOptions.AggressiveInlining)] public ImmutableArray AsImmutableArray() { return Unsafe.As>(ref Unsafe.AsRef(in this.array)); } /// /// Creates an instance from a given . /// /// The input instance. /// An instance from a given . public static EquatableArray FromImmutableArray(ImmutableArray array) { return new(array); } /// /// Returns a wrapping the current items. /// /// A wrapping the current items. public ReadOnlySpan AsSpan() { return AsImmutableArray().AsSpan(); } /// /// Copies the contents of this instance to a mutable array. /// /// The newly instantiated array. public T[] ToArray() { return AsImmutableArray().ToArray(); } /// /// Gets an value to traverse items in the current array. /// /// An value to traverse items in the current array. public ImmutableArray.Enumerator GetEnumerator() { return AsImmutableArray().GetEnumerator(); } /// IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)AsImmutableArray()).GetEnumerator(); } /// IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)AsImmutableArray()).GetEnumerator(); } /// /// Implicitly converts an to . /// /// An instance from a given . public static implicit operator EquatableArray(ImmutableArray array) { return FromImmutableArray(array); } /// /// Implicitly converts an to . /// /// An instance from a given . public static implicit operator ImmutableArray(EquatableArray array) { return array.AsImmutableArray(); } /// /// Checks whether two values are the same. /// /// The first value. /// The second value. /// Whether and are equal. public static bool operator ==(EquatableArray left, EquatableArray right) { return left.Equals(right); } /// /// Checks whether two values are not the same. /// /// The first value. /// The second value. /// Whether and are not equal. public static bool operator !=(EquatableArray left, EquatableArray right) { return !left.Equals(right); } }