Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
Span.cs
Go to the documentation of this file.
7
8namespace System;
9
10[DebuggerTypeProxy(typeof(SpanDebugView<>))]
11[DebuggerDisplay("{ToString(),raw}")]
12[NonVersionable]
13public readonly ref struct Span<T>
14{
15 public ref struct Enumerator
16 {
17 private readonly Span<T> _span;
18
19 private int _index;
20
21 public ref T Current
22 {
23 [MethodImpl(MethodImplOptions.AggressiveInlining)]
24 get
25 {
26 return ref _span[_index];
27 }
28 }
29
30 [MethodImpl(MethodImplOptions.AggressiveInlining)]
31 internal Enumerator(Span<T> span)
32 {
33 _span = span;
34 _index = -1;
35 }
36
37 [MethodImpl(MethodImplOptions.AggressiveInlining)]
38 public bool MoveNext()
39 {
40 int num = _index + 1;
41 if (num < _span.Length)
42 {
43 _index = num;
44 return true;
45 }
46 return false;
47 }
48 }
49
50 internal readonly ByReference<T> _pointer;
51
52 private readonly int _length;
53
54 public ref T this[int index]
55 {
56 [MethodImpl(MethodImplOptions.AggressiveInlining)]
57 [Intrinsic]
58 [NonVersionable]
59 get
60 {
61 if ((uint)index >= (uint)_length)
62 {
64 }
65 return ref Unsafe.Add(ref _pointer.Value, (nint)(uint)index);
66 }
67 }
68
69 public int Length
70 {
71 [NonVersionable]
72 get
73 {
74 return _length;
75 }
76 }
77
78 public bool IsEmpty
79 {
80 [NonVersionable]
81 get
82 {
83 return 0u >= (uint)_length;
84 }
85 }
86
87 public static Span<T> Empty => default(Span<T>);
88
89 [MethodImpl(MethodImplOptions.AggressiveInlining)]
90 public Span(T[]? array)
91 {
92 if (array == null)
93 {
94 this = default(Span<T>);
95 return;
96 }
97 if (!typeof(T).IsValueType && array.GetType() != typeof(T[]))
98 {
100 }
102 _length = array.Length;
103 }
104
105 [MethodImpl(MethodImplOptions.AggressiveInlining)]
106 public Span(T[]? array, int start, int length)
107 {
108 if (array == null)
109 {
110 if (start != 0 || length != 0)
111 {
113 }
114 this = default(Span<T>);
115 return;
116 }
117 if (!typeof(T).IsValueType && array.GetType() != typeof(T[]))
118 {
120 }
121 if ((ulong)((long)(uint)start + (long)(uint)length) > (ulong)(uint)array.Length)
122 {
124 }
126 _length = length;
127 }
128
129 [MethodImpl(MethodImplOptions.AggressiveInlining)]
130 [CLSCompliant(false)]
131 public unsafe Span(void* pointer, int length)
132 {
133 if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
134 {
136 }
137 if (length < 0)
138 {
140 }
141 _pointer = new ByReference<T>(ref Unsafe.As<byte, T>(ref *(byte*)pointer));
142 _length = length;
143 }
144
145 [MethodImpl(MethodImplOptions.AggressiveInlining)]
146 internal Span(ref T ptr, int length)
147 {
148 _pointer = new ByReference<T>(ref ptr);
149 _length = length;
150 }
151
152 public static bool operator !=(Span<T> left, Span<T> right)
153 {
154 return !(left == right);
155 }
156
157 [Obsolete("Equals() on Span will always throw an exception. Use the equality operator instead.")]
158 [EditorBrowsable(EditorBrowsableState.Never)]
159 public override bool Equals(object? obj)
160 {
162 }
163
164 [Obsolete("GetHashCode() on Span will always throw an exception.")]
165 [EditorBrowsable(EditorBrowsableState.Never)]
166 public override int GetHashCode()
167 {
169 }
170
171 public static implicit operator Span<T>(T[]? array)
172 {
173 return new Span<T>(array);
174 }
175
176 public static implicit operator Span<T>(ArraySegment<T> segment)
177 {
178 return new Span<T>(segment.Array, segment.Offset, segment.Count);
179 }
180
182 {
183 return new Enumerator(this);
184 }
185
186 [EditorBrowsable(EditorBrowsableState.Never)]
187 public ref T GetPinnableReference()
188 {
189 ref T result = ref Unsafe.NullRef<T>();
190 if (_length != 0)
191 {
192 result = ref _pointer.Value;
193 }
194 return ref result;
195 }
196
197 [MethodImpl(MethodImplOptions.AggressiveInlining)]
198 public unsafe void Clear()
199 {
200 if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
201 {
202 SpanHelpers.ClearWithReferences(ref Unsafe.As<T, IntPtr>(ref _pointer.Value), (nuint)(uint)_length * (nuint)(Unsafe.SizeOf<T>() / sizeof(UIntPtr)));
203 }
204 else
205 {
206 SpanHelpers.ClearWithoutReferences(ref Unsafe.As<T, byte>(ref _pointer.Value), (nuint)(uint)_length * (nuint)Unsafe.SizeOf<T>());
207 }
208 }
209
210 [MethodImpl(MethodImplOptions.AggressiveInlining)]
211 public void Fill(T value)
212 {
213 if (Unsafe.SizeOf<T>() == 1)
214 {
215 Unsafe.InitBlockUnaligned(ref Unsafe.As<T, byte>(ref _pointer.Value), Unsafe.As<T, byte>(ref value), (uint)_length);
216 }
217 else
218 {
219 SpanHelpers.Fill(ref _pointer.Value, (uint)_length, value);
220 }
221 }
222
223 [MethodImpl(MethodImplOptions.AggressiveInlining)]
225 {
226 if ((uint)_length <= (uint)destination.Length)
227 {
228 Buffer.Memmove<T>(ref destination._pointer.Value, ref _pointer.Value, (uint)_length);
229 }
230 else
231 {
233 }
234 }
235
237 {
238 bool result = false;
239 if ((uint)_length <= (uint)destination.Length)
240 {
241 Buffer.Memmove<T>(ref destination._pointer.Value, ref _pointer.Value, (uint)_length);
242 result = true;
243 }
244 return result;
245 }
246
247 public static bool operator ==(Span<T> left, Span<T> right)
248 {
249 if (left._length == right._length)
250 {
251 return Unsafe.AreSame(ref left._pointer.Value, ref right._pointer.Value);
252 }
253 return false;
254 }
255
256 public static implicit operator ReadOnlySpan<T>(Span<T> span)
257 {
258 return new ReadOnlySpan<T>(ref span._pointer.Value, span._length);
259 }
260
261 public override string ToString()
262 {
263 if (typeof(T) == typeof(char))
264 {
265 return new string(new ReadOnlySpan<char>(ref Unsafe.As<T, char>(ref _pointer.Value), _length));
266 }
267 return $"System.Span<{typeof(T).Name}>[{_length}]";
268 }
269
270 [MethodImpl(MethodImplOptions.AggressiveInlining)]
271 public Span<T> Slice(int start)
272 {
273 if ((uint)start > (uint)_length)
274 {
276 }
277 return new Span<T>(ref Unsafe.Add(ref _pointer.Value, (nint)(uint)start), _length - start);
278 }
279
280 [MethodImpl(MethodImplOptions.AggressiveInlining)]
281 public Span<T> Slice(int start, int length)
282 {
283 if ((ulong)((long)(uint)start + (long)(uint)length) > (ulong)(uint)_length)
284 {
286 }
287 return new Span<T>(ref Unsafe.Add(ref _pointer.Value, (nint)(uint)start), length);
288 }
289
290 [MethodImpl(MethodImplOptions.AggressiveInlining)]
291 public T[] ToArray()
292 {
293 if (_length == 0)
294 {
295 return Array.Empty<T>();
296 }
297 T[] array = new T[_length];
299 return array;
300 }
301}
static void InitBlockUnaligned(ref byte startAddress, byte value, uint byteCount)
Definition Unsafe.cs:107
static void Memmove(ref byte dest, ref byte src, nuint len)
Definition Buffer.cs:215
static unsafe ref byte GetArrayDataReference(Array array)
static string NotSupported_CannotCallGetHashCodeOnSpan
Definition SR.cs:1660
static string NotSupported_CannotCallEqualsOnSpan
Definition SR.cs:1658
Definition SR.cs:7
static void ClearWithReferences(ref IntPtr ip, nuint pointerSizeLength)
static void ClearWithoutReferences(ref byte b, nuint byteLength)
static void ThrowArrayTypeMismatchException()
static void ThrowIndexOutOfRangeException()
static void ThrowArgumentOutOfRangeException(System.ExceptionArgument argument)
static void ThrowInvalidTypeWithPointersNotSupported(Type targetType)
static void ThrowArgumentException_DestinationTooShort()
readonly Span< T > _span
Definition Span.cs:17
Enumerator(Span< T > span)
Definition Span.cs:31
Span< T > Slice(int start, int length)
Definition Span.cs:281
void CopyTo(Span< T > destination)
Definition Span.cs:224
Span(T[]? array, int start, int length)
Definition Span.cs:106
void Fill(T value)
Definition Span.cs:211
Span(ref T ptr, int length)
Definition Span.cs:146
readonly ByReference< T > _pointer
Definition Span.cs:50
Enumerator GetEnumerator()
Definition Span.cs:181
override bool Equals(object? obj)
Definition Span.cs:159
Span(T[]? array)
Definition Span.cs:90
bool IsEmpty
Definition Span.cs:79
static bool operator!=(Span< T > left, Span< T > right)
Definition Span.cs:152
readonly int _length
Definition Span.cs:52
Span< T > Slice(int start)
Definition Span.cs:271
unsafe void Clear()
Definition Span.cs:198
override int GetHashCode()
Definition Span.cs:166
ref T GetPinnableReference()
Definition Span.cs:187
static bool operator==(Span< T > left, Span< T > right)
Definition Span.cs:247
unsafe Span(void *pointer, int length)
Definition Span.cs:131
T[] ToArray()
Definition Span.cs:291
int Length
Definition Span.cs:70
override string ToString()
Definition Span.cs:261
bool TryCopyTo(Span< T > destination)
Definition Span.cs:236