4
4
5
5
using System ;
6
6
using System . ComponentModel ;
7
+ using System . Data . Common ;
7
8
using System . Diagnostics ;
8
9
using System . Runtime . CompilerServices ;
9
10
using System . Runtime . InteropServices ;
@@ -55,7 +56,17 @@ public readonly ref partial struct Span2D<T>
55
56
// discontiguous row, so that any arbitrary memory locations
56
57
// can be used to internally represent a 2D span. This gives
57
58
// users much more flexibility when creating spans from data.
58
- #if NETSTANDARD2_1_OR_GREATER
59
+ #if NET7_0_OR_GREATER
60
+ /// <summary>
61
+ /// The <typeparamref name="T"/> reference for the <see cref="Span2D{T}"/> instance.
62
+ /// </summary>
63
+ private readonly ref T reference ;
64
+
65
+ /// <summary>
66
+ /// The height of the specified 2D region.
67
+ /// </summary>
68
+ private readonly int height ;
69
+ #elif NETSTANDARD2_1_OR_GREATER
59
70
/// <summary>
60
71
/// The <see cref="Span{T}"/> instance pointing to the first item in the target memory area.
61
72
/// </summary>
@@ -106,7 +117,12 @@ public readonly ref partial struct Span2D<T>
106
117
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
107
118
internal Span2D ( ref T value , int height , int width , int pitch )
108
119
{
120
+ #if NET7_0_OR_GREATER
121
+ this . reference = ref value ;
122
+ this . height = height ;
123
+ #else
109
124
this . span = MemoryMarshal . CreateSpan ( ref value , height ) ;
125
+ #endif
110
126
this . width = width ;
111
127
this . Stride = width + pitch ;
112
128
}
@@ -144,7 +160,10 @@ public unsafe Span2D(void* pointer, int height, int width, int pitch)
144
160
145
161
OverflowHelper . EnsureIsInNativeIntRange ( height , width , pitch ) ;
146
162
147
- #if NETSTANDARD2_1_OR_GREATER
163
+ #if NET7_0_OR_GREATER
164
+ this . reference = ref Unsafe . AsRef < T > ( pointer ) ;
165
+ this . height = height ;
166
+ #elif NETSTANDARD2_1_OR_GREATER
148
167
this . span = new Span < T > ( pointer , height ) ;
149
168
#else
150
169
this . Instance = null ;
@@ -245,7 +264,10 @@ public Span2D(T[] array, int offset, int height, int width, int pitch)
245
264
ThrowHelper . ThrowArgumentException ( ) ;
246
265
}
247
266
248
- #if NETSTANDARD2_1_OR_GREATER
267
+ #if NET7_0_OR_GREATER
268
+ this . reference = ref array . DangerousGetReferenceAt ( offset ) ;
269
+ this . height = height ;
270
+ #elif NETSTANDARD2_1_OR_GREATER
249
271
this . span = MemoryMarshal . CreateSpan ( ref array . DangerousGetReferenceAt ( offset ) , height ) ;
250
272
#else
251
273
this . Instance = array ;
@@ -277,7 +299,10 @@ public Span2D(T[,]? array)
277
299
ThrowHelper . ThrowArrayTypeMismatchException ( ) ;
278
300
}
279
301
280
- #if NETSTANDARD2_1_OR_GREATER
302
+ #if NET7_0_OR_GREATER
303
+ this . reference = ref array . DangerousGetReference ( ) ;
304
+ this . height = array . GetLength ( 0 ) ;
305
+ #elif NETSTANDARD2_1_OR_GREATER
281
306
this . span = MemoryMarshal . CreateSpan ( ref array . DangerousGetReference ( ) , array . GetLength ( 0 ) ) ;
282
307
#else
283
308
this . Instance = array ;
@@ -344,7 +369,10 @@ public Span2D(T[,]? array, int row, int column, int height, int width)
344
369
ThrowHelper . ThrowArgumentOutOfRangeExceptionForWidth ( ) ;
345
370
}
346
371
347
- #if NETSTANDARD2_1_OR_GREATER
372
+ #if NET7_0_OR_GREATER
373
+ this . reference = ref array . DangerousGetReferenceAt ( row , column ) ;
374
+ this . height = height ;
375
+ #elif NETSTANDARD2_1_OR_GREATER
348
376
this . span = MemoryMarshal . CreateSpan ( ref array . DangerousGetReferenceAt ( row , column ) , height ) ;
349
377
#else
350
378
this . Instance = array ;
@@ -376,7 +404,10 @@ public Span2D(T[,,] array, int depth)
376
404
ThrowHelper . ThrowArgumentOutOfRangeExceptionForDepth ( ) ;
377
405
}
378
406
379
- #if NETSTANDARD2_1_OR_GREATER
407
+ #if NET7_0_OR_GREATER
408
+ this . reference = ref array . DangerousGetReferenceAt ( depth , 0 , 0 ) ;
409
+ this . height = array . GetLength ( 1 ) ;
410
+ #elif NETSTANDARD2_1_OR_GREATER
380
411
this . span = MemoryMarshal . CreateSpan ( ref array . DangerousGetReferenceAt ( depth , 0 , 0 ) , array . GetLength ( 1 ) ) ;
381
412
#else
382
413
this . Instance = array ;
@@ -434,7 +465,10 @@ public Span2D(T[,,] array, int depth, int row, int column, int height, int width
434
465
ThrowHelper . ThrowArgumentOutOfRangeExceptionForWidth ( ) ;
435
466
}
436
467
437
- #if NETSTANDARD2_1_OR_GREATER
468
+ #if NET7_0_OR_GREATER
469
+ this . reference = ref array . DangerousGetReferenceAt ( depth , row , column ) ;
470
+ this . height = height ;
471
+ #elif NETSTANDARD2_1_OR_GREATER
438
472
this . span = MemoryMarshal . CreateSpan ( ref array . DangerousGetReferenceAt ( depth , row , column ) , height ) ;
439
473
#else
440
474
this . Instance = array ;
@@ -512,7 +546,12 @@ internal Span2D(Span<T> span, int offset, int height, int width, int pitch)
512
546
ThrowHelper . ThrowArgumentException ( ) ;
513
547
}
514
548
549
+ #if NET7_0_OR_GREATER
550
+ this . reference = ref span . DangerousGetReferenceAt ( offset ) ;
551
+ this . height = height ;
552
+ #else
515
553
this . span = MemoryMarshal . CreateSpan ( ref span . DangerousGetReferenceAt ( offset ) , height ) ;
554
+ #endif
516
555
this . width = width ;
517
556
this . Stride = width + pitch ;
518
557
}
@@ -580,7 +619,9 @@ public int Height
580
619
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
581
620
get
582
621
{
583
- #if NETSTANDARD2_1_OR_GREATER
622
+ #if NET7_0_OR_GREATER
623
+ return this. height;
624
+ #elif NETSTANDARD2_1_OR_GREATER
584
625
return this. span. Length;
585
626
#else
586
627
return this. height;
@@ -902,7 +943,9 @@ public unsafe ref T GetPinnableReference()
902
943
903
944
if ( Length ! = 0 )
904
945
{
905
- #if NETSTANDARD2_1_OR_GREATER
946
+ #if NET7_0_OR_GREATER
947
+ r0 = ref this . reference ;
948
+ #elif NETSTANDARD2_1_OR_GREATER
906
949
r0 = ref MemoryMarshal . GetReference ( this . span ) ;
907
950
#else
908
951
r0 = ref RuntimeHelpers . GetObjectDataAtOffsetOrPointerReference < T > ( this . Instance , this . Offset ) ;
@@ -919,7 +962,9 @@ public unsafe ref T GetPinnableReference()
919
962
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
920
963
public ref T DangerousGetReference( )
921
964
{
922
- #if NETSTANDARD2_1_OR_GREATER
965
+ #if NET7_0_OR_GREATER
966
+ return ref this . reference;
967
+ #elif NETSTANDARD2_1_OR_GREATER
923
968
return ref MemoryMarshal . GetReference ( this . span ) ;
924
969
#else
925
970
return ref RuntimeHelpers . GetObjectDataAtOffsetOrPointerReference < T > ( this . Instance , this . Offset ) ;
@@ -935,7 +980,9 @@ public ref T DangerousGetReference()
935
980
[ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
936
981
public ref T DangerousGetReferenceAt( int i , int j )
937
982
{
938
- #if NETSTANDARD2_1_OR_GREATER
983
+ #if NET7_0_OR_GREATER
984
+ ref T r0 = ref this . reference ;
985
+ #elif NETSTANDARD2_1_OR_GREATER
939
986
ref T r0 = ref MemoryMarshal . GetReference ( this . span ) ;
940
987
#else
941
988
ref T r0 = ref RuntimeHelpers . GetObjectDataAtOffsetOrPointerReference < T > ( this . Instance , this . Offset ) ;
@@ -982,7 +1029,11 @@ public unsafe Span2D<T> Slice(int row, int column, int height, int width)
982
1029
nint shift = ( ( nint ) ( uint ) this . Stride * ( nint ) ( uint ) row) + ( nint ) ( uint ) column;
983
1030
int pitch = this . Stride - width;
984
1031
985
- #if NETSTANDARD2_1_OR_GREATER
1032
+ #if NET7_0_OR_GREATER
1033
+ ref T r0 = ref Unsafe. Add( ref this . reference, shift) ;
1034
+
1035
+ return new ( ref r0, height, width, pitch) ;
1036
+ #elif NETSTANDARD2_1_OR_GREATER
986
1037
ref T r0 = ref this . span. DangerousGetReferenceAt( shift) ;
987
1038
988
1039
return new ( ref r0, height, width, pitch) ;
@@ -1024,7 +1075,11 @@ public bool TryGetSpan(out Span<T> span)
1024
1075
if ( this . Stride == this . width &&
1025
1076
Length <= int . MaxValue)
1026
1077
{
1027
- #if NETSTANDARD2_1_OR_GREATER
1078
+ #if NET7_0_OR_GREATER
1079
+ span = MemoryMarshal. CreateSpan( ref this . reference, ( int ) Length) ;
1080
+
1081
+ return true;
1082
+ #elif NETSTANDARD2_1_OR_GREATER
1028
1083
span = MemoryMarshal. CreateSpan( ref MemoryMarshal. GetReference( this . span) , ( int ) Length) ;
1029
1084
1030
1085
return true;
@@ -1135,7 +1190,10 @@ public override string ToString()
1135
1190
public static bool operator == ( Span2D < T > left , Span2D < T > right )
1136
1191
{
1137
1192
return
1138
- #if NETSTANDARD2_1_OR_GREATER
1193
+ #if NET7_0_OR_GREATER
1194
+ Unsafe . AreSame ( ref left . reference , ref right . reference ) &&
1195
+ left . height == right . height &&
1196
+ #elif NETSTANDARD2_1_OR_GREATER
1139
1197
left . span = = right . span &&
1140
1198
#else
1141
1199
ReferenceEquals (
0 commit comments