Loading...
Searching...
No Matches
span.h
Go to the documentation of this file.
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2020 John Wellbelove
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files(the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions :
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
******************************************************************************/
#ifndef ETL_SPAN_INCLUDED
#define ETL_SPAN_INCLUDED
#include "platform.h"
#include "algorithm.h"
#include "alignment.h"
#include "array.h"
#include "byte.h"
#include "circular_iterator.h"
#include "container.h"
#include "error_handler.h"
#include "exception.h"
#include "hash.h"
#include "integral_limits.h"
#include "iterator.h"
#include "memory.h"
#include "nullptr.h"
#include "static_assert.h"
#include "type_traits.h"
#include "private/tuple_size.h"
#if ETL_USING_STL && ETL_USING_CPP20
#include <span>
#endif
#include "private/dynamic_extent.h"
namespace etl
{
template <typename T>
struct is_std_array : etl::false_type
{
};
#if ETL_USING_STL && ETL_USING_CPP11
template <typename T, size_t N>
struct is_std_array<std::array<T, N>> : etl::true_type
{
};
#endif
template <typename T>
struct is_std_array<const T> : is_std_array<T>
{
};
template <typename T>
struct is_std_array<volatile T> : is_std_array<T>
{
};
template <typename T>
struct is_std_array<const volatile T> : is_std_array<T>
{
};
template <typename T>
struct is_etl_array : etl::false_type
{
};
template <typename T, size_t N>
struct is_etl_array<etl::array<T, N> > : etl::true_type
{
};
template <typename T>
struct is_etl_array<const T> : is_etl_array<T>
{
};
template <typename T>
struct is_etl_array<volatile T> : is_etl_array<T>
{
};
template <typename T>
struct is_etl_array<const volatile T> : is_etl_array<T>
{
};
//***************************************************************************
// Tag to indicate a class is a span.
//***************************************************************************
// Forward declaration for trait
template <typename T, size_t Extent>
class span;
namespace private_span
{
template <typename T>
struct is_span_helper : etl::false_type
{
};
template <typename T, size_t Extent>
struct is_span_helper<etl::span<T, Extent> > : etl::true_type
{
};
} // namespace private_span
template <typename T>
struct is_span : private_span::is_span_helper<typename etl::remove_cvref<T>::type>
{
};
#if ETL_USING_CPP17
template <typename T>
inline constexpr bool is_span_v = is_span<T>::value;
#endif
//***************************************************************************
//***************************************************************************
class span_exception : public exception
{
public:
span_exception(string_type reason_, string_type file_name_, numeric_type line_number_)
: exception(reason_, file_name_, line_number_)
{
}
};
//***************************************************************************
//***************************************************************************
class span_alignment_exception : public span_exception
{
public:
span_alignment_exception(string_type file_name_, numeric_type line_number_)
: span_exception(ETL_ERROR_TEXT("span:alignment", ETL_SPAN_FILE_ID"A"), file_name_, line_number_)
{
}
};
//***************************************************************************
//***************************************************************************
class span_size_mismatch : public span_exception
{
public:
span_size_mismatch(string_type file_name_, numeric_type line_number_)
: span_exception(ETL_ERROR_TEXT("span:size", ETL_SPAN_FILE_ID"B"), file_name_, line_number_)
{
}
};
//***************************************************************************
//***************************************************************************
class span_out_of_range : public span_exception
{
public:
span_out_of_range(string_type file_name_, numeric_type line_number_)
: span_exception(ETL_ERROR_TEXT("span:range", ETL_SPAN_FILE_ID"C"), file_name_, line_number_)
{
}
};
//***************************************************************************
class span_tag
{
};
//***************************************************************************
//***************************************************************************
template <typename T, size_t Extent = etl::dynamic_extent>
class span : public span_tag
{
public:
typedef T element_type;
typedef typename etl::remove_cv<T>::type value_type;
typedef size_t size_type;
typedef T& reference;
typedef const T& const_reference;
typedef T* pointer;
typedef const T* const_pointer;
typedef T* iterator;
typedef const T* const_iterator;
typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
typedef etl::circular_iterator<pointer> circular_iterator;
typedef etl::circular_iterator<ETL_OR_STD::reverse_iterator<pointer> > reverse_circular_iterator;
static ETL_CONSTANT size_t extent = Extent;
//*************************************************************************
//*************************************************************************
#if ETL_USING_CPP11
template <size_t E = Extent, typename = typename etl::enable_if<E == 0, void>::type>
ETL_CONSTEXPR span() ETL_NOEXCEPT
: pbegin(ETL_NULLPTR)
{
}
#else
ETL_CONSTEXPR span() ETL_NOEXCEPT
: pbegin(ETL_NULLPTR)
{
ETL_STATIC_ASSERT(Extent == 0, "Default constructor only available for zero extent");
}
#endif
//*************************************************************************
//*************************************************************************
template <typename TIterator>
explicit ETL_CONSTEXPR14 span(const TIterator begin_, const size_t size_) ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS)
: pbegin(etl::to_address(begin_))
{
ETL_ASSERT(size_ == Extent, ETL_ERROR(span_size_mismatch));
(void)size_;
}
//*************************************************************************
//*************************************************************************
template <typename TIteratorBegin, typename TIteratorEnd>
ETL_CONSTEXPR14 span(const TIteratorBegin begin_, const TIteratorEnd end_,
typename etl::enable_if< !etl::is_integral<TIteratorEnd>::value, void>::type* = 0) ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS)
: pbegin(etl::to_address(begin_))
{
ETL_ASSERT(etl::distance(begin_, end_) == Extent, ETL_ERROR(span_size_mismatch));
(void)end_;
}
//*************************************************************************
//*************************************************************************
template <size_t Array_Size>
ETL_CONSTEXPR span(typename etl::type_identity<element_type>::type (&begin_)[Array_Size],
typename etl::enable_if<(Array_Size == Extent), void>::type* = 0) ETL_NOEXCEPT
: pbegin(begin_)
{
}
#if ETL_USING_CPP11
//*************************************************************************
//*************************************************************************
template <typename TContainer>
ETL_CONSTEXPR14 span(TContainer&& a,
typename etl::enable_if<
!etl::is_span<TContainer>::value && !etl::is_std_array< typename etl::remove_reference<TContainer>::type>::value
&& !etl::is_etl_array< typename etl::remove_reference<TContainer>::type>::value
&& !etl::is_pointer< typename etl::remove_reference<TContainer>::type>::value && !etl::is_array<TContainer>::value
&& etl::is_lvalue_reference<TContainer&&>::value && has_size<TContainer>::value && has_data<TContainer>::value
&& etl::is_convertible< decltype(etl::declval< typename etl::remove_reference<TContainer>::type&>().data()), pointer>::value
&& etl::is_same< typename etl::remove_cv<T>::type,
typename etl::remove_cv<typename etl::remove_reference< TContainer>::type::value_type>::type>::value,
void>::type* = 0) ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS)
: pbegin(a.data())
{
ETL_ASSERT(a.size() == Extent, ETL_ERROR(span_size_mismatch));
}
#else
//*************************************************************************
//*************************************************************************
template <typename TContainer>
span(TContainer& a, typename etl::enable_if<
!etl::is_span<TContainer>::value && !etl::is_std_array< typename etl::remove_reference<TContainer>::type>::value
&& !etl::is_etl_array< typename etl::remove_reference<TContainer>::type>::value
&& !etl::is_pointer< typename etl::remove_reference<TContainer>::type>::value && !etl::is_array<TContainer>::value
&& has_size<TContainer>::value && has_data<TContainer>::value
&& etl::is_same< typename etl::remove_cv<T>::type,
typename etl::remove_cv<typename etl::remove_reference< TContainer>::type::value_type>::type>::value,
void>::type* = 0)
: pbegin(a.data())
{
ETL_ASSERT(a.size() == Extent, ETL_ERROR(span_size_mismatch));
}
//*************************************************************************
//*************************************************************************
template <typename TContainer>
span(
const TContainer& a,
typename etl::enable_if<
!etl::is_span<TContainer>::value && !etl::is_std_array< typename etl::remove_reference<TContainer>::type>::value
&& !etl::is_etl_array< typename etl::remove_reference<TContainer>::type>::value
&& !etl::is_pointer< typename etl::remove_reference<TContainer>::type>::value && has_size<TContainer>::value && has_data<TContainer>::value
&& etl::is_same< typename etl::remove_cv<T>::type,
typename etl::remove_cv<typename etl::remove_reference< TContainer>::type::value_type>::type>::value,
void>::type* = 0)
: pbegin(a.data())
{
ETL_ASSERT(a.size() == Extent, ETL_ERROR(span_size_mismatch));
}
#endif
//*************************************************************************
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR span(etl::array<U, Size>& other,
typename etl::enable_if<(Size == Extent) && etl::is_convertible<U (*)[], T (*)[]>::value, void>::type* = 0) ETL_NOEXCEPT
: pbegin(other.data())
{
}
//*************************************************************************
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR span(const etl::array<U, Size>& other,
typename etl::enable_if<(Size == Extent) && etl::is_convertible<U (*)[], T (*)[]>::value, void>::type* = 0) ETL_NOEXCEPT
: pbegin(other.data())
{
}
#if ETL_USING_CPP11
template <typename U, size_t Size>
span(etl::array<U, Size>&&) = delete;
#endif
#if ETL_USING_STL && ETL_USING_CPP11
//*************************************************************************
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR span(std::array<U, Size>& other,
typename etl::enable_if<(Size == Extent) && etl::is_convertible<U (*)[], T (*)[]>::value, void>::type* = 0) ETL_NOEXCEPT
: pbegin(other.data())
{
}
//*************************************************************************
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR span(const std::array<U, Size>& other,
typename etl::enable_if<(Size == Extent) && etl::is_convertible<U (*)[], T (*)[]>::value, void>::type* = 0) ETL_NOEXCEPT
: pbegin(other.data())
{
}
template <typename U, size_t Size>
span(std::array<U, Size>&&) = delete;
#endif
//*************************************************************************
//*************************************************************************
ETL_CONSTEXPR span(const span& other) ETL_NOEXCEPT
: pbegin(other.pbegin)
{
}
//*************************************************************************
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR span(const etl::span<U, Size>& other,
typename etl::enable_if<(Size == Extent) && (Size != etl::dynamic_extent), void>::type* = 0) ETL_NOEXCEPT
: pbegin(other.data())
{
}
//*************************************************************************
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR14 explicit span(const etl::span<U, Size>& other, typename etl::enable_if<(Size == etl::dynamic_extent), void>::type* = 0)
: pbegin(other.data())
{
ETL_ASSERT(other.size() == Extent, ETL_ERROR(span_size_mismatch));
}
#if ETL_USING_STL && ETL_USING_CPP20
//*************************************************************************
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR span(const std::span<U, Size>& other,
typename etl::enable_if<(Size == Extent) && etl::is_convertible<U (*)[], T (*)[]>::value, int>::type* = 0) ETL_NOEXCEPT
: pbegin(other.data())
{
}
//*************************************************************************
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR14 span(const std::span<U, Size>& other,
typename etl::enable_if<(Size == etl::dynamic_extent && etl::is_convertible<U (*)[], T (*)[]>::value), int>::type* = 0)
ETL_NOEXCEPT
: pbegin(other.data())
{
ETL_ASSERT(other.size() == Extent, ETL_ERROR(span_size_mismatch));
}
#endif
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
{
ETL_STATIC_ASSERT(Extent > 0, "Span is empty");
return *pbegin;
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
{
ETL_STATIC_ASSERT(Extent > 0, "Span is empty");
return *((pbegin + Extent) - 1);
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
{
return pbegin;
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR const_iterator cbegin() const ETL_NOEXCEPT
{
return pbegin;
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
{
return pbegin;
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR circular_iterator begin_circular() const ETL_NOEXCEPT
{
return circular_iterator(begin(), end());
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR const_iterator cend() const ETL_NOEXCEPT
{
return (pbegin + Extent);
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
{
return (pbegin + Extent);
}
//*************************************************************************
// Returns a const reverse iterator to the reverse beginning of the span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR const_reverse_iterator crbegin() const ETL_NOEXCEPT
{
return const_reverse_iterator((pbegin + Extent));
}
//*************************************************************************
// Returns an reverse iterator to the reverse beginning of the span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rbegin() const ETL_NOEXCEPT
{
return reverse_iterator((pbegin + Extent));
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reverse_circular_iterator rbegin_circular() const ETL_NOEXCEPT
{
return reverse_circular_iterator(rbegin(), rend());
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR const_reverse_iterator crend() const ETL_NOEXCEPT
{
return const_reverse_iterator(pbegin);
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rend() const ETL_NOEXCEPT
{
return reverse_iterator(pbegin);
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
{
return Extent == 0;
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
{
return Extent;
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
{
return sizeof(element_type) * Extent;
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR size_t max_size() const ETL_NOEXCEPT
{
return size();
}
//*************************************************************************
//*************************************************************************
ETL_CONSTEXPR14 span& operator=(const span& other) ETL_NOEXCEPT
{
pbegin = other.pbegin;
return *this;
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR14 reference at(size_t i)
{
ETL_ASSERT(i < size(), ETL_ERROR(span_out_of_range));
return pbegin[i];
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR14 const_reference at(size_t i) const
{
ETL_ASSERT(i < size(), ETL_ERROR(span_out_of_range));
return pbegin[i];
}
//*************************************************************************
//*************************************************************************
ETL_CONSTEXPR reference operator[](const size_t i) const
{
#if ETL_USING_CPP11 && ETL_NOT_USING_CPP14 && ETL_USING_EXCEPTIONS && ETL_CHECKING_INDEX_OPERATOR
return i < size() ? pbegin[i] : throw(ETL_ERROR(span_out_of_range));
#else
ETL_ASSERT_CHECK_INDEX_OPERATOR(i < size(), ETL_ERROR(span_out_of_range));
return pbegin[i];
#endif
}
//*************************************************************************
//*************************************************************************
template <size_t COUNT>
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, COUNT> first() const ETL_NOEXCEPT
{
// If Extent is static, check that original span contains at least COUNT
// elements
ETL_STATIC_ASSERT(COUNT <= Extent, "Original span does not contain COUNT elements");
return etl::span<element_type, COUNT>(pbegin, pbegin + COUNT);
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, etl::dynamic_extent> first(size_t count) const
ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
{
#if ETL_USING_CPP11 && ETL_NOT_USING_CPP14 && ETL_USING_EXCEPTIONS && ETL_CHECKING_EXTRA
return count <= size() ? etl::span<element_type, etl::dynamic_extent>(pbegin, pbegin + count) : throw(ETL_ERROR(span_out_of_range));
#else
ETL_ASSERT_CHECK_EXTRA(count <= size(), ETL_ERROR(span_out_of_range));
return etl::span<element_type, etl::dynamic_extent>(pbegin, pbegin + count);
#endif
}
//*************************************************************************
//*************************************************************************
template <size_t COUNT>
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, COUNT> last() const ETL_NOEXCEPT
{
// If Extent is static, check that original span contains at least COUNT
// elements
ETL_STATIC_ASSERT(COUNT <= Extent, "Original span does not contain COUNT elements");
return etl::span<element_type, COUNT>(pbegin + Extent - COUNT, (pbegin + Extent));
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, etl::dynamic_extent> last(size_t count) const
ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
{
#if ETL_USING_CPP11 && ETL_NOT_USING_CPP14 && ETL_USING_EXCEPTIONS && ETL_CHECKING_EXTRA
return count <= size() ? etl::span<element_type, etl::dynamic_extent>((pbegin + Extent) - count, (pbegin + Extent))
: throw(ETL_ERROR(span_out_of_range));
#else
ETL_ASSERT_CHECK_EXTRA(count <= size(), ETL_ERROR(span_out_of_range));
return etl::span<element_type, etl::dynamic_extent>((pbegin + Extent) - count, (pbegin + Extent));
#endif
}
#if ETL_USING_CPP11
//*************************************************************************
//*************************************************************************
template <size_t OFFSET, size_t COUNT = etl::dynamic_extent>
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET> subspan() const ETL_NOEXCEPT
{
// If Extent is static, check that OFFSET is within the original span
ETL_STATIC_ASSERT(OFFSET <= Extent, "OFFSET is not within the original span");
// If count is also static, check that OFFSET + COUNT is within the
// original span
ETL_STATIC_ASSERT((COUNT != etl::dynamic_extent) ? COUNT <= (Extent - OFFSET) : true, "OFFSET + COUNT is not within the original span");
return (COUNT == etl::dynamic_extent) ? etl::span < element_type,
COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET > (pbegin + OFFSET, (pbegin + Extent)) : etl::span < element_type,
COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET > (pbegin + OFFSET, pbegin + OFFSET + COUNT);
}
#else
//*************************************************************************
//*************************************************************************
template <size_t OFFSET, size_t COUNT>
etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET> subspan() const
{
// If Extent is static, check that OFFSET is within the original span
ETL_STATIC_ASSERT(OFFSET <= Extent, "OFFSET is not within the original span");
// If count is also static, check that OFFSET + COUNT is within the
// original span
ETL_STATIC_ASSERT((COUNT != etl::dynamic_extent) ? COUNT <= (Extent - OFFSET) : true, "OFFSET + COUNT is not within the original span");
if (COUNT == etl::dynamic_extent)
{
return etl::span<element_type, (COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET)>(pbegin + OFFSET, (pbegin + Extent));
}
else
{
return etl::span < element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET > (pbegin + OFFSET, pbegin + OFFSET + COUNT);
}
}
#endif
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, etl::dynamic_extent> subspan(size_t offset, size_t count = etl::dynamic_extent) const
ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
{
#if ETL_USING_CPP11 && ETL_NOT_USING_CPP14 && ETL_USING_EXCEPTIONS && ETL_CHECKING_EXTRA
return (offset <= size()) && (count != etl::dynamic_extent ? count <= (size() - offset) : true)
? ((count == etl::dynamic_extent) ? etl::span<element_type, etl::dynamic_extent>(pbegin + offset, (pbegin + Extent))
: etl::span<element_type, etl::dynamic_extent>(pbegin + offset, pbegin + offset + count))
: throw(ETL_ERROR(span_out_of_range));
#else
ETL_ASSERT_CHECK_EXTRA(offset <= size(), ETL_ERROR(span_out_of_range));
ETL_ASSERT_CHECK_EXTRA(count != etl::dynamic_extent ? count <= (size() - offset) : true, ETL_ERROR(span_out_of_range));
return (count == etl::dynamic_extent) ? etl::span<element_type, etl::dynamic_extent>(pbegin + offset, (pbegin + Extent))
: etl::span<element_type, etl::dynamic_extent>(pbegin + offset, pbegin + offset + count);
#endif
}
//*************************************************************************
//*************************************************************************
template <typename TNew>
ETL_NODISCARD ETL_CONSTEXPR14 etl::span<TNew, Extent * sizeof(element_type) / sizeof(TNew)> reinterpret_as() const
{
ETL_ASSERT(etl::is_aligned<etl::alignment_of<TNew>::value>(pbegin), ETL_ERROR(span_alignment_exception));
return etl::span<TNew, Extent * sizeof(element_type) / sizeof(TNew)>(reinterpret_cast<TNew*>(pbegin),
Extent * sizeof(element_type) / sizeof(TNew));
}
private:
pointer pbegin;
};
//*************************************************************************
//*************************************************************************
template <typename T, size_t Extent>
ETL_CONSTEXPR span<T, Extent> make_span(T (&data)[Extent])
{
return span<T, Extent>(data);
}
//***************************************************************************
//***************************************************************************
template <typename T>
class span<T, etl::dynamic_extent> : public span_tag
{
public:
typedef T element_type;
typedef typename etl::remove_cv<T>::type value_type;
typedef size_t size_type;
typedef T& reference;
typedef const T& const_reference;
typedef T* pointer;
typedef const T* const_pointer;
typedef T* iterator;
typedef const T* const_iterator;
typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
typedef etl::circular_iterator<pointer> circular_iterator;
typedef etl::circular_iterator<ETL_OR_STD::reverse_iterator<pointer> > reverse_circular_iterator;
static ETL_CONSTANT size_t extent = etl::dynamic_extent;
//*************************************************************************
//*************************************************************************
ETL_CONSTEXPR span() ETL_NOEXCEPT
: pbegin(ETL_NULLPTR)
, pend(ETL_NULLPTR)
{
}
//*************************************************************************
//*************************************************************************
template <typename TIterator>
ETL_CONSTEXPR span(const TIterator begin_, size_t size_) ETL_NOEXCEPT
: pbegin(etl::to_address(begin_))
, pend(etl::to_address(begin_) + size_)
{
}
//*************************************************************************
//*************************************************************************
template <typename TIteratorBegin, typename TIteratorEnd>
ETL_CONSTEXPR span(const TIteratorBegin begin_, const TIteratorEnd end_,
typename etl::enable_if<!etl::is_integral<TIteratorEnd>::value, void>::type* = 0) ETL_NOEXCEPT
: pbegin(etl::to_address(begin_))
, pend(etl::to_address(begin_) + etl::distance(begin_, end_))
{
}
//*************************************************************************
//*************************************************************************
template <size_t Array_Size>
ETL_CONSTEXPR span(element_type (&begin_)[Array_Size]) ETL_NOEXCEPT
: pbegin(begin_)
, pend(begin_ + Array_Size)
{
}
#if ETL_USING_CPP11
//*************************************************************************
//*************************************************************************
template <typename TContainer>
ETL_CONSTEXPR span(TContainer&& a,
typename etl::enable_if<
!etl::is_span<TContainer>::value && !etl::is_std_array< typename etl::remove_reference<TContainer>::type>::value
&& !etl::is_etl_array< typename etl::remove_reference<TContainer>::type>::value
&& !etl::is_pointer< typename etl::remove_reference<TContainer>::type>::value && !etl::is_array<TContainer>::value
&& etl::is_lvalue_reference<TContainer&&>::value && has_size<TContainer>::value && has_data<TContainer>::value
&& etl::is_convertible< decltype(etl::declval< typename etl::remove_reference<TContainer>::type&>().data()), pointer>::value
&& etl::is_same< typename etl::remove_cv<T>::type,
typename etl::remove_cv<typename etl::remove_reference< TContainer>::type::value_type>::type>::value,
void>::type* = 0) ETL_NOEXCEPT
: pbegin(a.data())
, pend(a.data() + a.size())
{
}
#else
//*************************************************************************
//*************************************************************************
template <typename TContainer>
span(TContainer& a, typename etl::enable_if<
!etl::is_span<TContainer>::value && !etl::is_std_array< typename etl::remove_reference<TContainer>::type>::value
&& !etl::is_etl_array< typename etl::remove_reference<TContainer>::type>::value
&& !etl::is_pointer< typename etl::remove_reference<TContainer>::type>::value && !etl::is_array<TContainer>::value
&& has_size<TContainer>::value && has_data<TContainer>::value
&& etl::is_same< typename etl::remove_cv<T>::type,
typename etl::remove_cv<typename etl::remove_reference< TContainer>::type::value_type>::type>::value,
void>::type* = 0) ETL_NOEXCEPT
: pbegin(a.data())
, pend(a.data() + a.size())
{
}
//*************************************************************************
//*************************************************************************
template <typename TContainer>
span(const TContainer& a,
typename etl::enable_if<
!etl::is_span<TContainer>::value && !etl::is_std_array< typename etl::remove_reference<TContainer>::type>::value
&& !etl::is_etl_array< typename etl::remove_reference<TContainer>::type>::value
&& !etl::is_pointer< typename etl::remove_reference<TContainer>::type>::value && !etl::is_array<TContainer>::value
&& has_size<TContainer>::value && has_data<TContainer>::value
&& etl::is_same< typename etl::remove_cv<T>::type,
typename etl::remove_cv<typename etl::remove_reference< TContainer>::type::value_type>::type>::value,
void>::type* = 0) ETL_NOEXCEPT
: pbegin(a.data())
, pend(a.data() + a.size())
{
}
#endif
#if ETL_USING_STL && ETL_USING_CPP20
//*************************************************************************
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR span(std::span<U, Size>& other, typename etl::enable_if<etl::is_convertible<U (*)[], T (*)[]>::value, int>::type* = 0) ETL_NOEXCEPT
: pbegin(other.data())
, pend(other.data() + other.size())
{
}
//*************************************************************************
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR span(const std::span<U, Size>& other, typename etl::enable_if<etl::is_convertible<U (*)[], T (*)[]>::value, int>::type* = 0)
ETL_NOEXCEPT
: pbegin(other.data())
, pend(other.data() + other.size())
{
}
#endif
//*************************************************************************
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR span(etl::array<U, Size>& other, typename etl::enable_if<etl::is_convertible<U (*)[], T (*)[]>::value, void>::type* = 0)
ETL_NOEXCEPT
: pbegin(other.data())
, pend(other.data() + Size)
{
}
//*************************************************************************
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR span(const etl::array<U, Size>& other, typename etl::enable_if<etl::is_convertible<U (*)[], T (*)[]>::value, void>::type* = 0)
ETL_NOEXCEPT
: pbegin(other.data())
, pend(other.data() + Size)
{
}
#if ETL_USING_CPP11
template <typename U, size_t Size>
span(etl::array<U, Size>&&) = delete;
#endif
#if ETL_USING_STL && ETL_USING_CPP11
//*************************************************************************
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR span(std::array<U, Size>& other, typename etl::enable_if<etl::is_convertible<U (*)[], T (*)[]>::value, void>::type* = 0)
ETL_NOEXCEPT
: pbegin(other.data())
, pend(other.data() + Size)
{
}
//*************************************************************************
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR span(const std::array<U, Size>& other, typename etl::enable_if<etl::is_convertible<U (*)[], T (*)[]>::value, void>::type* = 0)
ETL_NOEXCEPT
: pbegin(other.data())
, pend(other.data() + Size)
{
}
template <typename U, size_t Size>
span(std::array<U, Size>&&) = delete;
#endif
//*************************************************************************
//*************************************************************************
ETL_CONSTEXPR span(const span& other) ETL_NOEXCEPT
: pbegin(other.pbegin)
, pend(other.pend)
{
}
//*************************************************************************
//*************************************************************************
template <typename U, size_t Size>
ETL_CONSTEXPR span(const etl::span<U, Size>& other) ETL_NOEXCEPT
: pbegin(other.data())
, pend(other.data() + other.size())
{
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
{
#if ETL_USING_CPP11 && ETL_NOT_USING_CPP14 && ETL_USING_EXCEPTIONS && ETL_CHECKING_EXTRA
return size() > 0 ? *pbegin : throw(ETL_ERROR(span_out_of_range));
#else
ETL_ASSERT_CHECK_EXTRA(size() > 0, ETL_ERROR(span_out_of_range));
return *pbegin;
#endif
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
{
#if ETL_USING_CPP11 && ETL_NOT_USING_CPP14 && ETL_USING_EXCEPTIONS && ETL_CHECKING_EXTRA
return size() > 0 ? *(pend - 1) : throw(ETL_ERROR(span_out_of_range));
#else
ETL_ASSERT_CHECK_EXTRA(size() > 0, ETL_ERROR(span_out_of_range));
return *(pend - 1);
#endif
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
{
return pbegin;
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR const_iterator cbegin() const ETL_NOEXCEPT
{
return pbegin;
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
{
return pbegin;
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR circular_iterator begin_circular() const ETL_NOEXCEPT
{
return circular_iterator(begin(), end());
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR const_iterator cend() const ETL_NOEXCEPT
{
return pend;
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
{
return pend;
}
//*************************************************************************
// Returns an reverse iterator to the reverse beginning of the span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rbegin() const ETL_NOEXCEPT
{
return reverse_iterator(pend);
}
//*************************************************************************
// Returns a const reverse iterator to the reverse beginning of the span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR const_reverse_iterator crbegin() const ETL_NOEXCEPT
{
return const_reverse_iterator(pend);
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reverse_circular_iterator rbegin_circular() const ETL_NOEXCEPT
{
return reverse_circular_iterator(rbegin(), rend());
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR const_reverse_iterator crend() const ETL_NOEXCEPT
{
return const_reverse_iterator(pbegin);
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rend() const ETL_NOEXCEPT
{
return reverse_iterator(pbegin);
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
{
return (pbegin == pend);
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
{
return static_cast<size_t>(pend - pbegin);
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
{
return sizeof(element_type) * static_cast<size_t>(pend - pbegin);
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR size_t max_size() const ETL_NOEXCEPT
{
return size();
}
//*************************************************************************
//*************************************************************************
ETL_CONSTEXPR14 span& operator=(const span& other) ETL_NOEXCEPT
{
pbegin = other.pbegin;
pend = other.pend;
return *this;
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR14 reference at(size_t i)
{
ETL_ASSERT(i < size(), ETL_ERROR(span_out_of_range));
return pbegin[i];
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR14 const_reference at(size_t i) const
{
ETL_ASSERT(i < size(), ETL_ERROR(span_out_of_range));
return pbegin[i];
}
//*************************************************************************
//*************************************************************************
ETL_CONSTEXPR reference operator[](const size_t i) const
{
#if ETL_USING_CPP11 && ETL_NOT_USING_CPP14 && ETL_USING_EXCEPTIONS && ETL_CHECKING_INDEX_OPERATOR
return i < size() ? pbegin[i] : throw(ETL_ERROR(span_out_of_range));
#else
ETL_ASSERT_CHECK_INDEX_OPERATOR(i < size(), ETL_ERROR(span_out_of_range));
return pbegin[i];
#endif
}
//*************************************************************************
//*************************************************************************
template <size_t COUNT>
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, COUNT> first() const ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
{
#if ETL_USING_CPP11 && ETL_NOT_USING_CPP14 && ETL_USING_EXCEPTIONS && ETL_CHECKING_EXTRA
return COUNT <= size() ? etl::span<element_type, COUNT>(pbegin, pbegin + COUNT) : throw(ETL_ERROR(span_out_of_range));
#else
ETL_ASSERT_CHECK_EXTRA(COUNT <= size(), ETL_ERROR(span_out_of_range));
return etl::span<element_type, COUNT>(pbegin, pbegin + COUNT);
#endif
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, etl::dynamic_extent> first(size_t count) const
ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
{
#if ETL_USING_CPP11 && ETL_NOT_USING_CPP14 && ETL_USING_EXCEPTIONS && ETL_CHECKING_EXTRA
return count <= size() ? etl::span<element_type, etl::dynamic_extent>(pbegin, pbegin + count) : throw(ETL_ERROR(span_out_of_range));
#else
ETL_ASSERT_CHECK_EXTRA(count <= size(), ETL_ERROR(span_out_of_range));
return etl::span<element_type, etl::dynamic_extent>(pbegin, pbegin + count);
#endif
}
//*************************************************************************
//*************************************************************************
template <size_t COUNT>
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, COUNT> last() const ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
{
#if ETL_USING_CPP11 && ETL_NOT_USING_CPP14 && ETL_USING_EXCEPTIONS && ETL_CHECKING_EXTRA
return COUNT <= size() ? etl::span<element_type, COUNT>(pend - COUNT, pend) : throw(ETL_ERROR(span_out_of_range));
#else
ETL_ASSERT_CHECK_EXTRA(COUNT <= size(), ETL_ERROR(span_out_of_range));
return etl::span<element_type, COUNT>(pend - COUNT, pend);
#endif
}
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR etl::span<element_type, etl::dynamic_extent> last(size_t count) const
ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
{
#if ETL_USING_CPP11 && ETL_NOT_USING_CPP14 && ETL_USING_EXCEPTIONS && ETL_CHECKING_EXTRA
return count <= size() ? etl::span<element_type, etl::dynamic_extent>(pend - count, pend) : throw(ETL_ERROR(span_out_of_range));
#else
ETL_ASSERT_CHECK_EXTRA(count <= size(), ETL_ERROR(span_out_of_range));
return etl::span<element_type, etl::dynamic_extent>(pend - count, pend);
#endif
}
#if ETL_USING_CPP11
//*************************************************************************
//*************************************************************************
template <size_t OFFSET, size_t COUNT = etl::dynamic_extent>
ETL_NODISCARD ETL_CONSTEXPR etl::span< element_type, COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent> subspan() const
ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
{
#if ETL_USING_CPP11 && ETL_NOT_USING_CPP14 && ETL_USING_EXCEPTIONS && ETL_CHECKING_EXTRA
return (OFFSET <= size()) && (COUNT != etl::dynamic_extent ? COUNT <= (size() - OFFSET) : true)
? ((COUNT == etl::dynamic_extent) ? etl::span < element_type,
COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent > (pbegin + OFFSET, pend) : etl::span < element_type,
COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent > (pbegin + OFFSET, pbegin + OFFSET + COUNT))
: throw(ETL_ERROR(span_out_of_range));
#else
ETL_ASSERT_CHECK_EXTRA(OFFSET <= size(), ETL_ERROR(span_out_of_range));
ETL_ASSERT_CHECK_EXTRA(COUNT != etl::dynamic_extent ? COUNT <= (size() - OFFSET) : true, ETL_ERROR(span_out_of_range));
return (COUNT == etl::dynamic_extent) ? etl::span < element_type,
COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent > (pbegin + OFFSET, pend) : etl::span < element_type,
COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent > (pbegin + OFFSET, pbegin + OFFSET + COUNT);
#endif
}
#else
//*************************************************************************
//*************************************************************************
template <size_t OFFSET, size_t COUNT>
etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent> subspan() const
{
ETL_ASSERT_CHECK_EXTRA(OFFSET <= size(), ETL_ERROR(span_out_of_range));
ETL_ASSERT_CHECK_EXTRA(COUNT != etl::dynamic_extent ? COUNT <= (size() - OFFSET) : true, ETL_ERROR(span_out_of_range));
if (COUNT == etl::dynamic_extent)
{
return etl::span < element_type, COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent > (pbegin + OFFSET, pend);
}
else
{
return etl::span < element_type, COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent > (pbegin + OFFSET, pbegin + OFFSET + COUNT);
}
}
#endif
//*************************************************************************
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR14 etl::span<element_type, etl::dynamic_extent> subspan(size_t offset, size_t count = etl::dynamic_extent) const
ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS || ETL_NOT_CHECKING_EXTRA)
{
ETL_ASSERT_CHECK_EXTRA(offset <= size(), ETL_ERROR(span_out_of_range));
ETL_ASSERT_CHECK_EXTRA(count != etl::dynamic_extent ? count <= (size() - offset) : true, ETL_ERROR(span_out_of_range));
return (count == etl::dynamic_extent) ? etl::span<element_type, etl::dynamic_extent>(pbegin + offset, pend)
: etl::span<element_type, etl::dynamic_extent>(pbegin + offset, pbegin + offset + count);
}
//*************************************************************************
//*************************************************************************
void advance(size_t elements) ETL_NOEXCEPT
{
elements = etl::min(elements, size());
pbegin += elements;
}
//*************************************************************************
//*************************************************************************
template <typename TNew>
ETL_NODISCARD ETL_CONSTEXPR14 etl::span<TNew, etl::dynamic_extent> reinterpret_as() const
{
ETL_ASSERT(etl::is_aligned<etl::alignment_of<TNew>::value>(pbegin), ETL_ERROR(span_alignment_exception));
return etl::span<TNew, etl::dynamic_extent>(reinterpret_cast<TNew*>(pbegin),
static_cast<size_t>(pend - pbegin) * sizeof(element_type) / sizeof(TNew));
}
//*************************************************************************
//*************************************************************************
template <typename TRet>
ETL_NODISCARD
etl::span<TRet> take(size_t const n)
{
ETL_STATIC_ASSERT(sizeof(TRet) % sizeof(element_type) == 0, "sizeof(TRet) must be divisible by sizeof(T)");
ETL_ASSERT(etl::is_aligned<etl::alignment_of<TRet>::value>(pbegin), ETL_ERROR(span_alignment_exception));
ETL_ASSERT(sizeof(TRet) * n <= sizeof(element_type) * size(), ETL_ERROR(span_size_mismatch));
etl::span<TRet> result = reinterpret_as<TRet>().first(n);
advance(sizeof(TRet) / sizeof(element_type) * n);
return result;
}
//*************************************************************************
//*************************************************************************
template <typename TRet>
ETL_NODISCARD
TRet& take()
{
ETL_STATIC_ASSERT(sizeof(TRet) % sizeof(element_type) == 0, "sizeof(TRet) must be divisible by sizeof(T)");
ETL_ASSERT(etl::is_aligned<etl::alignment_of<TRet>::value>(pbegin), ETL_ERROR(span_alignment_exception));
ETL_ASSERT(sizeof(TRet) <= sizeof(element_type) * size(), ETL_ERROR(span_size_mismatch));
TRet& result = *reinterpret_cast<TRet*>(data());
advance(sizeof(TRet) / sizeof(element_type));
return result;
}
private:
pointer pbegin;
pointer pend;
};
//*************************************************************************
//*************************************************************************
template <typename T>
ETL_CONSTEXPR span<typename T::value_type, etl::dynamic_extent> make_span(T& data)
{
return span<typename T::value_type, etl::dynamic_extent>(data);
}
//*************************************************************************
//*************************************************************************
template <typename T>
ETL_CONSTEXPR span<typename T::value_type const, etl::dynamic_extent> make_span(const T& data)
{
return span<typename T::value_type const, etl::dynamic_extent>(data);
}
template <typename T, size_t Extent>
ETL_CONSTANT size_t span<T, Extent>::extent;
template <typename T>
ETL_CONSTANT size_t span<T, etl::dynamic_extent>::extent;
//*************************************************************************
//*************************************************************************
template <typename T1, size_t N1, typename T2, size_t N2>
ETL_NODISCARD
ETL_CONSTEXPR typename etl::enable_if< etl::is_same<typename etl::remove_cv<T1>::type, typename etl::remove_cv<T2>::type>::value, bool>::type
operator==(const etl::span<T1, N1>& lhs, const etl::span<T2, N2>& rhs) ETL_NOEXCEPT
{
return (lhs.begin() == rhs.begin()) && (lhs.size() == rhs.size());
}
//*************************************************************************
//*************************************************************************
template <typename T1, size_t N1, typename T2, size_t N2>
ETL_NODISCARD ETL_CONSTEXPR bool operator!=(const etl::span<T1, N1>& lhs, const etl::span<T2, N2>& rhs) ETL_NOEXCEPT
{
return !(lhs == rhs);
}
//*************************************************************************
//*************************************************************************
template <typename T1, size_t N1, typename T2, size_t N2>
typename etl::enable_if< etl::is_same<typename etl::remove_cv<T1>::type, typename etl::remove_cv<T2>::type>::value, bool>::type
equal(const etl::span<T1, N1>& lhs, const etl::span<T2, N2>& rhs)
{
return (lhs.empty() && rhs.empty()) || ((lhs.begin() == rhs.begin()) && (lhs.size() == rhs.size()))
|| etl::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
}
//*************************************************************************
//*************************************************************************
template <typename T1, size_t N1, typename T2, size_t N2>
typename etl::enable_if< etl::is_same<typename etl::remove_cv<T1>::type, typename etl::remove_cv<T2>::type>::value && !etl::is_const<T2>::value,
bool>::type
copy(const etl::span<T1, N1>& src, const etl::span<T2, N2>& dst)
{
if (src.empty() || (src.begin() == dst.begin()))
{
return true;
}
if (src.size() > dst.size())
{
return false;
}
(void)etl::copy(src.begin(), src.end(), dst.begin());
return true;
}
//*************************************************************************
//*************************************************************************
#if ETL_USING_CPP17
template <typename TIterator>
span(const TIterator begin_, const TIterator end_) -> span<etl::remove_pointer_t<TIterator>, etl::dynamic_extent>;
template <typename TIterator, typename TSize>
span(const TIterator begin_, const TSize size_) -> span<etl::remove_pointer_t<TIterator>, etl::dynamic_extent>;
template <typename T, size_t Size>
span(T (&)[Size]) -> span<T, Size>;
template <typename T, size_t Size>
span(etl::array<T, Size>&) -> span<T, Size>;
template <typename T, size_t Size>
span(const etl::array<T, Size>&) -> span<const T, Size>;
// Forward declaration of etl::ivector
template <typename T, typename Enable>
class ivector;
template <typename T, typename Enable>
span(etl::ivector<T, Enable>&) -> span<T>;
template <typename T, typename Enable>
span(const etl::ivector<T, Enable>&) -> span<const T>;
#if ETL_USING_STL && ETL_USING_CPP11
template <typename T, size_t Size>
span(std::array<T, Size>&) -> span<T, Size>;
template <typename T, size_t Size>
span(const std::array<T, Size>&) -> span<const T, Size>;
#endif
#endif
//*************************************************************************
//*************************************************************************
#if ETL_USING_8BIT_TYPES
template <typename T, size_t Extent>
struct hash<etl::span<T, Extent> >
{
size_t operator()(const etl::span<T>& view) const
{
return etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(view.data()),
reinterpret_cast<const uint8_t*>(view.data() + view.size()));
}
};
#endif
//*************************************************************************
//*************************************************************************
template <class T, size_t Size>
span<const byte, (Size == etl::dynamic_extent) ? (etl::dynamic_extent) : (Size * sizeof(T))> as_bytes(span<T, Size> s) ETL_NOEXCEPT
{
return span < const byte,
(Size == etl::dynamic_extent) ? (etl::dynamic_extent) : (Size * sizeof(T)) > (reinterpret_cast<const byte*>(s.data()), s.size_bytes());
}
//*************************************************************************
//*************************************************************************
template <class T, size_t Size>
span<byte, (Size == etl::dynamic_extent) ? (etl::dynamic_extent) : (Size * sizeof(T))> as_writable_bytes(span<T, Size> s) ETL_NOEXCEPT
{
ETL_STATIC_ASSERT(!etl::is_const<T>::value, "span<T> must be of non-const type");
return span < byte,
(Size == etl::dynamic_extent) ? (etl::dynamic_extent) : (Size * sizeof(T)) > (reinterpret_cast<byte*>(s.data()), s.size_bytes());
}
} // namespace etl
#endif
algorithm.h
alignment.h
array.h
byte.h
circular_iterator.h
etl::byte
The byte class.
Definition byte.h:147
etl::ivector
Definition vector.h:65
etl::reverse_iterator
Definition iterator.h:310
etl::span< T, etl::dynamic_extent >::begin_circular
ETL_NODISCARD ETL_CONSTEXPR circular_iterator begin_circular() const ETL_NOEXCEPT
Returns a circular iterator to the beginning of the span.
Definition span.h:1056
etl::span< T, etl::dynamic_extent >::last
ETL_NODISCARD ETL_CONSTEXPR etl::span< element_type, etl::dynamic_extent > last(size_t count) const ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS||ETL_NOT_CHECKING_EXTRA)
Obtains a span that is a view over the last count elements of this span.
Definition span.h:1243
etl::span< T, etl::dynamic_extent >::take
ETL_NODISCARD etl::span< TRet > take(size_t const n)
Definition span.h:1346
etl::span< T, etl::dynamic_extent >::span
span(const TContainer &a, typename etl::enable_if< !etl::is_span< TContainer >::value &&!etl::is_std_array< typename etl::remove_reference< TContainer >::type >::value &&!etl::is_etl_array< typename etl::remove_reference< TContainer >::type >::value &&!etl::is_pointer< typename etl::remove_reference< TContainer >::type >::value &&!etl::is_array< TContainer >::value &&has_size< TContainer >::value &&has_data< TContainer >::value &&etl::is_same< typename etl::remove_cv< T >::type, typename etl::remove_cv< typename etl::remove_reference< TContainer >::type::value_type >::type >::value, void >::type *=0) ETL_NOEXCEPT
Definition span.h:890
etl::span< T, etl::dynamic_extent >::span
ETL_CONSTEXPR span(const span &other) ETL_NOEXCEPT
Copy constructor.
Definition span.h:985
etl::span< T, etl::dynamic_extent >::back
ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS||ETL_NOT_CHECKING_EXTRA)
Returns a reference to the last element.
Definition span.h:1018
etl::span< T, etl::dynamic_extent >::span
ETL_CONSTEXPR span() ETL_NOEXCEPT
Default constructor.
Definition span.h:809
etl::span< T, etl::dynamic_extent >::span
ETL_CONSTEXPR span(etl::array< U, Size > &other, typename etl::enable_if< etl::is_convertible< U(*)[], T(*)[]>::value, void >::type *=0) ETL_NOEXCEPT
Constructor from etl array.
Definition span.h:932
etl::span< T, etl::dynamic_extent >::subspan
etl::span< element_type, COUNT !=etl::dynamic_extent ? COUNT :etl::dynamic_extent > subspan() const
Definition span.h:1285
etl::span< T, etl::dynamic_extent >::advance
void advance(size_t elements) ETL_NOEXCEPT
Definition span.h:1320
etl::span< T, etl::dynamic_extent >::rbegin_circular
ETL_NODISCARD ETL_CONSTEXPR reverse_circular_iterator rbegin_circular() const ETL_NOEXCEPT
Returns a reverse circular iterator to the end of the span.
Definition span.h:1096
etl::span< T, etl::dynamic_extent >::take
ETL_NODISCARD TRet & take()
Definition span.h:1366
etl::span< T, etl::dynamic_extent >::size
ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
Returns the size of the span.
Definition span.h:1128
etl::span< T, etl::dynamic_extent >::subspan
ETL_NODISCARD ETL_CONSTEXPR14 etl::span< element_type, etl::dynamic_extent > subspan(size_t offset, size_t count=etl::dynamic_extent) const ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS||ETL_NOT_CHECKING_EXTRA)
Definition span.h:1305
etl::span< T, etl::dynamic_extent >::operator=
ETL_CONSTEXPR14 span & operator=(const span &other) ETL_NOEXCEPT
Assign from a span.
Definition span.h:1152
etl::span< T, etl::dynamic_extent >::empty
ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
Returns true if the span size is zero.
Definition span.h:1120
etl::span< T, etl::dynamic_extent >::front
ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS||ETL_NOT_CHECKING_EXTRA)
Returns a reference to the first element.
Definition span.h:1004
etl::span< T, etl::dynamic_extent >::crend
ETL_NODISCARD ETL_CONSTEXPR const_reverse_iterator crend() const ETL_NOEXCEPT
Returns a const reverse iterator to the end of the span.
Definition span.h:1104
etl::span< T, etl::dynamic_extent >::operator[]
ETL_CONSTEXPR reference operator[](const size_t i) const
Returns a reference to the indexed value.
Definition span.h:1182
etl::span< T, etl::dynamic_extent >::cend
ETL_NODISCARD ETL_CONSTEXPR const_iterator cend() const ETL_NOEXCEPT
Returns a const iterator to the end of the span.
Definition span.h:1064
etl::span< T, etl::dynamic_extent >::span
span(TContainer &a, typename etl::enable_if< !etl::is_span< TContainer >::value &&!etl::is_std_array< typename etl::remove_reference< TContainer >::type >::value &&!etl::is_etl_array< typename etl::remove_reference< TContainer >::type >::value &&!etl::is_pointer< typename etl::remove_reference< TContainer >::type >::value &&!etl::is_array< TContainer >::value &&has_size< TContainer >::value &&has_data< TContainer >::value &&etl::is_same< typename etl::remove_cv< T >::type, typename etl::remove_cv< typename etl::remove_reference< TContainer >::type::value_type >::type >::value, void >::type *=0) ETL_NOEXCEPT
Definition span.h:872
etl::span< T, etl::dynamic_extent >::begin
ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
Returns an iterator to the beginning of the span.
Definition span.h:1048
etl::span< T, etl::dynamic_extent >::at
ETL_NODISCARD ETL_CONSTEXPR14 const_reference at(size_t i) const
Returns a const reference to the value at index 'i'.
Definition span.h:1172
etl::span< T, etl::dynamic_extent >::last
ETL_NODISCARD ETL_CONSTEXPR etl::span< element_type, COUNT > last() const ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS||ETL_NOT_CHECKING_EXTRA)
Obtains a span that is a view over the last COUNT elements of this span.
Definition span.h:1229
etl::span< T, etl::dynamic_extent >::span
ETL_CONSTEXPR span(const TIteratorBegin begin_, const TIteratorEnd end_, typename etl::enable_if<!etl::is_integral< TIteratorEnd >::value, void >::type *=0) ETL_NOEXCEPT
Construct from iterators.
Definition span.h:829
etl::span< T, etl::dynamic_extent >::first
ETL_NODISCARD ETL_CONSTEXPR etl::span< element_type, etl::dynamic_extent > first(size_t count) const ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS||ETL_NOT_CHECKING_EXTRA)
Definition span.h:1213
etl::span< T, etl::dynamic_extent >::reinterpret_as
ETL_NODISCARD ETL_CONSTEXPR14 etl::span< TNew, etl::dynamic_extent > reinterpret_as() const
Reinterpret the span as a span with different element type.
Definition span.h:1330
etl::span< T, etl::dynamic_extent >::span
ETL_CONSTEXPR span(element_type(&begin_)[Array_Size]) ETL_NOEXCEPT
Construct from C array.
Definition span.h:840
etl::span< T, etl::dynamic_extent >::end
ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
Returns an iterator to the end of the span.
Definition span.h:1072
etl::span< T, etl::dynamic_extent >::span
ETL_CONSTEXPR span(const etl::array< U, Size > &other, typename etl::enable_if< etl::is_convertible< U(*)[], T(*)[]>::value, void >::type *=0) ETL_NOEXCEPT
Constructor from const etl array.
Definition span.h:943
etl::span< T, etl::dynamic_extent >::span
ETL_CONSTEXPR span(const TIterator begin_, size_t size_) ETL_NOEXCEPT
Construct from iterator + size.
Definition span.h:819
etl::span< T, etl::dynamic_extent >::cbegin
ETL_NODISCARD ETL_CONSTEXPR const_iterator cbegin() const ETL_NOEXCEPT
Returns a const iterator to the beginning of the span.
Definition span.h:1040
etl::span< T, etl::dynamic_extent >::data
ETL_NODISCARD ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
Returns a pointer to the first element of the internal storage.
Definition span.h:1032
etl::span< T, etl::dynamic_extent >::rend
ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rend() const ETL_NOEXCEPT
Returns a reverse iterator to the end of the span.
Definition span.h:1112
etl::span< T, etl::dynamic_extent >::max_size
ETL_NODISCARD ETL_CONSTEXPR size_t max_size() const ETL_NOEXCEPT
Returns the maximum possible size of the span.
Definition span.h:1144
etl::span< T, etl::dynamic_extent >::size_bytes
ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
Returns the size of the span in bytes.
Definition span.h:1136
etl::span< T, etl::dynamic_extent >::first
ETL_NODISCARD ETL_CONSTEXPR etl::span< element_type, COUNT > first() const ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS||ETL_NOT_CHECKING_EXTRA)
Definition span.h:1198
etl::span< T, etl::dynamic_extent >::span
ETL_CONSTEXPR span(const etl::span< U, Size > &other) ETL_NOEXCEPT
Copy constructor.
Definition span.h:995
etl::span< T, etl::dynamic_extent >::at
ETL_NODISCARD ETL_CONSTEXPR14 reference at(size_t i)
Returns a reference to the value at index 'i'.
Definition span.h:1162
etl::span
Span - Fixed Extent.
Definition span.h:208
etl::span::rend
ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rend() const ETL_NOEXCEPT
Returns a reverse iterator to the end of the span.
Definition span.h:548
etl::span::span
ETL_CONSTEXPR span(const etl::span< U, Size > &other, typename etl::enable_if<(Size==Extent) &&(Size !=etl::dynamic_extent), void >::type *=0) ETL_NOEXCEPT
Definition span.h:402
etl::span::begin_circular
ETL_NODISCARD ETL_CONSTEXPR circular_iterator begin_circular() const ETL_NOEXCEPT
Returns a circular iterator to the beginning of the span.
Definition span.h:492
etl::span::cbegin
ETL_NODISCARD ETL_CONSTEXPR const_iterator cbegin() const ETL_NOEXCEPT
Returns a const iterator to the beginning of the span.
Definition span.h:476
etl::span::last
ETL_NODISCARD ETL_CONSTEXPR etl::span< element_type, COUNT > last() const ETL_NOEXCEPT
Obtains a span that is a view over the last COUNT elements of this span.
Definition span.h:662
etl::span::span
ETL_CONSTEXPR span(etl::array< U, Size > &other, typename etl::enable_if<(Size==Extent) &&etl::is_convertible< U(*)[], T(*)[]>::value, void >::type *=0) ETL_NOEXCEPT
Constructor from etl array.
Definition span.h:343
etl::span::span
ETL_CONSTEXPR span(const span &other) ETL_NOEXCEPT
Copy constructor.
Definition span.h:392
etl::span::subspan
etl::span< element_type, COUNT !=etl::dynamic_extent ? COUNT :Extent - OFFSET > subspan() const
Definition span.h:712
etl::span::last
ETL_NODISCARD ETL_CONSTEXPR etl::span< element_type, etl::dynamic_extent > last(size_t count) const ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS||ETL_NOT_CHECKING_EXTRA)
Obtains a span that is a view over the last count elements of this span.
Definition span.h:674
etl::span::rbegin_circular
ETL_NODISCARD ETL_CONSTEXPR reverse_circular_iterator rbegin_circular() const ETL_NOEXCEPT
Returns a reverse circular iterator to the end of the span.
Definition span.h:532
etl::span::span
ETL_CONSTEXPR14 span(const TIterator begin_, const size_t size_) ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS)
Construct from iterator + size.
Definition span.h:251
etl::span::span
ETL_CONSTEXPR14 span(const TIteratorBegin begin_, const TIteratorEnd end_, typename etl::enable_if< !etl::is_integral< TIteratorEnd >::value, void >::type *=0) ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS)
Construct from iterators.
Definition span.h:262
etl::span::begin
ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
Returns an iterator to the beginning of the span.
Definition span.h:484
etl::span::span
ETL_CONSTEXPR span(const etl::array< U, Size > &other, typename etl::enable_if<(Size==Extent) &&etl::is_convertible< U(*)[], T(*)[]>::value, void >::type *=0) ETL_NOEXCEPT
Constructor from const etl array.
Definition span.h:353
etl::span::size_bytes
ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
Returns the size of the span in bytes.
Definition span.h:572
etl::span::empty
ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
Returns true if the span size is zero.
Definition span.h:556
etl::span::cend
ETL_NODISCARD ETL_CONSTEXPR const_iterator cend() const ETL_NOEXCEPT
Returns a const iterator to the end of the span.
Definition span.h:500
etl::span::first
ETL_NODISCARD ETL_CONSTEXPR etl::span< element_type, COUNT > first() const ETL_NOEXCEPT
Definition span.h:633
etl::span::size
ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
Returns the size of the span.
Definition span.h:564
etl::span::span
ETL_CONSTEXPR span(typename etl::type_identity< element_type >::type(&begin_)[Array_Size], typename etl::enable_if<(Array_Size==Extent), void >::type *=0) ETL_NOEXCEPT
Construct from C array.
Definition span.h:274
etl::span::back
ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
Returns a reference to the last element.
Definition span.h:458
etl::span::span
ETL_CONSTEXPR span() ETL_NOEXCEPT
Definition span.h:240
etl::span::span
span(TContainer &a, typename etl::enable_if< !etl::is_span< TContainer >::value &&!etl::is_std_array< typename etl::remove_reference< TContainer >::type >::value &&!etl::is_etl_array< typename etl::remove_reference< TContainer >::type >::value &&!etl::is_pointer< typename etl::remove_reference< TContainer >::type >::value &&!etl::is_array< TContainer >::value &&has_size< TContainer >::value &&has_data< TContainer >::value &&etl::is_same< typename etl::remove_cv< T >::type, typename etl::remove_cv< typename etl::remove_reference< TContainer >::type::value_type >::type >::value, void >::type *=0)
Definition span.h:306
etl::span::operator=
ETL_CONSTEXPR14 span & operator=(const span &other) ETL_NOEXCEPT
Assign from a span.
Definition span.h:588
etl::span::span
ETL_CONSTEXPR14 span(const etl::span< U, Size > &other, typename etl::enable_if<(Size==etl::dynamic_extent), void >::type *=0)
Definition span.h:413
etl::span::span
span(const TContainer &a, typename etl::enable_if< !etl::is_span< TContainer >::value &&!etl::is_std_array< typename etl::remove_reference< TContainer >::type >::value &&!etl::is_etl_array< typename etl::remove_reference< TContainer >::type >::value &&!etl::is_pointer< typename etl::remove_reference< TContainer >::type >::value &&has_size< TContainer >::value &&has_data< TContainer >::value &&etl::is_same< typename etl::remove_cv< T >::type, typename etl::remove_cv< typename etl::remove_reference< TContainer >::type::value_type >::type >::value, void >::type *=0)
Definition span.h:324
etl::span::reinterpret_as
ETL_NODISCARD ETL_CONSTEXPR14 etl::span< TNew, Extent *sizeof(element_type)/sizeof(TNew)> reinterpret_as() const
Reinterpret the span as a span with different element type.
Definition span.h:757
etl::span::first
ETL_NODISCARD ETL_CONSTEXPR etl::span< element_type, etl::dynamic_extent > first(size_t count) const ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS||ETL_NOT_CHECKING_EXTRA)
Definition span.h:646
etl::span::data
ETL_NODISCARD ETL_CONSTEXPR pointer data() const ETL_NOEXCEPT
Returns a pointer to the first element of the internal storage.
Definition span.h:468
etl::span::at
ETL_NODISCARD ETL_CONSTEXPR14 reference at(size_t i)
Returns a reference to the value at index 'i'.
Definition span.h:597
etl::span::operator[]
ETL_CONSTEXPR reference operator[](const size_t i) const
Returns a reference to the indexed value.
Definition span.h:617
etl::span::at
ETL_NODISCARD ETL_CONSTEXPR14 const_reference at(size_t i) const
Returns a const reference to the value at index 'i'.
Definition span.h:607
etl::span::crend
ETL_NODISCARD ETL_CONSTEXPR const_reverse_iterator crend() const ETL_NOEXCEPT
Returns a const reverse iterator to the end of the span.
Definition span.h:540
etl::span::subspan
ETL_NODISCARD ETL_CONSTEXPR etl::span< element_type, etl::dynamic_extent > subspan(size_t offset, size_t count=etl::dynamic_extent) const ETL_NOEXCEPT_IF(ETL_NOT_USING_EXCEPTIONS||ETL_NOT_CHECKING_EXTRA)
Definition span.h:736
etl::span::max_size
ETL_NODISCARD ETL_CONSTEXPR size_t max_size() const ETL_NOEXCEPT
Returns the maximum possible size of the span.
Definition span.h:580
etl::span::front
ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
Returns a reference to the first element.
Definition span.h:448
etl::span::end
ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
Returns an iterator to the end of the span.
Definition span.h:508
container.h
dynamic_extent.h
error_handler.h
exception.h
etl::array
Definition array.h:85
ETL_ASSERT
#define ETL_ASSERT(b, e)
Definition error_handler.h:511
etl::exception::exception
ETL_EXCEPTION_CONSTEXPR exception(string_type reason_, string_type, numeric_type)
Constructor.
Definition exception.h:81
type
etl::span_alignment_exception
Definition span.h:158
etl::span_out_of_range
Definition span.h:186
etl::span_size_mismatch
Definition span.h:172
etl::span_tag
Definition span.h:200
hash.h
integral_limits.h
iterator.h
memory.h
etl
Definition absolute.h:40
etl::operator==
ETL_CONSTEXPR14 bool operator==(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1078
etl::data
ETL_CONSTEXPR TContainer::pointer data(TContainer &container)
Definition iterator.h:1470
etl::false_type
integral_constant< bool, false > false_type
integral_constant specialisations
Definition type_traits.h:80
etl::is_aligned
bool is_aligned(const void *p, size_t required_alignment)
Check that 'p' has 'required_alignment'.
Definition alignment.h:91
etl::crbegin
TContainer::const_reverse_iterator crbegin(const TContainer &container)
Definition iterator.h:1350
etl::operator!=
ETL_CONSTEXPR14 bool operator!=(const etl::array< T, SIZE > &lhs, const etl::array< T, SIZE > &rhs)
Definition array.h:1090
etl::as_bytes
span< const byte,(Size==etl::dynamic_extent) ?(etl::dynamic_extent) :(Size *sizeof(T))> as_bytes(span< T, Size > s) ETL_NOEXCEPT
Template deduction guides.
Definition span.h:1531
etl::to_address
ETL_CONSTEXPR T * to_address(T *p) ETL_NOEXCEPT
Definition memory.h:61
etl::as_writable_bytes
span< byte,(Size==etl::dynamic_extent) ?(etl::dynamic_extent) :(Size *sizeof(T))> as_writable_bytes(span< T, Size > s) ETL_NOEXCEPT
Obtains a view to the byte representation of the elements of the span s.
Definition span.h:1541
etl::size
ETL_CONSTEXPR TContainer::size_type size(const TContainer &container)
Definition iterator.h:1434
etl::make_span
ETL_CONSTEXPR span< T, Extent > make_span(T(&data)[Extent])
Definition span.h:775
etl::rbegin
TContainer::reverse_iterator rbegin(TContainer &container)
Definition iterator.h:1330
nullptr.h
platform.h
etl::is_etl_array
Definition span.h:89
etl::is_span
Definition span.h:131
etl::is_std_array
Definition span.h:66
etl::pointer
etl::type
etl::private_span::is_span_helper
Definition span.h:120
etl::remove_cv
remove_cv
Definition type_traits.h:325
etl::remove_reference
remove_reference
Definition type_traits.h:122
tuple_size.h
type_traits.h