Skip to content

Commit

Permalink
Add UnsafeEx.ReadUnaligned/WriteUnaligned methods that work on ref T
Browse files Browse the repository at this point in the history
  • Loading branch information
buybackoff committed Jan 12, 2020
1 parent d3cacc2 commit d2d2c7b
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 1 deletion.
2 changes: 1 addition & 1 deletion dotnet/build/common.props
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<QVersion>1</QVersion>

<!-- Overrides -->
<MMDDVersion>112</MMDDVersion>
<MMDDVersion>114</MMDDVersion>
<PackageHHMMSSSuffix></PackageHHMMSSSuffix>

</PropertyGroup>
Expand Down
12 changes: 12 additions & 0 deletions dotnet/src/Spreads.Native/UnsafeEx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,18 @@ public static void SetAsObject<T>(object obj, IntPtr offset, int index, object v
Unsafe.WriteUnaligned(ref Unsafe.As<T, byte>(ref GetRef<T>(obj, offset, index)), value);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T ReadUnaligned<T>(ref T source)
{
return Unsafe.ReadUnaligned<T>(ref Unsafe.As<T, byte>(ref source));
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void WriteUnaligned<T>(ref T destination, T value)
{
Unsafe.WriteUnaligned<T>(ref Unsafe.As<T, byte>(ref destination), value);
}

/// <summary>
/// Get a native method pointer to <see cref="SetAsObject{T}"/> method for type <typeparamref name="T"/>.
/// The pointer should be used with <see cref="SetIndirect"/> method.
Expand Down
24 changes: 24 additions & 0 deletions dotnet/tests/Spreads.Native.Tests/VecTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,30 @@ public void CouldUseVecSlice()
Assert.IsTrue(vecT.Span.SequenceEqual(vec.AsSpan<int>()));
}

[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<int>(i), vPtr.Get<int>(i));
}

pin.Dispose();
}

[MethodImpl(MethodImplOptions.NoInlining
#if NETCOREAPP3_0
| MethodImplOptions.AggressiveOptimization
Expand Down

0 comments on commit d2d2c7b

Please sign in to comment.