17
17
#ifndef BLE_ARRAY_VIEW_H_
18
18
#define BLE_ARRAY_VIEW_H_
19
19
20
+ #include < algorithm>
21
+
20
22
#include < stddef.h>
21
23
#include < stdint.h>
24
+ #include " platform/mbed_assert.h"
22
25
23
26
/* *
24
27
* @addtogroup ble
33
36
34
37
namespace ble {
35
38
39
+ /* *
40
+ * Special value for the Size parameter of ArrayView.
41
+ * If the type use this value then the size of the array is stored in the object
42
+ * at runtime.
43
+ */
44
+ #define ARRAY_VIEW_DYNAMIC_SIZE -1
45
+
36
46
/* *
37
47
* Immutable view to an array.
38
48
*
39
49
* Array views encapsulate the pointer to an array and its size into a single
40
- * object; however, it does not manage the lifetime of the array viewed.
50
+ * object or type ; however, it does not manage the lifetime of the array viewed.
41
51
* You can use instances of ArrayView to replace the traditional pair of pointer
42
52
* and size arguments in function calls.
43
53
*
@@ -48,20 +58,28 @@ namespace ble {
48
58
* @note You can create ArrayView instances with the help of the function
49
59
* template make_ArrayView() and make_const_ArrayView().
50
60
*
61
+ * @note ArrayView<T, Size> objects can be implicitly converted to ArrayView<T>
62
+ * objects where required.
63
+ *
51
64
* @tparam T type of objects held by the array.
65
+ * @tparam Size The size of the array viewed. The default value
66
+ * ARRAY_VIEW_DYNAMIC_SIZE is special as it allows construction of ArrayView
67
+ * objects of any size (set at runtime).
52
68
*/
53
- template <typename T>
69
+ template <typename T, ptrdiff_t Size = ARRAY_VIEW_DYNAMIC_SIZE >
54
70
struct ArrayView {
55
71
72
+ MBED_STATIC_ASSERT (Size >= 0 , " Invalid size for an ArrayView" );
73
+
56
74
/* *
57
75
* Construct a view to an empty array.
58
76
*
59
77
* @post a call to size() will return 0, and data() will return NULL.
60
78
*/
61
- ArrayView () : _array(0 ), _size( 0 ) { }
79
+ ArrayView () : _array(NULL ) { }
62
80
63
81
/* *
64
- * Construct an array view from a pointer to a buffer and its size .
82
+ * Construct an array view from a pointer to a buffer.
65
83
*
66
84
* @param array_ptr Pointer to the array data
67
85
* @param array_size Number of elements of T present in the array.
@@ -70,7 +88,9 @@ struct ArrayView {
70
88
* array_tpr.
71
89
*/
72
90
ArrayView (T* array_ptr, size_t array_size) :
73
- _array (array_ptr), _size(array_size) { }
91
+ _array (array_ptr) {
92
+ MBED_ASSERT (array_size >= (size_t ) Size);
93
+ }
74
94
75
95
/* *
76
96
* Construct an array view from the reference to an array.
@@ -82,9 +102,8 @@ struct ArrayView {
82
102
* @post a call to size() will return Size, and data() will return
83
103
* a pointer to elements.
84
104
*/
85
- template <size_t Size>
86
105
ArrayView (T (&elements)[Size]):
87
- _array (elements), _size(Size) { }
106
+ _array (elements) { }
88
107
89
108
/* *
90
109
* Return the size of the array viewed.
@@ -93,7 +112,7 @@ struct ArrayView {
93
112
*/
94
113
size_t size () const
95
114
{
96
- return _size ;
115
+ return _array ? Size : 0 ;
97
116
}
98
117
99
118
/* *
@@ -144,40 +163,115 @@ struct ArrayView {
144
163
return _array;
145
164
}
146
165
166
+ private:
167
+ T* const _array;
168
+ };
169
+
170
+ /* *
171
+ * ArrayView specialisation that handle dynamic array size.
172
+ */
173
+ template <typename T>
174
+ struct ArrayView <T, ARRAY_VIEW_DYNAMIC_SIZE> {
175
+
176
+ /* *
177
+ * Construct a view to an empty array.
178
+ *
179
+ * @post a call to size() will return 0, and data() will return NULL.
180
+ */
181
+ ArrayView () : _array(0 ), _size(0 ) { }
182
+
183
+ /* *
184
+ * Construct an array view from a pointer to a buffer and its size.
185
+ *
186
+ * @param array_ptr Pointer to the array data
187
+ * @param array_size Number of elements of T present in the array.
188
+ *
189
+ * @post a call to size() will return array_size and data() will return
190
+ * array_tpr.
191
+ */
192
+ ArrayView (T* array_ptr, size_t array_size) :
193
+ _array (array_ptr), _size(array_size) { }
194
+
147
195
/* *
148
- * Equality operator .
196
+ * Construct an array view from the reference to an array .
149
197
*
150
- * @param lhs Left hand side of the binary operation.
151
- * @param rhs Right hand side of the binary operation.
198
+ * @param elements Reference to the array viewed.
199
+ *
200
+ * @tparam Size Number of elements of T presents in the array.
201
+ *
202
+ * @post a call to size() will return Size, and data() will return
203
+ * a pointer to elements.
204
+ */
205
+ template <size_t Size>
206
+ ArrayView (T (&elements)[Size]):
207
+ _array (elements), _size(Size) { }
208
+
209
+
210
+ /* *
211
+ * Construct a ArrayView object with a dynamic size from an ArrayView object
212
+ * with a static size.
213
+ * @param other The ArrayView object used to construct this.
214
+ */
215
+ template <size_t Size>
216
+ ArrayView (ArrayView<T, Size> other):
217
+ _array (other.data()), _size(other.size()) { }
218
+
219
+ /* *
220
+ * Return the size of the array viewed.
152
221
*
153
- * @return True if arrays in input have the same size and the same content
154
- * and false otherwise.
222
+ * @return The number of elements present in the array viewed.
155
223
*/
156
- friend bool operator ==( const ArrayView& lhs, const ArrayView& rhs)
224
+ size_t size () const
157
225
{
158
- if (lhs.size () != rhs.size ()) {
159
- return false ;
160
- }
226
+ return _size;
227
+ }
161
228
162
- if (lhs.data () == rhs.data ()) {
163
- return true ;
164
- }
229
+ /* *
230
+ * Access to a mutable element of the array.
231
+ *
232
+ * @param index Element index to access.
233
+ *
234
+ * @return A reference to the element at the index specified in input.
235
+ *
236
+ * @pre index shall be less than size().
237
+ */
238
+ T& operator [](size_t index)
239
+ {
240
+ return _array[index];
241
+ }
165
242
166
- return memcmp (lhs.data (), rhs.data (), lhs.size ()) == 0 ;
243
+ /* *
244
+ * Access to an immutable element of the array.
245
+ *
246
+ * @param index Element index to access.
247
+ *
248
+ * @return A const reference to the element at the index specified in input.
249
+ *
250
+ * @pre index shall be less than size().
251
+ */
252
+ const T& operator [](size_t index) const
253
+ {
254
+ return _array[index];
167
255
}
168
256
169
257
/* *
170
- * Not equal operator
258
+ * Get the raw pointer to the array.
171
259
*
172
- * @param lhs Left hand side of the binary operation.
173
- * @param rhs Right hand side of the binary operation.
260
+ * @return The raw pointer to the array.
261
+ */
262
+ T* data ()
263
+ {
264
+ return _array;
265
+ }
266
+
267
+ /* *
268
+ * Get the raw const pointer to the array.
174
269
*
175
- * @return True if arrays in input do not have the same size or the same
176
- * content and false otherwise.
270
+ * @return The raw pointer to the array.
177
271
*/
178
- friend bool operator !=( const ArrayView& lhs, const ArrayView& rhs)
272
+ const T* data () const
179
273
{
180
- return !(lhs == rhs) ;
274
+ return _array ;
181
275
}
182
276
183
277
private:
@@ -186,6 +280,45 @@ struct ArrayView {
186
280
};
187
281
188
282
283
+ /* *
284
+ * Equality operator.
285
+ *
286
+ * @param lhs Left hand side of the binary operation.
287
+ * @param rhs Right hand side of the binary operation.
288
+ *
289
+ * @return True if arrays in input have the same size and the same content
290
+ * and false otherwise.
291
+ */
292
+ template <typename T, ptrdiff_t LhsSize, ptrdiff_t RhsSize>
293
+ bool operator ==(const ArrayView<T, LhsSize>& lhs, const ArrayView<T, LhsSize>& rhs)
294
+ {
295
+ if (lhs.size () != rhs.size ()) {
296
+ return false ;
297
+ }
298
+
299
+ if (lhs.data () == rhs.data ()) {
300
+ return true ;
301
+ }
302
+
303
+ return std::equal (lhs.data (), lhs.data () + lhs.size (), rhs.data ());
304
+ }
305
+
306
+ /* *
307
+ * Not equal operator
308
+ *
309
+ * @param lhs Left hand side of the binary operation.
310
+ * @param rhs Right hand side of the binary operation.
311
+ *
312
+ * @return True if arrays in input do not have the same size or the same
313
+ * content and false otherwise.
314
+ */
315
+ template <typename T, ptrdiff_t LhsSize, ptrdiff_t RhsSize>
316
+ bool operator !=(const ArrayView<T, LhsSize>& lhs, const ArrayView<T, LhsSize>& rhs)
317
+ {
318
+ return !(lhs == rhs);
319
+ }
320
+
321
+
189
322
/* *
190
323
* Generate an array view from a reference to a C/C++ array.
191
324
*
@@ -200,9 +333,28 @@ struct ArrayView {
200
333
* created 'inline'.
201
334
*/
202
335
template <typename T, size_t Size>
203
- ArrayView<T> make_ArrayView (T (&elements)[Size])
336
+ ArrayView<T, Size > make_ArrayView (T (&elements)[Size])
204
337
{
205
- return ArrayView<T>(elements);
338
+ return ArrayView<T, Size>(elements);
339
+ }
340
+
341
+ /* *
342
+ * Generate an array view from a pointer to a C/C++ array.
343
+ *
344
+ * @tparam Size Number of items held in elements.
345
+ * @tparam T Type of elements held in elements.
346
+ *
347
+ * @param elements The reference to the array viewed.
348
+ *
349
+ * @return The ArrayView to elements.
350
+ *
351
+ * @note This helper avoids the typing of template parameter when ArrayView is
352
+ * created 'inline'.
353
+ */
354
+ template <size_t Size, typename T>
355
+ ArrayView<T, Size> make_ArrayView (T* elements)
356
+ {
357
+ return ArrayView<T, Size>(elements, Size);
206
358
}
207
359
208
360
/* *
@@ -237,9 +389,28 @@ ArrayView<T> make_ArrayView(T* array_ptr, size_t array_size)
237
389
* created 'inline'.
238
390
*/
239
391
template <typename T, size_t Size>
240
- ArrayView<const T> make_const_ArrayView (T (&elements)[Size])
392
+ ArrayView<const T, Size> make_const_ArrayView (T (&elements)[Size])
393
+ {
394
+ return ArrayView<const T, Size>(elements);
395
+ }
396
+
397
+ /* *
398
+ * Generate a const array view from a pointer to a C/C++ array.
399
+ *
400
+ * @tparam Size Number of items held in elements.
401
+ * @tparam T Type of elements held in elements.
402
+ *
403
+ * @param elements The reference to the array viewed.
404
+ *
405
+ * @return The ArrayView to elements.
406
+ *
407
+ * @note This helper avoids the typing of template parameter when ArrayView is
408
+ * created 'inline'.
409
+ */
410
+ template <size_t Size, typename T>
411
+ ArrayView<const T, Size> make_const_ArrayView (const T* elements)
241
412
{
242
- return ArrayView<const T>(elements);
413
+ return ArrayView<const T, Size >(elements, Size );
243
414
}
244
415
245
416
/* *
0 commit comments