diff options
author | nietras <nietras@users.noreply.github.com> | 2016-10-22 04:39:59 +0300 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2016-10-22 04:39:59 +0300 |
commit | b1937cb6f0bc01f11be2fc363643a8af558d8dcb (patch) | |
tree | b88ddb07b42740efc6e87e27881adbbd288d477a | |
parent | 0a1ca15ee8d854b88aefb89393162432cca3443a (diff) |
S.R.CS.Unsafe: Add 'IntPtr ByteOffset<T>(ref T origin, ref T target)' (#12895)
3 files changed, 50 insertions, 0 deletions
diff --git a/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.il b/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.il index c8a5758f4e..3251744263 100644 --- a/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.il +++ b/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.il @@ -305,6 +305,16 @@ ret } // end of method Unsafe::SubtractByteOffset + .method public hidebysig static native int ByteOffset<T>(!!T& origin, !!T& target) cil managed aggressiveinlining + { + .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 ) + .maxstack 2 + ldarg.1 + ldarg.0 + sub + ret + } // end of method Unsafe::ByteOffset + .method public hidebysig static bool AreSame<T>(!!T& left, !!T& right) cil managed aggressiveinlining { .custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 ) diff --git a/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.xml b/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.xml index a2dd77301b..bd8f42271a 100644 --- a/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.xml +++ b/src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.xml @@ -135,6 +135,15 @@ <param name="bytesOffset">The offset to subtract.</param> <returns>A new reference that reflects the subraction of byte offset from pointer.</returns> </member> + <member name="M:System.Runtime.CompilerServices.Unsafe.ByteOffset``1(``0@,``0@)"> + <summary> + Determines the byte offset from origin to target from the given references. + </summary> + <typeparam name="T">The type of reference.</typeparam> + <param name="origin">The reference to origin.</param> + <param name="target">The reference to target.</param> + <returns>Byte offset from origin to target i.e. <paramref name="target"/> - <paramref name="origin"/>.</returns> + </member> <member name="M:System.Runtime.CompilerServices.Unsafe.AreSame``1(``0@,``0@)"> <summary> Determines whether the specified references point to the same location. diff --git a/src/System.Runtime.CompilerServices.Unsafe/tests/UnsafeTests.cs b/src/System.Runtime.CompilerServices.Unsafe/tests/UnsafeTests.cs index 2a90b63525..1385fbe442 100644 --- a/src/System.Runtime.CompilerServices.Unsafe/tests/UnsafeTests.cs +++ b/src/System.Runtime.CompilerServices.Unsafe/tests/UnsafeTests.cs @@ -387,6 +387,37 @@ namespace System.Runtime.CompilerServices Assert.IsType(typeof(Object), Unsafe.As<string>(o)); } + [Fact] + public static void ByteOffsetArray() + { + var a = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 }; + + Assert.Equal(new IntPtr(0), Unsafe.ByteOffset(ref a[0], ref a[0])); + Assert.Equal(new IntPtr(1), Unsafe.ByteOffset(ref a[0], ref a[1])); + Assert.Equal(new IntPtr(-1), Unsafe.ByteOffset(ref a[1], ref a[0])); + Assert.Equal(new IntPtr(2), Unsafe.ByteOffset(ref a[0], ref a[2])); + Assert.Equal(new IntPtr(-2), Unsafe.ByteOffset(ref a[2], ref a[0])); + Assert.Equal(new IntPtr(3), Unsafe.ByteOffset(ref a[0], ref a[3])); + Assert.Equal(new IntPtr(4), Unsafe.ByteOffset(ref a[0], ref a[4])); + Assert.Equal(new IntPtr(5), Unsafe.ByteOffset(ref a[0], ref a[5])); + Assert.Equal(new IntPtr(6), Unsafe.ByteOffset(ref a[0], ref a[6])); + Assert.Equal(new IntPtr(7), Unsafe.ByteOffset(ref a[0], ref a[7])); + } + + [Fact] + public static void ByteOffsetStackByte4() + { + var byte4 = new Byte4(); + + Assert.Equal(new IntPtr(0), Unsafe.ByteOffset(ref byte4.B0, ref byte4.B0)); + Assert.Equal(new IntPtr(1), Unsafe.ByteOffset(ref byte4.B0, ref byte4.B1)); + Assert.Equal(new IntPtr(-1), Unsafe.ByteOffset(ref byte4.B1, ref byte4.B0)); + Assert.Equal(new IntPtr(2), Unsafe.ByteOffset(ref byte4.B0, ref byte4.B2)); + Assert.Equal(new IntPtr(-2), Unsafe.ByteOffset(ref byte4.B2, ref byte4.B0)); + Assert.Equal(new IntPtr(3), Unsafe.ByteOffset(ref byte4.B0, ref byte4.B3)); + Assert.Equal(new IntPtr(-3), Unsafe.ByteOffset(ref byte4.B3, ref byte4.B0)); + } + // Active Issue: https://github.com/dotnet/coreclr/issues/6505 // These tests require C# compiler with support for ref returns and locals #if false |