@@ -33,29 +33,140 @@ namespace mbed {
33
33
#define SPAN_DYNAMIC_EXTENT -1
34
34
35
35
/* *
36
- * View to an array .
36
+ * Non owning view to a sequence of contiguous elements .
37
37
*
38
- * Spans encapsulate the pointer to an array and its size into a single object.
39
- * However, it does not manage the lifetime of the array viewed. You can use
40
- * instances of Span to replace the traditional pair of pointer and size
41
- * arguments in function calls.
38
+ * Spans encapsulate a pointer to a sequence of contiguous elements and its size
39
+ * into a single object. Span can replace the traditional pair of pointer and
40
+ * size arguments passed as array definition in function calls.
42
41
*
43
- * You can use the size member function to query the number of elements present
44
- * in the array, and the subscript operator allow code using this object to
45
- * access the content of the array viewed.
42
+ * @paragraph Operations
46
43
*
47
- * Subspans can be created with the help of the functions first(), last() and
48
- * subspan().
44
+ * Span objects can be copied and assigned like regular value types with the help
45
+ * of copy constructor and copy assignment (=) operator.
46
+ *
47
+ * Elements of the object can be retrieved with the subscript ([]) operator. The
48
+ * pointer to the first element of the sequence viewed can be accessed with data()
49
+ * while the function size() returns the number of elements in the sequence and
50
+ * empty() informs if the there is any element in the sequence.
51
+ *
52
+ * Span can be sliced from the beginning of the sequence (first()), from the end
53
+ * of the sequence (last()) or from an arbitrary point of the sequence (subspan()).
54
+ *
55
+ * @paragraph Size encoding
56
+ *
57
+ * The size of the sequence can be encoded in the type itself or in the value of
58
+ * the instance with the help of the template parameter Extent:
59
+ *
60
+ * - Span<uint8_t, 6>: Span over a sequence of 6 element
61
+ * - Span<uint8_t>: Span over an arbitrary long sequence.
62
+ *
63
+ * When the size is encoded in the type itself, it is guaranteed that the Span
64
+ * view a valid sequence (not empty() and not NULL). The type system also prevent
65
+ * automatic conversion from Span of different sizes. Finally, the size of the
66
+ * span object is a single pointer.
67
+ *
68
+ * When the size of the sequence viewed is encoded in the Span value, span
69
+ * instances can view invalid sequence (empty and NULL pointer). The function
70
+ * empty() helps client code to decide if valid content is being viewed or not.
71
+ *
72
+ * @paragraph Example
73
+ *
74
+ * - Encoding fixed size array: Array values in parameter decays automatically
75
+ * to pointer which leaves room for subtitle bugs:
76
+ *
77
+ * @code
78
+ * typedef uint8_t mac_address_t[6];
79
+ * void process_mac(mac_address_t);
80
+ *
81
+ * // compile just fine
82
+ * uint8_t* invalid_value = NULL;
83
+ * process_mac(invalid_value);
84
+ *
85
+ *
86
+ * // correct way
87
+ * typedef Span<uint8_t, 6> mac_address_t;
88
+ * void process_mac(mac_address_t);
89
+ *
90
+ * // compilation error
91
+ * uint8_t* invalid_value = NULL;
92
+ * process_mac(invalid_value);
93
+ *
94
+ * // compilation ok
95
+ * uint8_t valid_value[6];
96
+ * process_mac(valid_value);
97
+ * @endcode
98
+ *
99
+ * - Arbitrary buffer: When dealing with multiple buffers, it becomes painful to
100
+ * keep track of every buffer size and pointer.
101
+ *
102
+ * @code
103
+ * const uint8_t options_tag[OPTIONS_TAG_SIZE];
104
+ *
105
+ * struct parsed_value_t {
106
+ * uint8_t* header;
107
+ * uint8_t* options;
108
+ * uint8_t* payload;
109
+ * size_t payload_size;
110
+ * }
111
+ *
112
+ * parsed_value_t parse(uint8_t* buffer, size_t buffer_size) {
113
+ * parsed_value_t parsed_value { 0 };
114
+ *
115
+ * if (buffer != NULL && buffer_size <= MINIMAL_BUFFER_SIZE) {
116
+ * return parsed_value;
117
+ * }
118
+ *
119
+ * parsed_value.header = buffer;
120
+ * parsed_value.header_size = BUFFER_HEADER_SIZE;
121
+ *
122
+ * if (memcmp(buffer + HEADER_OPTIONS_INDEX, options_tag, sizeof(options_tag)) == 0) {
123
+ * options = buffer + BUFFER_HEADER_SIZE;
124
+ * payload = buffer + BUFFER_HEADER_SIZE + OPTIONS_SIZE;
125
+ * payload_size = buffer_size - BUFFER_HEADER_SIZE + OPTIONS_SIZE;
126
+ * } else {
127
+ * payload = buffer + BUFFER_HEADER_SIZE;
128
+ * payload_size = buffer_size - BUFFER_HEADER_SIZE;
129
+ * }
130
+ *
131
+ * return parsed_value;
132
+ * }
133
+ *
134
+ *
135
+ * //with span
136
+ * struct parsed_value_t {
137
+ * Span<uint8_t> header;
138
+ * Span<uint8_t> options;
139
+ * Span<uint8_t> payload;
140
+ * }
141
+ *
142
+ * parsed_value_t parse(Span<uint8_t> buffer) {
143
+ * parsed_value_t parsed_value;
144
+ *
145
+ * if (buffer.size() <= MINIMAL_BUFFER_SIZE) {
146
+ * return parsed_value;
147
+ * }
148
+ *
149
+ * parsed_value.header = buffer.first(BUFFER_HEADER_SIZE);
150
+ *
151
+ * if (buffer.subspan<HEADER_OPTIONS_INDEX, sizeof(options_tag)>() == option_tag) {
152
+ * options = buffer.supspan(parsed_value.header.size(), OPTIONS_SIZE);
153
+ * }
154
+ *
155
+ * payload = buffer.subspan(parsed_value.header.size() + parsed_value.options.size());
156
+ *
157
+ * return parsed_value;
158
+ * }
159
+ * @endcode
49
160
*
50
161
* @note You can create Span instances with the help of the function template
51
162
* make_Span() and make_const_Span().
52
163
*
53
164
* @note Span<T, Extent> objects can be implicitly converted to Span<T> objects
54
165
* where required.
55
166
*
56
- * @tparam ElementType type of objects held in the array viewed .
167
+ * @tparam ElementType type of objects viewed by the Span .
57
168
*
58
- * @tparam Extent The size of the array viewed. The default value
169
+ * @tparam Extent The size of the contiguous sequence viewed. The default value
59
170
* SPAN_DYNAMIC_SIZE is special as it allows construction of Span objects of
60
171
* any size (set at runtime).
61
172
*/
@@ -90,7 +201,7 @@ struct Span {
90
201
MBED_STATIC_ASSERT (Extent >= 0 , " Invalid extent for a Span" );
91
202
92
203
/* *
93
- * Construct an empty span .
204
+ * Construct an empty Span .
94
205
*
95
206
* @post a call to size() will return 0, and data() will return NULL.
96
207
*
@@ -112,7 +223,7 @@ struct Span {
112
223
* @param count Number of elements viewed.
113
224
*
114
225
* @pre [ptr, ptr + count) must be be a valid range.
115
- * @pre count must be equal to extent .
226
+ * @pre count must be equal to Extent .
116
227
*
117
228
* @post a call to size() will return Extent and data() will return @p ptr.
118
229
*/
@@ -153,19 +264,19 @@ struct Span {
153
264
_data (elements) { }
154
265
155
266
/* *
156
- * Return the size of the array viewed.
267
+ * Return the size of the sequence viewed.
157
268
*
158
- * @return The number of elements present in the array viewed.
269
+ * @return The size of the sequence viewed.
159
270
*/
160
271
index_type size () const
161
272
{
162
273
return Extent;
163
274
}
164
275
165
276
/* *
166
- * Return if the array is empty or not.
277
+ * Return if the sequence is empty or not.
167
278
*
168
- * @return true if the array is empty and false otherwise
279
+ * @return true if the sequence is empty and false otherwise
169
280
*/
170
281
bool empty () const
171
282
{
@@ -190,10 +301,10 @@ struct Span {
190
301
}
191
302
192
303
/* *
193
- * Return a pointer to the first element of the sequence or NULL if the span
304
+ * Return a pointer to the first element of the sequence or NULL if the Span
194
305
* is empty().
195
306
*
196
- * @return The pointer to the first element of the span .
307
+ * @return The pointer to the first element of the Span .
197
308
*/
198
309
pointer data () const
199
310
{
@@ -246,7 +357,7 @@ struct Span {
246
357
* is equal to SPAN_DYNAMIC_EXTENT then a span starting at offset and
247
358
* containing the rest of the elements is returned.
248
359
*
249
- * @return
360
+ * @return A subspan of this starting at Offset and Count long.
250
361
*/
251
362
template <std::ptrdiff_t Offset, std::ptrdiff_t Count>
252
363
Span<element_type, Count == SPAN_DYNAMIC_EXTENT ? Extent - Offset : Count>
@@ -324,7 +435,7 @@ struct Span {
324
435
};
325
436
326
437
/* *
327
- * Span specialisation that handle dynamic array size.
438
+ * Span specialisation that handle dynamic size.
328
439
*/
329
440
template <typename ElementType>
330
441
struct Span <ElementType, SPAN_DYNAMIC_EXTENT> {
@@ -355,7 +466,7 @@ struct Span<ElementType, SPAN_DYNAMIC_EXTENT> {
355
466
static const index_type extent = SPAN_DYNAMIC_EXTENT;
356
467
357
468
/* *
358
- * Construct an empty span .
469
+ * Construct an empty Span .
359
470
*
360
471
* @post a call to size() will return 0, and data() will return NULL.
361
472
*
@@ -437,17 +548,17 @@ struct Span<ElementType, SPAN_DYNAMIC_EXTENT> {
437
548
}
438
549
439
550
/* *
440
- * Return if the array is empty or not.
551
+ * Return if the sequence viewed is empty or not.
441
552
*
442
- * @return true if the array is empty and false otherwise
553
+ * @return true if the sequence is empty and false otherwise
443
554
*/
444
555
bool empty () const
445
556
{
446
557
return size () == 0 ;
447
558
}
448
559
449
560
/* *
450
- * Access to an element of the array .
561
+ * Access to an element of the sequence .
451
562
*
452
563
* @param index Element index to access.
453
564
*
@@ -464,17 +575,17 @@ struct Span<ElementType, SPAN_DYNAMIC_EXTENT> {
464
575
}
465
576
466
577
/* *
467
- * Get the raw pointer to the array .
578
+ * Get the raw pointer to the sequence viewed .
468
579
*
469
- * @return The raw pointer to the array .
580
+ * @return The raw pointer to the first element viewed .
470
581
*/
471
582
pointer data () const
472
583
{
473
584
return _data;
474
585
}
475
586
476
587
/* *
477
- * Create a new span over the first @p Count elements of the existing view.
588
+ * Create a new Span over the first @p Count elements of the existing view.
478
589
*
479
590
* @tparam Count The number of element viewed by the new Span
480
591
*
@@ -489,7 +600,7 @@ struct Span<ElementType, SPAN_DYNAMIC_EXTENT> {
489
600
}
490
601
491
602
/* *
492
- * Create a new span over the last @p Count elements of the existing view.
603
+ * Create a new Span over the last @p Count elements of the existing view.
493
604
*
494
605
* @tparam Count The number of element viewed by the new Span
495
606
*
@@ -513,7 +624,7 @@ struct Span<ElementType, SPAN_DYNAMIC_EXTENT> {
513
624
* is equal to SPAN_DYNAMIC_EXTENT then a span starting at offset and
514
625
* containing the rest of the elements is returned.
515
626
*
516
- * @return
627
+ * @return A subspan of this starting at Offset and Count long.
517
628
*/
518
629
template <std::ptrdiff_t Offset, std::ptrdiff_t Count>
519
630
Span<element_type, Count == SPAN_DYNAMIC_EXTENT ? SPAN_DYNAMIC_EXTENT : Count>
@@ -542,7 +653,7 @@ struct Span<ElementType, SPAN_DYNAMIC_EXTENT> {
542
653
}
543
654
544
655
/* *
545
- * Create a new span over the last @p count elements of the existing view.
656
+ * Create a new Span over the last @p count elements of the existing view.
546
657
*
547
658
* @param count The number of element viewed by the new Span
548
659
*
@@ -566,7 +677,7 @@ struct Span<ElementType, SPAN_DYNAMIC_EXTENT> {
566
677
* is equal to SPAN_DYNAMIC_EXTENT then a span starting at offset and
567
678
* containing the rest of the elements is returned.
568
679
*
569
- * @return
680
+ * @return A subspan of this starting at offset and count long.
570
681
*/
571
682
Span<element_type, SPAN_DYNAMIC_EXTENT> subspan (
572
683
index_type offset, index_type count = SPAN_DYNAMIC_EXTENT
@@ -593,8 +704,8 @@ struct Span<ElementType, SPAN_DYNAMIC_EXTENT> {
593
704
* @param lhs Left hand side of the binary operation.
594
705
* @param rhs Right hand side of the binary operation.
595
706
*
596
- * @return True if arrays in input have the same size and the same content
597
- * and false otherwise.
707
+ * @return True if Spans in input have the same size and the same content and
708
+ * false otherwise.
598
709
*/
599
710
template <typename T, typename U, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent>
600
711
bool operator ==(const Span<T, LhsExtent> &lhs, const Span<U, RhsExtent> &rhs)
@@ -616,8 +727,8 @@ bool operator==(const Span<T, LhsExtent> &lhs, const Span<U, RhsExtent> &rhs)
616
727
* @param lhs Left hand side of the binary operation.
617
728
* @param rhs Right hand side of the binary operation.
618
729
*
619
- * @return True if arrays in input have the same size and the same content
620
- * and false otherwise.
730
+ * @return True if elements in input have the same size and the same content and
731
+ * false otherwise.
621
732
*/
622
733
template <typename T, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent>
623
734
bool operator ==(const Span<T, LhsExtent> &lhs, T (&rhs)[RhsExtent])
@@ -626,12 +737,12 @@ bool operator==(const Span<T, LhsExtent> &lhs, T (&rhs)[RhsExtent])
626
737
}
627
738
628
739
/* *
629
- * Equality operation between a span and a reference to a C++ array.
740
+ * Equality operation between a Span and a reference to a C++ array.
630
741
*
631
742
* @param lhs Left hand side of the binary operation.
632
743
* @param rhs Right hand side of the binary operation.
633
744
*
634
- * @return True if arrays in input have the same size and the same content
745
+ * @return True if elements in input have the same size and the same content
635
746
* and false otherwise.
636
747
*/
637
748
template <typename T, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent>
@@ -646,8 +757,8 @@ bool operator==(T (&lhs)[LhsExtent], const Span<T, RhsExtent> &rhs)
646
757
* @param lhs Left hand side of the binary operation.
647
758
* @param rhs Right hand side of the binary operation.
648
759
*
649
- * @return True if arrays in input do not have the same size or the same
650
- * content and false otherwise.
760
+ * @return True if arrays in input do not have the same size or the same content
761
+ * and false otherwise.
651
762
*/
652
763
template <typename T, typename U, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent>
653
764
bool operator !=(const Span<T, LhsExtent> &lhs, const Span<U, RhsExtent> &rhs)
@@ -656,12 +767,12 @@ bool operator!=(const Span<T, LhsExtent> &lhs, const Span<U, RhsExtent> &rhs)
656
767
}
657
768
658
769
/* *
659
- * Not Equal operation between a span and a reference to a C++ array.
770
+ * Not Equal operation between a Span and a reference to a C++ array.
660
771
*
661
772
* @param lhs Left hand side of the binary operation.
662
773
* @param rhs Right hand side of the binary operation.
663
774
*
664
- * @return True if arrays in input have the same size and the same content
775
+ * @return True if elements in input have the same size and the same content
665
776
* and false otherwise.
666
777
*/
667
778
template <typename T, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent>
@@ -671,12 +782,12 @@ bool operator!=(const Span<T, LhsExtent> &lhs, T (&rhs)[RhsExtent])
671
782
}
672
783
673
784
/* *
674
- * Not Equal operation between a span and a reference to a C++ array.
785
+ * Not Equal operation between a Span and a reference to a C++ array.
675
786
*
676
787
* @param lhs Left hand side of the binary operation.
677
788
* @param rhs Right hand side of the binary operation.
678
789
*
679
- * @return True if arrays in input have the same size and the same content
790
+ * @return True if elements in input have the same size and the same content
680
791
* and false otherwise.
681
792
*/
682
793
template <typename T, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent>
@@ -728,7 +839,7 @@ Span<T, Extent> make_Span(T *elements)
728
839
*
729
840
* @tparam T Type of elements held in array_ptr.
730
841
*
731
- * @param array_ptr The pointer to the array to viewed.
842
+ * @param array_ptr The pointer to the array viewed.
732
843
* @param array_size The number of T elements in the array.
733
844
*
734
845
* @return The Span to array_ptr with a size of array_size.
0 commit comments