Buffers.cs 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. using System;
  2. using System.Diagnostics;
  3. using System.Runtime.CompilerServices;
  4. using System.Runtime.InteropServices;
  5. namespace Ryujinx.Common.Utilities
  6. {
  7. [DebuggerDisplay("{ToString()}")]
  8. [StructLayout(LayoutKind.Sequential, Size = 16)]
  9. public struct Buffer16
  10. {
  11. [DebuggerBrowsable(DebuggerBrowsableState.Never)] private ulong _dummy0;
  12. [DebuggerBrowsable(DebuggerBrowsableState.Never)] private ulong _dummy1;
  13. public byte this[int i]
  14. {
  15. get => Bytes[i];
  16. set => Bytes[i] = value;
  17. }
  18. public Span<byte> Bytes => SpanHelpers.AsByteSpan(ref this);
  19. // Prevent a defensive copy by changing the read-only in reference to a reference with Unsafe.AsRef()
  20. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  21. public static implicit operator Span<byte>(in Buffer16 value)
  22. {
  23. return SpanHelpers.AsByteSpan(ref Unsafe.AsRef(in value));
  24. }
  25. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  26. public static implicit operator ReadOnlySpan<byte>(in Buffer16 value)
  27. {
  28. return SpanHelpers.AsReadOnlyByteSpan(ref Unsafe.AsRef(in value));
  29. }
  30. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  31. public ref T As<T>() where T : unmanaged
  32. {
  33. if (Unsafe.SizeOf<T>() > (uint)Unsafe.SizeOf<Buffer16>())
  34. {
  35. throw new ArgumentException();
  36. }
  37. return ref MemoryMarshal.GetReference(AsSpan<T>());
  38. }
  39. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  40. public Span<T> AsSpan<T>() where T : unmanaged
  41. {
  42. return SpanHelpers.AsSpan<Buffer16, T>(ref this);
  43. }
  44. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  45. public readonly ReadOnlySpan<T> AsReadOnlySpan<T>() where T : unmanaged
  46. {
  47. return SpanHelpers.AsReadOnlySpan<Buffer16, T>(ref Unsafe.AsRef(in this));
  48. }
  49. }
  50. }