Skip to content

Instantly share code, notes, and snippets.

@lucasteles
Created February 1, 2024 14:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lucasteles/cf5d86b1dd7e0641f218356c1dcac22e to your computer and use it in GitHub Desktop.
Save lucasteles/cf5d86b1dd7e0641f218356c1dcac22e to your computer and use it in GitHub Desktop.
Disposable memory buffer
readonly struct MemoryBuffer<T> : IDisposable
{
readonly bool clearArray;
readonly T[] array;
public int Length { get; }
public Memory<T> Memory { get; }
internal MemoryBuffer(int size, bool clearArray = false)
{
var buffer =
size is 0
? Array.Empty<T>()
: ArrayPool<T>.Shared.Rent(size);
array = buffer;
Memory = buffer;
Length = size;
this.clearArray = clearArray;
}
public Span<T> Span => Memory.Span;
public ref T this[int index] => ref Span[index];
public Span<T> this[Range range] => Span[range];
public void Dispose()
{
if (array?.Length > 0)
ArrayPool<T>.Shared.Return(array, clearArray);
}
public static implicit operator Span<T>(MemoryBuffer<T> @this) => @this.Span;
public static implicit operator ReadOnlySpan<T>(MemoryBuffer<T> @this) => @this.Span;
}
static class MemoryBuffer
{
const int MaximumBufferSize = int.MaxValue;
public static MemoryBuffer<T> Empty<T>() => new(0);
public static MemoryBuffer<T> Rent<T>(int size = -1, bool clearArray = false)
{
if (size == -1)
size = 1 + 4095 / Unsafe.SizeOf<T>();
else if ((uint)size > MaximumBufferSize)
throw new ArgumentOutOfRangeException(nameof(size));
return new(size, clearArray);
}
public static MemoryBuffer<byte> Rent(int size, bool clearArray = false) =>
Rent<byte>(size, clearArray);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment