using System; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace Ryujinx.Common.Utilities { [DebuggerDisplay("{ToString()}")] [StructLayout(LayoutKind.Sequential, Size = 16)] public struct Buffer16 { [DebuggerBrowsable(DebuggerBrowsableState.Never)] private ulong _dummy0; [DebuggerBrowsable(DebuggerBrowsableState.Never)] private ulong _dummy1; public byte this[int i] { get => Bytes[i]; set => Bytes[i] = value; } public Span Bytes => SpanHelpers.AsByteSpan(ref this); // Prevent a defensive copy by changing the read-only in reference to a reference with Unsafe.AsRef() [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator Span(in Buffer16 value) { return SpanHelpers.AsByteSpan(ref Unsafe.AsRef(in value)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator ReadOnlySpan(in Buffer16 value) { return SpanHelpers.AsReadOnlyByteSpan(ref Unsafe.AsRef(in value)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public ref T As() where T : unmanaged { if (Unsafe.SizeOf() > (uint)Unsafe.SizeOf()) { throw new ArgumentException(); } return ref MemoryMarshal.GetReference(AsSpan()); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public Span AsSpan() where T : unmanaged { return SpanHelpers.AsSpan(ref this); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly ReadOnlySpan AsReadOnlySpan() where T : unmanaged { return SpanHelpers.AsReadOnlySpan(ref Unsafe.AsRef(in this)); } } }