Mbed OS Reference
Loading...
Searching...
No Matches
Span.h
1/* mbed Microcontroller Library
2 * Copyright (c) 2018-2019 ARM Limited
3 * SPDX-License-Identifier: Apache-2.0
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#ifndef MBED_PLATFORM_SPAN_H_
19#define MBED_PLATFORM_SPAN_H_
20
21#include <algorithm>
22#include <iterator>
23#include <stddef.h>
24#include <stdint.h>
25
26#include "platform/mbed_assert.h"
27
28namespace mbed {
29
30/** \addtogroup platform-public-api */
31/** @{*/
32
33/**
34 * \defgroup platform_Span Span class
35 * @{
36 */
37
38// Internal details of Span
39// It is used construct Span from Span of convertible types (non const -> const)
40namespace span_detail {
41
42// If From type is convertible to To type, then the compilation constant value is
43// true; otherwise, it is false.
44template<typename From, typename To>
46 struct true_type {
47 char x[512];
48 };
49 struct false_type { };
50
51 static const From &generator();
52 static true_type sink(const To &);
53 static false_type sink(...);
54
55public:
56 static const bool value = sizeof(true_type) == sizeof(sink(generator()));
57};
58
59}
60
61#if defined(DOXYGEN_ONLY)
62/**
63 * Special value for the Extent parameter of Span.
64 * If the type uses this value, then the size of the array is stored in the object
65 * at runtime.
66 *
67 * @relates Span
68 */
69const ptrdiff_t SPAN_DYNAMIC_EXTENT = -1;
70#else
71#define SPAN_DYNAMIC_EXTENT -1
72#endif
73
74/**
75 * Nonowning view to a sequence of contiguous elements.
76 *
77 * Spans encapsulate a pointer to a sequence of contiguous elements and its size
78 * into a single object. Span can replace the traditional pair of pointer and
79 * size arguments passed as array definitions in function calls.
80 *
81 * @par Operations
82 *
83 * Span objects can be copied and assigned like regular value types with the help
84 * of the copy constructor or the copy assignment (=) operator.
85 *
86 * You can retrieve elements of the object with the subscript ([]) operator. You can access the
87 * pointer to the first element of the sequence viewed with data().
88 * The function size() returns the number of elements in the sequence, and
89 * empty() informs whether there is any element in the sequence.
90 *
91 * You can slice Span from the beginning of the sequence (first()), from the end
92 * of the sequence (last()) or from an arbitrary point of the sequence (subspan()).
93 *
94 * @par Size encoding
95 *
96 * The size of the sequence can be encoded in the type itself or in the value of
97 * the instance with the help of the template parameter Extent:
98 *
99 * - Span<uint8_t, 6>: Span over a sequence of 6 elements.
100 * - Span<uint8_t>: Span over an arbitrary long sequence.
101 *
102 * When the size is encoded in the type itself, it is guaranteed that the Span
103 * view is a valid sequence (not empty() and not NULL) - unless Extent equals 0.
104 * The type system also prevents automatic conversion from Span of different
105 * sizes. Finally, the Span object is internally represented as a single pointer.
106 *
107 * When the size of the sequence viewed is encoded in the Span value, Span
108 * instances can view an empty sequence. The function empty() helps client code
109 * decide whether Span is viewing valid content or not.
110 *
111 * @par Example
112 *
113 * - Encoding fixed size array: Array values in parameter decays automatically
114 * to pointer, which leaves room for subtitle bugs:
115 *
116 * @code
117 typedef uint8_t mac_address_t[6];
118 void process_mac(mac_address_t);
119
120 // compile just fine
121 uint8_t *invalid_value = NULL;
122 process_mac(invalid_value);
123
124
125 // correct way
126 typedef Span<uint8_t, 6> mac_address_t;
127 void process_mac(mac_address_t);
128
129 // compilation error
130 uint8_t *invalid_value = NULL;
131 process_mac(invalid_value);
132
133 // compilation ok
134 uint8_t valid_value[6];
135 process_mac(valid_value);
136 * @endcode
137 *
138 * - Arbitrary buffer: When dealing with multiple buffers, it becomes painful to
139 * keep track of every buffer size and pointer.
140 *
141 * @code
142 const uint8_t options_tag[OPTIONS_TAG_SIZE];
143
144 struct parsed_value_t {
145 uint8_t *header;
146 uint8_t *options;
147 uint8_t *payload;
148 size_t payload_size;
149 }
150
151 parsed_value_t parse(uint8_t *buffer, size_t buffer_size)
152 {
153 parsed_value_t parsed_value { 0 };
154
155 if (buffer != NULL && buffer_size <= MINIMAL_BUFFER_SIZE) {
156 return parsed_value;
157 }
158
159 parsed_value.header = buffer;
160 parsed_value.header_size = BUFFER_HEADER_SIZE;
161
162 if (memcmp(buffer + HEADER_OPTIONS_INDEX, options_tag, sizeof(options_tag)) == 0) {
163 options = buffer + BUFFER_HEADER_SIZE;
164 payload = buffer + BUFFER_HEADER_SIZE + OPTIONS_SIZE;
165 payload_size = buffer_size - BUFFER_HEADER_SIZE + OPTIONS_SIZE;
166 } else {
167 payload = buffer + BUFFER_HEADER_SIZE;
168 payload_size = buffer_size - BUFFER_HEADER_SIZE;
169 }
170
171 return parsed_value;
172 }
173
174
175 //with Span
176 struct parsed_value_t {
177 Span<uint8_t> header;
178 Span<uint8_t> options;
179 Span<uint8_t> payload;
180 }
181
182 parsed_value_t parse(const Span<uint8_t> &buffer)
183 {
184 parsed_value_t parsed_value;
185
186 if (buffer.size() <= MINIMAL_BUFFER_SIZE) {
187 return parsed_value;
188 }
189
190 parsed_value.header = buffer.first(BUFFER_HEADER_SIZE);
191
192 if (buffer.subspan<HEADER_OPTIONS_INDEX, sizeof(options_tag)>() == option_tag) {
193 options = buffer.supspan(parsed_value.header.size(), OPTIONS_SIZE);
194 }
195
196 payload = buffer.subspan(parsed_value.header.size() + parsed_value.options.size());
197
198 return parsed_value;
199 }
200 * @endcode
201 *
202 * @note You can create Span instances with the help of the function template
203 * make_Span() and make_const_Span().
204 *
205 * @note Span<T, Extent> objects can be implicitly converted to Span<T> objects
206 * where required.
207 *
208 * @tparam ElementType type of objects the Span views.
209 *
210 * @tparam Extent The size of the contiguous sequence viewed. The default value
211 * SPAN_DYNAMIC_SIZE is special because it allows construction of Span objects of
212 * any size (set at runtime).
213 */
214template<typename ElementType, ptrdiff_t Extent = SPAN_DYNAMIC_EXTENT>
215struct Span {
216
217 /**
218 * Type of the element contained
219 */
220 typedef ElementType element_type;
221
222 /**
223 * Type of the index.
224 */
225 typedef ptrdiff_t index_type;
226
227 /**
228 * Pointer to an ElementType
229 */
231
232 /**
233 * Reference to an ElementType
234 */
236
237 /**
238 * Iterator to an ElementType
239 */
241
242 /**
243 * Reverse iterator to an ElementType
244 */
245 typedef std::reverse_iterator<iterator> reverse_iterator;
246
247 /**
248 * Size of the Extent; -1 if dynamic.
249 */
250 static const index_type extent = Extent;
251
252 static_assert(Extent >= 0, "Invalid extent for a Span");
253
254 /**
255 * Construct an empty Span.
256 *
257 * @post a call to size() returns 0, and data() returns NULL.
258 *
259 * @note This function is not accessible if Extent != SPAN_DYNAMIC_EXTENT or
260 * Extent != 0 .
261 */
263 _data(NULL)
264 {
265 static_assert(
266 Extent == 0,
267 "Cannot default construct a static-extent Span (unless Extent is 0)"
268 );
269 }
270
271 /**
272 * Construct a Span from a pointer to a buffer and its size.
273 *
274 * @param ptr Pointer to the beginning of the data viewed.
275 *
276 * @param count Number of elements viewed.
277 *
278 * @pre [ptr, ptr + count) must be be a valid range.
279 * @pre count must be equal to Extent.
280 *
281 * @post a call to size() returns Extent, and data() returns @p ptr.
282 */
283 Span(pointer ptr, index_type count) :
284 _data(ptr)
285 {
286 MBED_ASSERT(count == Extent);
287 MBED_ASSERT(Extent == 0 || ptr != NULL);
288 }
289
290 /**
291 * Construct a Span from the range [first, last).
292 *
293 * @param first Pointer to the beginning of the data viewed.
294 * @param last End of the range (element after the last element).
295 *
296 * @pre [first, last) must be be a valid range.
297 * @pre first <= last.
298 * @pre last - first must be equal to Extent.
299 *
300 * @post a call to size() returns Extent, and data() returns @p first.
301 */
303 _data(first)
304 {
306 MBED_ASSERT((last - first) == Extent);
307 MBED_ASSERT(Extent == 0 || first != NULL);
308 }
309
310 // AStyle ignore, not handling correctly below
311 // *INDENT-OFF*
312 /**
313 * Construct a Span from the reference to an array.
314 *
315 * @param elements Reference to the array viewed.
316 *
317 * @post a call to size() returns Extent, and data() returns a
318 * pointer to elements.
319 */
320 Span(element_type (&elements)[Extent]):
321 _data(elements) { }
322
323 /**
324 * Construct a Span object from another Span of the same size.
325 *
326 * @param other The Span object used to construct this.
327 *
328 * @note For Span with a positive extent, this function is not accessible.
329 *
330 * @note OtherElementType(*)[] must be convertible to ElementType(*)[].
331 */
332 template<typename OtherElementType>
334 _data(other.data())
335 {
336 static_assert(
337 (span_detail::is_convertible<OtherElementType (*)[1], ElementType (*)[1]>::value),
338 "OtherElementType(*)[] should be convertible to ElementType (*)[]"
339 );
340 }
341 // *INDENT-ON*
342
343 /**
344 * Return the size of the sequence viewed.
345 *
346 * @return The size of the sequence viewed.
347 */
349 {
350 return Extent;
351 }
352
353 /**
354 * Return if the sequence is empty or not.
355 *
356 * @return true if the sequence is empty and false otherwise.
357 */
358 bool empty() const
359 {
360 return size() == 0;
361 }
362
363 /**
364 * Return an iterator to the first element of the sequence.
365 *
366 * @return An iterator to the first element of the sequence.
367 */
369 {
370 return _data;
371 }
372
373 /**
374 * Return an iterator to the element following the last element of the sequence.
375 *
376 * @return An iterator to the element following the last element of the sequence.
377 */
378 iterator end() const
379 {
380 return _data + Extent;
381 }
382
383 /**
384 * Return a reverse_iterator to the first element of the reversed sequence.
385 *
386 * @return A reverse_iterator to the first element of the reversed sequence.
387 */
389 {
390 return reverse_iterator(end());
391 }
392
393 /**
394 * Return a reverse_iterator to the element following the last element of the reversed sequence.
395 *
396 * @return A reverse_iterator to the element following the last element of the reversed sequence.
397 */
399 {
400 return reverse_iterator(begin());
401 }
402
403 /**
404 * Returns a reference to the element at position @p index.
405 *
406 * @param index Index of the element to access.
407 *
408 * @return A reference to the element at the index specified in input.
409 *
410 * @pre 0 <= index < Extent.
411 */
413 {
414#ifdef MBED_DEBUG
415 MBED_ASSERT(0 <= index && index < Extent);
416#endif
417 return _data[index];
418 }
419
420 /**
421 * Return a pointer to the first element of the sequence or NULL if the Span
422 * is empty().
423 *
424 * @return The pointer to the first element of the Span.
425 */
426 pointer data() const
427 {
428 return _data;
429 }
430
431 /**
432 * Create a new Span over the first @p Count elements of the existing view.
433 *
434 * @tparam Count The number of element viewed by the new Span
435 *
436 * @return A new Span over the first @p Count elements.
437 *
438 * @pre Count >= 0 && Count <= size().
439 */
440 template<ptrdiff_t Count>
442 {
443 static_assert(
444 (0 <= Count) && (Count <= Extent),
445 "Invalid subspan extent"
446 );
447 return Span<element_type, Count>(_data, Count);
448 }
449
450 /**
451 * Create a new Span over the last @p Count elements of the existing view.
452 *
453 * @tparam Count The number of element viewed by the new Span.
454 *
455 * @return A new Span over the last @p Count elements.
456 *
457 * @pre Count >= 0 && Count <= size().
458 */
459 template<ptrdiff_t Count>
461 {
462 static_assert(
463 (0 <= Count) && (Count <= Extent),
464 "Invalid subspan extent"
465 );
466 return Span<element_type, Count>(_data + (Extent - Count), Count);
467 }
468
469 // AStyle ignore, not handling correctly below
470 // *INDENT-OFF*
471 /**
472 * Create a subspan that is a view of other Count elements; the view starts at
473 * element Offset.
474 *
475 * @tparam Offset The offset of the first element viewed by the subspan.
476 *
477 * @tparam Count The number of elements present in the subspan. If Count
478 * is equal to SPAN_DYNAMIC_EXTENT, then a Span starting at offset and
479 * containing the rest of the elements is returned.
480 *
481 * @return A subspan of this starting at Offset and Count long.
482 */
483 template<std::ptrdiff_t Offset, std::ptrdiff_t Count>
484 Span<element_type, Count == SPAN_DYNAMIC_EXTENT ? Extent - Offset : Count>
485 subspan() const
486 {
487 static_assert(
488 0 <= Offset && Offset <= Extent,
489 "Invalid subspan offset"
490 );
491 static_assert(
492 (Count == SPAN_DYNAMIC_EXTENT) ||
493 (0 <= Count && (Count + Offset) <= Extent),
494 "Invalid subspan count"
495 );
496 return Span<element_type, Count == SPAN_DYNAMIC_EXTENT ? Extent - Offset : Count>(
497 _data + Offset,
498 Count == SPAN_DYNAMIC_EXTENT ? Extent - Offset : Count
499 );
500 }
501 // *INDENT-ON*
502
503 /**
504 * Create a new Span over the first @p count elements of the existing view.
505 *
506 * @param count The number of element viewed by the new Span.
507 *
508 * @return A new Span over the first @p count elements.
509 */
511 {
512 MBED_ASSERT(0 <= count && count <= Extent);
513 return Span<element_type, SPAN_DYNAMIC_EXTENT>(_data, count);
514 }
515
516 /**
517 * Create a new Span over the last @p count elements of the existing view.
518 *
519 * @param count The number of elements viewed by the new Span.
520 *
521 * @return A new Span over the last @p count elements.
522 */
524 {
525 MBED_ASSERT(0 <= count && count <= Extent);
527 _data + (Extent - count),
528 count
529 );
530 }
531
532 /**
533 * Create a subspan that is a view of other count elements; the view starts at
534 * element offset.
535 *
536 * @param offset The offset of the first element viewed by the subspan.
537 *
538 * @param count The number of elements present in the subspan. If Count
539 * is equal to SPAN_DYNAMIC_EXTENT, then a span starting at offset and
540 * containing the rest of the elements is returned.
541 *
542 * @return
543 */
546 ) const
547 {
548 MBED_ASSERT(0 <= offset && offset <= Extent);
550 (count == SPAN_DYNAMIC_EXTENT) ||
551 (0 <= count && (count + offset) <= Extent)
552 );
554 _data + offset,
555 count == SPAN_DYNAMIC_EXTENT ? Extent - offset : count
556 );
557 }
558
559private:
560 pointer _data;
561};
562
563/**
564 * Span specialization that handle dynamic size.
565 */
566template<typename ElementType>
567struct Span<ElementType, SPAN_DYNAMIC_EXTENT> {
568 /**
569 * Type of the element contained.
570 */
571 typedef ElementType element_type;
572
573 /**
574 * Type of the index.
575 */
576 typedef ptrdiff_t index_type;
577
578 /**
579 * Pointer to an ElementType.
580 */
582
583 /**
584 * Reference to an ElementType.
585 */
587
588 /**
589 * Iterator to an ElementType
590 */
592
593 /**
594 * Reverse iterator to an ElementType
595 */
596 typedef std::reverse_iterator<iterator> reverse_iterator;
597
598 /**
599 * Size of the Extent; -1 if dynamic.
600 */
602
603 /**
604 * Construct an empty Span.
605 *
606 * @post a call to size() returns 0, and data() returns NULL.
607 *
608 * @note This function is not accessible if Extent != SPAN_DYNAMIC_EXTENT or
609 * Extent != 0 .
610 */
612 _data(NULL), _size(0) { }
613
614 /**
615 * Construct a Span from a pointer to a buffer and its size.
616 *
617 * @param ptr Pointer to the beginning of the data viewed.
618 *
619 * @param count Number of elements viewed.
620 *
621 * @pre [ptr, ptr + count) must be be a valid range.
622 * @pre count must be equal to extent.
623 *
624 * @post a call to size() returns count, and data() returns @p ptr.
625 */
626 Span(pointer ptr, index_type count) :
627 _data(ptr), _size(count)
628 {
629 MBED_ASSERT(count >= 0);
630 MBED_ASSERT(ptr != NULL || count == 0);
631 }
632
633 /**
634 * Construct a Span from the range [first, last).
635 *
636 * @param first Pointer to the beginning of the data viewed.
637 * @param last End of the range (element after the last element).
638 *
639 * @pre [first, last) must be be a valid range.
640 * @pre first <= last.
641 *
642 * @post a call to size() returns the result of (last - first), and
643 * data() returns @p first.
644 */
646 _data(first), _size(last - first)
647 {
649 MBED_ASSERT(first != NULL || (last - first) == 0);
650 }
651
652 // AStyle ignore, not handling correctly below
653 // *INDENT-OFF*
654 /**
655 * Construct a Span from the reference to an array.
656 *
657 * @param elements Reference to the array viewed.
658 *
659 * @tparam Count Number of elements of T presents in the array.
660 *
661 * @post a call to size() returns Count, and data() returns a
662 * pointer to elements.
663 */
664 template<size_t Count>
665 Span(element_type (&elements)[Count]):
666 _data(elements), _size(Count) { }
667
668 /**
669 * Construct a Span object from another Span.
670 *
671 * @param other The Span object used to construct this.
672 *
673 * @note For Span with a positive extent, this function is not accessible.
674 *
675 * @note OtherElementType(*)[] must be convertible to ElementType(*)[].
676 */
677 template<typename OtherElementType, ptrdiff_t OtherExtent>
679 _data(other.data()), _size(other.size())
680 {
681 static_assert(
682 (span_detail::is_convertible<OtherElementType (*)[1], ElementType (*)[1]>::value),
683 "OtherElementType(*)[] should be convertible to ElementType (*)[]"
684 );
685 }
686 // *INDENT-ON*
687
688 /**
689 * Return the size of the array viewed.
690 *
691 * @return The number of elements present in the array viewed.
692 */
694 {
695 return _size;
696 }
697
698 /**
699 * Return if the sequence viewed is empty or not.
700 *
701 * @return true if the sequence is empty and false otherwise.
702 */
703 bool empty() const
704 {
705 return size() == 0;
706 }
707
708 /**
709 * Return an iterator to the first element of the sequence.
710 *
711 * @return An iterator to the first element of the sequence.
712 */
714 {
715 return _data;
716 }
717
718 /**
719 * Return an iterator to the element following the last element of the sequence.
720 *
721 * @return An iterator to the element following the last element of the sequence.
722 */
723 iterator end() const
724 {
725 return _data + _size;
726 }
727
728 /**
729 * Return a reverse_iterator to the first element of the reversed sequence.
730 *
731 * @return A reverse_iterator to the first element of the reversed sequence.
732 */
734 {
735 return reverse_iterator(end());
736 }
737
738 /**
739 * Return a reverse_iterator to the element following the last element of the reversed sequence.
740 *
741 * @return A reverse_iterator to the element following the last element of the reversed sequence.
742 */
744 {
745 return reverse_iterator(begin());
746 }
747
748 /**
749 * Access to an element of the sequence.
750 *
751 * @param index Element index to access.
752 *
753 * @return A reference to the element at the index specified in input.
754 *
755 * @pre index is less than size().
756 */
758 {
759#ifdef MBED_DEBUG
760 MBED_ASSERT(0 <= index && index < _size);
761#endif
762 return _data[index];
763 }
764
765 /**
766 * Get the raw pointer to the sequence viewed.
767 *
768 * @return The raw pointer to the first element viewed.
769 */
770 pointer data() const
771 {
772 return _data;
773 }
774
775 /**
776 * Create a new Span over the first @p Count elements of the existing view.
777 *
778 * @tparam Count The number of elements viewed by the new Span.
779 *
780 * @return A new Span over the first @p Count elements.
781 *
782 * @pre Count >= 0 && Count <= size().
783 */
784 template<ptrdiff_t Count>
786 {
787 MBED_ASSERT((Count >= 0) && (Count <= _size));
788 return Span<element_type, Count>(_data, Count);
789 }
790
791 /**
792 * Create a new Span over the last @p Count elements of the existing view.
793 *
794 * @tparam Count The number of elements viewed by the new Span.
795 *
796 * @return A new Span over the last @p Count elements.
797 *
798 * @pre Count >= 0 && Count <= size().
799 */
800 template<ptrdiff_t Count>
802 {
803 MBED_ASSERT((0 <= Count) && (Count <= _size));
804 return Span<element_type, Count>(_data + (_size - Count), Count);
805 }
806
807 /**
808 * Create a subspan that is a view other Count elements; the view starts at
809 * element Offset.
810 *
811 * @tparam Offset The offset of the first element viewed by the subspan.
812 *
813 * @tparam Count The number of elements present in the subspan. If Count
814 * is equal to SPAN_DYNAMIC_EXTENT, then a Span starting at offset and
815 * containing the rest of the elements is returned.
816 *
817 * @return A subspan of this starting at Offset and Count long.
818 */
819 template<std::ptrdiff_t Offset, std::ptrdiff_t Count>
821 subspan() const
822 {
823 MBED_ASSERT(0 <= Offset && Offset <= _size);
825 (Count == SPAN_DYNAMIC_EXTENT) ||
826 (0 <= Count && (Count + Offset) <= _size)
827 );
829 _data + Offset,
830 Count == SPAN_DYNAMIC_EXTENT ? _size - Offset : Count
831 );
832 }
833
834 /**
835 * Create a new Span over the first @p count elements of the existing view.
836 *
837 * @param count The number of elements viewed by the new Span.
838 *
839 * @return A new Span over the first @p count elements.
840 */
842 {
843 MBED_ASSERT(0 <= count && count <= _size);
844 return Span<element_type, SPAN_DYNAMIC_EXTENT>(_data, count);
845 }
846
847 /**
848 * Create a new Span over the last @p count elements of the existing view.
849 *
850 * @param count The number of elements viewed by the new Span.
851 *
852 * @return A new Span over the last @p count elements.
853 */
855 {
856 MBED_ASSERT(0 <= count && count <= _size);
858 _data + (_size - count),
859 count
860 );
861 }
862
863 /**
864 * Create a subspan that is a view of other count elements; the view starts at
865 * element offset.
866 *
867 * @param offset The offset of the first element viewed by the subspan.
868 *
869 * @param count The number of elements present in the subspan. If Count
870 * is equal to SPAN_DYNAMIC_EXTENT, then a Span starting at offset and
871 * containing the rest of the elements is returned.
872 *
873 * @return A subspan of this starting at offset and count long.
874 */
877 ) const
878 {
879 MBED_ASSERT(0 <= offset && offset <= _size);
881 (count == SPAN_DYNAMIC_EXTENT) ||
882 (0 <= count && (count + offset) <= _size)
883 );
885 _data + offset,
886 count == SPAN_DYNAMIC_EXTENT ? _size - offset : count
887 );
888 }
889
890private:
891 pointer _data;
892 index_type _size;
893};
894
895/**
896 * Equality operator between two Span objects.
897 *
898 * @param lhs Left side of the binary operation.
899 * @param rhs Right side of the binary operation.
900 *
901 * @return True if Spans in input have the same size and the same content and
902 * false otherwise.
903 *
904 * @relates Span
905 */
906template<typename T, typename U, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent>
908{
909 if (lhs.size() != rhs.size()) {
910 return false;
911 }
912
913 if (lhs.data() == rhs.data()) {
914 return true;
915 }
916
917 return std::equal(lhs.data(), lhs.data() + lhs.size(), rhs.data());
918}
919
920// AStyle ignore, not handling correctly below
921// *INDENT-OFF*
922/**
923 * Equality operation between a Span and a reference to a C++ array.
924 *
925 * @param lhs Left side of the binary operation.
926 * @param rhs Right side of the binary operation.
927 *
928 * @return True if elements in input have the same size and the same content and
929 * false otherwise.
930 */
931template<typename T, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent>
932bool operator==(const Span<T, LhsExtent> &lhs, T (&rhs)[RhsExtent])
933{
934 return lhs == Span<T>(rhs);
935}
936
937/**
938 * Equality operation between a Span and a reference to a C++ array.
939 *
940 * @param lhs Left side of the binary operation.
941 * @param rhs Right side of the binary operation.
942 *
943 * @return True if elements in input have the same size and the same content
944 * and false otherwise.
945 */
946template<typename T, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent>
947bool operator==(T (&lhs)[LhsExtent], const Span<T, RhsExtent> &rhs)
948{
949 return Span<T>(lhs) == rhs;
950}
951
952/**
953 * Not equal operator
954 *
955 * @param lhs Left side of the binary operation.
956 * @param rhs Right side of the binary operation.
957 *
958 * @return True if arrays in input do not have the same size or the same content
959 * and false otherwise.
960 *
961 * @relates Span
962 */
963template<typename T, typename U, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent>
965{
966 return !(lhs == rhs);
967}
968
969/**
970 * Not Equal operation between a Span and a reference to a C++ array.
971 *
972 * @param lhs Left side of the binary operation.
973 * @param rhs Right side of the binary operation.
974 *
975 * @return True if elements in input have the same size and the same content
976 * and false otherwise.
977 */
978template<typename T, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent>
979bool operator!=(const Span<T, LhsExtent> &lhs, T (&rhs)[RhsExtent])
980{
981 return !(lhs == Span<T, RhsExtent>(rhs));
982}
983
984/**
985 * Not Equal operation between a Span and a reference to a C++ array.
986 *
987 * @param lhs Left side of the binary operation.
988 * @param rhs Right side of the binary operation.
989 *
990 * @return True if elements in input have the same size and the same content
991 * and false otherwise.
992 */
993template<typename T, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent>
994bool operator!=(T (&lhs)[LhsExtent], const Span<T, RhsExtent> &rhs)
995{
996 return !(Span<T, LhsExtent>(lhs) == rhs);
997}
998
999/**
1000 * Generate a Span from a reference to a C/C++ array.
1001 *
1002 * @tparam T Type of elements held in elements.
1003 * @tparam Extent Number of items held in elements.
1004 *
1005 * @param elements The reference to the array viewed.
1006 *
1007 * @return The Span to elements.
1008 *
1009 * @note This helper avoids the typing of template parameter when Span is
1010 * created 'inline'.
1011 *
1012 * @relates Span
1013 */
1014template<typename T, size_t Size>
1015Span<T, Size> make_Span(T (&elements)[Size])
1016{
1017 return Span<T, Size>(elements);
1018}
1019
1020/**
1021 * Generate a Span from a pointer to a C/C++ array.
1022 *
1023 * @tparam Extent Number of items held in elements.
1024 * @tparam T Type of elements held in elements.
1025 *
1026 * @param elements The reference to the array viewed.
1027 *
1028 * @return The Span to elements.
1029 *
1030 * @note This helper avoids the typing of template parameter when Span is
1031 * created 'inline'.
1032 */
1033template<ptrdiff_t Extent, typename T>
1034Span<T, Extent> make_Span(T *elements)
1035{
1036 return Span<T, Extent>(elements, Extent);
1037}
1038
1039/**
1040 * Generate a Span from a C/C++ pointer and the size of the array.
1041 *
1042 * @tparam T Type of elements held in array_ptr.
1043 *
1044 * @param array_ptr The pointer to the array viewed.
1045 * @param array_size The number of T elements in the array.
1046 *
1047 * @return The Span to array_ptr with a size of array_size.
1048 *
1049 * @note This helper avoids the typing of template parameter when Span is
1050 * created 'inline'.
1051 *
1052 * @relates Span
1053 */
1054template<typename T>
1055Span<T> make_Span(T *array_ptr, ptrdiff_t array_size)
1056{
1057 return Span<T>(array_ptr, array_size);
1058}
1059
1060/**
1061 * Generate a Span to a const content from a reference to a C/C++ array.
1062 *
1063 * @tparam T Type of elements held in elements.
1064 * @tparam Extent Number of items held in elements.
1065 *
1066 * @param elements The array viewed.
1067 * @return The Span to elements.
1068 *
1069 * @note This helper avoids the typing of template parameter when Span is
1070 * created 'inline'.
1071 */
1072template<typename T, size_t Extent>
1073Span<const T, Extent> make_const_Span(const T (&elements)[Extent])
1074{
1075 return Span<const T, Extent>(elements);
1076}
1077// *INDENT-ON*
1078/**
1079 * Generate a Span to a const content from a pointer to a C/C++ array.
1080 *
1081 * @tparam Extent Number of items held in elements.
1082 * @tparam T Type of elements held in elements.
1083 *
1084 * @param elements The reference to the array viewed.
1085 *
1086 * @return The Span to elements.
1087 *
1088 * @note This helper avoids the typing of template parameter when Span is
1089 * created 'inline'.
1090 *
1091 * @relates Span
1092 */
1093template<size_t Extent, typename T>
1095{
1096 return Span<const T, Extent>(elements, Extent);
1097}
1098
1099/**
1100 * Generate a Span to a const content from a C/C++ pointer and the size of the
1101 * array.
1102 *
1103 * @tparam T Type of elements held in array_ptr.
1104 *
1105 * @param array_ptr The pointer to the array to viewed.
1106 * @param array_size The number of T elements in the array.
1107 *
1108 * @return The Span to array_ptr with a size of array_size.
1109 *
1110 * @note This helper avoids the typing of template parameter when Span is
1111 * created 'inline'.
1112 *
1113 * @relates Span
1114 */
1115template<typename T>
1116Span<const T> make_const_Span(T *array_ptr, size_t array_size)
1117{
1118 return Span<const T>(array_ptr, array_size);
1119}
1120
1121/**@}*/
1122
1123/**@}*/
1124
1125} // namespace mbed
1126
1127#endif /* MBED_PLATFORM_SPAN_H_ */
void operator!=(const SafeBool< T > &lhs, const SafeBool< U > &rhs)
Avoid conversion to bool between different classes.
void operator==(const SafeBool< T > &lhs, const SafeBool< U > &rhs)
Avoid conversion to bool between different classes.
#define MBED_ASSERT(expr)
MBED_ASSERT Declare runtime assertions: results in runtime error if condition is false.
Definition: mbed_assert.h:66
bool operator!=(const Span< T, LhsExtent > &lhs, const Span< U, RhsExtent > &rhs)
Not equal operator.
Definition: Span.h:964
bool operator==(const Span< T, LhsExtent > &lhs, const Span< U, RhsExtent > &rhs)
Equality operator between two Span objects.
Definition: Span.h:907
Span< const T, Extent > make_const_Span(const T *elements)
Generate a Span to a const content from a pointer to a C/C++ array.
Definition: Span.h:1094
const ptrdiff_t SPAN_DYNAMIC_EXTENT
Special value for the Extent parameter of Span.
Definition: Span.h:69
Span< T, Size > make_Span(T(&elements)[Size])
Generate a Span from a reference to a C/C++ array.
Definition: Span.h:1015
Span< const T > make_const_Span(T *array_ptr, size_t array_size)
Generate a Span to a const content from a C/C++ pointer and the size of the array.
Definition: Span.h:1116
Span< T > make_Span(T *array_ptr, ptrdiff_t array_size)
Generate a Span from a C/C++ pointer and the size of the array.
Definition: Span.h:1055
Span(const Span< OtherElementType, OtherExtent > &other)
Construct a Span object from another Span.
Definition: Span.h:678
Span()
Construct an empty Span.
Definition: Span.h:611
iterator begin() const
Return an iterator to the first element of the sequence.
Definition: Span.h:713
Span(pointer ptr, index_type count)
Construct a Span from a pointer to a buffer and its size.
Definition: Span.h:626
Span< element_type, SPAN_DYNAMIC_EXTENT > last(index_type count) const
Create a new Span over the last count elements of the existing view.
Definition: Span.h:854
Span(pointer first, pointer last)
Construct a Span from the range [first, last).
Definition: Span.h:645
Span(element_type(&elements)[Count])
Construct a Span from the reference to an array.
Definition: Span.h:665
Span< element_type, SPAN_DYNAMIC_EXTENT > subspan(index_type offset, index_type count=SPAN_DYNAMIC_EXTENT) const
Create a subspan that is a view of other count elements; the view starts at element offset.
Definition: Span.h:875
Span< element_type, Count > first() const
Create a new Span over the first Count elements of the existing view.
Definition: Span.h:785
pointer iterator
Iterator to an ElementType.
Definition: Span.h:591
Span< element_type, Count > last() const
Create a new Span over the last Count elements of the existing view.
Definition: Span.h:801
reverse_iterator rbegin() const
Return a reverse_iterator to the first element of the reversed sequence.
Definition: Span.h:733
ElementType element_type
Type of the element contained.
Definition: Span.h:571
reference operator[](index_type index) const
Access to an element of the sequence.
Definition: Span.h:757
bool empty() const
Return if the sequence viewed is empty or not.
Definition: Span.h:703
iterator end() const
Return an iterator to the element following the last element of the sequence.
Definition: Span.h:723
Span< element_type, Count > subspan() const
Create a subspan that is a view other Count elements; the view starts at element Offset.
Definition: Span.h:821
ptrdiff_t index_type
Type of the index.
Definition: Span.h:576
element_type * pointer
Pointer to an ElementType.
Definition: Span.h:581
std::reverse_iterator< iterator > reverse_iterator
Reverse iterator to an ElementType.
Definition: Span.h:596
Span< element_type, SPAN_DYNAMIC_EXTENT > first(index_type count) const
Create a new Span over the first count elements of the existing view.
Definition: Span.h:841
reverse_iterator rend() const
Return a reverse_iterator to the element following the last element of the reversed sequence.
Definition: Span.h:743
pointer data() const
Get the raw pointer to the sequence viewed.
Definition: Span.h:770
element_type & reference
Reference to an ElementType.
Definition: Span.h:586
index_type size() const
Return the size of the array viewed.
Definition: Span.h:693
Nonowning view to a sequence of contiguous elements.
Definition: Span.h:215
Span()
Construct an empty Span.
Definition: Span.h:262
iterator begin() const
Return an iterator to the first element of the sequence.
Definition: Span.h:368
Span(pointer ptr, index_type count)
Construct a Span from a pointer to a buffer and its size.
Definition: Span.h:283
Span(const Span< OtherElementType, Extent > &other)
Construct a Span object from another Span of the same size.
Definition: Span.h:333
Span< element_type, SPAN_DYNAMIC_EXTENT > last(index_type count) const
Create a new Span over the last count elements of the existing view.
Definition: Span.h:523
Span(pointer first, pointer last)
Construct a Span from the range [first, last).
Definition: Span.h:302
Span< element_type, Count==SPAN_DYNAMIC_EXTENT ? Extent - Offset :Count > subspan() const
Create a subspan that is a view of other Count elements; the view starts at element Offset.
Definition: Span.h:485
Span< element_type, SPAN_DYNAMIC_EXTENT > subspan(index_type offset, index_type count=SPAN_DYNAMIC_EXTENT) const
Create a subspan that is a view of other count elements; the view starts at element offset.
Definition: Span.h:544
Span< element_type, Count > first() const
Create a new Span over the first Count elements of the existing view.
Definition: Span.h:441
static const index_type extent
Size of the Extent; -1 if dynamic.
Definition: Span.h:250
pointer iterator
Iterator to an ElementType.
Definition: Span.h:240
Span< element_type, Count > last() const
Create a new Span over the last Count elements of the existing view.
Definition: Span.h:460
reverse_iterator rbegin() const
Return a reverse_iterator to the first element of the reversed sequence.
Definition: Span.h:388
ElementType element_type
Type of the element contained.
Definition: Span.h:220
reference operator[](index_type index) const
Returns a reference to the element at position index.
Definition: Span.h:412
bool empty() const
Return if the sequence is empty or not.
Definition: Span.h:358
iterator end() const
Return an iterator to the element following the last element of the sequence.
Definition: Span.h:378
ptrdiff_t index_type
Type of the index.
Definition: Span.h:225
element_type * pointer
Pointer to an ElementType.
Definition: Span.h:230
std::reverse_iterator< iterator > reverse_iterator
Reverse iterator to an ElementType.
Definition: Span.h:245
Span< element_type, SPAN_DYNAMIC_EXTENT > first(index_type count) const
Create a new Span over the first count elements of the existing view.
Definition: Span.h:510
reverse_iterator rend() const
Return a reverse_iterator to the element following the last element of the reversed sequence.
Definition: Span.h:398
pointer data() const
Return a pointer to the first element of the sequence or NULL if the Span is empty().
Definition: Span.h:426
element_type & reference
Reference to an ElementType.
Definition: Span.h:235
index_type size() const
Return the size of the sequence viewed.
Definition: Span.h:348
Span(element_type(&elements)[Extent])
Construct a Span from the reference to an array.
Definition: Span.h:320