mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			
						commit
						c12c69fef0
					
				| 
						 | 
					@ -0,0 +1,983 @@
 | 
				
			||||||
 | 
					/* mbed Microcontroller Library
 | 
				
			||||||
 | 
					 * Copyright (c) 2018-2018 ARM Limited
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 | 
					 * you may not use this file except in compliance with the License.
 | 
				
			||||||
 | 
					 * You may obtain a copy of the License at
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 | 
					 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
				
			||||||
 | 
					 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 | 
					 * See the License for the specific language governing permissions and
 | 
				
			||||||
 | 
					 * limitations under the License.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef MBED_PLATFORM_SPAN_H_
 | 
				
			||||||
 | 
					#define MBED_PLATFORM_SPAN_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <algorithm>
 | 
				
			||||||
 | 
					#include <stddef.h>
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "platform/mbed_assert.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace mbed {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Internal details of Span
 | 
				
			||||||
 | 
					// It is used construct Span from Span of convertible types (non const -> const)
 | 
				
			||||||
 | 
					namespace span_detail {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// If From type is convertible to To type, then the compilation constant value is
 | 
				
			||||||
 | 
					// true; otherwise, it is false.
 | 
				
			||||||
 | 
					template<typename From, typename To>
 | 
				
			||||||
 | 
					class is_convertible
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    struct true_type { char x[512]; };
 | 
				
			||||||
 | 
					    struct false_type { };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static const From& generator();
 | 
				
			||||||
 | 
					    static true_type sink(const To &);
 | 
				
			||||||
 | 
					    static false_type sink(...);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    static const bool value = sizeof(true_type) == sizeof(sink(generator()));
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Special value for the Extent parameter of Span.
 | 
				
			||||||
 | 
					 * If the type uses this value, then the size of the array is stored in the object
 | 
				
			||||||
 | 
					 * at runtime.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define SPAN_DYNAMIC_EXTENT -1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Nonowning view to a sequence of contiguous elements.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Spans encapsulate a pointer to a sequence of contiguous elements and its size
 | 
				
			||||||
 | 
					 * into a single object. Span can replace the traditional pair of pointer and
 | 
				
			||||||
 | 
					 * size arguments passed as array definitions in function calls.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @par Operations
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Span objects can be copied and assigned like regular value types with the help
 | 
				
			||||||
 | 
					 * of the copy constructor or the copy assignment (=) operator.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You can retrieve elements of the object with the subscript ([]) operator. You can access the
 | 
				
			||||||
 | 
					 * pointer to the first element of the sequence viewed with data().
 | 
				
			||||||
 | 
					 * The function size() returns the number of elements in the sequence, and
 | 
				
			||||||
 | 
					 * empty() informs whether there is any element in the sequence.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * You can slice Span from the beginning of the sequence (first()), from the end
 | 
				
			||||||
 | 
					 * of the sequence (last()) or from an arbitrary point of the sequence (subspan()).
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @par Size encoding
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The size of the sequence can be encoded in the type itself or in the value of
 | 
				
			||||||
 | 
					 * the instance with the help of the template parameter Extent:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *   - Span<uint8_t, 6>: Span over a sequence of 6 elements.
 | 
				
			||||||
 | 
					 *   - Span<uint8_t>: Span over an arbitrary long sequence.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * When the size is encoded in the type itself, it is guaranteed that the Span
 | 
				
			||||||
 | 
					 * view is a valid sequence (not empty() and not NULL) - unless Extent equals 0.
 | 
				
			||||||
 | 
					 * The type system also prevents automatic conversion from Span of different
 | 
				
			||||||
 | 
					 * sizes. Finally, the Span object is internally represented as a single pointer.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * When the size of the sequence viewed is encoded in the Span value, Span
 | 
				
			||||||
 | 
					 * instances can view an empty sequence. The function empty() helps client code
 | 
				
			||||||
 | 
					 * decide whether Span is viewing valid content or not.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @par Example
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * - Encoding fixed size array: Array values in parameter decays automatically
 | 
				
			||||||
 | 
					 * to pointer, which leaves room for subtitle bugs:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @code
 | 
				
			||||||
 | 
					    typedef uint8_t mac_address_t[6];
 | 
				
			||||||
 | 
					    void process_mac(mac_address_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // compile just fine
 | 
				
			||||||
 | 
					    uint8_t *invalid_value = NULL;
 | 
				
			||||||
 | 
					    process_mac(invalid_value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // correct way
 | 
				
			||||||
 | 
					    typedef Span<uint8_t, 6> mac_address_t;
 | 
				
			||||||
 | 
					    void process_mac(mac_address_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // compilation error
 | 
				
			||||||
 | 
					    uint8_t *invalid_value = NULL;
 | 
				
			||||||
 | 
					    process_mac(invalid_value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // compilation ok
 | 
				
			||||||
 | 
					    uint8_t valid_value[6];
 | 
				
			||||||
 | 
					    process_mac(valid_value);
 | 
				
			||||||
 | 
					 * @endcode
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * - Arbitrary buffer: When dealing with multiple buffers, it becomes painful to
 | 
				
			||||||
 | 
					 * keep track of every buffer size and pointer.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @code
 | 
				
			||||||
 | 
					    const uint8_t options_tag[OPTIONS_TAG_SIZE];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    struct parsed_value_t {
 | 
				
			||||||
 | 
					       uint8_t *header;
 | 
				
			||||||
 | 
					       uint8_t *options;
 | 
				
			||||||
 | 
					       uint8_t *payload;
 | 
				
			||||||
 | 
					       size_t payload_size;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    parsed_value_t parse(uint8_t *buffer, size_t buffer_size)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					       parsed_value_t parsed_value { 0 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       if (buffer != NULL && buffer_size <= MINIMAL_BUFFER_SIZE) {
 | 
				
			||||||
 | 
					           return parsed_value;
 | 
				
			||||||
 | 
					       }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       parsed_value.header = buffer;
 | 
				
			||||||
 | 
					       parsed_value.header_size = BUFFER_HEADER_SIZE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       if (memcmp(buffer + HEADER_OPTIONS_INDEX, options_tag, sizeof(options_tag)) == 0) {
 | 
				
			||||||
 | 
					           options = buffer + BUFFER_HEADER_SIZE;
 | 
				
			||||||
 | 
					           payload = buffer + BUFFER_HEADER_SIZE + OPTIONS_SIZE;
 | 
				
			||||||
 | 
					           payload_size = buffer_size - BUFFER_HEADER_SIZE + OPTIONS_SIZE;
 | 
				
			||||||
 | 
					       } else {
 | 
				
			||||||
 | 
					           payload = buffer + BUFFER_HEADER_SIZE;
 | 
				
			||||||
 | 
					           payload_size = buffer_size - BUFFER_HEADER_SIZE;
 | 
				
			||||||
 | 
					       }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       return parsed_value;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //with Span
 | 
				
			||||||
 | 
					    struct parsed_value_t {
 | 
				
			||||||
 | 
					       Span<uint8_t> header;
 | 
				
			||||||
 | 
					       Span<uint8_t> options;
 | 
				
			||||||
 | 
					       Span<uint8_t> payload;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    parsed_value_t parse(const Span<uint8_t> &buffer)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					       parsed_value_t parsed_value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       if (buffer.size() <= MINIMAL_BUFFER_SIZE) {
 | 
				
			||||||
 | 
					           return parsed_value;
 | 
				
			||||||
 | 
					       }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       parsed_value.header = buffer.first(BUFFER_HEADER_SIZE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       if (buffer.subspan<HEADER_OPTIONS_INDEX, sizeof(options_tag)>() == option_tag) {
 | 
				
			||||||
 | 
					           options = buffer.supspan(parsed_value.header.size(), OPTIONS_SIZE);
 | 
				
			||||||
 | 
					       }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       payload = buffer.subspan(parsed_value.header.size() + parsed_value.options.size());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					       return parsed_value;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					 * @endcode
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @note You can create Span instances with the help of the function template
 | 
				
			||||||
 | 
					 * make_Span() and make_const_Span().
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @note Span<T, Extent> objects can be implicitly converted to Span<T> objects
 | 
				
			||||||
 | 
					 * where required.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @tparam ElementType type of objects the Span views.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @tparam Extent The size of the contiguous sequence viewed. The default value
 | 
				
			||||||
 | 
					 * SPAN_DYNAMIC_SIZE  is special because it allows construction of Span objects of
 | 
				
			||||||
 | 
					 * any size (set at runtime).
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					template<typename ElementType, ptrdiff_t Extent = SPAN_DYNAMIC_EXTENT>
 | 
				
			||||||
 | 
					struct Span {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Type of the element contained
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    typedef ElementType element_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Type of the index.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    typedef ptrdiff_t index_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Pointer to an ElementType
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    typedef element_type *pointer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Reference to an ElementType
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    typedef element_type &reference;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Size of the Extent; -1 if dynamic.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    static const index_type extent = Extent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    MBED_STATIC_ASSERT(Extent >= 0, "Invalid extent for a Span");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Construct an empty Span.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @post a call to size() returns 0, and data() returns NULL.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @note This function is not accessible if Extent != SPAN_DYNAMIC_EXTENT or
 | 
				
			||||||
 | 
					     * Extent != 0 .
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    Span() :
 | 
				
			||||||
 | 
					        _data(NULL)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MBED_STATIC_ASSERT(
 | 
				
			||||||
 | 
					            Extent == 0,
 | 
				
			||||||
 | 
					            "Cannot default construct a static-extent Span (unless Extent is 0)"
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Construct a Span from a pointer to a buffer and its size.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param ptr Pointer to the beginning of the data viewed.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param count Number of elements viewed.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @pre [ptr, ptr + count) must be be a valid range.
 | 
				
			||||||
 | 
					     * @pre count must be equal to Extent.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @post a call to size() returns Extent, and data() returns @p ptr.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    Span(pointer ptr, index_type count) :
 | 
				
			||||||
 | 
					        _data(ptr)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MBED_ASSERT(count == Extent);
 | 
				
			||||||
 | 
					        MBED_ASSERT(Extent == 0 || ptr != NULL);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Construct a Span from the range [first, last).
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param first Pointer to the beginning of the data viewed.
 | 
				
			||||||
 | 
					     * @param last End of the range (element after the last element).
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @pre [first, last) must be be a valid range.
 | 
				
			||||||
 | 
					     * @pre first <= last.
 | 
				
			||||||
 | 
					     * @pre last - first must be equal to Extent.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @post a call to size() returns Extent, and data() returns @p first.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    Span(pointer first, pointer last) :
 | 
				
			||||||
 | 
					        _data(first)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MBED_ASSERT(first <= last);
 | 
				
			||||||
 | 
					        MBED_ASSERT((last - first) == Extent);
 | 
				
			||||||
 | 
					        MBED_ASSERT(Extent == 0 || first != NULL);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Construct a Span from the reference to an array.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param elements Reference to the array viewed.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @post a call to size() returns Extent, and data() returns a
 | 
				
			||||||
 | 
					     * pointer to elements.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    Span(element_type (&elements)[Extent]):
 | 
				
			||||||
 | 
					        _data(elements) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Construct a Span object from another Span of the same size.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param other The Span object used to construct this.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @note For Span with a positive extent, this function is not accessible.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @note OtherElementType(*)[] must be convertible to ElementType(*)[].
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    template<typename OtherElementType>
 | 
				
			||||||
 | 
					    Span(const Span<OtherElementType, Extent> &other):
 | 
				
			||||||
 | 
					        _data(other.data())
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MBED_STATIC_ASSERT(
 | 
				
			||||||
 | 
					            (span_detail::is_convertible<OtherElementType (*)[], ElementType (*)[]>::value),
 | 
				
			||||||
 | 
					            "OtherElementType(*)[] should be convertible to ElementType (*)[]"
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Return the size of the sequence viewed.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return The size of the sequence viewed.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    index_type size() const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return Extent;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Return if the sequence is empty or not.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return true if the sequence is empty and false otherwise.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    bool empty() const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return size() == 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Returns a reference to the element at position @p index.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param index Index of the element to access.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return A reference to the element at the index specified in input.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @pre 0 <= index < Extent.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    reference operator[](index_type index) const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					#ifdef MBED_DEBUG
 | 
				
			||||||
 | 
					        MBED_ASSERT(0 <= index && index < Extent);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        return _data[index];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Return a pointer to the first element of the sequence or NULL if the Span
 | 
				
			||||||
 | 
					     * is empty().
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return The pointer to the first element of the Span.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    pointer data() const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return _data;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Create a new Span over the first @p Count elements of the existing view.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @tparam Count The number of element viewed by the new Span
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return A new Span over the first @p Count elements.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @pre Count >= 0 && Count <= size().
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    template<ptrdiff_t Count>
 | 
				
			||||||
 | 
					    Span<element_type, Count> first() const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MBED_STATIC_ASSERT(
 | 
				
			||||||
 | 
					            (0 <= Count) && (Count <= Extent),
 | 
				
			||||||
 | 
					            "Invalid subspan extent"
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        return Span<element_type, Count>(_data, Count);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Create a new Span over the last @p Count elements of the existing view.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @tparam Count The number of element viewed by the new Span.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return A new Span over the last @p Count elements.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @pre Count >= 0 && Count <= size().
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    template<ptrdiff_t Count>
 | 
				
			||||||
 | 
					    Span<element_type, Count> last() const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MBED_STATIC_ASSERT(
 | 
				
			||||||
 | 
					            (0 <= Count) && (Count <= Extent),
 | 
				
			||||||
 | 
					            "Invalid subspan extent"
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        return Span<element_type, Count>(_data + (Extent - Count), Count);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Create a subspan that is a view of other Count elements; the view starts at
 | 
				
			||||||
 | 
					     * element Offset.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @tparam Offset The offset of the first element viewed by the subspan.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @tparam Count The number of elements present in the subspan. If Count
 | 
				
			||||||
 | 
					     * is equal to SPAN_DYNAMIC_EXTENT, then a Span starting at offset and
 | 
				
			||||||
 | 
					     * containing the rest of the elements is returned.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return A subspan of this starting at Offset and Count long.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    template<std::ptrdiff_t Offset, std::ptrdiff_t Count>
 | 
				
			||||||
 | 
					    Span<element_type, Count == SPAN_DYNAMIC_EXTENT ? Extent - Offset : Count>
 | 
				
			||||||
 | 
					    subspan() const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MBED_STATIC_ASSERT(
 | 
				
			||||||
 | 
					            0 <= Offset && Offset <= Extent,
 | 
				
			||||||
 | 
					            "Invalid subspan offset"
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        MBED_STATIC_ASSERT(
 | 
				
			||||||
 | 
					            (Count == SPAN_DYNAMIC_EXTENT) ||
 | 
				
			||||||
 | 
					            (0 <= Count && (Count + Offset) <= Extent),
 | 
				
			||||||
 | 
					            "Invalid subspan count"
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        return Span<element_type, Count == SPAN_DYNAMIC_EXTENT ? Extent - Offset : Count>(
 | 
				
			||||||
 | 
					            _data + Offset,
 | 
				
			||||||
 | 
					            Count == SPAN_DYNAMIC_EXTENT ? Extent - Offset : Count
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Create a new Span over the first @p count elements of the existing view.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param count The number of element viewed by the new Span.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return A new Span over the first @p count elements.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    Span<element_type, SPAN_DYNAMIC_EXTENT> first(index_type count) const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MBED_ASSERT(0 <= count && count <= Extent);
 | 
				
			||||||
 | 
					        return Span<element_type, SPAN_DYNAMIC_EXTENT>(_data, count);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Create a new Span over the last @p count elements of the existing view.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param count The number of elements viewed by the new Span.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return A new Span over the last @p count elements.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    Span<element_type, SPAN_DYNAMIC_EXTENT> last(index_type count) const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MBED_ASSERT(0 <= count && count <= Extent);
 | 
				
			||||||
 | 
					        return Span<element_type, SPAN_DYNAMIC_EXTENT>(
 | 
				
			||||||
 | 
					            _data + (Extent - count),
 | 
				
			||||||
 | 
					            count
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Create a subspan that is a view of other count elements; the view starts at
 | 
				
			||||||
 | 
					     * element offset.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param offset The offset of the first element viewed by the subspan.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param count The number of elements present in the subspan. If Count
 | 
				
			||||||
 | 
					     * is equal to SPAN_DYNAMIC_EXTENT, then a span starting at offset and
 | 
				
			||||||
 | 
					     * containing the rest of the elements is returned.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    Span<element_type, SPAN_DYNAMIC_EXTENT> subspan(
 | 
				
			||||||
 | 
					        index_type offset, index_type count = SPAN_DYNAMIC_EXTENT
 | 
				
			||||||
 | 
					    ) const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MBED_ASSERT(0 <= offset && offset <= Extent);
 | 
				
			||||||
 | 
					        MBED_ASSERT(
 | 
				
			||||||
 | 
					            (count == SPAN_DYNAMIC_EXTENT) ||
 | 
				
			||||||
 | 
					            (0 <= count && (count + offset) <= Extent)
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        return Span<element_type, SPAN_DYNAMIC_EXTENT>(
 | 
				
			||||||
 | 
					            _data + offset,
 | 
				
			||||||
 | 
					            count == SPAN_DYNAMIC_EXTENT ? Extent - offset : count
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    pointer _data;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Span specialization that handle dynamic size.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					template<typename ElementType>
 | 
				
			||||||
 | 
					struct Span<ElementType, SPAN_DYNAMIC_EXTENT> {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Type of the element contained.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    typedef ElementType element_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Type of the index.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    typedef ptrdiff_t index_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Pointer to an ElementType.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    typedef element_type *pointer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Reference to an ElementType.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    typedef element_type &reference;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Size of the Extent; -1 if dynamic.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    static const index_type extent = SPAN_DYNAMIC_EXTENT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Construct an empty Span.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @post a call to size() returns 0, and data() returns NULL.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @note This function is not accessible if Extent != SPAN_DYNAMIC_EXTENT or
 | 
				
			||||||
 | 
					     * Extent != 0 .
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    Span() :
 | 
				
			||||||
 | 
					        _data(NULL), _size(0) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Construct a Span from a pointer to a buffer and its size.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param ptr Pointer to the beginning of the data viewed.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param count Number of elements viewed.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @pre [ptr, ptr + count) must be be a valid range.
 | 
				
			||||||
 | 
					     * @pre count must be equal to extent.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @post a call to size() returns count, and data() returns @p ptr.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    Span(pointer ptr, index_type count) :
 | 
				
			||||||
 | 
					        _data(ptr), _size(count)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MBED_ASSERT(count >= 0);
 | 
				
			||||||
 | 
					        MBED_ASSERT(ptr != NULL || count == 0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Construct a Span from the range [first, last).
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param first Pointer to the beginning of the data viewed.
 | 
				
			||||||
 | 
					     * @param last End of the range (element after the last element).
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @pre [first, last) must be be a valid range.
 | 
				
			||||||
 | 
					     * @pre first <= last.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @post a call to size() returns the result of (last - first), and
 | 
				
			||||||
 | 
					     * data() returns @p first.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    Span(pointer first, pointer last) :
 | 
				
			||||||
 | 
					        _data(first), _size(last - first)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MBED_ASSERT(first <= last);
 | 
				
			||||||
 | 
					        MBED_ASSERT(first != NULL  || (last - first) == 0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Construct a Span from the reference to an array.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param elements Reference to the array viewed.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @tparam Count Number of elements of T presents in the array.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @post a call to size() returns Count, and data() returns a
 | 
				
			||||||
 | 
					     * pointer to elements.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    template<size_t Count>
 | 
				
			||||||
 | 
					    Span(element_type (&elements)[Count]):
 | 
				
			||||||
 | 
					        _data(elements), _size(Count) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Construct a Span object from another Span.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param other The Span object used to construct this.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @note For Span with a positive extent, this function is not accessible.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @note OtherElementType(*)[] must be convertible to ElementType(*)[].
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    template<typename OtherElementType, ptrdiff_t OtherExtent>
 | 
				
			||||||
 | 
					    Span(const Span<OtherElementType, OtherExtent> &other):
 | 
				
			||||||
 | 
					        _data(other.data()), _size(other.size())
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MBED_STATIC_ASSERT(
 | 
				
			||||||
 | 
					            (span_detail::is_convertible<OtherElementType (*)[], ElementType (*)[]>::value),
 | 
				
			||||||
 | 
					            "OtherElementType(*)[] should be convertible to ElementType (*)[]"
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Return the size of the array viewed.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return The number of elements present in the array viewed.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    index_type size() const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return _size;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Return if the sequence viewed is empty or not.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return true if the sequence is empty and false otherwise.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    bool empty() const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return size() == 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Access to an element of the sequence.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param index Element index to access.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return A reference to the element at the index specified in input.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @pre index is less than size().
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    reference operator[](index_type index) const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					#ifdef MBED_DEBUG
 | 
				
			||||||
 | 
					        MBED_ASSERT(0 <= index && index < _size);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        return _data[index];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Get the raw pointer to the sequence viewed.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return The raw pointer to the first element viewed.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    pointer data() const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return _data;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Create a new Span over the first @p Count elements of the existing view.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @tparam Count The number of elements viewed by the new Span.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return A new Span over the first @p Count elements.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @pre Count >= 0 && Count <= size().
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    template<ptrdiff_t Count>
 | 
				
			||||||
 | 
					    Span<element_type, Count> first() const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MBED_ASSERT((Count >= 0) && (Count <= _size));
 | 
				
			||||||
 | 
					        return Span<element_type, Count>(_data, Count);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Create a new Span over the last @p Count elements of the existing view.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @tparam Count The number of elements viewed by the new Span.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return A new Span over the last @p Count elements.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @pre Count >= 0 && Count <= size().
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    template<ptrdiff_t Count>
 | 
				
			||||||
 | 
					    Span<element_type, Count> last() const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MBED_ASSERT((0 <= Count) && (Count <= _size));
 | 
				
			||||||
 | 
					        return Span<element_type, Count>(_data + (_size - Count), Count);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Create a subspan that is a view other Count elements; the view starts at
 | 
				
			||||||
 | 
					     * element Offset.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @tparam Offset The offset of the first element viewed by the subspan.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @tparam Count The number of elements present in the subspan. If Count
 | 
				
			||||||
 | 
					     * is equal to SPAN_DYNAMIC_EXTENT, then a Span starting at offset and
 | 
				
			||||||
 | 
					     * containing the rest of the elements is returned.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return A subspan of this starting at Offset and Count long.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    template<std::ptrdiff_t Offset, std::ptrdiff_t Count>
 | 
				
			||||||
 | 
					    Span<element_type, Count == SPAN_DYNAMIC_EXTENT ? SPAN_DYNAMIC_EXTENT : Count>
 | 
				
			||||||
 | 
					    subspan() const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MBED_ASSERT(0 <= Offset && Offset <= _size);
 | 
				
			||||||
 | 
					        MBED_ASSERT(
 | 
				
			||||||
 | 
					            (Count == SPAN_DYNAMIC_EXTENT) ||
 | 
				
			||||||
 | 
					            (0 <= Count && (Count + Offset) <= _size)
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        return Span<element_type, Count == SPAN_DYNAMIC_EXTENT ? SPAN_DYNAMIC_EXTENT : Count>(
 | 
				
			||||||
 | 
					            _data + Offset,
 | 
				
			||||||
 | 
					            Count == SPAN_DYNAMIC_EXTENT ? _size - Offset : Count
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Create a new Span over the first @p count elements of the existing view.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param count The number of elements viewed by the new Span.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return A new Span over the first @p count elements.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    Span<element_type, SPAN_DYNAMIC_EXTENT> first(index_type count) const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MBED_ASSERT(0 <= count && count <= _size);
 | 
				
			||||||
 | 
					        return Span<element_type, SPAN_DYNAMIC_EXTENT>(_data, count);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Create a new Span over the last @p count elements of the existing view.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param count The number of elements viewed by the new Span.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return A new Span over the last @p count elements.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    Span<element_type, SPAN_DYNAMIC_EXTENT> last(index_type count) const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MBED_ASSERT(0 <= count && count <= _size);
 | 
				
			||||||
 | 
					        return Span<element_type, SPAN_DYNAMIC_EXTENT>(
 | 
				
			||||||
 | 
					            _data + (_size - count),
 | 
				
			||||||
 | 
					            count
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Create a subspan that is a view of other count elements; the view starts at
 | 
				
			||||||
 | 
					     * element offset.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param offset The offset of the first element viewed by the subspan.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param count The number of elements present in the subspan. If Count
 | 
				
			||||||
 | 
					     * is equal to SPAN_DYNAMIC_EXTENT, then a Span starting at offset and
 | 
				
			||||||
 | 
					     * containing the rest of the elements is returned.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @return A subspan of this starting at offset and count long.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    Span<element_type, SPAN_DYNAMIC_EXTENT> subspan(
 | 
				
			||||||
 | 
					        index_type offset, index_type count = SPAN_DYNAMIC_EXTENT
 | 
				
			||||||
 | 
					    ) const
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        MBED_ASSERT(0 <= offset && offset <= _size);
 | 
				
			||||||
 | 
					        MBED_ASSERT(
 | 
				
			||||||
 | 
					            (count == SPAN_DYNAMIC_EXTENT) ||
 | 
				
			||||||
 | 
					            (0 <= count && (count + offset) <= _size)
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        return Span<element_type, SPAN_DYNAMIC_EXTENT>(
 | 
				
			||||||
 | 
					            _data + offset,
 | 
				
			||||||
 | 
					            count == SPAN_DYNAMIC_EXTENT ? _size - offset : count
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    pointer _data;
 | 
				
			||||||
 | 
					    index_type _size;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Equality operator between two Span objects.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param lhs Left side of the binary operation.
 | 
				
			||||||
 | 
					 * @param rhs Right side of the binary operation.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return True if Spans in input have the same size and the same content and
 | 
				
			||||||
 | 
					 * false otherwise.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					template<typename T, typename U, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent>
 | 
				
			||||||
 | 
					bool operator==(const Span<T, LhsExtent> &lhs, const Span<U, RhsExtent> &rhs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (lhs.size() != rhs.size()) {
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (lhs.data() == rhs.data()) {
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return std::equal(lhs.data(), lhs.data() + lhs.size(), rhs.data());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Equality operation between a Span and a reference to a C++ array.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param lhs Left side of the binary operation.
 | 
				
			||||||
 | 
					 * @param rhs Right side of the binary operation.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return True if elements in input have the same size and the same content and
 | 
				
			||||||
 | 
					 * false otherwise.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					template<typename T, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent>
 | 
				
			||||||
 | 
					bool operator==(const Span<T, LhsExtent> &lhs, T (&rhs)[RhsExtent])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return lhs == Span<T>(rhs);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Equality operation between a Span and a reference to a C++ array.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param lhs Left side of the binary operation.
 | 
				
			||||||
 | 
					 * @param rhs Right side of the binary operation.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return True if elements in input have the same size and the same content
 | 
				
			||||||
 | 
					 * and false otherwise.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					template<typename T, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent>
 | 
				
			||||||
 | 
					bool operator==(T (&lhs)[LhsExtent], const Span<T, RhsExtent> &rhs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return Span<T>(lhs) == rhs;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Not equal operator
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param lhs Left side of the binary operation.
 | 
				
			||||||
 | 
					 * @param rhs Right side of the binary operation.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return True if arrays in input do not have the same size or the same content
 | 
				
			||||||
 | 
					 * and false otherwise.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					template<typename T, typename U, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent>
 | 
				
			||||||
 | 
					bool operator!=(const Span<T, LhsExtent> &lhs, const Span<U, RhsExtent> &rhs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return !(lhs == rhs);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Not Equal operation between a Span and a reference to a C++ array.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param lhs Left side of the binary operation.
 | 
				
			||||||
 | 
					 * @param rhs Right side of the binary operation.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return True if elements in input have the same size and the same content
 | 
				
			||||||
 | 
					 * and false otherwise.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					template<typename T, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent>
 | 
				
			||||||
 | 
					bool operator!=(const Span<T, LhsExtent> &lhs, T (&rhs)[RhsExtent])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return !(lhs == Span<T, RhsExtent>(rhs));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Not Equal operation between a Span and a reference to a C++ array.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param lhs Left side of the binary operation.
 | 
				
			||||||
 | 
					 * @param rhs Right side of the binary operation.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return True if elements in input have the same size and the same content
 | 
				
			||||||
 | 
					 * and false otherwise.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					template<typename T, ptrdiff_t LhsExtent, ptrdiff_t RhsExtent>
 | 
				
			||||||
 | 
					bool operator!=(T (&lhs)[LhsExtent], const Span<T, RhsExtent> &rhs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return !(Span<T, LhsExtent>(lhs) == rhs);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Generate a Span from a reference to a C/C++ array.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @tparam T Type of elements held in elements.
 | 
				
			||||||
 | 
					 * @tparam Extent Number of items held in elements.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param elements The reference to the array viewed.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return The Span to elements.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @note This helper avoids the typing of template parameter when Span is
 | 
				
			||||||
 | 
					 * created 'inline'.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					template<typename T, size_t Size>
 | 
				
			||||||
 | 
					Span<T, Size> make_Span(T (&elements)[Size])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return Span<T, Size>(elements);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Generate a Span from a pointer to a C/C++ array.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @tparam Extent Number of items held in elements.
 | 
				
			||||||
 | 
					 * @tparam T Type of elements held in elements.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param elements The reference to the array viewed.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return The Span to elements.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @note This helper avoids the typing of template parameter when Span is
 | 
				
			||||||
 | 
					 * created 'inline'.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					template<ptrdiff_t Extent, typename T>
 | 
				
			||||||
 | 
					Span<T, Extent> make_Span(T *elements)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return Span<T, Extent>(elements, Extent);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Generate a Span from a C/C++ pointer and the size of the array.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @tparam T Type of elements held in array_ptr.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param array_ptr The pointer to the array viewed.
 | 
				
			||||||
 | 
					 * @param array_size The number of T elements in the array.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return The Span to array_ptr with a size of array_size.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @note This helper avoids the typing of template parameter when Span is
 | 
				
			||||||
 | 
					 * created 'inline'.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					template<typename T>
 | 
				
			||||||
 | 
					Span<T> make_Span(T *array_ptr, ptrdiff_t array_size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return Span<T>(array_ptr, array_size);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Generate a Span to a const content from a reference to a C/C++ array.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @tparam T Type of elements held in elements.
 | 
				
			||||||
 | 
					 * @tparam Extent Number of items held in elements.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param elements The array viewed.
 | 
				
			||||||
 | 
					 * @return The Span to elements.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @note This helper avoids the typing of template parameter when Span is
 | 
				
			||||||
 | 
					 * created 'inline'.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					template<typename T, size_t Extent>
 | 
				
			||||||
 | 
					Span<const T, Extent> make_const_Span(const T (&elements)[Extent])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return Span<const T, Extent>(elements);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Generate a Span to a const content from a pointer to a C/C++ array.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @tparam Extent Number of items held in elements.
 | 
				
			||||||
 | 
					 * @tparam T Type of elements held in elements.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param elements The reference to the array viewed.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return The Span to elements.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @note This helper avoids the typing of template parameter when Span is
 | 
				
			||||||
 | 
					 * created 'inline'.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					template<size_t Extent, typename T>
 | 
				
			||||||
 | 
					Span<const T, Extent> make_const_Span(const T *elements)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return Span<const T, Extent>(elements, Extent);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Generate a Span to a const content from a C/C++ pointer and the size of the
 | 
				
			||||||
 | 
					 * array.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @tparam T Type of elements held in array_ptr.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @param array_ptr The pointer to the array to viewed.
 | 
				
			||||||
 | 
					 * @param array_size The number of T elements in the array.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @return The Span to array_ptr with a size of array_size.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @note This helper avoids the typing of template parameter when Span is
 | 
				
			||||||
 | 
					 * created 'inline'.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					template<typename T>
 | 
				
			||||||
 | 
					Span<const T> make_const_Span(T *array_ptr, size_t array_size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return Span<const T>(array_ptr, array_size);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace mbed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* MBED_PLATFORM_SPAN_H_ */
 | 
				
			||||||
		Loading…
	
		Reference in New Issue