MemoryRental<T>
Represents the memory obtained from the pool or allocated
on the stack or heap.
using System;
using System.Buffers;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace DotNext.Buffers
{
[StructLayout(LayoutKind.Auto)]
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
public ref struct MemoryRental<[System.Runtime.CompilerServices.Nullable(2)] T>
{
private readonly object owner;
private readonly Span<T> memory;
[EditorBrowsable(EditorBrowsableState.Never)]
[CLSCompliant(false)]
public static int StackallocThreshold { get; } = 1 + LibrarySettings.StackallocThreshold / Unsafe.SizeOf<T>();
[System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
public Span<T> Span {
[IsReadOnly]
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
get {
return memory;
}
}
public bool IsEmpty {
[IsReadOnly]
get {
return memory.IsEmpty;
}
}
public int Length {
[IsReadOnly]
get {
return memory.Length;
}
}
public ref T this[int index] {
[IsReadOnly]
get {
return ref memory[index];
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public MemoryRental([System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] Span<T> span)
{
memory = span;
owner = null;
}
public MemoryRental([System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] Span<T> span, int length)
{
this = new MemoryRental<T>(span.Slice(0, length));
}
public MemoryRental(MemoryPool<T> pool, int minBufferSize, bool exactSize = true)
{
ArgumentNullException.ThrowIfNull((object)pool, "pool");
if (minBufferSize <= 0)
throw new ArgumentOutOfRangeException("minBufferSize");
IMemoryOwner<T> memoryOwner = pool.Rent(minBufferSize);
memory = memoryOwner.Memory.Span;
if (exactSize)
memory = memory.Slice(0, minBufferSize);
owner = memoryOwner;
}
public MemoryRental(MemoryPool<T> pool)
{
ArgumentNullException.ThrowIfNull((object)pool, "pool");
IMemoryOwner<T> memoryOwner = pool.Rent(-1);
memory = memoryOwner.Memory.Span;
owner = memoryOwner;
}
public MemoryRental(int minBufferSize, bool exactSize = true)
{
T[] array = ArrayPool<T>.Shared.Rent(minBufferSize);
memory = (exactSize ? new Span<T>(array, 0, minBufferSize) : new Span<T>(array));
owner = array;
}
public static implicit operator MemoryRental<T>([System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] Span<T> span)
{
return new MemoryRental<T>(span);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[IsReadOnly]
[EditorBrowsable(EditorBrowsableState.Never)]
public ref T GetPinnableReference()
{
return ref memory.GetPinnableReference();
}
[IsReadOnly]
public override string ToString()
{
return memory.ToString();
}
public void Dispose()
{
object obj = owner;
IDisposable disposable = obj as IDisposable;
if (disposable == null) {
T[] array = obj as T[];
if (array != null)
ArrayPool<T>.Shared.Return(array, RuntimeHelpers.IsReferenceOrContainsReferences<T>());
} else
disposable.Dispose();
this = default(MemoryRental<T>);
}
}
}