From d2d2c7bd2510929231e961d112a00d4adfcdb624 Mon Sep 17 00:00:00 2001 From: buybackoff Date: Sun, 12 Jan 2020 23:56:36 +0100 Subject: [PATCH] Add UnsafeEx.ReadUnaligned/WriteUnaligned methods that work on `ref T` --- dotnet/build/common.props | 2 +- dotnet/src/Spreads.Native/UnsafeEx.cs | 12 ++++++++++ dotnet/tests/Spreads.Native.Tests/VecTests.cs | 24 +++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/dotnet/build/common.props b/dotnet/build/common.props index 78e1b3a..d994b78 100644 --- a/dotnet/build/common.props +++ b/dotnet/build/common.props @@ -14,7 +14,7 @@ 1 - 112 + 114 diff --git a/dotnet/src/Spreads.Native/UnsafeEx.cs b/dotnet/src/Spreads.Native/UnsafeEx.cs index 0b33a07..e339ace 100644 --- a/dotnet/src/Spreads.Native/UnsafeEx.cs +++ b/dotnet/src/Spreads.Native/UnsafeEx.cs @@ -212,6 +212,18 @@ public static void SetAsObject(object obj, IntPtr offset, int index, object v Unsafe.WriteUnaligned(ref Unsafe.As(ref GetRef(obj, offset, index)), value); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T ReadUnaligned(ref T source) + { + return Unsafe.ReadUnaligned(ref Unsafe.As(ref source)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void WriteUnaligned(ref T destination, T value) + { + Unsafe.WriteUnaligned(ref Unsafe.As(ref destination), value); + } + /// /// Get a native method pointer to method for type . /// The pointer should be used with method. diff --git a/dotnet/tests/Spreads.Native.Tests/VecTests.cs b/dotnet/tests/Spreads.Native.Tests/VecTests.cs index 4956950..6d2990c 100644 --- a/dotnet/tests/Spreads.Native.Tests/VecTests.cs +++ b/dotnet/tests/Spreads.Native.Tests/VecTests.cs @@ -124,6 +124,30 @@ public void CouldUseVecSlice() Assert.IsTrue(vecT.Span.SequenceEqual(vec.AsSpan())); } + [Test] + public unsafe void ArrayAndPointerCtorsHaveSameBehavior() + { + var arr = new int[1000]; + var pin = arr.AsMemory().Pin(); + + var vArr = new Vec(arr, 500, 500); + var vPtr = new Vec((byte*)pin.Pointer + 500 * 4, 500, typeof(int)); + + Assert.AreEqual(vArr.Length, vPtr.Length); + + for (int i = 0; i < 1000; i++) + { + arr[i] = i; + } + + for (int i = 0; i < 500; i++) + { + Assert.AreEqual(vArr.Get(i), vPtr.Get(i)); + } + + pin.Dispose(); + } + [MethodImpl(MethodImplOptions.NoInlining #if NETCOREAPP3_0 | MethodImplOptions.AggressiveOptimization