namespace System.Buffers
{
/// <summary>
- /// Manager of Memory<typeparamref name="T"/> that provides the implementation.
+ /// Manager of <see cref="System.Memory{T}"/> that provides the implementation.
/// </summary>
public abstract class MemoryManager<T> : IMemoryOwner<T>, IPinnable
{
/// <summary>
- /// The number of items in the Memory<typeparamref name="T"/>.
+ /// Returns a <see cref="System.Memory{T}"/>.
/// </summary>
- public virtual int Length => GetSpan().Length;
-
- /// <summary>
- /// Returns a Memory<typeparamref name="T"/>.
- /// </summary>
- public virtual Memory<T> Memory => new Memory<T>(this, 0, Length);
+ public virtual Memory<T> Memory => new Memory<T>(this, GetSpan().Length);
/// <summary>
/// Returns a span wrapping the underlying memory.
/// <summary>
/// Returns a handle to the memory that has been pinned and hence its address can be taken.
- /// <param name="elementIndex">The offset to the element within the memory at which the returned <see cref="MemoryHandle"/> points to. (default = 0)</param>
/// </summary>
+ /// <param name="elementIndex">The offset to the element within the memory at which the returned <see cref="MemoryHandle"/> points to. (default = 0)</param>
public abstract MemoryHandle Pin(int elementIndex = 0);
/// <summary>
public abstract void Unpin();
/// <summary>
+ /// Returns a <see cref="System.Memory{T}"/> for the current <see cref="MemoryManager{T}"/>.
+ /// </summary>
+ /// <param name="length">The element count in the memory, starting at offset 0.</param>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ protected Memory<T> CreateMemory(int length) => new Memory<T>(this, length);
+
+ /// <summary>
+ /// Returns a <see cref="System.Memory{T}"/> for the current <see cref="MemoryManager{T}"/>.
+ /// </summary>
+ /// <param name="start">The offset to the element which the returned memory starts at.</param>
+ /// <param name="length">The element count in the memory, starting at element offset <paramref name="start"/>.</param>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ protected Memory<T> CreateMemory(int start, int length) => new Memory<T>(this, start, length);
+
+ /// <summary>
/// Returns an array segment.
/// <remarks>Returns the default array segment if not overriden.</remarks>
/// </summary>
/// <summary>
/// Creates a new memory from a memory manager that provides specific method implementations beginning
+ /// at 0 index and ending at 'end' index (exclusive).
+ /// </summary>
+ /// <param name="manager">The memory manager.</param>
+ /// <param name="length">The number of items in the memory.</param>
+ /// <exception cref="System.ArgumentOutOfRangeException">
+ /// Thrown when the specified <paramref name="length"/> is negative.
+ /// </exception>
+ /// <remarks>For internal infrastructure only</remarks>
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal Memory(MemoryManager<T> manager, int length)
+ {
+ Debug.Assert(manager != null);
+
+ if (length < 0)
+ ThrowHelper.ThrowArgumentOutOfRangeException();
+
+ _object = manager;
+ _index = (1 << 31); // Mark as MemoryManager type
+ // Before using _index, check if _index < 0, then 'and' it with RemoveFlagsBitMask
+ _length = length;
+ }
+
+ /// <summary>
+ /// Creates a new memory from a memory manager that provides specific method implementations beginning
/// at 'start' index and ending at 'end' index (exclusive).
/// </summary>
/// <param name="manager">The memory manager.</param>
/// <param name="start">The index at which to begin the memory.</param>
/// <param name="length">The number of items in the memory.</param>
- /// <exception cref="System.ArgumentNullException">
- /// Thrown when <paramref name="manager"/> is null.
- /// </exception>
/// <exception cref="System.ArgumentOutOfRangeException">
- /// Thrown when the specified <paramref name="start"/> or end index is not in the range (<0 or >=Length).
+ /// Thrown when the specified <paramref name="start"/> or <paramref name="length"/> is negative.
/// </exception>
+ /// <remarks>For internal infrastructure only</remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Memory(MemoryManager<T> manager, int start, int length)
+ internal Memory(MemoryManager<T> manager, int start, int length)
{
- if (manager == null)
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.manager);
- if ((uint)start > (uint)manager.Length || (uint)length > (uint)(manager.Length - start))
+ Debug.Assert(manager != null);
+
+ if (length < 0 || start < 0)
ThrowHelper.ThrowArgumentOutOfRangeException();
_object = manager;
- _index = start | (1 << 31); // Before using _index, check if _index < 0, then 'and' it with RemoveFlagsBitMask
+ _index = start | (1 << 31); // Mark as MemoryManager type
+ // Before using _index, check if _index < 0, then 'and' it with RemoveFlagsBitMask
_length = length;
}