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

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.