Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: nRF51_Vdd TextLCD BME280
Span.h
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2018-2018 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #ifndef MBED_PLATFORM_SPAN_H_ 00018 #define MBED_PLATFORM_SPAN_H_ 00019 00020 #include <algorithm> 00021 #include <stddef.h> 00022 #include <stdint.h> 00023 00024 #include "platform/mbed_assert.h" 00025 00026 namespace mbed { 00027 00028 /** \addtogroup platform */ 00029 /** @{*/ 00030 /** 00031 * \defgroup platform_Span Span class 00032 * @{ 00033 */ 00034 00035 // Internal details of Span 00036 // It is used construct Span from Span of convertible types (non const -> const) 00037 namespace span_detail { 00038 00039 // If From type is convertible to To type, then the compilation constant value is 00040 // true; otherwise, it is false. 00041 template<typename From, typename To> 00042 class is_convertible 00043 { 00044 struct true_type { char x[512]; }; 00045 struct false_type { }; 00046 00047 static const From& generator(); 00048 static true_type sink(const To &); 00049 static false_type sink(...); 00050 00051 public: 00052 static const bool value = sizeof(true_type) == sizeof(sink(generator())); 00053 }; 00054 00055 } 00056 00057 #if defined(DOXYGEN_ONLY) 00058 /** 00059 * Special value for the Extent parameter of Span. 00060 * If the type uses this value, then the size of the array is stored in the object 00061 * at runtime. 00062 * 00063 * @relates Span 00064 */ 00065 const ptrdiff_t SPAN_DYNAMIC_EXTENT = -1; 00066 #else 00067 #define SPAN_DYNAMIC_EXTENT -1 00068 #endif 00069 00070 /** 00071 * Nonowning view to a sequence of contiguous elements. 00072 * 00073 * Spans encapsulate a pointer to a sequence of contiguous elements and its size 00074 * into a single object. Span can replace the traditional pair of pointer and 00075 * size arguments passed as array definitions in function calls. 00076 * 00077 * @par Operations 00078 * 00079 * Span objects can be copied and assigned like regular value types with the help 00080 * of the copy constructor or the copy assignment (=) operator. 00081 * 00082 * You can retrieve elements of the object with the subscript ([]) operator. You can access the 00083 * pointer to the first element of the sequence viewed with data(). 00084 * The function size() returns the number of elements in the sequence, and 00085 * empty() informs whether there is any element in the sequence. 00086 * 00087 * You can slice Span from the beginning of the sequence (first()), from the end 00088 * of the sequence (last()) or from an arbitrary point of the sequence (subspan()). 00089 * 00090 * @par Size encoding 00091 * 00092 * The size of the sequence can be encoded in the type itself or in the value of 00093 * the instance with the help of the template parameter Extent: 00094 * 00095 * - Span<uint8_t, 6>: Span over a sequence of 6 elements. 00096 * - Span<uint8_t>: Span over an arbitrary long sequence. 00097 * 00098 * When the size is encoded in the type itself, it is guaranteed that the Span 00099 * view is a valid sequence (not empty() and not NULL) - unless Extent equals 0. 00100 * The type system also prevents automatic conversion from Span of different 00101 * sizes. Finally, the Span object is internally represented as a single pointer. 00102 * 00103 * When the size of the sequence viewed is encoded in the Span value, Span 00104 * instances can view an empty sequence. The function empty() helps client code 00105 * decide whether Span is viewing valid content or not. 00106 * 00107 * @par Example 00108 * 00109 * - Encoding fixed size array: Array values in parameter decays automatically 00110 * to pointer, which leaves room for subtitle bugs: 00111 * 00112 * @code 00113 typedef uint8_t mac_address_t[6]; 00114 void process_mac(mac_address_t); 00115 00116 // compile just fine 00117 uint8_t *invalid_value = NULL; 00118 process_mac(invalid_value); 00119 00120 00121 // correct way 00122 typedef Span<uint8_t, 6> mac_address_t; 00123 void process_mac(mac_address_t); 00124 00125 // compilation error 00126 uint8_t *invalid_value = NULL; 00127 process_mac(invalid_value); 00128 00129 // compilation ok 00130 uint8_t valid_value[6]; 00131 process_mac(valid_value); 00132 * @endcode 00133 * 00134 * - Arbitrary buffer: When dealing with multiple buffers, it becomes painful to 00135 * keep track of every buffer size and pointer. 00136 * 00137 * @code 00138 const uint8_t options_tag[OPTIONS_TAG_SIZE]; 00139 00140 struct parsed_value_t { 00141 uint8_t *header; 00142 uint8_t *options; 00143 uint8_t *payload; 00144 size_t payload_size; 00145 } 00146 00147 parsed_value_t parse(uint8_t *buffer, size_t buffer_size) 00148 { 00149 parsed_value_t parsed_value { 0 }; 00150 00151 if (buffer != NULL && buffer_size <= MINIMAL_BUFFER_SIZE) { 00152 return parsed_value; 00153 } 00154 00155 parsed_value.header = buffer; 00156 parsed_value.header_size = BUFFER_HEADER_SIZE; 00157 00158 if (memcmp(buffer + HEADER_OPTIONS_INDEX, options_tag, sizeof(options_tag)) == 0) { 00159 options = buffer + BUFFER_HEADER_SIZE; 00160 payload = buffer + BUFFER_HEADER_SIZE + OPTIONS_SIZE; 00161 payload_size = buffer_size - BUFFER_HEADER_SIZE + OPTIONS_SIZE; 00162 } else { 00163 payload = buffer + BUFFER_HEADER_SIZE; 00164 payload_size = buffer_size - BUFFER_HEADER_SIZE; 00165 } 00166 00167 return parsed_value; 00168 } 00169 00170 00171 //with Span 00172 struct parsed_value_t { 00173 Span<uint8_t> header; 00174 Span<uint8_t> options; 00175 Span<uint8_t> payload; 00176 } 00177 00178 parsed_value_t parse(const Span<uint8_t> &buffer) 00179 { 00180 parsed_value_t parsed_value; 00181 00182 if (buffer.size() <= MINIMAL_BUFFER_SIZE) { 00183 return parsed_value; 00184 } 00185 00186 parsed_value.header = buffer.first(BUFFER_HEADER_SIZE); 00187 00188 if (buffer.subspan<HEADER_OPTIONS_INDEX, sizeof(options_tag)>() == option_tag) { 00189 options = buffer.supspan(parsed_value.header.size(), OPTIONS_SIZE); 00190 } 00191 00192 payload = buffer.subspan(parsed_value.header.size() + parsed_value.options.size()); 00193 00194 return parsed_value; 00195 } 00196 * @endcode 00197 * 00198 * @note You can create Span instances with the help of the function template 00199 * make_Span() and make_const_Span(). 00200 * 00201 * @note Span<T, Extent> objects can be implicitly converted to Span<T> objects 00202 * where required. 00203 * 00204 * @tparam ElementType type of objects the Span views. 00205 * 00206 * @tparam Extent The size of the contiguous sequence viewed. The default value 00207 * SPAN_DYNAMIC_SIZE is special because it allows construction of Span objects of 00208 * any size (set at runtime). 00209 */ 00210 template<typename ElementType, ptrdiff_t Extent = SPAN_DYNAMIC_EXTENT> 00211 struct Span { 00212 00213 /** 00214 * Type of the element contained 00215 */ 00216 typedef ElementType element_type; 00217 00218 /** 00219 * Type of the index. 00220 */ 00221 typedef ptrdiff_t index_type; 00222 00223 /** 00224 * Pointer to an ElementType 00225 */ 00226 typedef element_type *pointer; 00227 00228 /** 00229 * Reference to an ElementType 00230 */ 00231 typedef element_type &reference; 00232 00233 /** 00234 * Size of the Extent; -1 if dynamic. 00235 */ 00236 static const index_type extent = Extent; 00237 00238 MBED_STATIC_ASSERT(Extent >= 0, "Invalid extent for a Span"); 00239 00240 /** 00241 * Construct an empty Span. 00242 * 00243 * @post a call to size() returns 0, and data() returns NULL. 00244 * 00245 * @note This function is not accessible if Extent != SPAN_DYNAMIC_EXTENT or 00246 * Extent != 0 . 00247 */ 00248 Span() : 00249 _data(NULL) 00250 { 00251 MBED_STATIC_ASSERT( 00252 Extent == 0, 00253 "Cannot default construct a static-extent Span (unless Extent is 0)" 00254 ); 00255 } 00256 00257 /** 00258 * Construct a Span from a pointer to a buffer and its size. 00259 * 00260 * @param ptr Pointer to the beginning of the data viewed. 00261 * 00262 * @param count Number of elements viewed. 00263 * 00264 * @pre [ptr, ptr + count) must be be a valid range. 00265 * @pre count must be equal to Extent. 00266 * 00267 * @post a call to size() returns Extent, and data() returns @p ptr. 00268 */ 00269 Span(pointer ptr, index_type count) : 00270 _data(ptr) 00271 { 00272 MBED_ASSERT(count == Extent); 00273 MBED_ASSERT(Extent == 0 || ptr != NULL); 00274 } 00275 00276 /** 00277 * Construct a Span from the range [first, last). 00278 * 00279 * @param first Pointer to the beginning of the data viewed. 00280 * @param last End of the range (element after the last element). 00281 * 00282 * @pre [first, last) must be be a valid range. 00283 * @pre first <= last. 00284 * @pre last - first must be equal to Extent. 00285 * 00286 * @post a call to size() returns Extent, and data() returns @p first. 00287 */ 00288 Span(pointer first, pointer last) : 00289 _data(first) 00290 { 00291 MBED_ASSERT(first <= last); 00292 MBED_ASSERT((last - first) == Extent); 00293 MBED_ASSERT(Extent == 0 || first != NULL); 00294 } 00295 00296 /** 00297 * Construct a Span from the reference to an array. 00298 * 00299 * @param elements Reference to the array viewed. 00300 * 00301 * @post a call to size() returns Extent, and data() returns a 00302 * pointer to elements. 00303 */ 00304 Span(element_type (&elements)[Extent]): 00305 _data(elements) { } 00306 00307 /** 00308 * Construct a Span object from another Span of the same size. 00309 * 00310 * @param other The Span object used to construct this. 00311 * 00312 * @note For Span with a positive extent, this function is not accessible. 00313 * 00314 * @note OtherElementType(*)[] must be convertible to ElementType(*)[]. 00315 */ 00316 template<typename OtherElementType> 00317 Span(const Span<OtherElementType, Extent> &other): 00318 _data(other.data()) 00319 { 00320 MBED_STATIC_ASSERT( 00321 (span_detail::is_convertible<OtherElementType (*)[1], ElementType (*)[1]>::value), 00322 "OtherElementType(*)[] should be convertible to ElementType (*)[]" 00323 ); 00324 } 00325 00326 /** 00327 * Return the size of the sequence viewed. 00328 * 00329 * @return The size of the sequence viewed. 00330 */ 00331 index_type size() const 00332 { 00333 return Extent; 00334 } 00335 00336 /** 00337 * Return if the sequence is empty or not. 00338 * 00339 * @return true if the sequence is empty and false otherwise. 00340 */ 00341 bool empty() const 00342 { 00343 return size() == 0; 00344 } 00345 00346 /** 00347 * Returns a reference to the element at position @p index. 00348 * 00349 * @param index Index of the element to access. 00350 * 00351 * @return A reference to the element at the index specified in input. 00352 * 00353 * @pre 0 <= index < Extent. 00354 */ 00355 reference operator[](index_type index) const 00356 { 00357 #ifdef MBED_DEBUG 00358 MBED_ASSERT(0 <= index && index < Extent); 00359 #endif 00360 return _data[index]; 00361 } 00362 00363 /** 00364 * Return a pointer to the first element of the sequence or NULL if the Span 00365 * is empty(). 00366 * 00367 * @return The pointer to the first element of the Span. 00368 */ 00369 pointer data() const 00370 { 00371 return _data; 00372 } 00373 00374 /** 00375 * Create a new Span over the first @p Count elements of the existing view. 00376 * 00377 * @tparam Count The number of element viewed by the new Span 00378 * 00379 * @return A new Span over the first @p Count elements. 00380 * 00381 * @pre Count >= 0 && Count <= size(). 00382 */ 00383 template<ptrdiff_t Count> 00384 Span<element_type, Count> first() const 00385 { 00386 MBED_STATIC_ASSERT( 00387 (0 <= Count) && (Count <= Extent), 00388 "Invalid subspan extent" 00389 ); 00390 return Span<element_type, Count>(_data, Count); 00391 } 00392 00393 /** 00394 * Create a new Span over the last @p Count elements of the existing view. 00395 * 00396 * @tparam Count The number of element viewed by the new Span. 00397 * 00398 * @return A new Span over the last @p Count elements. 00399 * 00400 * @pre Count >= 0 && Count <= size(). 00401 */ 00402 template<ptrdiff_t Count> 00403 Span<element_type, Count> last() const 00404 { 00405 MBED_STATIC_ASSERT( 00406 (0 <= Count) && (Count <= Extent), 00407 "Invalid subspan extent" 00408 ); 00409 return Span<element_type, Count>(_data + (Extent - Count), Count); 00410 } 00411 00412 /** 00413 * Create a subspan that is a view of other Count elements; the view starts at 00414 * element Offset. 00415 * 00416 * @tparam Offset The offset of the first element viewed by the subspan. 00417 * 00418 * @tparam Count The number of elements present in the subspan. If Count 00419 * is equal to SPAN_DYNAMIC_EXTENT, then a Span starting at offset and 00420 * containing the rest of the elements is returned. 00421 * 00422 * @return A subspan of this starting at Offset and Count long. 00423 */ 00424 template<std::ptrdiff_t Offset, std::ptrdiff_t Count> 00425 Span<element_type, Count == SPAN_DYNAMIC_EXTENT ? Extent - Offset : Count> 00426 subspan() const 00427 { 00428 MBED_STATIC_ASSERT( 00429 0 <= Offset && Offset <= Extent, 00430 "Invalid subspan offset" 00431 ); 00432 MBED_STATIC_ASSERT( 00433 (Count == SPAN_DYNAMIC_EXTENT) || 00434 (0 <= Count && (Count + Offset) <= Extent), 00435 "Invalid subspan count" 00436 ); 00437 return Span<element_type, Count == SPAN_DYNAMIC_EXTENT ? Extent - Offset : Count>( 00438 _data + Offset, 00439 Count == SPAN_DYNAMIC_EXTENT ? Extent - Offset : Count 00440 ); 00441 } 00442 00443 /** 00444 * Create a new Span over the first @p count elements of the existing view. 00445 * 00446 * @param count The number of element viewed by the new Span. 00447 * 00448 * @return A new Span over the first @p count elements. 00449 */ 00450 Span<element_type, SPAN_DYNAMIC_EXTENT> first(index_type count) const 00451 { 00452 MBED_ASSERT(0 <= count && count <= Extent); 00453 return Span<element_type, SPAN_DYNAMIC_EXTENT>(_data, count); 00454 } 00455 00456 /** 00457 * Create a new Span over the last @p count elements of the existing view. 00458 * 00459 * @param count The number of elements viewed by the new Span. 00460 * 00461 * @return A new Span over the last @p count elements. 00462 */ 00463 Span<element_type, SPAN_DYNAMIC_EXTENT> last(index_type count) const 00464 { 00465 MBED_ASSERT(0 <= count && count <= Extent); 00466 return Span<element_type, SPAN_DYNAMIC_EXTENT>( 00467 _data + (Extent - count), 00468 count 00469 ); 00470 } 00471 00472 /** 00473 * Create a subspan that is a view of other count elements; the view starts at 00474 * element offset. 00475 * 00476 * @param offset The offset of the first element viewed by the subspan. 00477 * 00478 * @param count The number of elements present in the subspan. If Count 00479 * is equal to SPAN_DYNAMIC_EXTENT, then a span starting at offset and 00480 * containing the rest of the elements is returned. 00481 * 00482 * @return 00483 */ 00484 Span<element_type, SPAN_DYNAMIC_EXTENT> subspan( 00485 index_type offset, index_type count = SPAN_DYNAMIC_EXTENT 00486 ) const 00487 { 00488 MBED_ASSERT(0 <= offset && offset <= Extent); 00489 MBED_ASSERT( 00490 (count == SPAN_DYNAMIC_EXTENT) || 00491 (0 <= count && (count + offset) <= Extent) 00492 ); 00493 return Span<element_type, SPAN_DYNAMIC_EXTENT>( 00494 _data + offset, 00495 count == SPAN_DYNAMIC_EXTENT ? Extent - offset : count 00496 ); 00497 } 00498 00499 private: 00500 pointer _data; 00501 }; 00502 00503 /** 00504 * Span specialization that handle dynamic size. 00505 */ 00506 template<typename ElementType> 00507 struct Span<ElementType, SPAN_DYNAMIC_EXTENT> { 00508 /** 00509 * Type of the element contained. 00510 */ 00511 typedef ElementType element_type; 00512 00513 /** 00514 * Type of the index. 00515 */ 00516 typedef ptrdiff_t index_type; 00517 00518 /** 00519 * Pointer to an ElementType. 00520 */ 00521 typedef element_type *pointer; 00522 00523 /** 00524 * Reference to an ElementType. 00525 */ 00526 typedef element_type &reference; 00527 00528 /** 00529 * Size of the Extent; -1 if dynamic. 00530 */ 00531 static const index_type extent = SPAN_DYNAMIC_EXTENT; 00532 00533 /** 00534 * Construct an empty Span. 00535 * 00536 * @post a call to size() returns 0, and data() returns NULL. 00537 * 00538 * @note This function is not accessible if Extent != SPAN_DYNAMIC_EXTENT or 00539 * Extent != 0 . 00540 */ 00541 Span() : 00542 _data(NULL), _size(0) { } 00543 00544 /** 00545 * Construct a Span from a pointer to a buffer and its size. 00546 * 00547 * @param ptr Pointer to the beginning of the data viewed. 00548 * 00549 * @param count Number of elements viewed. 00550 * 00551 * @pre [ptr, ptr + count) must be be a valid range. 00552 * @pre count must be equal to extent. 00553 * 00554 * @post a call to size() returns count, and data() returns @p ptr. 00555 */ 00556 Span(pointer ptr, index_type count) : 00557 _data(ptr), _size(count) 00558 { 00559 MBED_ASSERT(count >= 0); 00560 MBED_ASSERT(ptr != NULL || count == 0); 00561 } 00562 00563 /** 00564 * Construct a Span from the range [first, last). 00565 * 00566 * @param first Pointer to the beginning of the data viewed. 00567 * @param last End of the range (element after the last element). 00568 * 00569 * @pre [first, last) must be be a valid range. 00570 * @pre first <= last. 00571 * 00572 * @post a call to size() returns the result of (last - first), and 00573 * data() returns @p first. 00574 */ 00575 Span(pointer first, pointer last) : 00576 _data(first), _size(last - first) 00577 { 00578 MBED_ASSERT(first <= last); 00579 MBED_ASSERT(first != NULL || (last - first) == 0); 00580 } 00581 00582 /** 00583 * Construct a Span from the reference to an array. 00584 * 00585 * @param elements Reference to the array viewed. 00586 * 00587 * @tparam Count Number of elements of T presents in the array. 00588 * 00589 * @post a call to size() returns Count, and data() returns a 00590 * pointer to elements. 00591 */ 00592 template<size_t Count> 00593 Span(element_type (&elements)[Count]): 00594 _data(elements), _size(Count) { } 00595 00596 /** 00597 * Construct a Span object from another Span. 00598 * 00599 * @param other The Span object used to construct this. 00600 * 00601 * @note For Span with a positive extent, this function is not accessible. 00602 * 00603 * @note OtherElementType(*)[] must be convertible to ElementType(*)[]. 00604 */ 00605 template<typename OtherElementType, ptrdiff_t OtherExtent> 00606 Span(const Span<OtherElementType, OtherExtent> &other): 00607 _data(other.data()), _size(other.size()) 00608 { 00609 MBED_STATIC_ASSERT( 00610 (span_detail::is_convertible<OtherElementType (*)[1], ElementType (*)[1]>::value), 00611 "OtherElementType(*)[] should be convertible to ElementType (*)[]" 00612 ); 00613 } 00614 00615 /** 00616 * Return the size of the array viewed. 00617 * 00618 * @return The number of elements present in the array viewed. 00619 */ 00620 index_type size() const 00621 { 00622 return _size; 00623 } 00624 00625 /** 00626 * Return if the sequence viewed is empty or not. 00627 * 00628 * @return true if the sequence is empty and false otherwise. 00629 */ 00630 bool empty() const 00631 { 00632 return size() == 0; 00633 } 00634 00635 /** 00636 * Access to an element of the sequence. 00637 * 00638 * @param index Element index to access. 00639 * 00640 * @return A reference to the element at the index specified in input. 00641 * 00642 * @pre index is less than size(). 00643 */ 00644 reference operator[](index_type index) const 00645 { 00646 #ifdef MBED_DEBUG 00647 MBED_ASSERT(0 <= index && index < _size); 00648 #endif 00649 return _data[index]; 00650 } 00651 00652 /** 00653 * Get the raw pointer to the sequence viewed. 00654 * 00655 * @return The raw pointer to the first element viewed. 00656 */ 00657 pointer data() const 00658 { 00659 return _data; 00660 } 00661 00662 /** 00663 * Create a new Span over the first @p Count elements of the existing view. 00664 * 00665 * @tparam Count The number of elements viewed by the new Span. 00666 * 00667 * @return A new Span over the first @p Count elements. 00668 * 00669 * @pre Count >= 0 && Count <= size(). 00670 */ 00671 template<ptrdiff_t Count> 00672 Span<element_type, Count> first() const 00673 { 00674 MBED_ASSERT((Count >= 0) && (Count <= _size)); 00675 return Span<element_type, Count>(_data, Count); 00676 } 00677 00678 /** 00679 * Create a new Span over the last @p Count elements of the existing view. 00680 * 00681 * @tparam Count The number of elements viewed by the new Span. 00682 * 00683 * @return A new Span over the last @p Count elements. 00684 * 00685 * @pre Count >= 0 && Count <= size(). 00686 */ 00687 template<ptrdiff_t Count> 00688 Span<element_type, Count> last() const 00689 { 00690 MBED_ASSERT((0 <= Count) && (Count <= _size)); 00691 return Span<element_type, Count>(_data + (_size - Count), Count); 00692 } 00693 00694 /** 00695 * Create a subspan that is a view other Count elements; the view starts at 00696 * element Offset. 00697 * 00698 * @tparam Offset The offset of the first element viewed by the subspan. 00699 * 00700 * @tparam Count The number of elements present in the subspan. If Count 00701 * is equal to SPAN_DYNAMIC_EXTENT, then a Span starting at offset and 00702 * containing the rest of the elements is returned. 00703 * 00704 * @return A subspan of this starting at Offset and Count long. 00705 */ 00706 template<std::ptrdiff_t Offset, std::ptrdiff_t Count> 00707 Span<element_type, Count> 00708 subspan() const 00709 { 00710 MBED_ASSERT(0 <= Offset && Offset <= _size); 00711 MBED_ASSERT( 00712 (Count == SPAN_DYNAMIC_EXTENT) || 00713 (0 <= Count && (Count + Offset) <= _size) 00714 ); 00715 return Span<element_type, Count>( 00716 _data + Offset, 00717 Count == SPAN_DYNAMIC_EXTENT ? _size - Offset : Count 00718 ); 00719 } 00720 00721 /** 00722 * Create a new Span over the first @p count elements of the existing view. 00723 * 00724 * @param count The number of elements viewed by the new Span. 00725 * 00726 * @return A new Span over the first @p count elements. 00727 */ 00728 Span<element_type, SPAN_DYNAMIC_EXTENT> first(index_type count) const 00729 { 00730 MBED_ASSERT(0 <= count && count <= _size); 00731 return Span<element_type, SPAN_DYNAMIC_EXTENT>(_data, count); 00732 } 00733 00734 /** 00735 * Create a new Span over the last @p count elements of the existing view. 00736 * 00737 * @param count The number of elements viewed by the new Span. 00738 * 00739 * @return A new Span over the last @p count elements. 00740 */ 00741 Span<element_type, SPAN_DYNAMIC_EXTENT> last(index_type count) const 00742 { 00743 MBED_ASSERT(0 <= count && count <= _size); 00744 return Span<element_type, SPAN_DYNAMIC_EXTENT>( 00745 _data + (_size - count), 00746 count 00747 ); 00748 } 00749 00750 /** 00751 * Create a subspan that is a view of other count elements; the view starts at 00752 * element offset. 00753 * 00754 * @param offset The offset of the first element viewed by the subspan. 00755 * 00756 * @param count The number of elements present in the subspan. If Count 00757 * is equal to SPAN_DYNAMIC_EXTENT, then a Span starting at offset and 00758 * containing the rest of the elements is returned. 00759 * 00760 * @return A subspan of this starting at offset and count long. 00761 */ 00762 Span<element_type, SPAN_DYNAMIC_EXTENT> subspan( 00763 index_type offset, index_type count = SPAN_DYNAMIC_EXTENT 00764 ) const 00765 { 00766 MBED_ASSERT(0 <= offset && offset <= _size); 00767 MBED_ASSERT( 00768 (count == SPAN_DYNAMIC_EXTENT) || 00769 (0 <= count && (count + offset) <= _size) 00770 ); 00771 return Span<element_type, SPAN_DYNAMIC_EXTENT>( 00772 _data + offset, 00773 count == SPAN_DYNAMIC_EXTENT ? _size - offset : count 00774 ); 00775 } 00776 00777 private: 00778 pointer _data; 00779 index_type _size; 00780 }; 00781 00782 /** 00783 * Equality operator between two Span objects. 00784 * 00785 * @param lhs Left side of the binary operation. 00786 * @param rhs Right side of the binary operation. 00787 * 00788 * @return True if Spans in input have the same size and the same content and 00789 * false otherwise. 00790 * 00791 * @relates Span 00792 */ 00793 template<typename T, typename U, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent> 00794 bool operator==(const Span<T, LhsExtent> &lhs, const Span<U, RhsExtent> &rhs) 00795 { 00796 if (lhs.size() != rhs.size()) { 00797 return false; 00798 } 00799 00800 if (lhs.data() == rhs.data()) { 00801 return true; 00802 } 00803 00804 return std::equal(lhs.data(), lhs.data() + lhs.size(), rhs.data()); 00805 } 00806 00807 /** 00808 * Equality operation between a Span and a reference to a C++ array. 00809 * 00810 * @param lhs Left side of the binary operation. 00811 * @param rhs Right side of the binary operation. 00812 * 00813 * @return True if elements in input have the same size and the same content and 00814 * false otherwise. 00815 */ 00816 template<typename T, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent> 00817 bool operator==(const Span<T, LhsExtent> &lhs, T (&rhs)[RhsExtent]) 00818 { 00819 return lhs == Span<T>(rhs); 00820 } 00821 00822 /** 00823 * Equality operation between a Span and a reference to a C++ array. 00824 * 00825 * @param lhs Left side of the binary operation. 00826 * @param rhs Right side of the binary operation. 00827 * 00828 * @return True if elements in input have the same size and the same content 00829 * and false otherwise. 00830 */ 00831 template<typename T, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent> 00832 bool operator==(T (&lhs)[LhsExtent], const Span<T, RhsExtent> &rhs) 00833 { 00834 return Span<T>(lhs) == rhs; 00835 } 00836 00837 /** 00838 * Not equal operator 00839 * 00840 * @param lhs Left side of the binary operation. 00841 * @param rhs Right side of the binary operation. 00842 * 00843 * @return True if arrays in input do not have the same size or the same content 00844 * and false otherwise. 00845 * 00846 * @relates Span 00847 */ 00848 template<typename T, typename U, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent> 00849 bool operator!=(const Span<T, LhsExtent> &lhs, const Span<U, RhsExtent> &rhs) 00850 { 00851 return !(lhs == rhs); 00852 } 00853 00854 /** 00855 * Not Equal operation between a Span and a reference to a C++ array. 00856 * 00857 * @param lhs Left side of the binary operation. 00858 * @param rhs Right side of the binary operation. 00859 * 00860 * @return True if elements in input have the same size and the same content 00861 * and false otherwise. 00862 */ 00863 template<typename T, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent> 00864 bool operator!=(const Span<T, LhsExtent> &lhs, T (&rhs)[RhsExtent]) 00865 { 00866 return !(lhs == Span<T, RhsExtent>(rhs)); 00867 } 00868 00869 /** 00870 * Not Equal operation between a Span and a reference to a C++ array. 00871 * 00872 * @param lhs Left side of the binary operation. 00873 * @param rhs Right side of the binary operation. 00874 * 00875 * @return True if elements in input have the same size and the same content 00876 * and false otherwise. 00877 */ 00878 template<typename T, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent> 00879 bool operator!=(T (&lhs)[LhsExtent], const Span<T, RhsExtent> &rhs) 00880 { 00881 return !(Span<T, LhsExtent>(lhs) == rhs); 00882 } 00883 00884 /** 00885 * Generate a Span from a reference to a C/C++ array. 00886 * 00887 * @tparam T Type of elements held in elements. 00888 * @tparam Extent Number of items held in elements. 00889 * 00890 * @param elements The reference to the array viewed. 00891 * 00892 * @return The Span to elements. 00893 * 00894 * @note This helper avoids the typing of template parameter when Span is 00895 * created 'inline'. 00896 * 00897 * @relates Span 00898 */ 00899 template<typename T, size_t Size> 00900 Span<T, Size> make_Span(T (&elements)[Size]) 00901 { 00902 return Span<T, Size>(elements); 00903 } 00904 00905 /** 00906 * Generate a Span from a pointer to a C/C++ array. 00907 * 00908 * @tparam Extent Number of items held in elements. 00909 * @tparam T Type of elements held in elements. 00910 * 00911 * @param elements The reference to the array viewed. 00912 * 00913 * @return The Span to elements. 00914 * 00915 * @note This helper avoids the typing of template parameter when Span is 00916 * created 'inline'. 00917 */ 00918 template<ptrdiff_t Extent, typename T> 00919 Span<T, Extent> make_Span(T *elements) 00920 { 00921 return Span<T, Extent>(elements, Extent); 00922 } 00923 00924 /** 00925 * Generate a Span from a C/C++ pointer and the size of the array. 00926 * 00927 * @tparam T Type of elements held in array_ptr. 00928 * 00929 * @param array_ptr The pointer to the array viewed. 00930 * @param array_size The number of T elements in the array. 00931 * 00932 * @return The Span to array_ptr with a size of array_size. 00933 * 00934 * @note This helper avoids the typing of template parameter when Span is 00935 * created 'inline'. 00936 * 00937 * @relates Span 00938 */ 00939 template<typename T> 00940 Span<T> make_Span(T *array_ptr, ptrdiff_t array_size) 00941 { 00942 return Span<T>(array_ptr, array_size); 00943 } 00944 00945 /** 00946 * Generate a Span to a const content from a reference to a C/C++ array. 00947 * 00948 * @tparam T Type of elements held in elements. 00949 * @tparam Extent Number of items held in elements. 00950 * 00951 * @param elements The array viewed. 00952 * @return The Span to elements. 00953 * 00954 * @note This helper avoids the typing of template parameter when Span is 00955 * created 'inline'. 00956 */ 00957 template<typename T, size_t Extent> 00958 Span<const T, Extent> make_const_Span(const T (&elements)[Extent]) 00959 { 00960 return Span<const T, Extent>(elements); 00961 } 00962 00963 /** 00964 * Generate a Span to a const content from a pointer to a C/C++ array. 00965 * 00966 * @tparam Extent Number of items held in elements. 00967 * @tparam T Type of elements held in elements. 00968 * 00969 * @param elements The reference to the array viewed. 00970 * 00971 * @return The Span to elements. 00972 * 00973 * @note This helper avoids the typing of template parameter when Span is 00974 * created 'inline'. 00975 * 00976 * @relates Span 00977 */ 00978 template<size_t Extent, typename T> 00979 Span<const T, Extent> make_const_Span(const T *elements) 00980 { 00981 return Span<const T, Extent>(elements, Extent); 00982 } 00983 00984 /** 00985 * Generate a Span to a const content from a C/C++ pointer and the size of the 00986 * array. 00987 * 00988 * @tparam T Type of elements held in array_ptr. 00989 * 00990 * @param array_ptr The pointer to the array to viewed. 00991 * @param array_size The number of T elements in the array. 00992 * 00993 * @return The Span to array_ptr with a size of array_size. 00994 * 00995 * @note This helper avoids the typing of template parameter when Span is 00996 * created 'inline'. 00997 * 00998 * @relates Span 00999 */ 01000 template<typename T> 01001 Span<const T> make_const_Span(T *array_ptr, size_t array_size) 01002 { 01003 return Span<const T>(array_ptr, array_size); 01004 } 01005 01006 /**@}*/ 01007 01008 /**@}*/ 01009 01010 } // namespace mbed 01011 01012 #endif /* MBED_PLATFORM_SPAN_H_ */
Generated on Tue Jul 12 2022 15:15:59 by
