mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-14 19:29:36 +01:00
* Source gen reorganizations + component unpause generator. This commit (and subsequent commits) aims to clean up our Roslyn plugin (source gens + analyzers) stack to more sanely re-use common code I also built a new source-gen that automatically generates unpausing implementations for components, incrementing attributed TimeSpan field when unpaused. * Fix warnings in all Roslyn projects
202 lines
7.2 KiB
C#
202 lines
7.2 KiB
C#
// 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
|
|
|
|
/// <summary>
|
|
/// Extensions for <see cref="EquatableArray{T}"/>.
|
|
/// </summary>
|
|
public static class EquatableArray
|
|
{
|
|
/// <summary>
|
|
/// Creates an <see cref="EquatableArray{T}"/> instance from a given <see cref="ImmutableArray{T}"/>.
|
|
/// </summary>
|
|
/// <typeparam name="T">The type of items in the input array.</typeparam>
|
|
/// <param name="array">The input <see cref="ImmutableArray{T}"/> instance.</param>
|
|
/// <returns>An <see cref="EquatableArray{T}"/> instance from a given <see cref="ImmutableArray{T}"/>.</returns>
|
|
public static EquatableArray<T> AsEquatableArray<T>(this ImmutableArray<T> array)
|
|
where T : IEquatable<T>
|
|
{
|
|
return new(array);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// An immutable, equatable array. This is equivalent to <see cref="ImmutableArray{T}"/> but with value equality support.
|
|
/// </summary>
|
|
/// <typeparam name="T">The type of values in the array.</typeparam>
|
|
public readonly struct EquatableArray<T> : IEquatable<EquatableArray<T>>, IEnumerable<T>
|
|
where T : IEquatable<T>
|
|
{
|
|
/// <summary>
|
|
/// The underlying <typeparamref name="T"/> array.
|
|
/// </summary>
|
|
private readonly T[]? array;
|
|
|
|
/// <summary>
|
|
/// Creates a new <see cref="EquatableArray{T}"/> instance.
|
|
/// </summary>
|
|
/// <param name="array">The input <see cref="ImmutableArray{T}"/> to wrap.</param>
|
|
public EquatableArray(ImmutableArray<T> array)
|
|
{
|
|
this.array = Unsafe.As<ImmutableArray<T>, T[]?>(ref array);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a reference to an item at a specified position within the array.
|
|
/// </summary>
|
|
/// <param name="index">The index of the item to retrieve a reference to.</param>
|
|
/// <returns>A reference to an item at a specified position within the array.</returns>
|
|
public ref readonly T this[int index]
|
|
{
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
get => ref AsImmutableArray().ItemRef(index);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a value indicating whether the current array is empty.
|
|
/// </summary>
|
|
public bool IsEmpty
|
|
{
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
get => AsImmutableArray().IsEmpty;
|
|
}
|
|
|
|
/// <sinheritdoc/>
|
|
public bool Equals(EquatableArray<T> array)
|
|
{
|
|
return AsSpan().SequenceEqual(array.AsSpan());
|
|
}
|
|
|
|
/// <sinheritdoc/>
|
|
public override bool Equals([NotNullWhen(true)] object? obj)
|
|
{
|
|
return obj is EquatableArray<T> array && Equals(this, array);
|
|
}
|
|
|
|
/// <sinheritdoc/>
|
|
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();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets an <see cref="ImmutableArray{T}"/> instance from the current <see cref="EquatableArray{T}"/>.
|
|
/// </summary>
|
|
/// <returns>The <see cref="ImmutableArray{T}"/> from the current <see cref="EquatableArray{T}"/>.</returns>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public ImmutableArray<T> AsImmutableArray()
|
|
{
|
|
return Unsafe.As<T[]?, ImmutableArray<T>>(ref Unsafe.AsRef(in this.array));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates an <see cref="EquatableArray{T}"/> instance from a given <see cref="ImmutableArray{T}"/>.
|
|
/// </summary>
|
|
/// <param name="array">The input <see cref="ImmutableArray{T}"/> instance.</param>
|
|
/// <returns>An <see cref="EquatableArray{T}"/> instance from a given <see cref="ImmutableArray{T}"/>.</returns>
|
|
public static EquatableArray<T> FromImmutableArray(ImmutableArray<T> array)
|
|
{
|
|
return new(array);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a <see cref="ReadOnlySpan{T}"/> wrapping the current items.
|
|
/// </summary>
|
|
/// <returns>A <see cref="ReadOnlySpan{T}"/> wrapping the current items.</returns>
|
|
public ReadOnlySpan<T> AsSpan()
|
|
{
|
|
return AsImmutableArray().AsSpan();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Copies the contents of this <see cref="EquatableArray{T}"/> instance to a mutable array.
|
|
/// </summary>
|
|
/// <returns>The newly instantiated array.</returns>
|
|
public T[] ToArray()
|
|
{
|
|
return AsImmutableArray().ToArray();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets an <see cref="ImmutableArray{T}.Enumerator"/> value to traverse items in the current array.
|
|
/// </summary>
|
|
/// <returns>An <see cref="ImmutableArray{T}.Enumerator"/> value to traverse items in the current array.</returns>
|
|
public ImmutableArray<T>.Enumerator GetEnumerator()
|
|
{
|
|
return AsImmutableArray().GetEnumerator();
|
|
}
|
|
|
|
/// <sinheritdoc/>
|
|
IEnumerator<T> IEnumerable<T>.GetEnumerator()
|
|
{
|
|
return ((IEnumerable<T>)AsImmutableArray()).GetEnumerator();
|
|
}
|
|
|
|
/// <sinheritdoc/>
|
|
IEnumerator IEnumerable.GetEnumerator()
|
|
{
|
|
return ((IEnumerable)AsImmutableArray()).GetEnumerator();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Implicitly converts an <see cref="ImmutableArray{T}"/> to <see cref="EquatableArray{T}"/>.
|
|
/// </summary>
|
|
/// <returns>An <see cref="EquatableArray{T}"/> instance from a given <see cref="ImmutableArray{T}"/>.</returns>
|
|
public static implicit operator EquatableArray<T>(ImmutableArray<T> array)
|
|
{
|
|
return FromImmutableArray(array);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Implicitly converts an <see cref="EquatableArray{T}"/> to <see cref="ImmutableArray{T}"/>.
|
|
/// </summary>
|
|
/// <returns>An <see cref="ImmutableArray{T}"/> instance from a given <see cref="EquatableArray{T}"/>.</returns>
|
|
public static implicit operator ImmutableArray<T>(EquatableArray<T> array)
|
|
{
|
|
return array.AsImmutableArray();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks whether two <see cref="EquatableArray{T}"/> values are the same.
|
|
/// </summary>
|
|
/// <param name="left">The first <see cref="EquatableArray{T}"/> value.</param>
|
|
/// <param name="right">The second <see cref="EquatableArray{T}"/> value.</param>
|
|
/// <returns>Whether <paramref name="left"/> and <paramref name="right"/> are equal.</returns>
|
|
public static bool operator ==(EquatableArray<T> left, EquatableArray<T> right)
|
|
{
|
|
return left.Equals(right);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks whether two <see cref="EquatableArray{T}"/> values are not the same.
|
|
/// </summary>
|
|
/// <param name="left">The first <see cref="EquatableArray{T}"/> value.</param>
|
|
/// <param name="right">The second <see cref="EquatableArray{T}"/> value.</param>
|
|
/// <returns>Whether <paramref name="left"/> and <paramref name="right"/> are not equal.</returns>
|
|
public static bool operator !=(EquatableArray<T> left, EquatableArray<T> right)
|
|
{
|
|
return !left.Equals(right);
|
|
}
|
|
}
|