forked from nanoframework/nanoFramework.IoT.Device
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSpanCharacter.cs
184 lines (164 loc) · 6.79 KB
/
SpanCharacter.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
179
180
181
182
183
184
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using Iot.Device.Tm1637;
namespace System
{
/// <summary>
/// Provides a type- and memory-safe representation of a contiguous region of arbitrary array.
/// </summary>
[Serializable, CLSCompliant(false)]
public struct SpanCharacter
{
private readonly Character[] _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>
/// Initializes a new instance of the <see cref="SpanCharacter" /> struct.
/// </summary>
/// <param name="array">The array from which to create the System.Span object.</param>
public SpanCharacter(Character[] array)
{
_array = array;
_length = array is null ? 0 : array.Length;
_start = 0;
}
/// <summary>
/// Initializes a new instance of the<see cref="SpanCharacter" /> struct.
/// </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 SpanCharacter(Character[] 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 Character this[int index]
{
// public ref Character this[int index] => ref _array[_start + index]; // <= this is not working and raises exception after few access
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 SpanCharacter Empty => new SpanCharacter();
/// <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>
/// Converts array of charaters to SpanCharacters.
/// </summary>
/// <param name="array">Arra to convert from.</param>
public static implicit operator SpanCharacter(Character[] array)
{
return new SpanCharacter(array);
}
/// <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(SpanCharacter 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 SpanCharacter 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 SpanCharacter 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 SpanCharacter(_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 Character[] ToArray()
{
var array = new Character[_length];
for (int i = 0; i < _length; i++)
{
array[i] = _array[_start + i];
}
return array;
}
}
}