From 93922f3cef3b19657058f7f8e6ce06fad076d4d2 Mon Sep 17 00:00:00 2001 From: Tarek Mahmoud Sayed Date: Fri, 2 Feb 2018 11:40:39 -0800 Subject: [PATCH] Span factoring (dotnet/corefx#26667) Commit migrated from https://github.com/dotnet/corefx/commit/a68803c848df70ae900f53e602424ba71a4760b1 --- .../System.Memory/src/Resources/Strings.resx | 4 +- .../System.Memory/src/System.Memory.csproj | 6 +- .../{ReadOnlySpan.cs => ReadOnlySpan.Portable.cs} | 115 +-------------------- .../src/System/{Span.cs => Span.Portable.cs} | 106 +------------------ 4 files changed, 10 insertions(+), 221 deletions(-) rename src/libraries/System.Memory/src/System/{ReadOnlySpan.cs => ReadOnlySpan.Portable.cs} (73%) rename src/libraries/System.Memory/src/System/{Span.cs => Span.Portable.cs} (81%) diff --git a/src/libraries/System.Memory/src/Resources/Strings.resx b/src/libraries/System.Memory/src/Resources/Strings.resx index 219d3c9..802f755 100644 --- a/src/libraries/System.Memory/src/Resources/Strings.resx +++ b/src/libraries/System.Memory/src/Resources/Strings.resx @@ -117,10 +117,10 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - + Equals() on Span and ReadOnlySpan is not supported. Use operator== instead. - + GetHashCode() on Span and ReadOnlySpan is not supported. diff --git a/src/libraries/System.Memory/src/System.Memory.csproj b/src/libraries/System.Memory/src/System.Memory.csproj index 7150e7f..26dd461 100644 --- a/src/libraries/System.Memory/src/System.Memory.csproj +++ b/src/libraries/System.Memory/src/System.Memory.csproj @@ -106,13 +106,15 @@ + + - - + + diff --git a/src/libraries/System.Memory/src/System/ReadOnlySpan.cs b/src/libraries/System.Memory/src/System/ReadOnlySpan.Portable.cs similarity index 73% rename from src/libraries/System.Memory/src/System/ReadOnlySpan.cs rename to src/libraries/System.Memory/src/System/ReadOnlySpan.Portable.cs index 9bb869e..a1025f3 100644 --- a/src/libraries/System.Memory/src/System/ReadOnlySpan.cs +++ b/src/libraries/System.Memory/src/System/ReadOnlySpan.Portable.cs @@ -17,7 +17,7 @@ namespace System /// [DebuggerTypeProxy(typeof(SpanDebugView<>))] [DebuggerDisplay("{DebuggerDisplay,nq}")] - public readonly ref struct ReadOnlySpan + public readonly ref partial struct ReadOnlySpan { /// /// Creates a new read-only span over the entirety of the target array. @@ -106,16 +106,6 @@ namespace System private string DebuggerDisplay => string.Format("System.ReadOnlySpan<{0}>[{1}]", typeof(T).Name, Length); /// - /// The number of items in the read-only span. - /// - public int Length => _length; - - /// - /// Returns true if Length is 0. - /// - public bool IsEmpty => _length == 0; - - /// /// Returns the specified element of the read-only span. /// /// @@ -190,55 +180,12 @@ namespace System } /// - /// Returns false if left and right point at the same memory and have the same length. Note that - /// this does *not* check to see if the *contents* are equal. - /// - public static bool operator !=(ReadOnlySpan left, ReadOnlySpan right) => !(left == right); - - /// - /// This method is not supported as spans cannot be boxed. To compare two spans, use operator==. - /// - /// Always thrown by this method. - /// - /// - [Obsolete("Equals() on ReadOnlySpan will always throw an exception. Use == instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public override bool Equals(object obj) - { - throw new NotSupportedException(SR.CannotCallEqualsOnSpan); - } - - /// - /// This method is not supported as spans cannot be boxed. - /// - /// Always thrown by this method. - /// - /// - [Obsolete("GetHashCode() on ReadOnlySpan will always throw an exception.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public override int GetHashCode() - { - throw new NotSupportedException(SR.CannotCallGetHashCodeOnSpan); - } - - /// /// Returns a with the name of the type and the number of elements /// /// A with the name of the type and the number of elements public override string ToString() => string.Format("System.ReadOnlySpan<{0}>[{1}]", typeof(T).Name, _length); /// - /// Defines an implicit conversion of an array to a - /// - public static implicit operator ReadOnlySpan(T[] array) => array != null ? new ReadOnlySpan(array) : default; - - /// - /// Defines an implicit conversion of a to a - /// - public static implicit operator ReadOnlySpan(ArraySegment arraySegment) - => arraySegment.Array != null ? new ReadOnlySpan(arraySegment.Array, arraySegment.Offset, arraySegment.Count) : default; - - /// /// Forms a slice out of the given read-only span, beginning at 'start'. /// /// The index at which to begin this slice. @@ -290,11 +237,6 @@ namespace System } /// - /// Returns a 0-length read-only span whose base is the null pointer. - /// - public static ReadOnlySpan Empty => default(ReadOnlySpan); - - /// /// This method is obsolete, use System.Runtime.InteropServices.MemoryMarshal.GetReference instead. /// Returns a reference to the 0th element of the Span. If the Span is empty, returns a reference to the location where the 0th element /// would have been stored. Such a reference can be used for pinning but must never be dereferenced. @@ -309,61 +251,6 @@ namespace System return ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset); } - /// Gets an enumerator for this span. - public Enumerator GetEnumerator() => new Enumerator(this); - - /// Enumerates the elements of a . - public ref struct Enumerator - { - /// The span being enumerated. - private readonly ReadOnlySpan _span; - /// The next index to yield. - private int _index; - - /// Initialize the enumerator. - /// The span to enumerate. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal Enumerator(ReadOnlySpan span) - { - _span = span; - _index = -1; - } - - /// Advances the enumerator to the next element of the span. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool MoveNext() - { - int index = _index + 1; - if (index < _span.Length) - { - _index = index; - return true; - } - - return false; - } - - /// Gets the element at the current position of the enumerator. - public ref readonly T Current - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get - { - // TODO https://github.com/dotnet/corefx/issues/24105: - // Change this to simply be: - // get => ref _span[_index]; - // once ReadOnlySpan's indexer returns ref readonly. - - if ((uint)_index >= (uint)_span.Length) - { - ThrowHelper.ThrowIndexOutOfRangeException(); - } - - return ref Unsafe.Add(ref _span.DangerousGetPinnableReference(), _index); - } - } - } - // These expose the internal representation for Span-related apis use only. internal Pinnable Pinnable => _pinnable; internal IntPtr ByteOffset => _byteOffset; diff --git a/src/libraries/System.Memory/src/System/Span.cs b/src/libraries/System.Memory/src/System/Span.Portable.cs similarity index 81% rename from src/libraries/System.Memory/src/System/Span.cs rename to src/libraries/System.Memory/src/System/Span.Portable.cs index 471c530..39162b0 100644 --- a/src/libraries/System.Memory/src/System/Span.cs +++ b/src/libraries/System.Memory/src/System/Span.Portable.cs @@ -17,7 +17,7 @@ namespace System /// [DebuggerTypeProxy(typeof(SpanDebugView<>))] [DebuggerDisplay("{DebuggerDisplay,nq}")] - public readonly ref struct Span + public readonly ref partial struct Span { /// /// Creates a new span over the entirety of the target array. @@ -110,16 +110,6 @@ namespace System private string DebuggerDisplay => string.Format("System.Span<{0}>[{1}]", typeof(T).Name, _length); /// - /// The number of items in the span. - /// - public int Length => _length; - - /// - /// Returns true if Length is 0. - /// - public bool IsEmpty => _length == 0; - - /// /// Returns a reference to specified element of the Span. /// /// @@ -297,36 +287,9 @@ namespace System } /// - /// Returns false if left and right point at the same memory and have the same length. Note that - /// this does *not* check to see if the *contents* are equal. - /// - public static bool operator !=(Span left, Span right) => !(left == right); - - /// - /// This method is not supported as spans cannot be boxed. To compare two spans, use operator==. - /// - /// Always thrown by this method. - /// - /// - [Obsolete("Equals() on Span will always throw an exception. Use == instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public override bool Equals(object obj) - { - throw new NotSupportedException(SR.CannotCallEqualsOnSpan); - } - - /// - /// This method is not supported as spans cannot be boxed. - /// - /// Always thrown by this method. - /// + /// Defines an implicit conversion of a to a /// - [Obsolete("GetHashCode() on Span will always throw an exception.")] - [EditorBrowsable(EditorBrowsableState.Never)] - public override int GetHashCode() - { - throw new NotSupportedException(SR.CannotCallGetHashCodeOnSpan); - } + public static implicit operator ReadOnlySpan(Span span) => new ReadOnlySpan(span._pinnable, span._byteOffset, span._length); /// /// Returns a with the name of the type and the number of elements @@ -335,22 +298,6 @@ namespace System public override string ToString() => string.Format("System.Span<{0}>[{1}]", typeof(T).Name, Length); /// - /// Defines an implicit conversion of an array to a - /// - public static implicit operator Span(T[] array) => array != null ? new Span(array) : default; - - /// - /// Defines an implicit conversion of a to a - /// - public static implicit operator Span(ArraySegment arraySegment) - => arraySegment.Array != null ? new Span(arraySegment.Array, arraySegment.Offset, arraySegment.Count) : default; - - /// - /// Defines an implicit conversion of a to a - /// - public static implicit operator ReadOnlySpan(Span span) => new ReadOnlySpan(span._pinnable, span._byteOffset, span._length); - - /// /// Forms a slice out of the given span, beginning at 'start'. /// /// The index at which to begin this slice. @@ -402,11 +349,6 @@ namespace System } /// - /// Returns a 0-length span whose base is the null pointer. - /// - public static Span Empty => default(Span); - - /// /// This method is obsolete, use System.Runtime.InteropServices.MemoryMarshal.GetReference instead. /// Returns a reference to the 0th element of the Span. If the Span is empty, returns a reference to the location where the 0th element /// would have been stored. Such a reference can be used for pinning but must never be dereferenced. @@ -421,48 +363,6 @@ namespace System return ref Unsafe.AddByteOffset(ref _pinnable.Data, _byteOffset); } - /// Gets an enumerator for this span. - public Enumerator GetEnumerator() => new Enumerator(this); - - /// Enumerates the elements of a . - public ref struct Enumerator - { - /// The span being enumerated. - private readonly Span _span; - /// The next index to yield. - private int _index; - - /// Initialize the enumerator. - /// The span to enumerate. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal Enumerator(Span span) - { - _span = span; - _index = -1; - } - - /// Advances the enumerator to the next element of the span. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool MoveNext() - { - int index = _index + 1; - if (index < _span.Length) - { - _index = index; - return true; - } - - return false; - } - - /// Gets the element at the current position of the enumerator. - public ref T Current - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => ref _span[_index]; - } - } - // These expose the internal representation for Span-related apis use only. internal Pinnable Pinnable => _pinnable; internal IntPtr ByteOffset => _byteOffset; -- 2.7.4