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