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