[MethodImpl(MethodImplOptions.AggressiveInlining)] // forced to ensure no perf drop for small memory buffers (hot path) public static T[] AllocateUninitializedArray <T>(int length, bool pinned = false) // T[] rather than T?[] to match `new T[length]` behavior { if (!pinned) { if (RuntimeHelpers.IsReferenceOrContainsReferences <T>()) { return(new T[length]); } // for debug builds we always want to call AllocateNewArray to detect AllocateNewArray bugs #if !DEBUG // small arrays are allocated using `new[]` as that is generally faster. if (length < 2048 / Unsafe.SizeOf <T>()) { return(new T[length]); } #endif } else if (RuntimeHelpers.IsReferenceOrContainsReferences <T>()) { ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T)); } // kept outside of the small arrays hot path to have inlining without big size growth return(AllocateNewUninitializedArray(length, pinned));
public unsafe ReadOnlySpan(void* pointer, int length) { if (RuntimeHelpers.IsReferenceOrContainsReferences<T>()) ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T)); if (length < 0) ThrowHelper.ThrowArgumentOutOfRangeException(); _pointer = new ByReference<T>(ref Unsafe.As<byte, T>(ref *(byte*)pointer)); _length = length; }
/// <summary> /// Casts a ReadOnlySpan of one primitive type <typeparamref name="T"/> to ReadOnlySpan of bytes. /// That type may not contain pointers or references. This is checked at runtime in order to preserve type safety. /// </summary> /// <param name="source">The source slice, of type <typeparamref name="T"/>.</param> /// <exception cref="System.ArgumentException"> /// Thrown when <typeparamref name="T"/> contains pointers. /// </exception> public static ReadOnlySpan <byte> AsBytes <T>(this ReadOnlySpan <T> source) where T : struct { if (JitHelpers.ContainsReferences <T>()) { ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T)); } return(new ReadOnlySpan <byte>( ref Unsafe.As <T, byte>(ref source.GetRawPointer()), checked (source.Length * Unsafe.SizeOf <T>()))); }
public static ReadOnlySpan <byte> AsBytes <T>(this ReadOnlySpan <T> source) where T : struct { if (RuntimeHelpers.IsReferenceOrContainsReferences <T>()) { ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T)); } return(new ReadOnlySpan <byte>( ref Unsafe.As <T, byte>(ref source.DangerousGetPinnableReference()), checked (source.Length * Unsafe.SizeOf <T>()))); }
public static Span <byte> AsBytes <T>(this Span <T> source) where T : struct { if (RuntimeHelpers.IsReferenceOrContainsReferences <T>()) { ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T)); } return(new Span <byte>( ref Unsafe.As <T, byte>(ref MemoryMarshal.GetReference(source)), checked (source.Length * Unsafe.SizeOf <T>()))); }
public static T[] AllocateArray <T>(int length, bool pinned = false) { if (pinned) { if (RuntimeHelpers.IsReferenceOrContainsReferences <T>()) { ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T)); } return(Unsafe.As <T[]>(AllocPinnedArray(typeof(T[]), length))); } return(new T[length]); }
public unsafe Span(void *pointer, int length) { if (JitHelpers.ContainsReferences <T>()) { ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T)); } if (length < 0) { ThrowHelper.ThrowArgumentOutOfRangeException(); } _pointer = new ByReference <T>(ref Unsafe.As <byte, T>(ref *(byte *)pointer)); _length = length; }
public unsafe Span(void *pointer, int length) { if (JitHelpers.ContainsReferences <T>()) { ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(T)); } if (length < 0) { ThrowHelper.ThrowArgumentOutOfRangeException(); } _rawPointer = (IntPtr)pointer; _length = length; }
/// <summary> /// Casts a ReadOnlySpan of one primitive type <typeparamref name="TFrom"/> to another primitive type <typeparamref name="TTo"/>. /// These types may not contain pointers or references. This is checked at runtime in order to preserve type safety. /// </summary> /// <remarks> /// Supported only for platforms that support misaligned memory access. /// </remarks> /// <param name="source">The source slice, of type <typeparamref name="TFrom"/>.</param> /// <exception cref="System.ArgumentException"> /// Thrown when <typeparamref name="TFrom"/> or <typeparamref name="TTo"/> contains pointers. /// </exception> public static unsafe ReadOnlySpan <TTo> NonPortableCast <TFrom, TTo>(this ReadOnlySpan <TFrom> source) where TFrom : struct where TTo : struct { if (JitHelpers.ContainsReferences <TFrom>()) { ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(TFrom)); } if (JitHelpers.ContainsReferences <TTo>()) { ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(TTo)); } return(new ReadOnlySpan <TTo>( ref Unsafe.As <TFrom, TTo>(ref source.GetRawPointer()), checked ((int)((long)source.Length * Unsafe.SizeOf <TFrom>() / Unsafe.SizeOf <TTo>())))); }
public static Span <TTo> NonPortableCast <TFrom, TTo>(this Span <TFrom> source) where TFrom : struct where TTo : struct { if (RuntimeHelpers.IsReferenceOrContainsReferences <TFrom>()) { ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(TFrom)); } if (RuntimeHelpers.IsReferenceOrContainsReferences <TTo>()) { ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(TTo)); } return(new Span <TTo>( ref Unsafe.As <TFrom, TTo>(ref source.DangerousGetPinnableReference()), checked ((int)((long)source.Length * Unsafe.SizeOf <TFrom>() / Unsafe.SizeOf <TTo>())))); }