@@ -28,7 +28,17 @@ namespace CommunityToolkit.HighPerformance;
2828[ DebuggerDisplay ( "{ToString(),raw}" ) ]
2929public readonly ref partial struct ReadOnlySpan2D< T >
3030{
31- #if NETSTANDARD2_1_OR_GREATER
31+ #if NET7_0_OR_GREATER
32+ /// <summary>
33+ /// The <typeparamref name="T"/> reference for the <see cref="ReadOnlySpan2D{T}"/> instance.
34+ /// </summary>
35+ private readonly ref readonly T reference ;
36+
37+ /// <summary>
38+ /// The height of the specified 2D region.
39+ /// </summary>
40+ private readonly int height ;
41+ #elif NETSTANDARD2_1_OR_GREATER
3242 /// <summary>
3343 /// The <see cref="ReadOnlySpan{T}"/> instance pointing to the first item in the target memory area.
3444 /// </summary>
@@ -71,7 +81,12 @@ public readonly ref partial struct ReadOnlySpan2D<T>
7181 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
7282 internal ReadOnlySpan2D ( in T value , int height , int width , int pitch )
7383 {
84+ #if NET7_0_OR_GREATER
85+ this . reference = ref value ;
86+ this . height = height ;
87+ #else
7488 this . span = MemoryMarshal . CreateReadOnlySpan ( ref Unsafe . AsRef ( value ) , height ) ;
89+ #endif
7590 this . width = width ;
7691 this . stride = width + pitch ;
7792 }
@@ -109,7 +124,10 @@ public unsafe ReadOnlySpan2D(void* pointer, int height, int width, int pitch)
109124
110125 OverflowHelper . EnsureIsInNativeIntRange ( height , width , pitch ) ;
111126
112- #if NETSTANDARD2_1_OR_GREATER
127+ #if NET7_0_OR_GREATER
128+ this . reference = ref Unsafe . AsRef < T > ( pointer ) ;
129+ this . height = height ;
130+ #elif NETSTANDARD2_1_OR_GREATER
113131 this . span = new ReadOnlySpan < T > ( pointer , height ) ;
114132#else
115133 this . instance = null ;
@@ -206,7 +224,10 @@ public ReadOnlySpan2D(T[] array, int offset, int height, int width, int pitch)
206224 ThrowHelper . ThrowArgumentException ( ) ;
207225 }
208226
209- #if NETSTANDARD2_1_OR_GREATER
227+ #if NET7_0_OR_GREATER
228+ this . reference = ref array . DangerousGetReferenceAt ( offset ) ;
229+ this . height = height ;
230+ #elif NETSTANDARD2_1_OR_GREATER
210231 this . span = MemoryMarshal . CreateReadOnlySpan ( ref array . DangerousGetReferenceAt ( offset ) , height ) ;
211232#else
212233 this . instance = array ;
@@ -230,7 +251,10 @@ public ReadOnlySpan2D(T[,]? array)
230251 return ;
231252 }
232253
233- #if NETSTANDARD2_1_OR_GREATER
254+ #if NET7_0_OR_GREATER
255+ this . reference = ref array . DangerousGetReference ( ) ;
256+ this . height = array . GetLength ( 0 ) ;
257+ #elif NETSTANDARD2_1_OR_GREATER
234258 this . span = MemoryMarshal . CreateReadOnlySpan ( ref array . DangerousGetReference ( ) , array . GetLength ( 0 ) ) ;
235259#else
236260 this . instance = array ;
@@ -289,7 +313,10 @@ public ReadOnlySpan2D(T[,]? array, int row, int column, int height, int width)
289313 ThrowHelper . ThrowArgumentOutOfRangeExceptionForWidth ( ) ;
290314 }
291315
292- #if NETSTANDARD2_1_OR_GREATER
316+ #if NET7_0_OR_GREATER
317+ this . reference = ref array . DangerousGetReferenceAt ( row , column ) ;
318+ this . height = height ;
319+ #elif NETSTANDARD2_1_OR_GREATER
293320 this . span = MemoryMarshal . CreateReadOnlySpan ( ref array . DangerousGetReferenceAt ( row , column ) , height ) ;
294321#else
295322 this . instance = array ;
@@ -313,7 +340,10 @@ public ReadOnlySpan2D(T[,,] array, int depth)
313340 ThrowHelper . ThrowArgumentOutOfRangeExceptionForDepth ( ) ;
314341 }
315342
316- #if NETSTANDARD2_1_OR_GREATER
343+ #if NET7_0_OR_GREATER
344+ this . reference = ref array . DangerousGetReferenceAt ( depth , 0 , 0 ) ;
345+ this . height = array . GetLength ( 1 ) ;
346+ #elif NETSTANDARD2_1_OR_GREATER
317347 this . span = MemoryMarshal . CreateReadOnlySpan ( ref array . DangerousGetReferenceAt ( depth , 0 , 0 ) , array . GetLength ( 1 ) ) ;
318348#else
319349 this . instance = array ;
@@ -363,7 +393,10 @@ public ReadOnlySpan2D(T[,,] array, int depth, int row, int column, int height, i
363393 ThrowHelper . ThrowArgumentOutOfRangeExceptionForWidth ( ) ;
364394 }
365395
366- #if NETSTANDARD2_1_OR_GREATER
396+ #if NET7_0_OR_GREATER
397+ this . reference = ref array . DangerousGetReferenceAt ( depth , row , column ) ;
398+ this . height = height ;
399+ #elif NETSTANDARD2_1_OR_GREATER
367400 this . span = MemoryMarshal . CreateReadOnlySpan ( ref array . DangerousGetReferenceAt ( depth , row , column ) , height ) ;
368401#else
369402 this . instance = array ;
@@ -441,7 +474,12 @@ internal ReadOnlySpan2D(ReadOnlySpan<T> span, int offset, int height, int width,
441474 ThrowHelper . ThrowArgumentException ( ) ;
442475 }
443476
477+ #if NET7_0_OR_GREATER
478+ this . reference = ref span . DangerousGetReferenceAt ( offset ) ;
479+ this . height = height ;
480+ #else
444481 this . span = MemoryMarshal . CreateSpan ( ref span . DangerousGetReferenceAt ( offset ) , height ) ;
482+ #endif
445483 this . width = width ;
446484 this . stride = width + pitch ;
447485 }
@@ -509,7 +547,9 @@ public int Height
509547 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
510548 get
511549 {
512- #if NETSTANDARD2_1_OR_GREATER
550+ #if NET7_0_OR_GREATER
551+ return this. height;
552+ #elif NETSTANDARD2_1_OR_GREATER
513553 return this. span. Length;
514554#else
515555 return this. height;
@@ -746,7 +786,9 @@ public unsafe ref T GetPinnableReference()
746786
747787 if ( Length != 0 )
748788 {
749- #if NETSTANDARD2_1_OR_GREATER
789+ #if NET7_0_OR_GREATER
790+ r0 = ref Unsafe. AsRef( in this . reference) ;
791+ #elif NETSTANDARD2_1_OR_GREATER
750792 r0 = ref MemoryMarshal. GetReference( this . span) ;
751793#else
752794 r0 = ref RuntimeHelpers. GetObjectDataAtOffsetOrPointerReference< T> ( this . instance, this . offset) ;
@@ -763,7 +805,9 @@ public unsafe ref T GetPinnableReference()
763805 [ MethodImpl( MethodImplOptions. AggressiveInlining) ]
764806 public ref T DangerousGetReference( )
765807 {
766- #if NETSTANDARD2_1_OR_GREATER
808+ #if NET7_0_OR_GREATER
809+ return ref Unsafe. AsRef( in this . reference) ;
810+ #elif NETSTANDARD2_1_OR_GREATER
767811 return ref MemoryMarshal. GetReference( this . span) ;
768812#else
769813 return ref RuntimeHelpers. GetObjectDataAtOffsetOrPointerReference< T> ( this . instance, this . offset) ;
@@ -779,7 +823,9 @@ public ref T DangerousGetReference()
779823 [ MethodImpl( MethodImplOptions. AggressiveInlining) ]
780824 public ref T DangerousGetReferenceAt( int i, int j)
781825 {
782- #if NETSTANDARD2_1_OR_GREATER
826+ #if NET7_0_OR_GREATER
827+ ref T r0 = ref Unsafe. AsRef( in this . reference) ;
828+ #elif NETSTANDARD2_1_OR_GREATER
783829 ref T r0 = ref MemoryMarshal. GetReference( this . span) ;
784830#else
785831 ref T r0 = ref RuntimeHelpers. GetObjectDataAtOffsetOrPointerReference< T> ( this . instance, this . offset) ;
@@ -826,7 +872,11 @@ public unsafe ReadOnlySpan2D<T> Slice(int row, int column, int height, int width
826872 nint shift = ( ( nint ) ( uint ) this . stride * ( nint ) ( uint ) row) + ( nint ) ( uint ) column;
827873 int pitch = this . stride - width;
828874
829- #if NETSTANDARD2_1_OR_GREATER
875+ #if NET7_0_OR_GREATER
876+ ref T r0 = ref Unsafe. Add( ref Unsafe. AsRef( in this . reference) , shift) ;
877+
878+ return new ( in r0, height, width, pitch) ;
879+ #elif NETSTANDARD2_1_OR_GREATER
830880 ref T r0 = ref this . span. DangerousGetReferenceAt( shift) ;
831881
832882 return new ( in r0, height, width, pitch) ;
@@ -868,7 +918,11 @@ public bool TryGetSpan(out ReadOnlySpan<T> span)
868918 if ( this . stride == this . width &&
869919 Length <= int . MaxValue)
870920 {
871- #if NETSTANDARD2_1_OR_GREATER
921+ #if NET7_0_OR_GREATER
922+ span = MemoryMarshal. CreateSpan( ref Unsafe. AsRef( in this . reference) , ( int ) Length) ;
923+
924+ return true;
925+ #elif NETSTANDARD2_1_OR_GREATER
872926 span = MemoryMarshal. CreateReadOnlySpan( ref MemoryMarshal. GetReference( this . span) , ( int ) Length) ;
873927
874928 return true;
@@ -979,7 +1033,10 @@ public override string ToString()
9791033 public static bool operator == ( ReadOnlySpan2D< T> left, ReadOnlySpan2D< T> right)
9801034 {
9811035 return
982- #if NETSTANDARD2_1_OR_GREATER
1036+ #if NET7_0_OR_GREATER
1037+ Unsafe. AreSame( ref Unsafe. AsRef( in left. reference) , ref Unsafe. AsRef( in right. reference) ) &&
1038+ left. height == right. height &&
1039+ #elif NETSTANDARD2_1_OR_GREATER
9831040 left. span == right. span &&
9841041#else
9851042 ReferenceEquals(
0 commit comments