Intrinsics
Represents highly optimized runtime intrinsic methods.
using DotNext.Runtime.CompilerServices;
using System;
using System.ComponentModel;
using System.Diagnostics;
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
{
[StructLayout(LayoutKind.Auto)]
private struct FNV1a32 : IConsumer<int>, IFunctional<Action<int>>
{
private const int Offset = -2128831035;
private const int Prime = 16777619;
private int result;
internal int Result {
[IsReadOnly]
get {
return result;
}
}
public FNV1a32()
{
result = -2128831035;
}
public void Invoke(int data)
{
result = (result ^ data) * 16777619;
}
}
[StructLayout(LayoutKind.Auto)]
private struct FNV1a64 : IConsumer<long>, IFunctional<Action<long>>
{
private const long Offset = -3750763034362895579;
private const long Prime = 1099511628211;
private long result;
internal long Result {
[IsReadOnly]
get {
return result;
}
}
public FNV1a64()
{
result = -3750763034362895579;
}
public void Invoke(long data)
{
result = (result ^ data) * 1099511628211;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[System.Runtime.CompilerServices.NullableContext(2)]
public static bool IsNullable<T>()
{
Unsafe.SkipInit(out T value);
return value == null;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal unsafe static ref TTo InToRef<TFrom, TTo>([In] [IsReadOnly] ref TFrom source)
{
return ref *(TTo*)(&source);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[System.Runtime.CompilerServices.NullableContext(2)]
[Obsolete("Use default keyword in C# instead")]
public static T DefaultOf<T>()
{
return default(T);
}
public unsafe static void Bitcast<[System.Runtime.CompilerServices.IsUnmanaged] T, [System.Runtime.CompilerServices.IsUnmanaged] TResult>([In] [LifetimeAnnotation(true, false)] [IsReadOnly] ref T input, out TResult output) where T : struct where TResult : struct
{
if ((uint)sizeof(T) >= (uint)sizeof(TResult))
output = *(TResult*)(&input);
else
*(T*)(&output) = input;
}
[System.Runtime.CompilerServices.NullableContext(1)]
public unsafe static bool IsDefault<[System.Runtime.CompilerServices.Nullable(2)] T>([In] [LifetimeAnnotation(true, false)] [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)]
[System.Runtime.CompilerServices.NullableContext(2)]
public static RuntimeTypeHandle TypeOf<T>()
{
return typeof(T).TypeHandle;
}
public static bool HasFlag<T>(T value, T flag) where T : struct, Enum
{
switch (Unsafe.SizeOf<T>()) {
case 0:
return true;
case 1:
return (ReinterpretCast<T, byte>(value) & ReinterpretCast<T, byte>(flag)) != 0;
case 2:
return (ReinterpretCast<T, ushort>(value) & ReinterpretCast<T, ushort>(flag)) != 0;
case 4:
return (ReinterpretCast<T, uint>(value) & ReinterpretCast<T, uint>(flag)) != 0;
case 8:
return (ReinterpretCast<T, ulong>(value) & ReinterpretCast<T, ulong>(flag)) != 0;
default:
return value.HasFlag(flag);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[System.Runtime.CompilerServices.NullableContext(1)]
public static T Cast<T>([System.Runtime.CompilerServices.Nullable(2)] object obj)
{
if (obj == null)
<Cast>g__ThrowInvalidCastException|9_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)]
[System.Runtime.CompilerServices.NullableContext(1)]
[return: System.Runtime.CompilerServices.NativeInteger]
public unsafe static IntPtr AddressOf<[System.Runtime.CompilerServices.Nullable(2)] T>([In] [LifetimeAnnotation(true, false)] [IsReadOnly] ref T value)
{
return (IntPtr)(&value);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[System.Runtime.CompilerServices.NullableContext(1)]
[CLSCompliant(false)]
public static ref T AsRef<[System.Runtime.CompilerServices.Nullable(2)] T>(this TypedReference reference)
{
return ref __refvalue(reference, T);
}
internal unsafe static int CompareUnaligned(ref byte first, ref byte second, [System.Runtime.CompilerServices.NativeInteger] 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)]
[Obsolete("Use Compare overload that accepts the length as unsigned integer")]
public unsafe static int Compare([In] void* first, [In] void* second, [System.Runtime.CompilerServices.NativeInteger] IntPtr length)
{
if ((long)length < 0)
throw new ArgumentOutOfRangeException("length");
return Compare(first, second, (UIntPtr)(void*)(long)length);
}
[CLSCompliant(false)]
public unsafe static int Compare([In] void* first, [In] void* second, [System.Runtime.CompilerServices.NativeInteger] UIntPtr length)
{
return CompareUnaligned(ref Unsafe.AsRef<byte>(first), ref Unsafe.AsRef<byte>(second), length);
}
internal unsafe static bool EqualsUnaligned([LifetimeAnnotation(true, false)] ref byte first, [LifetimeAnnotation(true, false)] ref byte second, [System.Runtime.CompilerServices.NativeInteger] 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;
}
[Obsolete("Use Compare overload that accepts the length as unsigned integer")]
[CLSCompliant(false)]
public unsafe static bool Equals([In] void* first, [In] void* second, [System.Runtime.CompilerServices.NativeInteger] IntPtr length)
{
if ((long)length < 0)
throw new ArgumentOutOfRangeException("length");
return Equals(first, second, (UIntPtr)(void*)(long)length);
}
[CLSCompliant(false)]
public unsafe static bool Equals([In] void* first, [In] void* second, [System.Runtime.CompilerServices.NativeInteger] UIntPtr length)
{
return EqualsUnaligned(ref Unsafe.AsRef<byte>(first), ref Unsafe.AsRef<byte>(second), length);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[System.Runtime.CompilerServices.NullableContext(1)]
[Obsolete("Can be replaced with regular indexer applied to the array and ObjectExtensions.As<T>() method")]
[return: IsReadOnly]
public static ref TBase GetReadonlyRef<T, [System.Runtime.CompilerServices.Nullable(2)] TBase>(this T[] array, [System.Runtime.CompilerServices.NativeInteger] IntPtr index) where T : class, TBase
{
return ref ((TBase[])array)[(long)index];
}
[System.Runtime.CompilerServices.NullableContext(1)]
public static void ThrowIfNull<[System.Runtime.CompilerServices.Nullable(2)] T>([In] [LifetimeAnnotation(true, false)] [IsReadOnly] ref T value)
{
if (Unsafe.IsNullRef(ref Unsafe.AsRef(ref value)))
<ThrowIfNull>g__Throw|20_0<T>();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Copy<T>([In] [LifetimeAnnotation(true, false)] [IsReadOnly] ref T input, out T output) where T : struct
{
output = input;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public unsafe static void CopyUnaligned<[System.Runtime.CompilerServices.IsUnmanaged] T>([In] T* input, [Out] T* output) where T : struct
{
*output = *input;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public unsafe static void Copy<[System.Runtime.CompilerServices.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, [System.Runtime.CompilerServices.NativeInteger] 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);
}
}
[Obsolete("Use Copy overload that accepts the length as unsigned integer")]
public unsafe static void Copy<[System.Runtime.CompilerServices.IsUnmanaged] T>([In] [LifetimeAnnotation(true, false)] [IsReadOnly] ref T source, out T destination, long count) where T : struct
{
if (count < 0)
throw new ArgumentOutOfRangeException("count");
Copy(ref source, out destination, (UIntPtr)(void*)count);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public unsafe static void Copy<[System.Runtime.CompilerServices.IsUnmanaged] T>([In] [LifetimeAnnotation(true, false)] [IsReadOnly] ref T source, out T destination, [System.Runtime.CompilerServices.NativeInteger] UIntPtr count) where T : struct
{
Unsafe.SkipInit(out destination);
Copy(ref Unsafe.As<T, byte>(ref Unsafe.AsRef(ref source)), ref Unsafe.As<T, byte>(ref destination), (UIntPtr)(void*)checked(unchecked((ulong)count) * unchecked((ulong)checked((UIntPtr)(ulong)sizeof(T)))));
}
[System.Runtime.CompilerServices.NullableContext(1)]
public static void Swap<[System.Runtime.CompilerServices.Nullable(2)] T>([LifetimeAnnotation(true, false)] ref T first, [LifetimeAnnotation(true, false)] ref T second)
{
T val = first;
first = second;
second = val;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public unsafe static void Swap<[System.Runtime.CompilerServices.IsUnmanaged] T>(T* first, T* second) where T : struct
{
Swap(ref *first, ref *second);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[System.Runtime.CompilerServices.NullableContext(1)]
public static bool AreSame<[System.Runtime.CompilerServices.Nullable(2)] T>([In] [LifetimeAnnotation(true, false)] [IsReadOnly] ref T first, [In] [LifetimeAnnotation(true, false)] [IsReadOnly] ref T second)
{
return ref first == ref second;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private unsafe static ref byte Advance<[System.Runtime.CompilerServices.IsUnmanaged] T>(ref byte ptr) where T : struct
{
return ref Unsafe.Add(ref ptr, sizeof(T));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private unsafe static ref byte Advance<[System.Runtime.CompilerServices.IsUnmanaged] T>([In] ref byte address, [In] [Out] [System.Runtime.CompilerServices.NativeInteger] UIntPtr* length) where T : struct
{
*length -= (UIntPtr)(void*)sizeof(T);
return ref ref address.Advance<T>();
}
private unsafe static bool IsZero([In] [LifetimeAnnotation(true, false)] ref byte address, [System.Runtime.CompilerServices.NativeInteger] 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;
}
[CLSCompliant(false)]
[Obsolete("Use ClearBits overload that accepts the length as unsigned integer")]
public unsafe static void ClearBits([In] [Out] void* address, [System.Runtime.CompilerServices.NativeInteger] IntPtr length)
{
if ((long)length < 0)
throw new ArgumentOutOfRangeException("length");
ClearBits(address, (UIntPtr)(void*)(long)length);
}
[CLSCompliant(false)]
public unsafe static void ClearBits([In] [Out] void* address, [System.Runtime.CompilerServices.NativeInteger] UIntPtr length)
{
while (length != (UIntPtr)(void*)null) {
int num = ((ulong)length > 2147483647) ? 2147483647 : ((int)(ulong)length);
Unsafe.InitBlockUnaligned(address, 0, (uint)num);
length = (UIntPtr)(void*)((long)(ulong)length - (long)num);
address = Unsafe.Add<byte>(address, num);
}
}
internal unsafe static void GetHashCode64Unaligned<THashFunction>([LifetimeAnnotation(true, false)] ref THashFunction hash, [In] [LifetimeAnnotation(true, false)] ref byte source, [System.Runtime.CompilerServices.NativeInteger] UIntPtr length) where THashFunction : struct, IConsumer<long>
{
ulong num = (ulong)length;
ulong num2 = num;
if (num2 <= 4) {
switch (num2) {
case 0:
return;
case 1:
((IConsumer<long>)hash).Invoke((long)source);
return;
case 2:
((IConsumer<long>)hash).Invoke((long)Unsafe.ReadUnaligned<ushort>(ref source));
return;
case 4:
((IConsumer<long>)hash).Invoke((long)Unsafe.ReadUnaligned<uint>(ref source));
return;
}
}
while ((ulong)length >= 8) {
((IConsumer<long>)hash).Invoke(Unsafe.ReadUnaligned<long>(ref source));
ref source = ref ref source.Advance<long>(&length);
}
while (length != (UIntPtr)(void*)null) {
((IConsumer<long>)hash).Invoke((long)source);
ref source = ref ref source.Advance<byte>(&length);
}
}
internal static long GetHashCode64Unaligned([In] [LifetimeAnnotation(true, false)] ref byte source, [System.Runtime.CompilerServices.NativeInteger] UIntPtr length, bool salted)
{
FNV1a64 hash = new FNV1a64();
GetHashCode64Unaligned(ref hash, ref source, length);
if (salted)
hash.Invoke(RandomExtensions.BitwiseHashSalt);
return hash.Result;
}
private static THashFunction GetHashCode<T, TInput, THashFunction>(Func<T, int, TInput> getter, int count, T arg) where THashFunction : IConsumer<TInput>, new
{
THashFunction result = new THashFunction();
for (int i = 0; i < count; i++) {
((IConsumer<TInput>)result).Invoke(getter(arg, i));
}
return result;
}
[System.Runtime.CompilerServices.NullableContext(1)]
public static long GetHashCode64<[System.Runtime.CompilerServices.Nullable(2)] T>(Func<T, int, long> getter, int count, T arg, bool salted = true)
{
ArgumentNullException.ThrowIfNull((object)getter, "getter");
FNV1a64 hashCode = GetHashCode<T, long, FNV1a64>(getter, count, arg);
if (salted)
hashCode.Invoke(RandomExtensions.BitwiseHashSalt);
return hashCode.Result;
}
[System.Runtime.CompilerServices.NullableContext(1)]
public static int GetHashCode32<[System.Runtime.CompilerServices.Nullable(2)] T>(Func<T, int, int> getter, int count, T arg, bool salted = true)
{
ArgumentNullException.ThrowIfNull((object)getter, "getter");
FNV1a32 hashCode = GetHashCode<T, int, FNV1a32>(getter, count, arg);
if (salted)
hashCode.Invoke(RandomExtensions.BitwiseHashSalt);
return hashCode.Result;
}
[CLSCompliant(false)]
[Obsolete("Use GetHashCode64 overload that accepts the length as unsigned integer")]
public unsafe static long GetHashCode64([In] void* source, [System.Runtime.CompilerServices.NativeInteger] IntPtr length, long hash, [System.Runtime.CompilerServices.Nullable(1)] Func<long, long, long> hashFunction, bool salted = true)
{
if ((long)length < 0)
throw new ArgumentOutOfRangeException("length");
return GetHashCode64(source, (UIntPtr)(void*)(long)length, hash, hashFunction, salted);
}
[CLSCompliant(false)]
public unsafe static long GetHashCode64([In] void* source, [System.Runtime.CompilerServices.NativeInteger] UIntPtr length, long hash, [System.Runtime.CompilerServices.Nullable(1)] Func<long, long, long> hashFunction, bool salted = true)
{
Accumulator<long, long> hash2 = new Accumulator<long, long>(hashFunction, hash);
GetHashCode64Unaligned(ref hash2, ref *(byte*)source, length);
if (salted)
hash2.Invoke(RandomExtensions.BitwiseHashSalt);
return hash2.Invoke();
}
[CLSCompliant(false)]
[Obsolete("Use GetHashCode64 overload that accepts the length as unsigned integer")]
public unsafe static long GetHashCode64<THashFunction>([In] void* source, [System.Runtime.CompilerServices.NativeInteger] IntPtr length, bool salted = true) where THashFunction : struct, IConsumer<long>, ISupplier<long>
{
if ((long)length < 0)
throw new ArgumentOutOfRangeException("length");
return GetHashCode64<THashFunction>(source, (UIntPtr)(void*)(long)length, salted);
}
[CLSCompliant(false)]
public unsafe static long GetHashCode64<THashFunction>([In] void* source, [System.Runtime.CompilerServices.NativeInteger] UIntPtr length, bool salted = true) where THashFunction : struct, IConsumer<long>, ISupplier<long>
{
THashFunction hash = new THashFunction();
GetHashCode64Unaligned(ref hash, ref *(byte*)source, length);
if (salted)
((IConsumer<long>)hash).Invoke((long)RandomExtensions.BitwiseHashSalt);
return ((ISupplier<long>)hash).Invoke();
}
[CLSCompliant(false)]
[Obsolete("Use GetHashCode64 overload that accepts the length as unsigned integer")]
public unsafe static long GetHashCode64([In] void* source, [System.Runtime.CompilerServices.NativeInteger] IntPtr length, bool salted = true)
{
if ((long)length < 0)
throw new ArgumentOutOfRangeException("length");
return GetHashCode64Unaligned(ref *(byte*)source, (UIntPtr)(void*)(long)length, salted);
}
[CLSCompliant(false)]
public unsafe static long GetHashCode64([In] void* source, [System.Runtime.CompilerServices.NativeInteger] UIntPtr length, bool salted = true)
{
return GetHashCode64Unaligned(ref *(byte*)source, length, salted);
}
[CLSCompliant(false)]
[Obsolete("Use GetHashCode32 overload that accepts the length as unsigned integer")]
public unsafe static int GetHashCode32([In] void* source, [System.Runtime.CompilerServices.NativeInteger] IntPtr length, int hash, [System.Runtime.CompilerServices.Nullable(1)] Func<int, int, int> hashFunction, bool salted = true)
{
if ((long)length < 0)
throw new ArgumentOutOfRangeException("length");
return GetHashCode32(source, (UIntPtr)(void*)(long)length, hash, hashFunction, salted);
}
[CLSCompliant(false)]
public unsafe static int GetHashCode32([In] void* source, [System.Runtime.CompilerServices.NativeInteger] UIntPtr length, int hash, [System.Runtime.CompilerServices.Nullable(1)] Func<int, int, int> hashFunction, bool salted = true)
{
Accumulator<int, int> hash2 = new Accumulator<int, int>(hashFunction, hash);
GetHashCode32Unaligned(ref hash2, ref *(byte*)source, length);
if (salted)
hash2.Invoke(RandomExtensions.BitwiseHashSalt);
return hash2.Invoke();
}
internal unsafe static void GetHashCode32Unaligned<THashFunction>([LifetimeAnnotation(true, false)] ref THashFunction hash, [In] [LifetimeAnnotation(true, false)] ref byte source, [System.Runtime.CompilerServices.NativeInteger] UIntPtr length) where THashFunction : struct, IConsumer<int>
{
ulong num = (ulong)length;
ulong num2 = num;
if (num2 <= 2) {
switch (num2) {
case 0:
return;
case 1:
((IConsumer<int>)hash).Invoke((int)source);
return;
case 2:
((IConsumer<int>)hash).Invoke((int)Unsafe.ReadUnaligned<ushort>(ref source));
return;
}
}
while ((ulong)length >= 4) {
((IConsumer<int>)hash).Invoke(Unsafe.ReadUnaligned<int>(ref source));
ref source = ref ref source.Advance<int>(&length);
}
while (length != (UIntPtr)(void*)null) {
((IConsumer<int>)hash).Invoke((int)source);
ref source = ref ref source.Advance<byte>(&length);
}
}
internal static int GetHashCode32Unaligned([In] [LifetimeAnnotation(true, false)] ref byte source, [System.Runtime.CompilerServices.NativeInteger] UIntPtr length, bool salted)
{
FNV1a32 hash = new FNV1a32();
GetHashCode32Unaligned(ref hash, ref source, length);
if (salted)
hash.Invoke(RandomExtensions.BitwiseHashSalt);
return hash.Result;
}
[CLSCompliant(false)]
[Obsolete("Use GetHashCode32 overload that accepts the length as unsigned integer")]
public unsafe static int GetHashCode32<THashFunction>([In] void* source, [System.Runtime.CompilerServices.NativeInteger] IntPtr length, bool salted = true) where THashFunction : struct, IConsumer<int>, ISupplier<int>
{
if ((long)length < 0)
throw new ArgumentOutOfRangeException("length");
return GetHashCode32<THashFunction>(source, (UIntPtr)(void*)(long)length, salted);
}
[CLSCompliant(false)]
public unsafe static int GetHashCode32<THashFunction>([In] void* source, [System.Runtime.CompilerServices.NativeInteger] UIntPtr length, bool salted = true) where THashFunction : struct, IConsumer<int>, ISupplier<int>
{
THashFunction hash = new THashFunction();
GetHashCode32Unaligned(ref hash, ref *(byte*)source, length);
if (salted)
((IConsumer<int>)hash).Invoke(RandomExtensions.BitwiseHashSalt);
return ((ISupplier<int>)hash).Invoke();
}
[CLSCompliant(false)]
[Obsolete("Use GetHashCode32 overload that accepts the length as unsigned integer")]
public unsafe static int GetHashCode32([In] void* source, [System.Runtime.CompilerServices.NativeInteger] IntPtr length, bool salted = true)
{
if ((long)length < 0)
throw new ArgumentOutOfRangeException("length");
return GetHashCode32(source, (UIntPtr)(void*)(long)length, salted);
}
[CLSCompliant(false)]
public unsafe static int GetHashCode32([In] void* source, [System.Runtime.CompilerServices.NativeInteger] UIntPtr length, bool salted = true)
{
return GetHashCode32Unaligned(ref *(byte*)source, length, salted);
}
public static void Reverse<[System.Runtime.CompilerServices.IsUnmanaged] T>([LifetimeAnnotation(true, false)] ref T value) where T : struct
{
Span.AsBytes(ref value).Reverse();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[System.Runtime.CompilerServices.NullableContext(2)]
public static bool IsExactTypeOf<T>(object obj)
{
return obj?.GetType() == typeof(T);
}
[System.Runtime.CompilerServices.NullableContext(1)]
[DoesNotReturn]
[StackTraceHidden]
public static void Throw(object obj)
{
throw obj;
}
[System.Runtime.CompilerServices.NullableContext(1)]
[DoesNotReturn]
[StackTraceHidden]
public static Exception Error(object obj)
{
throw obj;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[System.Runtime.CompilerServices.NullableContext(1)]
public static T ShallowCopy<T>(T obj) where T : class
{
return (T)((object)obj).MemberwiseClone();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[System.Runtime.CompilerServices.NullableContext(1)]
[return: System.Runtime.CompilerServices.NativeInteger]
public unsafe static IntPtr GetLength(Array array)
{
return (IntPtr)(void*)array.LongLength;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static TOutput ReinterpretCast<TInput, TOutput>(TInput input)
{
return Unsafe.As<TInput, TOutput>(ref input);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static Span<TOutput> ReinterpretCast<[System.Runtime.CompilerServices.IsUnmanaged] TInput, [System.Runtime.CompilerServices.IsUnmanaged] TOutput>(Span<TInput> input) where TInput : struct where TOutput : struct
{
return MemoryMarshal.CreateSpan(ref Unsafe.As<TInput, TOutput>(ref MemoryMarshal.GetReference(input)), input.Length);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[System.Runtime.CompilerServices.NullableContext(1)]
public static void Finalize(object obj)
{
obj.Finalize();
}
[System.Runtime.CompilerServices.NullableContext(1)]
public unsafe static bool HasFinalizer(object obj)
{
return (IntPtr)(void*) != (IntPtr)(void*);
}
}
}