/// <summary> /// Initializes a new instance of the <see cref="Span2D{T}"/> struct with the specified parameters. /// </summary> /// <param name="pointer">The pointer to the first <typeparamref name="T"/> item to map.</param> /// <param name="height">The height of the 2D memory area to map.</param> /// <param name="width">The width of the 2D memory area to map.</param> /// <param name="pitch">The pitch of the 2D memory area to map (the distance between each row).</param> /// <exception cref="ArgumentOutOfRangeException">Thrown when one of the parameters are negative.</exception> public unsafe Span2D(void *pointer, int height, int width, int pitch) { if (RuntimeHelpers.IsReferenceOrContainsReferences <T>()) { ThrowHelper.ThrowArgumentExceptionForManagedType(); } if (width < 0) { ThrowHelper.ThrowArgumentOutOfRangeExceptionForWidth(); } if (height < 0) { ThrowHelper.ThrowArgumentOutOfRangeExceptionForHeight(); } if (pitch < 0) { ThrowHelper.ThrowArgumentOutOfRangeExceptionForPitch(); } OverflowHelper.EnsureIsInNativeIntRange(height, width, pitch); #if SPAN_RUNTIME_SUPPORT this.span = new Span <T>(pointer, height); #else this.Instance = null; this.Offset = (IntPtr)pointer; this.height = height; #endif this.width = width; this.Stride = width + pitch; }
/// <inheritdoc/> public Memory <T> GetMemory <T>(int offset, int length) where T : unmanaged { // Like in the other memory manager, calculate the absolute offset and length int absoluteOffset = this.offset + RuntimeHelpers.ConvertLength <TTo, TFrom>(offset), absoluteLength = RuntimeHelpers.ConvertLength <TTo, TFrom>(length); // Skip one indirection level and slice the original memory manager, if possible if (typeof(T) == typeof(TFrom)) { return((Memory <T>)(object) this.memoryManager.Memory.Slice(absoluteOffset, absoluteLength)); } return(new ProxyMemoryManager <TFrom, T>(this.memoryManager, absoluteOffset, absoluteLength).Memory); }