-
-
Notifications
You must be signed in to change notification settings - Fork 114
/
Copy pathSpanPinValue.cs
178 lines (159 loc) · 6.52 KB
/
SpanPinValue.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
using System.Device.Gpio;
namespace System
{
/// <summary>
/// Provides a type- and memory-safe representation of a contiguous region of arbitrary array.
/// </summary>
[Serializable, CLSCompliant(false)]
public readonly ref struct SpanPinValue
{
private readonly PinValue[] _array; // internal array
private readonly int _start; // offset in the internal array
private readonly int _length; // accessible length after offset in the internal array
/// <summary>
/// Creates a new Span object over the entirety of a specified array.
/// </summary>
/// <param name="array">The array from which to create the System.Span object.</param>
public SpanPinValue(PinValue[] array)
{
_array = array;
_length = array!=null ? array.Length : 0;
_start = 0;
}
/// <summary>
/// Creates a new Span object that includes a specified number of elements
/// of an array starting at a specified index.
/// </summary>
/// <param name="array">The source array.</param>
/// <param name="start">The index of the first element to include in the new System.Span</param>
/// <param name="length">The number of elements to include in the new System.Span</param>
/// <exception cref="System.ArgumentOutOfRangeException">
/// array is null, but start or length is non-zero. -or- start is outside the bounds
/// of the array. -or- start and length exceeds the number of elements in the array.
/// </exception>
public SpanPinValue(PinValue[] array, int start, int length)
{
if (array != null)
{
if (start < 0 ||
length < 0 ||
start + length > array.Length ||
(start == array.Length && start > 0))
{
// Array length too small
throw new ArgumentOutOfRangeException();
}
}
else
{
if ((start != 0) || (length != 0))
{
// Array is null but start and length are not 0
throw new ArgumentOutOfRangeException();
}
}
_array = array;
_start = start;
_length = length;
}
/// <summary>
/// Gets the element at the specified zero-based index.
/// </summary>
/// <param name="index">The zero-based index of the element.</param>
/// <returns>The element at the specified index.</returns>
// public ref PinValue this[int index] => ref _array[_start + index]; // <= this is not working and raises exception after few access
public PinValue this[int index]
{
get
{
if (index >= _length)
{
throw new ArgumentOutOfRangeException();
}
return _array[_start + index];
}
set
{
if (index >= _length)
{
throw new ArgumentOutOfRangeException();
}
_array[_start + index] = value;
}
}
/// <summary>
/// Returns an empty System.Span object.
/// </summary>
public static SpanPinValue Empty => new SpanPinValue();
/// <summary>
/// Returns the length of the current span.
/// </summary>
public int Length => _length;
/// <summary>
/// Returns a value that indicates whether the current System.Span is empty.
/// true if the current span is empty; otherwise, false.
/// </summary>
public bool IsEmpty => _length == 0;
/// <summary>
/// Copies the contents of this System.Span into a destination System.Span.
/// </summary>
/// <param name="destination"> The destination System.Span object.</param>
/// <exception cref="System.ArgumentException">
/// destination is shorter than the source System.Span.
/// </exception>
public void CopyTo(SpanPinValue destination)
{
if (destination.Length < _length)
{
throw new ArgumentException();
}
for (int i = 0; i < _length; i++)
{
destination[i] = _array[_start + i];
}
}
/// <summary>
/// Forms a slice out of the current span that begins at a specified index.
/// </summary>
/// <param name="start">The index at which to begin the slice.</param>
/// <returns>A span that consists of all elements of the current span from start to the end of the span.</returns>
/// <exception cref="System.ArgumentOutOfRangeException">start is less than zero or greater than System.Span.Length.</exception>
public SpanPinValue Slice(int start)
{
return Slice(start, _length - start);
}
/// <summary>
/// Forms a slice out of the current span starting at a specified index for a specified length.
/// </summary>
/// <param name="start">The index at which to begin this slice.</param>
/// <param name="length">The desired length for the slice.</param>
/// <returns>A span that consists of length elements from the current span starting at start.</returns>
/// <exception cref="System.ArgumentOutOfRangeException">start or start + length is less than zero or greater than System.Span.Length.</exception>
public SpanPinValue Slice(int start, int length)
{
if ((start < 0) || (length < 0) || (start + length > _length))
{
// start or start + length is less than zero or greater than length
throw new ArgumentOutOfRangeException();
}
return new SpanPinValue(_array, _start + start, length);
}
/// <summary>
/// Copies the contents of this span into a new array.
/// </summary>
/// <returns> An array containing the data in the current span.</returns>
public PinValue[] ToArray()
{
var array = new PinValue[_length];
for (int i = 0; i < _length; i++)
{
array[i] = _array[_start + i];
}
return array;
}
public static implicit operator SpanPinValue(PinValue[] array)
{
return new(array);
}
}
}