Intrinsics
Represents highly optimized runtime intrinsic methods.
using System;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace DotNext.Runtime
{
[EditorBrowsable(EditorBrowsableState.Advanced)]
public static class Intrinsics
{
[ExcludeFromCodeCoverage]
private readonly struct AlignmentHelperType<T>
{
private readonly byte field1;
private readonly T field2;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[NullableContext(2)]
public static bool IsNullable<T>()
{
T val = default(T);
Unsafe.SkipInit<T>(ref val);
return val == null;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal unsafe static ref TTo InToRef<TFrom, TTo>([In] [RequiresLocation] ref TFrom source)
{
return ref *(TTo*)(&source);
}
[NullableContext(1)]
public unsafe static bool IsDefault<[Nullable(2)] T>([In] [IsReadOnly] ref T value)
{
switch (Unsafe.SizeOf<T>()) {
case 0:
return true;
case 1:
return InToRef<T, byte>(ref value) == 0;
case 2:
return Unsafe.ReadUnaligned<ushort>(ref InToRef<T, byte>(ref value)) == 0;
case 4:
return Unsafe.ReadUnaligned<uint>(ref InToRef<T, byte>(ref value)) == 0;
case 8:
return Unsafe.ReadUnaligned<ulong>(ref InToRef<T, byte>(ref value)) == 0;
default:
return IsZero(ref InToRef<T, byte>(ref value), (UIntPtr)(void*)Unsafe.SizeOf<T>());
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[NullableContext(2)]
public static RuntimeTypeHandle TypeOf<T>()
{
return typeof(T).TypeHandle;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[NullableContext(1)]
public static T Cast<T>([Nullable(2)] object obj)
{
if (obj == null)
<Cast>g__ThrowInvalidCastException|4_0<T>();
return (T)obj;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public unsafe static int PointerHashCode([In] void* pointer)
{
return ((UIntPtr*)(&pointer))->GetHashCode();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[NullableContext(1)]
public unsafe static IntPtr AddressOf<[Nullable(2)] T>([In] [RequiresLocation] ref T value)
{
return (IntPtr)Unsafe.AsPointer<T>(ref Unsafe.AsRef<T>(ref value));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[NullableContext(1)]
[CLSCompliant(false)]
public static ref T AsRef<[Nullable(2)] T>(this TypedReference reference)
{
return ref __refvalue(reference, T);
}
internal unsafe static int CompareUnaligned(ref byte first, ref byte second, UIntPtr length)
{
int num = 0;
while (length != (UIntPtr)(void*)null && num == 0) {
UIntPtr uIntPtr = (UIntPtr)(void*)(long)(((ulong)length > 2147483647) ? ((IntPtr)2147483647) : ((IntPtr)(void*)(ulong)length));
num = MemoryMarshal.CreateReadOnlySpan(ref first, (int)(ulong)uIntPtr).SequenceCompareTo(MemoryMarshal.CreateReadOnlySpan(ref second, (int)(ulong)uIntPtr));
length = (UIntPtr)(void*)((long)(ulong)length - (long)(ulong)uIntPtr);
ref first = ref Unsafe.Add<byte>(ref first, uIntPtr);
ref second = ref Unsafe.Add<byte>(ref second, uIntPtr);
}
return num;
}
[CLSCompliant(false)]
public unsafe static int Compare([In] void* first, [In] void* second, UIntPtr length)
{
return CompareUnaligned(ref Unsafe.AsRef<byte>(first), ref Unsafe.AsRef<byte>(second), length);
}
internal unsafe static bool EqualsUnaligned(ref byte first, ref byte second, UIntPtr length)
{
while (length != (UIntPtr)(void*)null) {
UIntPtr uIntPtr = (UIntPtr)(void*)(long)(((ulong)length > 2147483647) ? ((IntPtr)2147483647) : ((IntPtr)(void*)(ulong)length));
if (!MemoryMarshal.CreateReadOnlySpan(ref first, (int)(ulong)uIntPtr).SequenceEqual(MemoryMarshal.CreateReadOnlySpan(ref second, (int)(ulong)uIntPtr)))
return false;
length = (UIntPtr)(void*)((long)(ulong)length - (long)(ulong)uIntPtr);
ref first = ref Unsafe.Add<byte>(ref first, uIntPtr);
ref second = ref Unsafe.Add<byte>(ref second, uIntPtr);
}
return true;
}
[CLSCompliant(false)]
public unsafe static bool Equals([In] void* first, [In] void* second, UIntPtr length)
{
return EqualsUnaligned(ref Unsafe.AsRef<byte>(first), ref Unsafe.AsRef<byte>(second), length);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Copy<T>([In] [IsReadOnly] ref T input, out T output) where T : struct
{
output = input;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public unsafe static void CopyUnaligned<[IsUnmanaged] T>([In] T* input, [Out] T* output) where T : struct
{
Unsafe.WriteUnaligned<T>((void*)output, Unsafe.ReadUnaligned<T>((void*)input));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public unsafe static void Copy<[IsUnmanaged] T>([In] T* input, [Out] T* output) where T : struct
{
Copy(ref *input, out *output);
}
private unsafe static void Copy([In] ref byte source, [In] ref byte destination, UIntPtr length)
{
while (length != (UIntPtr)(void*)null) {
UIntPtr uIntPtr = (UIntPtr)(void*)(long)(((ulong)length > 4294967295) ? ((IntPtr)(void*)uint.MaxValue) : ((IntPtr)(void*)(ulong)length));
Unsafe.CopyBlockUnaligned(ref destination, ref source, (uint)(ulong)uIntPtr);
length = (UIntPtr)(void*)((long)(ulong)length - (long)(ulong)uIntPtr);
ref source = ref Unsafe.Add<byte>(ref source, uIntPtr);
ref destination = ref Unsafe.Add<byte>(ref destination, uIntPtr);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public unsafe static void Copy<[IsUnmanaged] T>([In] [IsReadOnly] ref T source, out T destination, UIntPtr count) where T : struct
{
Unsafe.SkipInit<T>(ref destination);
Copy(ref Unsafe.As<T, byte>(ref Unsafe.AsRef<T>(ref source)), ref Unsafe.As<T, byte>(ref destination), (UIntPtr)(void*)checked(unchecked((ulong)count) * unchecked((ulong)checked((UIntPtr)(ulong)sizeof(T)))));
}
[NullableContext(1)]
public static void Swap<[Nullable(2)] T>(ref T first, ref T second)
{
T val = first;
T val2 = second;
second = val;
first = val2;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public unsafe static void Swap<[IsUnmanaged] T>(T* first, T* second) where T : struct
{
Swap(ref *first, ref *second);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private unsafe static ref byte Advance<[IsUnmanaged] T>(ref byte ptr) where T : struct
{
return ref Unsafe.Add<byte>(ref ptr, sizeof(T));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private unsafe static ref byte Advance<[IsUnmanaged] T>([In] ref byte address, [In] [Out] UIntPtr* length) where T : struct
{
*length -= (UIntPtr)(void*)sizeof(T);
return ref ref address.Advance<T>();
}
private unsafe static bool IsZero([In] ref byte address, UIntPtr length)
{
bool result = false;
if (Vector.IsHardwareAccelerated && Vector<byte>.Count > sizeof(UIntPtr)) {
while ((ulong)length >= (ulong)Vector<byte>.Count) {
if (Unsafe.ReadUnaligned<Vector<byte>>(ref address) == Vector<byte>.Zero) {
ref address = ref ref address.Advance<Vector<byte>>(&length);
continue;
}
goto IL_0076;
}
}
while (true) {
if ((ulong)length < (ulong)sizeof(UIntPtr)) {
while (true) {
if (length == (UIntPtr)(void*)null) {
result = true;
break;
}
if (address != 0)
break;
ref address = ref ref address.Advance<byte>(&length);
}
break;
}
if (Unsafe.ReadUnaligned<UIntPtr>(ref address) != (UIntPtr)(void*)null)
break;
ref address = ref ref address.Advance<UIntPtr>(&length);
}
goto IL_0076;
IL_0076:
return result;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[NullableContext(2)]
public static bool IsExactTypeOf<T>(object obj)
{
return obj?.GetType() == typeof(T);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[NullableContext(1)]
[CLSCompliant(false)]
public unsafe static UIntPtr GetLength(this Array array)
{
return (UIntPtr)(void*)array.LongLength;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static ReadOnlySpan<TOutput> ReinterpretCast<[IsUnmanaged] TInput, [IsUnmanaged] TOutput>(ReadOnlySpan<TInput> input) where TInput : struct where TOutput : struct
{
return MemoryMarshal.CreateReadOnlySpan(ref Unsafe.As<TInput, TOutput>(ref MemoryMarshal.GetReference(input)), input.Length);
}
[NullableContext(1)]
public unsafe static bool HasFinalizer(object obj)
{
return (IntPtr)(void*) != (IntPtr)(void*);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[NullableContext(2)]
public static int AlignOf<T>()
{
return Unsafe.SizeOf<AlignmentHelperType<T>>() - Unsafe.SizeOf<T>();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[NullableContext(2)]
public static bool AreCompatible<T1, T2>()
{
if (Unsafe.SizeOf<T1>() == Unsafe.SizeOf<T2>())
return AlignOf<T1>() == AlignOf<T2>();
return false;
}
}
}