@@ -28,7 +28,17 @@ namespace CommunityToolkit.HighPerformance;
28
28
[ DebuggerDisplay ( "{ToString(),raw}" ) ]
29
29
public readonly ref partial struct ReadOnlySpan2D< T >
30
30
{
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
32
42
/// <summary>
33
43
/// The <see cref="ReadOnlySpan{T}"/> instance pointing to the first item in the target memory area.
34
44
/// </summary>
@@ -71,7 +81,12 @@ public readonly ref partial struct ReadOnlySpan2D<T>
71
81
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
72
82
internal ReadOnlySpan2D ( in T value , int height , int width , int pitch )
73
83
{
84
+ #if NET7_0_OR_GREATER
85
+ this . reference = ref value ;
86
+ this . height = height ;
87
+ #else
74
88
this . span = MemoryMarshal . CreateReadOnlySpan ( ref Unsafe . AsRef ( value ) , height ) ;
89
+ #endif
75
90
this . width = width ;
76
91
this . stride = width + pitch ;
77
92
}
@@ -109,7 +124,10 @@ public unsafe ReadOnlySpan2D(void* pointer, int height, int width, int pitch)
109
124
110
125
OverflowHelper . EnsureIsInNativeIntRange ( height , width , pitch ) ;
111
126
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
113
131
this . span = new ReadOnlySpan < T > ( pointer , height ) ;
114
132
#else
115
133
this . instance = null ;
@@ -206,7 +224,10 @@ public ReadOnlySpan2D(T[] array, int offset, int height, int width, int pitch)
206
224
ThrowHelper . ThrowArgumentException ( ) ;
207
225
}
208
226
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
210
231
this . span = MemoryMarshal . CreateReadOnlySpan ( ref array . DangerousGetReferenceAt ( offset ) , height ) ;
211
232
#else
212
233
this . instance = array ;
@@ -230,7 +251,10 @@ public ReadOnlySpan2D(T[,]? array)
230
251
return ;
231
252
}
232
253
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
234
258
this . span = MemoryMarshal . CreateReadOnlySpan ( ref array . DangerousGetReference ( ) , array . GetLength ( 0 ) ) ;
235
259
#else
236
260
this . instance = array ;
@@ -289,7 +313,10 @@ public ReadOnlySpan2D(T[,]? array, int row, int column, int height, int width)
289
313
ThrowHelper . ThrowArgumentOutOfRangeExceptionForWidth ( ) ;
290
314
}
291
315
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
293
320
this . span = MemoryMarshal . CreateReadOnlySpan ( ref array . DangerousGetReferenceAt ( row , column ) , height ) ;
294
321
#else
295
322
this . instance = array ;
@@ -313,7 +340,10 @@ public ReadOnlySpan2D(T[,,] array, int depth)
313
340
ThrowHelper . ThrowArgumentOutOfRangeExceptionForDepth ( ) ;
314
341
}
315
342
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
317
347
this . span = MemoryMarshal . CreateReadOnlySpan ( ref array . DangerousGetReferenceAt ( depth , 0 , 0 ) , array . GetLength ( 1 ) ) ;
318
348
#else
319
349
this . instance = array ;
@@ -363,7 +393,10 @@ public ReadOnlySpan2D(T[,,] array, int depth, int row, int column, int height, i
363
393
ThrowHelper . ThrowArgumentOutOfRangeExceptionForWidth ( ) ;
364
394
}
365
395
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
367
400
this . span = MemoryMarshal . CreateReadOnlySpan ( ref array . DangerousGetReferenceAt ( depth , row , column ) , height ) ;
368
401
#else
369
402
this . instance = array ;
@@ -441,7 +474,12 @@ internal ReadOnlySpan2D(ReadOnlySpan<T> span, int offset, int height, int width,
441
474
ThrowHelper . ThrowArgumentException ( ) ;
442
475
}
443
476
477
+ #if NET7_0_OR_GREATER
478
+ this . reference = ref span . DangerousGetReferenceAt ( offset ) ;
479
+ this . height = height ;
480
+ #else
444
481
this . span = MemoryMarshal . CreateSpan ( ref span . DangerousGetReferenceAt ( offset ) , height ) ;
482
+ #endif
445
483
this . width = width ;
446
484
this . stride = width + pitch ;
447
485
}
@@ -509,7 +547,9 @@ public int Height
509
547
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
510
548
get
511
549
{
512
- #if NETSTANDARD2_1_OR_GREATER
550
+ #if NET7_0_OR_GREATER
551
+ return this. height;
552
+ #elif NETSTANDARD2_1_OR_GREATER
513
553
return this. span. Length;
514
554
#else
515
555
return this. height;
@@ -746,7 +786,9 @@ public unsafe ref T GetPinnableReference()
746
786
747
787
if ( Length != 0 )
748
788
{
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
750
792
r0 = ref MemoryMarshal. GetReference( this . span) ;
751
793
#else
752
794
r0 = ref RuntimeHelpers. GetObjectDataAtOffsetOrPointerReference< T> ( this . instance, this . offset) ;
@@ -763,7 +805,9 @@ public unsafe ref T GetPinnableReference()
763
805
[ MethodImpl( MethodImplOptions. AggressiveInlining) ]
764
806
public ref T DangerousGetReference( )
765
807
{
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
767
811
return ref MemoryMarshal. GetReference( this . span) ;
768
812
#else
769
813
return ref RuntimeHelpers. GetObjectDataAtOffsetOrPointerReference< T> ( this . instance, this . offset) ;
@@ -779,7 +823,9 @@ public ref T DangerousGetReference()
779
823
[ MethodImpl( MethodImplOptions. AggressiveInlining) ]
780
824
public ref T DangerousGetReferenceAt( int i, int j)
781
825
{
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
783
829
ref T r0 = ref MemoryMarshal. GetReference( this . span) ;
784
830
#else
785
831
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
826
872
nint shift = ( ( nint ) ( uint ) this . stride * ( nint ) ( uint ) row) + ( nint ) ( uint ) column;
827
873
int pitch = this . stride - width;
828
874
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
830
880
ref T r0 = ref this . span. DangerousGetReferenceAt( shift) ;
831
881
832
882
return new ( in r0, height, width, pitch) ;
@@ -868,7 +918,11 @@ public bool TryGetSpan(out ReadOnlySpan<T> span)
868
918
if ( this . stride == this . width &&
869
919
Length <= int . MaxValue)
870
920
{
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
872
926
span = MemoryMarshal. CreateReadOnlySpan( ref MemoryMarshal. GetReference( this . span) , ( int ) Length) ;
873
927
874
928
return true;
@@ -979,7 +1033,10 @@ public override string ToString()
979
1033
public static bool operator == ( ReadOnlySpan2D< T> left, ReadOnlySpan2D< T> right)
980
1034
{
981
1035
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
983
1040
left. span == right. span &&
984
1041
#else
985
1042
ReferenceEquals(
0 commit comments