Remove MemoryManager.Length (#17498)
authorBen Adams <thundercat@illyriad.co.uk>
Wed, 11 Apr 2018 20:48:52 +0000 (21:48 +0100)
committerAhson Khan <ahkha@microsoft.com>
Wed, 11 Apr 2018 20:48:52 +0000 (13:48 -0700)
* Remove MemoryManager.Length

* Feedback

* XML comment nits

src/mscorlib/shared/System/Buffers/MemoryManager.cs
src/mscorlib/shared/System/Memory.cs

index cc47e02..acba3d2 100644 (file)
@@ -8,19 +8,14 @@ using System.Runtime.CompilerServices;
 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.
@@ -29,8 +24,8 @@ namespace System.Buffers
 
         /// <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>
@@ -39,6 +34,21 @@ namespace System.Buffers
         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>
index c3affff..a500ec5 100644 (file)
@@ -115,27 +115,50 @@ namespace System
 
         /// <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 (&lt;0 or &gt;=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;
         }