Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 83f35ef

Browse files
Add Unsafe.IsAddressGreaterThan and IsAddressLessThan
1 parent 2836df3 commit 83f35ef

File tree

4 files changed

+84
-0
lines changed

4 files changed

+84
-0
lines changed

src/System.Runtime.CompilerServices.Unsafe/ref/System.Runtime.CompilerServices.Unsafe.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ public static void InitBlock(ref byte startAddress, byte value, uint byteCount)
3030
public unsafe static void InitBlock(void* startAddress, byte value, uint byteCount) { }
3131
public static void InitBlockUnaligned(ref byte startAddress, byte value, uint byteCount) { }
3232
public unsafe static void InitBlockUnaligned(void* startAddress, byte value, uint byteCount) { }
33+
public static bool IsAddressGreaterThan<T>(ref T left, ref T right) { throw null; }
34+
public static bool IsAddressLessThan<T>(ref T left, ref T right) { throw null; }
3335
public unsafe static T Read<T>(void* source) { throw null; }
3436
public unsafe static T ReadUnaligned<T>(void* source) { throw null; }
3537
public static T ReadUnaligned<T>(ref byte source) { throw null; }

src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.il

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,26 @@
419419
ret
420420
} // end of method Unsafe::AreSame
421421

422+
.method public hidebysig static bool IsAddressGreaterThan<T>(!!T& left, !!T& right) cil managed aggressiveinlining
423+
{
424+
.custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 )
425+
.maxstack 2
426+
ldarg.0
427+
ldarg.1
428+
cgt.un
429+
ret
430+
} // end of method Unsafe::IsAddressGreaterThan
431+
432+
.method public hidebysig static bool IsAddressLessThan<T>(!!T& left, !!T& right) cil managed aggressiveinlining
433+
{
434+
.custom instance void System.Runtime.Versioning.NonVersionableAttribute::.ctor() = ( 01 00 00 00 )
435+
.maxstack 2
436+
ldarg.0
437+
ldarg.1
438+
clt.un
439+
ret
440+
} // end of method Unsafe::IsAddressLessThan
441+
422442
} // end of class System.Runtime.CompilerServices.Unsafe
423443

424444
.class private auto ansi sealed beforefieldinit System.Runtime.Versioning.NonVersionableAttribute

src/System.Runtime.CompilerServices.Unsafe/src/System.Runtime.CompilerServices.Unsafe.xml

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/System.Runtime.CompilerServices.Unsafe/tests/UnsafeTests.cs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,44 @@ public static void RefAreSame()
608608
Assert.False(Unsafe.AreSame(ref a[0], ref a[1]));
609609
}
610610

611+
[Fact]
612+
public static unsafe void RefIsAddressGreaterThan()
613+
{
614+
int[] a = new int[2];
615+
616+
Assert.False(Unsafe.IsAddressGreaterThan(ref a[0], ref a[0]));
617+
Assert.False(Unsafe.IsAddressGreaterThan(ref a[0], ref a[1]));
618+
Assert.True(Unsafe.IsAddressGreaterThan(ref a[1], ref a[0]));
619+
Assert.False(Unsafe.IsAddressGreaterThan(ref a[1], ref a[1]));
620+
621+
// The following tests ensure that we're using unsigned comparison logic
622+
623+
Assert.False(Unsafe.IsAddressGreaterThan(ref Unsafe.AsRef<byte>((void*)(1)), ref Unsafe.AsRef<byte>((void*)(-1))));
624+
Assert.True(Unsafe.IsAddressGreaterThan(ref Unsafe.AsRef<byte>((void*)(-1)), ref Unsafe.AsRef<byte>((void*)(1))));
625+
Assert.True(Unsafe.IsAddressGreaterThan(ref Unsafe.AsRef<byte>((void*)(Int32.MinValue)), ref Unsafe.AsRef<byte>((void*)(Int32.MaxValue))));
626+
Assert.False(Unsafe.IsAddressGreaterThan(ref Unsafe.AsRef<byte>((void*)(Int32.MaxValue)), ref Unsafe.AsRef<byte>((void*)(Int32.MinValue))));
627+
Assert.False(Unsafe.IsAddressGreaterThan(ref Unsafe.AsRef<byte>(null), ref Unsafe.AsRef<byte>(null)));
628+
}
629+
630+
[Fact]
631+
public static unsafe void RefIsAddressLessThan()
632+
{
633+
int[] a = new int[2];
634+
635+
Assert.False(Unsafe.IsAddressLessThan(ref a[0], ref a[0]));
636+
Assert.True(Unsafe.IsAddressLessThan(ref a[0], ref a[1]));
637+
Assert.False(Unsafe.IsAddressLessThan(ref a[1], ref a[0]));
638+
Assert.False(Unsafe.IsAddressLessThan(ref a[1], ref a[1]));
639+
640+
// The following tests ensure that we're using unsigned comparison logic
641+
642+
Assert.True(Unsafe.IsAddressLessThan(ref Unsafe.AsRef<byte>((void*)(1)), ref Unsafe.AsRef<byte>((void*)(-1))));
643+
Assert.False(Unsafe.IsAddressLessThan(ref Unsafe.AsRef<byte>((void*)(-1)), ref Unsafe.AsRef<byte>((void*)(1))));
644+
Assert.False(Unsafe.IsAddressLessThan(ref Unsafe.AsRef<byte>((void*)(Int32.MinValue)), ref Unsafe.AsRef<byte>((void*)(Int32.MaxValue))));
645+
Assert.True(Unsafe.IsAddressLessThan(ref Unsafe.AsRef<byte>((void*)(Int32.MaxValue)), ref Unsafe.AsRef<byte>((void*)(Int32.MinValue))));
646+
Assert.False(Unsafe.IsAddressLessThan(ref Unsafe.AsRef<byte>(null), ref Unsafe.AsRef<byte>(null)));
647+
}
648+
611649
[Fact]
612650
public static unsafe void ReadUnaligned_ByRef_Int32()
613651
{

0 commit comments

Comments
 (0)