Skip to content

Commit 4e7fa91

Browse files
committed
Span: amend documentation
1 parent 95fc284 commit 4e7fa91

File tree

1 file changed

+157
-46
lines changed

1 file changed

+157
-46
lines changed

platform/Span.h

Lines changed: 157 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -33,29 +33,140 @@ namespace mbed {
3333
#define SPAN_DYNAMIC_EXTENT -1
3434

3535
/**
36-
* View to an array.
36+
* Non owning view to a sequence of contiguous elements.
3737
*
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.
4241
*
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
4643
*
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
49160
*
50161
* @note You can create Span instances with the help of the function template
51162
* make_Span() and make_const_Span().
52163
*
53164
* @note Span<T, Extent> objects can be implicitly converted to Span<T> objects
54165
* where required.
55166
*
56-
* @tparam ElementType type of objects held in the array viewed.
167+
* @tparam ElementType type of objects viewed by the Span.
57168
*
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
59170
* SPAN_DYNAMIC_SIZE is special as it allows construction of Span objects of
60171
* any size (set at runtime).
61172
*/
@@ -90,7 +201,7 @@ struct Span {
90201
MBED_STATIC_ASSERT(Extent >= 0, "Invalid extent for a Span");
91202

92203
/**
93-
* Construct an empty span.
204+
* Construct an empty Span.
94205
*
95206
* @post a call to size() will return 0, and data() will return NULL.
96207
*
@@ -112,7 +223,7 @@ struct Span {
112223
* @param count Number of elements viewed.
113224
*
114225
* @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.
116227
*
117228
* @post a call to size() will return Extent and data() will return @p ptr.
118229
*/
@@ -153,19 +264,19 @@ struct Span {
153264
_data(elements) { }
154265

155266
/**
156-
* Return the size of the array viewed.
267+
* Return the size of the sequence viewed.
157268
*
158-
* @return The number of elements present in the array viewed.
269+
* @return The size of the sequence viewed.
159270
*/
160271
index_type size() const
161272
{
162273
return Extent;
163274
}
164275

165276
/**
166-
* Return if the array is empty or not.
277+
* Return if the sequence is empty or not.
167278
*
168-
* @return true if the array is empty and false otherwise
279+
* @return true if the sequence is empty and false otherwise
169280
*/
170281
bool empty() const
171282
{
@@ -190,10 +301,10 @@ struct Span {
190301
}
191302

192303
/**
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
194305
* is empty().
195306
*
196-
* @return The pointer to the first element of the span.
307+
* @return The pointer to the first element of the Span.
197308
*/
198309
pointer data() const
199310
{
@@ -246,7 +357,7 @@ struct Span {
246357
* is equal to SPAN_DYNAMIC_EXTENT then a span starting at offset and
247358
* containing the rest of the elements is returned.
248359
*
249-
* @return
360+
* @return A subspan of this starting at Offset and Count long.
250361
*/
251362
template<std::ptrdiff_t Offset, std::ptrdiff_t Count>
252363
Span<element_type, Count == SPAN_DYNAMIC_EXTENT ? Extent - Offset : Count>
@@ -324,7 +435,7 @@ struct Span {
324435
};
325436

326437
/**
327-
* Span specialisation that handle dynamic array size.
438+
* Span specialisation that handle dynamic size.
328439
*/
329440
template<typename ElementType>
330441
struct Span<ElementType, SPAN_DYNAMIC_EXTENT> {
@@ -355,7 +466,7 @@ struct Span<ElementType, SPAN_DYNAMIC_EXTENT> {
355466
static const index_type extent = SPAN_DYNAMIC_EXTENT;
356467

357468
/**
358-
* Construct an empty span.
469+
* Construct an empty Span.
359470
*
360471
* @post a call to size() will return 0, and data() will return NULL.
361472
*
@@ -437,17 +548,17 @@ struct Span<ElementType, SPAN_DYNAMIC_EXTENT> {
437548
}
438549

439550
/**
440-
* Return if the array is empty or not.
551+
* Return if the sequence viewed is empty or not.
441552
*
442-
* @return true if the array is empty and false otherwise
553+
* @return true if the sequence is empty and false otherwise
443554
*/
444555
bool empty() const
445556
{
446557
return size() == 0;
447558
}
448559

449560
/**
450-
* Access to an element of the array.
561+
* Access to an element of the sequence.
451562
*
452563
* @param index Element index to access.
453564
*
@@ -464,17 +575,17 @@ struct Span<ElementType, SPAN_DYNAMIC_EXTENT> {
464575
}
465576

466577
/**
467-
* Get the raw pointer to the array.
578+
* Get the raw pointer to the sequence viewed.
468579
*
469-
* @return The raw pointer to the array.
580+
* @return The raw pointer to the first element viewed.
470581
*/
471582
pointer data() const
472583
{
473584
return _data;
474585
}
475586

476587
/**
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.
478589
*
479590
* @tparam Count The number of element viewed by the new Span
480591
*
@@ -489,7 +600,7 @@ struct Span<ElementType, SPAN_DYNAMIC_EXTENT> {
489600
}
490601

491602
/**
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.
493604
*
494605
* @tparam Count The number of element viewed by the new Span
495606
*
@@ -513,7 +624,7 @@ struct Span<ElementType, SPAN_DYNAMIC_EXTENT> {
513624
* is equal to SPAN_DYNAMIC_EXTENT then a span starting at offset and
514625
* containing the rest of the elements is returned.
515626
*
516-
* @return
627+
* @return A subspan of this starting at Offset and Count long.
517628
*/
518629
template<std::ptrdiff_t Offset, std::ptrdiff_t Count>
519630
Span<element_type, Count == SPAN_DYNAMIC_EXTENT ? SPAN_DYNAMIC_EXTENT : Count>
@@ -542,7 +653,7 @@ struct Span<ElementType, SPAN_DYNAMIC_EXTENT> {
542653
}
543654

544655
/**
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.
546657
*
547658
* @param count The number of element viewed by the new Span
548659
*
@@ -566,7 +677,7 @@ struct Span<ElementType, SPAN_DYNAMIC_EXTENT> {
566677
* is equal to SPAN_DYNAMIC_EXTENT then a span starting at offset and
567678
* containing the rest of the elements is returned.
568679
*
569-
* @return
680+
* @return A subspan of this starting at offset and count long.
570681
*/
571682
Span<element_type, SPAN_DYNAMIC_EXTENT> subspan(
572683
index_type offset, index_type count = SPAN_DYNAMIC_EXTENT
@@ -593,8 +704,8 @@ struct Span<ElementType, SPAN_DYNAMIC_EXTENT> {
593704
* @param lhs Left hand side of the binary operation.
594705
* @param rhs Right hand side of the binary operation.
595706
*
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.
598709
*/
599710
template<typename T, typename U, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent>
600711
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)
616727
* @param lhs Left hand side of the binary operation.
617728
* @param rhs Right hand side of the binary operation.
618729
*
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.
621732
*/
622733
template<typename T, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent>
623734
bool operator==(const Span<T, LhsExtent> &lhs, T (&rhs)[RhsExtent])
@@ -626,12 +737,12 @@ bool operator==(const Span<T, LhsExtent> &lhs, T (&rhs)[RhsExtent])
626737
}
627738

628739
/**
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.
630741
*
631742
* @param lhs Left hand side of the binary operation.
632743
* @param rhs Right hand side of the binary operation.
633744
*
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
635746
* and false otherwise.
636747
*/
637748
template<typename T, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent>
@@ -646,8 +757,8 @@ bool operator==(T (&lhs)[LhsExtent], const Span<T, RhsExtent> &rhs)
646757
* @param lhs Left hand side of the binary operation.
647758
* @param rhs Right hand side of the binary operation.
648759
*
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.
651762
*/
652763
template<typename T, typename U, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent>
653764
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)
656767
}
657768

658769
/**
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.
660771
*
661772
* @param lhs Left hand side of the binary operation.
662773
* @param rhs Right hand side of the binary operation.
663774
*
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
665776
* and false otherwise.
666777
*/
667778
template<typename T, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent>
@@ -671,12 +782,12 @@ bool operator!=(const Span<T, LhsExtent> &lhs, T (&rhs)[RhsExtent])
671782
}
672783

673784
/**
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.
675786
*
676787
* @param lhs Left hand side of the binary operation.
677788
* @param rhs Right hand side of the binary operation.
678789
*
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
680791
* and false otherwise.
681792
*/
682793
template<typename T, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent>
@@ -728,7 +839,7 @@ Span<T, Extent> make_Span(T *elements)
728839
*
729840
* @tparam T Type of elements held in array_ptr.
730841
*
731-
* @param array_ptr The pointer to the array to viewed.
842+
* @param array_ptr The pointer to the array viewed.
732843
* @param array_size The number of T elements in the array.
733844
*
734845
* @return The Span to array_ptr with a size of array_size.

0 commit comments

Comments
 (0)