From d876665a8db891b65b9fadfcb05a9d910c1a0336 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Thu, 19 Jul 2018 08:29:36 -0700 Subject: [PATCH] Add MemoryMarshal.AsRef implementation (dotnet/coreclr#19021) Contributes to https://github.com/dotnet/corefx/issues/30613 Commit migrated from https://github.com/dotnet/coreclr/commit/660d90405f322b0290170d1f947e53da484d81ad --- .../Runtime/InteropServices/MemoryMarshal.Fast.cs | 4 +- .../Runtime/InteropServices/MemoryMarshal.cs | 44 ++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/MemoryMarshal.Fast.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/MemoryMarshal.Fast.cs index a954529..e3cf0a8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/MemoryMarshal.Fast.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/MemoryMarshal.Fast.cs @@ -102,7 +102,7 @@ namespace System.Runtime.InteropServices /// These types may not contain pointers or references. This is checked at runtime in order to preserve type safety. /// /// - /// Supported only for platforms that support misaligned memory access. + /// Supported only for platforms that support misaligned memory access or when the memory block is aligned by other means. /// /// The source slice, of type . /// @@ -157,7 +157,7 @@ namespace System.Runtime.InteropServices /// These types may not contain pointers or references. This is checked at runtime in order to preserve type safety. /// /// - /// Supported only for platforms that support misaligned memory access. + /// Supported only for platforms that support misaligned memory access or when the memory block is aligned by other means. /// /// The source slice, of type . /// diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/MemoryMarshal.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/MemoryMarshal.cs index 5e33ced..fcc9c4f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/MemoryMarshal.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/MemoryMarshal.cs @@ -212,6 +212,50 @@ namespace System.Runtime.InteropServices } /// + /// Re-interprets a span of bytes as a reference to structure of type T. + /// The type may not contain pointers or references. This is checked at runtime in order to preserve type safety. + /// + /// + /// Supported only for platforms that support misaligned memory access or when the memory block is aligned by other means. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ref T AsRef(Span span) + where T : struct + { + if (RuntimeHelpers.IsReferenceOrContainsReferences()) + { + ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T)); + } + if (Unsafe.SizeOf() > (uint)span.Length) + { + ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.length); + } + return ref Unsafe.As(ref GetReference(span)); + } + + /// + /// Re-interprets a span of bytes as a reference to structure of type T. + /// The type may not contain pointers or references. This is checked at runtime in order to preserve type safety. + /// + /// + /// Supported only for platforms that support misaligned memory access or when the memory block is aligned by other means. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ref readonly T AsRef(ReadOnlySpan span) + where T : struct + { + if (RuntimeHelpers.IsReferenceOrContainsReferences()) + { + ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T)); + } + if (Unsafe.SizeOf() > (uint)span.Length) + { + ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.length); + } + return ref Unsafe.As(ref GetReference(span)); + } + + /// /// Creates a new memory over the portion of the pre-pinned target array beginning /// at 'start' index and ending at 'end' index (exclusive). /// -- 2.7.4