Added etl::poly_span

Refacted parts of etl::span
This commit is contained in:
John Wellbelove 2022-07-14 12:19:08 +01:00
parent 7cc8d95157
commit bcf147f096
9 changed files with 1994 additions and 455 deletions

View File

@ -46,7 +46,7 @@ SOFTWARE.
#include "private/dynamic_extent.h"
#if ETL_USING_CPP11 && ETL_USING_STL
#include <array>
#include <array>
#endif
///\defgroup poly_span poly_span
@ -70,7 +70,7 @@ namespace etl
template <typename U, size_t Extent>
friend class etl::poly_span;
template <typename TBase>
template <typename UBase>
friend class const_iterator;
typedef TBase value_type;
@ -249,7 +249,7 @@ namespace etl
//***************************************************************************
/// Poly Span - Fixed Extent
//***************************************************************************
template <typename TBase, size_t Extent_ = etl::dynamic_extent>
template <typename TBase, size_t Extent = etl::dynamic_extent>
class poly_span
{
public:
@ -265,9 +265,9 @@ namespace etl
typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
static ETL_CONSTANT size_t Extent = Extent_;
static ETL_CONSTANT size_t extent = Extent;
template <typename U, size_t Extent>
template <typename UBase, size_t UExtent>
friend class poly_span;
//*************************************************************************
@ -285,16 +285,13 @@ namespace etl
template <typename TIterator, typename TSize>
ETL_CONSTEXPR poly_span(const TIterator begin_, const TSize size_) ETL_NOEXCEPT
: pbegin(etl::addressof(*begin_))
, element_size(sizeof(typename etl::iterator_traits<TIterator>::value_type))
{
typedef typename etl::iterator_traits<TIterator>::value_type data_type;
typedef typename etl::iterator_traits<TIterator>::iterator_category iterator_category;
ETL_STATIC_ASSERT((etl::is_same<ETL_OR_STD::random_access_iterator_tag, typename etl::iterator_traits<TIterator>::iterator_category>::value), "Not a random access iterator");
ETL_STATIC_ASSERT((etl::is_base_of<TBase, data_type>::value || etl::is_same<TBase, data_type>::value), "TBase not a base of the data type");
static ETL_CONSTANT size_t Element_Size = sizeof(data_type);
element_size = Element_Size;
}
//*************************************************************************
@ -303,16 +300,13 @@ namespace etl
template <typename TIterator>
ETL_CONSTEXPR poly_span(const TIterator begin_, const TIterator end_)
: pbegin(etl::addressof(*begin_))
, element_size(sizeof(typename etl::iterator_traits<TIterator>::value_type))
{
typedef typename etl::iterator_traits<TIterator>::value_type data_type;
typedef typename etl::iterator_traits<TIterator>::iterator_category iterator_category;
ETL_STATIC_ASSERT((etl::is_same<ETL_OR_STD::random_access_iterator_tag, iterator_category>::value), "Not a random access iterator");
ETL_STATIC_ASSERT((etl::is_base_of<TBase, data_type>::value || etl::is_same<TBase, data_type>::value), "TBase not a base of the data type");
static ETL_CONSTANT size_t Element_Size = sizeof(data_type);
element_size = Element_Size;
}
//*************************************************************************
@ -321,13 +315,10 @@ namespace etl
template<typename U, size_t N>
ETL_CONSTEXPR poly_span(U(&begin_)[N]) ETL_NOEXCEPT
: pbegin(begin_)
, element_size(sizeof(U))
{
ETL_STATIC_ASSERT(N <= Extent, "Array data overflow");
ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of the data type");
static ETL_CONSTANT size_t Element_Size = sizeof(U);
element_size = Element_Size;
}
//*************************************************************************
@ -336,13 +327,10 @@ namespace etl
template <typename U, size_t N>
ETL_CONSTEXPR poly_span(etl::array<U, N>& a) ETL_NOEXCEPT
: pbegin(a.data())
, element_size(sizeof(U))
{
ETL_STATIC_ASSERT(N <= Extent, "Array data overflow");
ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of the data type");
static ETL_CONSTANT size_t Element_Size = sizeof(U);
element_size = Element_Size;
}
//*************************************************************************
@ -351,13 +339,10 @@ namespace etl
template <typename U, size_t N>
ETL_CONSTEXPR poly_span(const etl::array<U, N>& a) ETL_NOEXCEPT
: pbegin(a.data())
, element_size(sizeof(U))
{
ETL_STATIC_ASSERT(N <= Extent, "Array data overflow");
ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of the data type");
static ETL_CONSTANT size_t Element_Size = sizeof(U);
element_size = Element_Size;
}
#if ETL_USING_CPP11 && ETL_USING_STL
@ -367,13 +352,10 @@ namespace etl
template <typename U, size_t N>
ETL_CONSTEXPR poly_span(std::array<U, N>& a) ETL_NOEXCEPT
: pbegin(a.data())
, element_size(sizeof(U))
{
ETL_STATIC_ASSERT(N <= Extent, "Array data overflow");
ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of U");
static ETL_CONSTANT size_t Element_Size = sizeof(U);
element_size = Element_Size;
}
//*************************************************************************
@ -382,13 +364,10 @@ namespace etl
template <typename U, size_t N>
ETL_CONSTEXPR poly_span(const std::array<U, N>& a) ETL_NOEXCEPT
: pbegin(a.data())
, element_size(sizeof(U))
{
ETL_STATIC_ASSERT(N <= Extent, "Array data overflow");
ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of U");
static ETL_CONSTANT size_t Element_Size = sizeof(U);
element_size = Element_Size;
}
#endif
@ -410,23 +389,23 @@ namespace etl
, element_size(other.element_size)
{
}
//
// //*************************************************************************
// /// Returns a reference to the first element.
// //*************************************************************************
// ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
// {
// return *pbegin;
// }
//
// //*************************************************************************
// /// Returns a reference to the last element.
// //*************************************************************************
// ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
// {
// return *(pend - 1);
// }
//
//*************************************************************************
/// Returns a reference to the first element.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reference front() const ETL_NOEXCEPT
{
return *pbegin;
}
//*************************************************************************
/// Returns a reference to the last element.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
{
return *element_at(Extent - 1U);
}
//*************************************************************************
/// Returns a pointer to the first element of the internal storage.
//*************************************************************************
@ -435,44 +414,44 @@ namespace etl
return pbegin;
}
////*************************************************************************
///// Returns an iterator to the beginning of the poly_span.
////*************************************************************************
//ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
//{
// return iterator(pbegin, 0U, element_size);
//}
//*************************************************************************
/// Returns an iterator to the beginning of the poly_span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR iterator begin() const ETL_NOEXCEPT
{
return iterator(pbegin, 0U, element_size);
}
////*************************************************************************
///// Returns an iterator to the end of the poly_span.
////*************************************************************************
//ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
//{
// return iterator(pbegin, extent, element_size);
//}
//*************************************************************************
/// Returns an iterator to the end of the poly_span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
{
return iterator(pbegin, Extent, element_size);
}
//*************************************************************************
// Returns an reverse iterator to the reverse beginning of the poly_span.
//*************************************************************************
ETL_CONSTEXPR reverse_iterator rbegin() const ETL_NOEXCEPT
{
return reverse_iterator(end());
}
//*************************************************************************
/// Returns a reverse iterator to the end of the poly_span.
//*************************************************************************
ETL_CONSTEXPR reverse_iterator rend() const ETL_NOEXCEPT
{
return reverse_iterator(begin());
}
// //*************************************************************************
// // Returns an reverse iterator to the reverse beginning of the poly_span.
// //*************************************************************************
// ETL_CONSTEXPR reverse_iterator rbegin() const ETL_NOEXCEPT
// {
// return reverse_iterator(pend);
// }
//
// //*************************************************************************
// /// Returns a reverse iterator to the end of the poly_span.
// //*************************************************************************
// ETL_CONSTEXPR reverse_iterator rend() const ETL_NOEXCEPT
// {
// return reverse_iterator(pbegin);
// }
//
//*************************************************************************
/// Returns <b>true</b> if the poly_span size is zero.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
{
return (Extent != 0U)
return (Extent == 0U);
}
//*************************************************************************
@ -499,108 +478,133 @@ namespace etl
return Extent * element_size;
}
// //*************************************************************************
// /// Assign from a poly_span.
// //*************************************************************************
// ETL_CONSTEXPR14 poly_span& operator =(const poly_span& other) ETL_NOEXCEPT
// {
// pbegin = other.pbegin;
// pend = other.pend;
// return *this;
// }
//
// //*************************************************************************
// /// Returns a reference to the indexed value.
// //*************************************************************************
// ETL_CONSTEXPR reference operator[](const size_t i) const
// {
// return pbegin[i];
// }
//
// //*************************************************************************
// /// Obtains a poly_span that is a view over the first COUNT elements of this poly_span.
// //*************************************************************************
// template <size_t COUNT>
// ETL_CONSTEXPR etl::poly_span<element_type, COUNT> first() const
// {
// return etl::poly_span<element_type, COUNT>(pbegin, pbegin + COUNT);
// }
//
// //*************************************************************************
// /// Obtains a poly_span that is a view over the first count elements of this poly_span.
// //*************************************************************************
// ETL_CONSTEXPR etl::poly_span<element_type, etl::dynamic_extent> first(size_t count) const
// {
// return etl::poly_span<element_type, etl::dynamic_extent>(pbegin, pbegin + count);
// }
//
// //*************************************************************************
// /// Obtains a poly_span that is a view over the last COUNT elements of this poly_span.
// //*************************************************************************
// template <size_t COUNT>
// ETL_CONSTEXPR etl::poly_span<element_type, COUNT> last() const
// {
// return etl::poly_span<element_type, COUNT>(pend - COUNT, pend);
// }
//
// //*************************************************************************
// /// Obtains a poly_span that is a view over the last count elements of this poly_span.
// //*************************************************************************
// ETL_CONSTEXPR etl::poly_span<element_type, etl::dynamic_extent> last(size_t count) const
// {
// return etl::poly_span<element_type, etl::dynamic_extent>(pend - count, pend);
// }
//
//#if ETL_USING_CPP11
// //*************************************************************************
// /// Obtains a poly_span that is a view from OFFSET over the next COUNT elements of this poly_span.
// //*************************************************************************
// template <const size_t OFFSET, size_t COUNT = etl::dynamic_extent>
// ETL_CONSTEXPR
// etl::poly_span<element_type, (COUNT != etl::dynamic_extent ? COUNT : (Extent != etl::dynamic_extent ? Extent - OFFSET : etl::dynamic_extent))> subspan() const
// {
// if (COUNT == etl::dynamic_extent)
// {
// return etl::poly_span<element_type, (COUNT != etl::dynamic_extent ? COUNT : (Extent != etl::dynamic_extent ? Extent - OFFSET : etl::dynamic_extent))>(pbegin + OFFSET, pend);
// }
// else
// {
// return etl::poly_span<element_type, (COUNT != etl::dynamic_extent ? COUNT : (Extent != etl::dynamic_extent ? Extent - OFFSET : etl::dynamic_extent))>(pbegin + OFFSET, pbegin + OFFSET + COUNT);
// }
// }
//#else
// //*************************************************************************
// /// Obtains a poly_span that is a view from OFFSET over the next COUNT elements of this poly_span.
// //*************************************************************************
// template <const size_t OFFSET, size_t COUNT>
// ETL_CONSTEXPR
// etl::poly_span<element_type, (COUNT != etl::dynamic_extent ? COUNT : (Extent != etl::dynamic_extent ? Extent - OFFSET : etl::dynamic_extent))> subspan() const
// {
// if (COUNT == etl::dynamic_extent)
// {
// return etl::poly_span<element_type, (COUNT != etl::dynamic_extent ? COUNT : (Extent != etl::dynamic_extent ? Extent - OFFSET : etl::dynamic_extent))>(pbegin + OFFSET, pend);
// }
// else
// {
// return etl::poly_span<element_type, (COUNT != etl::dynamic_extent ? COUNT : (Extent != etl::dynamic_extent ? Extent - OFFSET : etl::dynamic_extent))>(pbegin + OFFSET, pbegin + OFFSET + COUNT);
// }
// }
//#endif
//
// //*************************************************************************
// /// Obtains a poly_span that is a view from 'offset' over the next 'count' elements of this poly_span.
// //*************************************************************************
// ETL_CONSTEXPR14 etl::poly_span<element_type, etl::dynamic_extent> subspan(size_t offset, size_t count = etl::dynamic_extent) const
// {
// if (count == etl::dynamic_extent)
// {
// return etl::poly_span<element_type, etl::dynamic_extent>(pbegin + offset, pend);
// }
// else
// {
// return etl::poly_span<element_type, etl::dynamic_extent>(pbegin + offset, pbegin + offset + count);
// }
// }
//*************************************************************************
/// Assign from a poly_span.
//*************************************************************************
ETL_CONSTEXPR14 poly_span& operator =(const poly_span& other) ETL_NOEXCEPT
{
pbegin = other.pbegin;
element_size = other.element_size;
return *this;
}
//*************************************************************************
/// Assign from a poly_span.
//*************************************************************************
template <typename UBase>
ETL_CONSTEXPR14 poly_span& operator =(const poly_span<UBase, Extent>& other) ETL_NOEXCEPT
{
pbegin = other.pbegin;
element_size = other.element_size;
return *this;
}
//*************************************************************************
/// Returns a reference to the indexed value.
//*************************************************************************
ETL_CONSTEXPR reference operator[](size_t i) const
{
return *element_at(i);
}
//*************************************************************************
/// Obtains a poly_span that is a view over the first COUNT elements of this poly_span.
//*************************************************************************
template <size_t COUNT>
ETL_CONSTEXPR etl::poly_span<element_type, COUNT> first() const
{
return etl::poly_span<element_type, COUNT>(pbegin, 0U, COUNT, element_size);
}
//*************************************************************************
/// Obtains a poly_span that is a view over the first count elements of this poly_span.
//*************************************************************************
ETL_CONSTEXPR etl::poly_span<element_type, etl::dynamic_extent> first(size_t count) const
{
return etl::poly_span<element_type, etl::dynamic_extent>(pbegin, 0U, count, element_size);
}
//*************************************************************************
/// Obtains a poly_span that is a view over the last COUNT elements of this poly_span.
//*************************************************************************
template <size_t COUNT>
ETL_CONSTEXPR etl::poly_span<element_type, COUNT> last() const
{
return etl::poly_span<element_type, COUNT>(pbegin, Extent - COUNT, COUNT, element_size);
}
//*************************************************************************
/// Obtains a poly_span that is a view over the last count elements of this poly_span.
//*************************************************************************
ETL_CONSTEXPR etl::poly_span<element_type, etl::dynamic_extent> last(size_t count) const
{
return etl::poly_span<element_type, etl::dynamic_extent>(pbegin, Extent - count, count, element_size);
}
#if ETL_USING_CPP11
//*************************************************************************
/// Obtains a poly_span that is a view from OFFSET over the next COUNT elements of this poly_span.
//*************************************************************************
template <const size_t OFFSET, size_t COUNT = etl::dynamic_extent>
ETL_CONSTEXPR etl::poly_span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET> subspan() const
{
return (COUNT == etl::dynamic_extent) ? etl::poly_span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET>(pbegin, OFFSET, Extent, element_size)
: etl::poly_span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET>(pbegin, OFFSET, COUNT, element_size);
}
#else
//*************************************************************************
/// Obtains a poly_span that is a view from OFFSET over the next COUNT elements of this poly_span.
//*************************************************************************
template <const size_t OFFSET, size_t COUNT>
etl::poly_span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET> subspan() const
{
if (COUNT == etl::dynamic_extent)
{
return etl::poly_span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET>(pbegin, OFFSET, Extent, element_size);
}
else
{
return etl::poly_span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET>(pbegin, OFFSET, element_size);
}
}
#endif
//*************************************************************************
/// Obtains a poly_span that is a view from 'offset' over the next 'count' elements of this poly_span.
//*************************************************************************
ETL_CONSTEXPR14 etl::poly_span<element_type, etl::dynamic_extent> subspan(size_t offset, size_t count = etl::dynamic_extent) const
{
return (count == etl::dynamic_extent) ? etl::poly_span<element_type, etl::dynamic_extent>(pbegin, offset, Extent, element_size)
: etl::poly_span<element_type, etl::dynamic_extent>(pbegin, offset, count, element_size);
}
protected:
//***************************************************************************
template <typename TFrom>
struct char_ptr_type
{
typedef typename etl::conditional<etl::is_const<TFrom>::value, const char*, char*>::type type;
};
typedef typename char_ptr_type<TBase>::type char_ptr_t;
//***************************************************************************
ETL_CONSTEXPR pointer element_at(size_t index) const ETL_NOEXCEPT
{
char_ptr_t base = reinterpret_cast<char_ptr_t>(pbegin);
return reinterpret_cast<pointer>(base + (index * element_size));
}
//*************************************************************************
/// Construct from iterator + offset + element size
/// extent_ is ignored.
//*************************************************************************
ETL_CONSTEXPR poly_span(TBase* pbegin_, size_t offset_, size_t extent_, size_t element_size_) ETL_NOEXCEPT
: pbegin(reinterpret_cast<pointer>(reinterpret_cast<char_ptr_t>(pbegin_) + (offset_ * element_size_)))
, element_size(element_size_)
{
}
private:
@ -618,17 +622,17 @@ namespace etl
typedef TBase element_type;
typedef typename etl::remove_cv<TBase>::type value_type;
typedef size_t size_type;
typedef TBase& reference;
typedef size_t size_type;
typedef TBase& reference;
typedef const TBase& const_reference;
typedef TBase* pointer;
typedef TBase* pointer;
typedef const TBase* const_pointer;
typedef etl::private_poly_span::iterator<TBase> iterator;
typedef const TBase* const_iterator;
typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
typedef ETL_OR_STD::reverse_iterator<const_iterator> const_reverse_iterator;
typedef ETL_OR_STD::reverse_iterator<iterator> reverse_iterator;
template <typename UBase, size_t Extent>
static ETL_CONSTANT size_t extent = etl::dynamic_extent;
template <typename UBase, size_t UExtent>
friend class poly_span;
//*************************************************************************
@ -636,7 +640,7 @@ namespace etl
//*************************************************************************
ETL_CONSTEXPR poly_span() ETL_NOEXCEPT
: pbegin(ETL_NULLPTR)
, extent(0U)
, span_extent(0U)
, element_size(0U)
{
}
@ -647,16 +651,14 @@ namespace etl
template <typename TIterator, typename TSize>
ETL_CONSTEXPR poly_span(const TIterator begin_, const TSize size_) ETL_NOEXCEPT
: pbegin(etl::addressof(*begin_))
, extent(size_)
, element_size(sizeof(typename etl::iterator_traits<TIterator>::value_type))
, span_extent(size_)
{
typedef typename etl::iterator_traits<TIterator>::value_type data_type;
typedef typename etl::iterator_traits<TIterator>::iterator_category iterator_category;
ETL_STATIC_ASSERT((etl::is_same<ETL_OR_STD::random_access_iterator_tag, iterator_category>::value), "Not a random access iterator");
ETL_STATIC_ASSERT((etl::is_base_of<TBase, data_type>::value || etl::is_same<TBase, data_type>::value), "TBase not a base of the data type");
static ETL_CONSTANT size_t Element_Size = sizeof(data_type);
element_size = Element_Size;
}
//*************************************************************************
@ -665,16 +667,14 @@ namespace etl
template <typename TIterator>
ETL_CONSTEXPR poly_span(const TIterator begin_, const TIterator end_)
: pbegin(etl::addressof(*begin_))
, extent(size_t(etl::distance(begin_, end_)))
, element_size(sizeof(typename etl::iterator_traits<TIterator>::value_type))
, span_extent(size_t(etl::distance(begin_, end_)))
{
typedef typename etl::iterator_traits<TIterator>::value_type data_type;
typedef typename etl::iterator_traits<TIterator>::iterator_category iterator_category;
ETL_STATIC_ASSERT((etl::is_same<ETL_OR_STD::random_access_iterator_tag, iterator_category>::value), "Not a random access iterator");
ETL_STATIC_ASSERT((etl::is_base_of<TBase, data_type>::value || etl::is_same<TBase, data_type>::value), "TBase not a base of the data type");
static ETL_CONSTANT size_t Element_Size = sizeof(data_type);
element_size = Element_Size;
}
//*************************************************************************
@ -683,12 +683,10 @@ namespace etl
template<typename U, size_t N>
ETL_CONSTEXPR poly_span(U(&begin_)[N]) ETL_NOEXCEPT
: pbegin(begin_)
, extent(N)
, element_size(sizeof(U))
, span_extent(N)
{
ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of the data type");
static ETL_CONSTANT size_t Element_Size = sizeof(U);
element_size = Element_Size;
}
//*************************************************************************
@ -697,12 +695,10 @@ namespace etl
template <typename U, size_t N>
ETL_CONSTEXPR poly_span(etl::array<U, N>& a) ETL_NOEXCEPT
: pbegin(a.data())
, extent(N)
, element_size(sizeof(U))
, span_extent(N)
{
ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of the data type");
static ETL_CONSTANT size_t Element_Size = sizeof(U);
element_size = Element_Size;
}
//*************************************************************************
@ -711,12 +707,10 @@ namespace etl
template <typename U, size_t N>
ETL_CONSTEXPR poly_span(const etl::array<U, N>& a) ETL_NOEXCEPT
: pbegin(a.data())
, extent(N)
, element_size(sizeof(U))
, span_extent(N)
{
ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of the data type");
static ETL_CONSTANT size_t Element_Size = sizeof(U);
element_size = Element_Size;
}
#if ETL_USING_CPP11 && ETL_USING_STL
@ -726,12 +720,10 @@ namespace etl
template <typename U, size_t N>
ETL_CONSTEXPR poly_span(std::array<U, N>& a) ETL_NOEXCEPT
: pbegin(a.data())
, extent(N)
, element_size(sizeof(U))
, span_extent(N)
{
ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of U");
static ETL_CONSTANT size_t Element_Size = sizeof(U);
element_size = Element_Size;
}
//*************************************************************************
@ -740,12 +732,10 @@ namespace etl
template <typename U, size_t N>
ETL_CONSTEXPR poly_span(const std::array<U, N>& a) ETL_NOEXCEPT
: pbegin(a.data())
, extent(N)
, element_size(sizeof(U))
, span_extent(N)
{
ETL_STATIC_ASSERT((etl::is_base_of<TBase, U>::value || etl::is_same<TBase, U>::value), "TBase not a base of U");
static ETL_CONSTANT size_t Element_Size = sizeof(U);
element_size = Element_Size;
}
#endif
@ -754,7 +744,7 @@ namespace etl
//*************************************************************************
ETL_CONSTEXPR poly_span(const poly_span<TBase, etl::dynamic_extent>& other) ETL_NOEXCEPT
: pbegin(other.pbegin)
, extent(other.extent)
, span_extent(other.span_extent)
, element_size(other.element_size)
{
}
@ -765,7 +755,7 @@ namespace etl
template <typename UBase>
ETL_CONSTEXPR poly_span(const poly_span<UBase, etl::dynamic_extent>& other) ETL_NOEXCEPT
: pbegin(other.pbegin)
, extent(other.extent)
, span_extent(other.span_extent)
, element_size(other.element_size)
{
}
@ -783,7 +773,7 @@ namespace etl
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reference back() const ETL_NOEXCEPT
{
return *element_at(extent - 1U);
return *element_at(span_extent - 1U);
}
//*************************************************************************
@ -807,31 +797,31 @@ namespace etl
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR iterator end() const ETL_NOEXCEPT
{
return iterator(pbegin, extent, element_size);
return iterator(pbegin, span_extent, element_size);
}
//*************************************************************************
// Returns an reverse iterator to the reverse beginning of the poly_span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rbegin() const ETL_NOEXCEPT
{
return reverse_iterator(end());
}
//*************************************************************************
/// Returns a reverse iterator to the end of the poly_span.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rend() const ETL_NOEXCEPT
{
return reverse_iterator(begin());
}
// //*************************************************************************
// // Returns an reverse iterator to the reverse beginning of the poly_span.
// //*************************************************************************
// ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rbegin() const ETL_NOEXCEPT
// {
// return reverse_iterator(pend);
// }
//
// //*************************************************************************
// /// Returns a reverse iterator to the end of the poly_span.
// //*************************************************************************
// ETL_NODISCARD ETL_CONSTEXPR reverse_iterator rend() const ETL_NOEXCEPT
// {
// return reverse_iterator(pbegin);
// }
//
//*************************************************************************
/// Returns <b>true</b> if the poly_span size is zero.
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR bool empty() const ETL_NOEXCEPT
{
return (extent == 0);
return (span_extent == 0);
}
//*************************************************************************
@ -839,7 +829,7 @@ namespace etl
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR size_t size() const ETL_NOEXCEPT
{
return extent;
return span_extent;
}
//*************************************************************************
@ -855,18 +845,31 @@ namespace etl
//*************************************************************************
ETL_NODISCARD ETL_CONSTEXPR size_t size_bytes() const ETL_NOEXCEPT
{
return element_size * extent;
return element_size * span_extent;
}
// //*************************************************************************
// /// Assign from a poly_span.
// //*************************************************************************
// ETL_CONSTEXPR14 poly_span& operator =(const poly_span& other) ETL_NOEXCEPT
// {
// pbegin = other.pbegin;
// pend = other.pend;
// return *this;
// }
//*************************************************************************
/// Assign from a poly_span.
//*************************************************************************
ETL_CONSTEXPR14 poly_span& operator =(const poly_span& other) ETL_NOEXCEPT
{
pbegin = other.pbegin;
span_extent = other.span_extent;
element_size = other.element_size;
return *this;
}
//*************************************************************************
/// Assign from a poly_span.
//*************************************************************************
template <typename UBase>
ETL_CONSTEXPR14 poly_span& operator =(const poly_span<UBase, etl::dynamic_extent>& other) ETL_NOEXCEPT
{
pbegin = other.pbegin;
span_extent = other.span_extent;
element_size = other.element_size;
return *this;
}
//*************************************************************************
/// Returns a reference to the indexed value.
@ -876,72 +879,64 @@ namespace etl
return *element_at(i);
}
// //*************************************************************************
// /// Obtains a poly_span that is a view over the first COUNT elements of this poly_span.
// //*************************************************************************
// template <size_t COUNT>
// ETL_CONSTEXPR etl::poly_span<element_type, COUNT> first() const
// {
// return etl::poly_span<element_type, COUNT>(pbegin, pbegin + COUNT);
// }
//
// //*************************************************************************
// /// Obtains a poly_span that is a view over the first count elements of this poly_span.
// //*************************************************************************
// ETL_CONSTEXPR etl::poly_span<element_type, etl::dynamic_extent> first(size_t count) const
// {
// return etl::poly_span<element_type, etl::dynamic_extent>(pbegin, pbegin + count);
// }
//
// //*************************************************************************
// /// Obtains a poly_span that is a view over the last COUNT elements of this poly_span.
// //*************************************************************************
// template <size_t COUNT>
// ETL_CONSTEXPR etl::poly_span<element_type, COUNT> last() const
// {
// return etl::poly_span<element_type, COUNT>(pend - COUNT, pend);
// }
//
// //*************************************************************************
// /// Obtains a poly_span that is a view over the last count elements of this poly_span.
// //*************************************************************************
// ETL_CONSTEXPR etl::poly_span<element_type, etl::dynamic_extent> last(size_t count) const
// {
// return etl::poly_span<element_type, etl::dynamic_extent>(pend - count, pend);
// }
//*************************************************************************
/// Obtains a poly_span that is a view over the first COUNT elements of this poly_span.
//*************************************************************************
template <size_t COUNT>
ETL_CONSTEXPR etl::poly_span<element_type, COUNT> first() const
{
return etl::poly_span<element_type, COUNT>(pbegin, 0U, COUNT, element_size);
}
//*************************************************************************
/// Obtains a poly_span that is a view over the first count elements of this poly_span.
//*************************************************************************
ETL_CONSTEXPR etl::poly_span<element_type, etl::dynamic_extent> first(size_t count) const
{
return etl::poly_span<element_type, etl::dynamic_extent>(pbegin, 0U, count, element_size);
}
//*************************************************************************
/// Obtains a poly_span that is a view over the last COUNT elements of this poly_span.
//*************************************************************************
template <size_t COUNT>
ETL_CONSTEXPR etl::poly_span<element_type, COUNT> last() const
{
return etl::poly_span<element_type, COUNT>(pbegin, span_extent - COUNT, COUNT, element_size);
}
//*************************************************************************
/// Obtains a poly_span that is a view over the last count elements of this poly_span.
//*************************************************************************
ETL_CONSTEXPR etl::poly_span<element_type, etl::dynamic_extent> last(size_t count) const
{
return etl::poly_span<element_type, etl::dynamic_extent>(pbegin, span_extent - count, count, element_size);
}
#if ETL_USING_CPP11
//*************************************************************************
/// Obtains a poly_span that is a view from OFFSET over the next COUNT elements of this poly_span.
//*************************************************************************
template <const size_t OFFSET, size_t COUNT = etl::dynamic_extent>
ETL_CONSTEXPR
etl::poly_span<element_type, COUNT> subspan() const
ETL_CONSTEXPR etl::poly_span<element_type, COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent> subspan() const
{
if (COUNT == etl::dynamic_extent)
{
return etl::poly_span<element_type, COUNT>(pbegin, OFFSET, extent, element_size);
}
else
{
return etl::poly_span<element_type, COUNT>(pbegin, OFFSET, COUNT, element_size);
}
return (COUNT == etl::dynamic_extent) ? etl::poly_span<element_type, COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent>(pbegin, OFFSET, span_extent, element_size)
: etl::poly_span<element_type, COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent>(pbegin, OFFSET, COUNT, element_size);
}
#else
//*************************************************************************
/// Obtains a poly_span that is a view from OFFSET over the next COUNT elements of this poly_span.
//*************************************************************************
template <const size_t OFFSET, size_t COUNT>
ETL_CONSTEXPR
etl::poly_span<element_type, (COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent)> subspan() const
etl::poly_span<element_type, COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent> subspan() const
{
if (COUNT == etl::dynamic_extent)
{
return etl::poly_span<element_type, COUNT>(pbegin, OFFSET, extent, element_size);
return etl::poly_span<element_type, COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent>(pbegin, OFFSET, span_extent, element_size);
}
else
{
return etl::poly_span<element_type, COUNT>(pbegin, OFFSET, COUNT, element_size);
return etl::poly_span<element_type, COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent>(pbegin, OFFSET, span_extent, element_size);
}
}
#endif
@ -951,14 +946,8 @@ namespace etl
//*************************************************************************
ETL_CONSTEXPR14 etl::poly_span<element_type, etl::dynamic_extent> subspan(size_t offset, size_t count = etl::dynamic_extent) const
{
if (count == etl::dynamic_extent)
{
return etl::poly_span<element_type, etl::dynamic_extent>(pbegin, offset, extent - offset, element_size);
}
else
{
return etl::poly_span<element_type, etl::dynamic_extent>(pbegin, offset, count, element_size);
}
return (count == etl::dynamic_extent) ? etl::poly_span<element_type, etl::dynamic_extent>(pbegin, offset, span_extent - offset, element_size)
: etl::poly_span<element_type, etl::dynamic_extent>(pbegin, offset, count, element_size);
}
protected:
@ -968,7 +957,7 @@ protected:
//*************************************************************************
ETL_CONSTEXPR poly_span(TBase* pbegin_, size_t offset_, size_t extent_, size_t element_size_) ETL_NOEXCEPT
: pbegin(reinterpret_cast<pointer>(reinterpret_cast<char_ptr_t>(pbegin_) + (offset_ * element_size_)))
, extent(extent_)
, span_extent(extent_)
, element_size(element_size_)
{
}
@ -976,10 +965,13 @@ protected:
private:
//***************************************************************************
template <typename TFrom, typename TTo>
using transfer_const = typename etl::conditional<etl::is_const<TFrom>::value, typename etl::add_const<TTo>::type, TTo>::type;
template <typename TFrom>
struct char_ptr_type
{
typedef typename etl::conditional<etl::is_const<TFrom>::value, const char*, char*>::type type;
};
typedef transfer_const<TBase, char>* char_ptr_t;
typedef typename char_ptr_type<TBase>::type char_ptr_t;
//***************************************************************************
ETL_CONSTEXPR pointer element_at(size_t index) const ETL_NOEXCEPT
@ -989,41 +981,59 @@ protected:
}
pointer pbegin;
size_t extent;
size_t span_extent;
size_t element_size;
};
//
// //*************************************************************************
// /// Template deduction guides.
// //*************************************************************************
//#if ETL_USING_CPP17
// template <typename TArray>
// poly_span(TArray& a)
// ->poly_span<typename TArray::value_type, etl::dynamic_extent>;
//
// template <typename TIterator>
// poly_span(const TIterator begin_, const TIterator end_)
// ->poly_span<etl::remove_pointer_t<TIterator>, etl::dynamic_extent>;
//
// template <typename TIterator, typename TSize>
// poly_span(const TIterator begin_, const TSize size_)
// ->poly_span<etl::remove_pointer_t<TIterator>, etl::dynamic_extent>;
//#endif
//
// //*************************************************************************
// /// Hash function.
// //*************************************************************************
//#if ETL_USING_8BIT_TYPES
// template <typename TBase>
// struct hash<etl::poly_span<TBase> >
// {
// size_t operator()(const etl::poly_span<TBase>& view) const
// {
// return etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(&view[0]),
// reinterpret_cast<const uint8_t*>(&view[view.size()]));
// }
// };
//#endif
//*************************************************************************
/// Template deduction guides.
//*************************************************************************
#if ETL_USING_CPP17
template <typename TIterator>
poly_span(const TIterator begin_, const TIterator end_)
->poly_span<etl::remove_pointer_t<TIterator>, etl::dynamic_extent>;
template <typename TIterator, typename TSize>
poly_span(const TIterator begin_, const TSize size_)
->poly_span<etl::remove_pointer_t<TIterator>, etl::dynamic_extent>;
template <class T, size_t N>
poly_span(T(&)[N])
->poly_span<T, N>;
template <class T, size_t N>
poly_span(etl::array<T, N>&)
->poly_span<T, N>;
template <class T, size_t N>
poly_span(const etl::array<T, N>&)
->poly_span<const T, N>;
#if ETL_USING_STL
template <class T, size_t N>
poly_span(std::array<T, N>&)
->poly_span<T, N>;
template <class T, size_t N>
poly_span(const std::array<T, N>&)
->poly_span<const T, N>;
#endif
#endif
//*************************************************************************
/// Hash function.
//*************************************************************************
#if ETL_USING_8BIT_TYPES
template <typename TBase, size_t Extent>
struct hash<etl::poly_span<TBase, Extent> >
{
size_t operator()(const etl::poly_span<TBase, Extent>& view) const
{
return etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(&view[0]),
reinterpret_cast<const uint8_t*>(&view[view.size()]));
}
};
#endif
}
#endif

View File

@ -52,7 +52,7 @@ SOFTWARE.
namespace etl
{
//***************************************************************************
/// Span
/// Span - Fixed Extent
//***************************************************************************
template <typename T, size_t Extent = etl::dynamic_extent>
class span
@ -167,6 +167,44 @@ namespace etl
}
#endif
#if ETL_USING_CPP11
//*************************************************************************
/// Construct from a container or other type that supports
/// data() and size() member functions.
//*************************************************************************
template <typename TContainer, typename = typename etl::enable_if<!etl::is_pointer<etl::remove_reference_t<TContainer>>::value &&
!etl::is_array<etl::remove_reference_t<TContainer>>::value&&
etl::is_same<etl::remove_cv_t<T>, etl::remove_cv_t<typename etl::remove_reference_t<TContainer>::value_type>>::value, void>::type>
ETL_CONSTEXPR span(TContainer&& a) ETL_NOEXCEPT
: pbegin(a.data())
{
}
#else
//*************************************************************************
/// Construct from a container or other type that supports
/// data() and size() member functions.
//*************************************************************************
template <typename TContainer>
span(TContainer& a, typename etl::enable_if<!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
!etl::is_array<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) ETL_NOEXCEPT
: pbegin(a.data())
{
}
//*************************************************************************
/// Construct from a container or other type that supports
/// data() and size() member functions.
//*************************************************************************
template <typename TContainer>
ETL_CONSTEXPR span(const TContainer& a, typename etl::enable_if<!etl::is_pointer<typename etl::remove_reference<TContainer>::type>::value &&
!etl::is_array<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) ETL_NOEXCEPT
: pbegin(a.data())
{
}
#endif
//*************************************************************************
/// Copy constructor
//*************************************************************************
@ -303,7 +341,7 @@ namespace etl
template <size_t COUNT>
ETL_CONSTEXPR etl::span<element_type, COUNT> last() const
{
return etl::span<element_type, COUNT>((pbegin + Extent) - COUNT, (pbegin + Extent));
return etl::span<element_type, COUNT>(pbegin + Extent - COUNT, (pbegin + Extent));
}
//*************************************************************************
@ -320,32 +358,25 @@ namespace etl
//*************************************************************************
template <const size_t OFFSET, size_t COUNT = etl::dynamic_extent>
ETL_CONSTEXPR
etl::span<element_type, (COUNT != etl::dynamic_extent ? COUNT : (Extent != etl::dynamic_extent ? Extent - OFFSET : etl::dynamic_extent))> subspan() const
etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET> subspan() const
{
if (COUNT == etl::dynamic_extent)
{
return etl::span<element_type, (COUNT != etl::dynamic_extent ? COUNT : (Extent != etl::dynamic_extent ? Extent - OFFSET : etl::dynamic_extent))>(pbegin + OFFSET, (pbegin + Extent));
}
else
{
return etl::span<element_type, (COUNT != etl::dynamic_extent ? COUNT : (Extent != etl::dynamic_extent ? Extent - OFFSET : etl::dynamic_extent))>(pbegin + OFFSET, pbegin + OFFSET + COUNT);
}
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
//*************************************************************************
/// Obtains a span that is a view from OFFSET over the next COUNT elements of this span.
//*************************************************************************
template <const size_t OFFSET, size_t COUNT>
ETL_CONSTEXPR
etl::span<element_type, (COUNT != etl::dynamic_extent ? COUNT : (Extent != etl::dynamic_extent ? Extent - OFFSET : etl::dynamic_extent))> subspan() const
etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET> subspan() const
{
if (COUNT == etl::dynamic_extent)
{
return etl::span<element_type, (COUNT != etl::dynamic_extent ? COUNT : (Extent != etl::dynamic_extent ? Extent - OFFSET : etl::dynamic_extent))>(pbegin + OFFSET, (pbegin + 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 != etl::dynamic_extent ? Extent - OFFSET : etl::dynamic_extent))>(pbegin + OFFSET, pbegin + OFFSET + COUNT);
return etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : Extent - OFFSET>(pbegin + OFFSET, pbegin + OFFSET + COUNT);
}
}
#endif
@ -355,14 +386,8 @@ namespace etl
//*************************************************************************
ETL_CONSTEXPR14 etl::span<element_type, etl::dynamic_extent> subspan(size_t offset, size_t count = etl::dynamic_extent) const
{
if (count == etl::dynamic_extent)
{
return etl::span<element_type, etl::dynamic_extent>(pbegin + offset, (pbegin + Extent));
}
else
{
return etl::span<element_type, etl::dynamic_extent>(pbegin + offset, pbegin + offset + count);
}
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);
}
private:
@ -371,7 +396,7 @@ namespace etl
};
//***************************************************************************
/// Span specialisation
/// Span - Dynamic Extent
//***************************************************************************
template <typename T>
class span<T, etl::dynamic_extent>
@ -691,32 +716,25 @@ namespace etl
//*************************************************************************
template <const size_t OFFSET, size_t COUNT = etl::dynamic_extent>
ETL_CONSTEXPR
etl::span<element_type, COUNT> subspan() const
etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent> subspan() const
{
if (COUNT == etl::dynamic_extent)
{
return etl::span<element_type, COUNT>(pbegin + OFFSET, pend);
}
else
{
return etl::span<element_type, COUNT>(pbegin + OFFSET, pbegin + OFFSET + COUNT);
}
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);
}
#else
//*************************************************************************
/// Obtains a span that is a view from OFFSET over the next COUNT elements of this span.
//*************************************************************************
template <const size_t OFFSET, size_t COUNT>
ETL_CONSTEXPR
etl::span<element_type, (COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent)> subspan() const
etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent> subspan() const
{
if (COUNT == etl::dynamic_extent)
{
return etl::span<element_type, COUNT>(pbegin + OFFSET, pend);
return etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent>(pbegin + OFFSET, pend);
}
else
{
return etl::span<element_type, COUNT>(pbegin + OFFSET, pbegin + OFFSET + COUNT);
return etl::span<element_type, COUNT != etl::dynamic_extent ? COUNT : etl::dynamic_extent>(pbegin + OFFSET, pbegin + OFFSET + COUNT);
}
}
#endif
@ -726,11 +744,8 @@ namespace etl
//*************************************************************************
ETL_CONSTEXPR14 etl::span<element_type, etl::dynamic_extent> subspan(size_t offset, size_t count = etl::dynamic_extent) const
{
if (count == etl::dynamic_extent)
{
return etl::span<element_type, etl::dynamic_extent>(pbegin + offset, pend);
}
return etl::span<element_type, etl::dynamic_extent>(pbegin + offset, pbegin + offset + count);
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);
}
private:
@ -743,25 +758,43 @@ namespace etl
/// Template deduction guides.
//*************************************************************************
#if ETL_USING_CPP17
template <typename TArray>
span(TArray& a)
->span<typename TArray::value_type, etl::dynamic_extent>;
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(const TIterator begin_, const TSize size_)
->span<etl::remove_pointer_t<TIterator>, etl::dynamic_extent>;
template <class T, size_t N>
span(T(&)[N])
-> span<T, N>;
template <class T, size_t N>
span(etl::array<T, N>&)
-> span<T, N>;
template <class T, size_t N>
span(const etl::array<T, N>&)
-> span<const T, N>;
#if ETL_USING_STL
template <class T, size_t N>
span(std::array<T, N>&)
->span<T, N>;
template <class T, size_t N>
span(const std::array<T, N>&)
->span<const T, N>;
#endif
#endif
//*************************************************************************
/// Hash function.
//*************************************************************************
#if ETL_USING_8BIT_TYPES
template <typename T>
struct hash<etl::span<T> >
template <typename T, size_t Extent>
struct hash<etl::span<T, Extent> >
{
size_t operator()(const etl::span<T>& view) const
{

View File

@ -196,6 +196,8 @@ set(TEST_SOURCE_FILES
test_parameter_type.cpp
test_parity_checksum.cpp
test_pearson.cpp
test_poly_span_dynamic_extent.cpp
test_poly_span_fixed_extent.cpp
test_pool.cpp
test_pool_external_buffer.cpp
test_priority_queue.cpp
@ -225,7 +227,8 @@ set(TEST_SOURCE_FILES
test_shared_message.cpp
test_singleton.cpp
test_smallest.cpp
test_span.cpp
test_span_dynamic_extent.cpp
test_span_fixed_extent.cpp
test_stack.cpp
test_standard_deviation.cpp
test_state_chart.cpp

View File

@ -5,7 +5,7 @@ Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2020 John Wellbelove
Copyright(c) 2022 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
@ -44,6 +44,10 @@ namespace
virtual int value() const = 0;
virtual void value(int) = 0;
virtual ~Base()
{
}
virtual bool operator ==(const Base& rhs) const
{
return value() == rhs.value();
@ -128,7 +132,7 @@ namespace
CHECK(s.empty());
CHECK_EQUAL(0U, s.size());
CHECK_EQUAL(0U, s.size_bytes());
//CHECK(s.begin() == s.end());
CHECK(s.begin() == s.end());
}
//*************************************************************************
@ -177,6 +181,7 @@ namespace
CHECK_EQUAL(data[3].value(), s[3].value());
}
#if ETL_USING_STL
//*************************************************************************
TEST(test_poly_span_construct_from_std_array)
{
@ -204,6 +209,7 @@ namespace
CHECK_EQUAL(data[2].value(), s[2].value());
CHECK_EQUAL(data[3].value(), s[3].value());
}
#endif
//*************************************************************************
TEST(test_poly_span_construct_from_etl_array)
@ -233,6 +239,7 @@ namespace
CHECK_EQUAL(data[3].value(), s[3].value());
}
#if ETL_USING_STL
//*************************************************************************
TEST(test_poly_span_copy_construct)
{
@ -240,11 +247,28 @@ namespace
etl::poly_span<Base> s1 = a;
etl::poly_span<Base> s2 = s1;
const etl::poly_span<const Base> s3 = s1;
//CHECK(equal(s1, s2));
CHECK(!s2.empty());
CHECK(!s3.empty());
CHECK(std::equal(s1.begin(), s1.end(), s2.begin()));
}
//*************************************************************************
TEST(test_poly_span_assignment)
{
std::array<Derived, 4> a = { 1, 2, 3, 4 };
etl::poly_span<Base> s1 = a;
etl::poly_span<Base> s2;
etl::poly_span<const Base> s3;
s2 = s1;
s3 = s1;
CHECK(!s2.empty());
CHECK(!s3.empty());
CHECK(std::equal(s1.begin(), s1.end(), s2.begin()));
}
#endif
//*************************************************************************
TEST(test_poly_span_multi_derived)
{
@ -350,7 +374,38 @@ namespace
}
//*************************************************************************
TEST(test_poly_span_random_access_iteratorUse)
TEST(test_poly_span_reverse_iterator)
{
Derived data[] = { 1, 2, 3, 4 };
etl::poly_span<Base> s1(data);
etl::poly_span<Base>::reverse_iterator itr1 = s1.rbegin();
CHECK(itr1 != s1.rend());
CHECK_EQUAL(data[3].value(), (*itr1).value());
CHECK_EQUAL(data[3].value(), itr1->value());
++itr1;
CHECK_EQUAL(data[2].value(), (*itr1).value());
CHECK_EQUAL(data[2].value(), itr1->value());
itr1++;
CHECK_EQUAL(data[1].value(), (*itr1).value());
CHECK_EQUAL(data[1].value(), itr1->value());
itr1 += 1;
CHECK_EQUAL(data[0].value(), (*itr1).value());
CHECK_EQUAL(data[0].value(), itr1->value());
itr1 = itr1 + 1;
CHECK(itr1 == s1.rend());
itr1 -= 1;
CHECK_EQUAL(data[0].value(), (*itr1).value());
CHECK_EQUAL(data[0].value(), itr1->value());
itr1 = itr1 - 1;
CHECK_EQUAL(data[1].value(), (*itr1).value());
CHECK_EQUAL(data[1].value(), itr1->value());
}
//*************************************************************************
TEST(test_poly_span_random_access_iterator_use)
{
int data[] = { 25, 4, 3, -2, 1 };
etl::poly_span<int> s = data;
@ -371,11 +426,6 @@ namespace
CHECK_EQUAL(s[1].value(), s1[0].value());
CHECK_EQUAL(s[2].value(), s1[1].value());
//auto s2 = s.subspan<1, 2>();
//CHECK_EQUAL(2, s2.size());
//CHECK_EQUAL(data[1].value(), s2[0].value());
//CHECK_EQUAL(data[2].value(), s2[1].value());
auto s2 = s.subspan(2);
CHECK_EQUAL(3, s2.size());
CHECK_EQUAL(s[2].value(), s2[0].value());
@ -383,59 +433,116 @@ namespace
CHECK_EQUAL(s[4].value(), s2[2].value());
}
////*************************************************************************
//TEST(test_poly_span_first)
//{
// const int data[] = { 1, 2, 3, 4, 5 };
// etl::poly_span<const int> s(data);
//
// CHECK_THROW(s.first(6), etl::poly_span_out_of_range);
// CHECK_EQUAL(s.first(5).size(), 5);
// CHECK(s.first(0).empty());
//
// auto s1 = s.first(3);
// CHECK_EQUAL(3, s1.size());
// CHECK_EQUAL(1, s1[0]);
// CHECK_EQUAL(3, s1[2]);
//}
//*************************************************************************
TEST(test_poly_span_first)
{
Derived data[] = { 1, 2, 3, 4 };
etl::poly_span<Base> s1(data);
////*************************************************************************
//TEST(test_poly_span_last)
//{
// const int data[] = { 1, 2, 3, 4, 5 };
// etl::poly_span<const int> s(data);
//
// CHECK_THROW(s.last(6), etl::poly_span_out_of_range);
// CHECK_EQUAL(s.last(5).size(), 5);
//
// auto s2 = s.last(2);
// CHECK_EQUAL(2, s2.size());
// CHECK_EQUAL(4, s2[0]);
// CHECK_EQUAL(5, s2[1]);
//}
auto s2 = s1.first(3);
auto s3 = s1.first<3>();
////*************************************************************************
//TEST(test_poly_span_equal_view)
//{
// std::vector<double> v = { 1.0, 2.0, 3.0 };
// etl::poly_span<double> s1 = v;
// etl::poly_span<const double> cs2 = v;
CHECK_EQUAL(data[0].value(), s2[0].value());
CHECK_EQUAL(data[1].value(), s2[1].value());
CHECK_EQUAL(data[2].value(), s2[2].value());
// CHECK(!etl::poly_span<const double>{}.equal_view(s1));
// CHECK(s1.equal_view(cs2));
// CHECK(s1.last(2).equal_view(cs2.subspan(1)));
//}
CHECK_EQUAL(data[0].value(), s3[0].value());
CHECK_EQUAL(data[1].value(), s3[1].value());
CHECK_EQUAL(data[2].value(), s3[2].value());
}
////*************************************************************************
//TEST(test_poly_span_at)
//{
// const int data[] = { 1, 2, 3 };
// etl::poly_span<const int> s(data);
//
// CHECK_EQUAL(s.at(0), 1);
// CHECK_EQUAL(s.at(2), 3);
// CHECK_THROW(s.at(3), etl::poly_span_out_of_range);
// CHECK_THROW(s.at(-1), etl::poly_span_out_of_range);
//}
//*************************************************************************
TEST(test_poly_span_last)
{
Derived data[] = { 1, 2, 3, 4 };
etl::poly_span<Base> s1(data);
auto s2 = s1.last(3);
auto s3 = s1.last<3>();
CHECK_EQUAL(data[1].value(), s2[0].value());
CHECK_EQUAL(data[2].value(), s2[1].value());
CHECK_EQUAL(data[3].value(), s2[2].value());
CHECK_EQUAL(data[1].value(), s3[0].value());
CHECK_EQUAL(data[2].value(), s3[1].value());
CHECK_EQUAL(data[3].value(), s3[2].value());
}
//*************************************************************************
TEST(test_hash)
{
int data[] = { 1, 2, 3, 4 };
etl::poly_span<int> s1(data);
size_t hashdata = etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(&s1[0]),
reinterpret_cast<const uint8_t*>(&s1[s1.size()]));
size_t hashview = etl::hash<etl::poly_span<int>>()(s1);
CHECK_EQUAL(hashdata, hashview);
}
//*************************************************************************
TEST(test_template_deduction_guide_for_c_array)
{
int data[] = { 1, 2, 3, 4 };
etl::poly_span s = data;
CHECK_EQUAL(std::size(data), s.extent);
CHECK_EQUAL(std::size(data), s.size());
CHECK((std::is_same_v<int, std::remove_reference_t<decltype(s.front())>>));
}
#if ETL_USING_STL
//*************************************************************************
TEST(test_template_deduction_guide_for_std_array)
{
std::array<int, 4U> data = { 1, 2, 3, 4 };
etl::poly_span s = data;
CHECK_EQUAL(std::size(data), s.extent);
CHECK_EQUAL(std::size(data), s.size());
CHECK((std::is_same_v<int, std::remove_reference_t<decltype(s.front())>>));
}
#endif
//*************************************************************************
TEST(test_template_deduction_guide_for_etl_array)
{
etl::array<int, 4U> data = { 1, 2, 3, 4 };
etl::poly_span s = data;
CHECK_EQUAL(std::size(data), s.extent);
CHECK_EQUAL(std::size(data), s.size());
CHECK((std::is_same_v<int, std::remove_reference_t<decltype(s.front())>>));
}
//*************************************************************************
TEST(test_template_deduction_guide_for_iterators)
{
etl::array<int, 4U> data = { 1, 2, 3, 4 };
etl::poly_span s{ data.begin(), data.end() };
CHECK_EQUAL(etl::dynamic_extent, s.extent);
CHECK_EQUAL(4U, s.size());
CHECK((std::is_same_v<int, std::remove_reference_t<decltype(s.front())>>));
}
//*************************************************************************
TEST(test_template_deduction_guide_for_iterator_and_size)
{
etl::array<int, 4U> data = { 1, 2, 3, 4 };
etl::poly_span s{ data.begin(), data.size() };
CHECK_EQUAL(etl::dynamic_extent, s.extent);
CHECK_EQUAL(4U, s.size());
CHECK((std::is_same_v<int, std::remove_reference_t<decltype(s.front())>>));
}
}
}

View File

@ -0,0 +1,567 @@
/******************************************************************************
The MIT License(MIT)
Embedded Template Library.
https://github.com/ETLCPP/etl
https://www.etlcpp.com
Copyright(c) 2022 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.
******************************************************************************/
#include "unit_test_framework.h"
#include "etl/poly_span.h"
#include <array>
#include <vector>
#include <algorithm>
#include <iterator>
#include <vector>
namespace
{
//***************************************************************************
struct Base
{
virtual int value() const = 0;
virtual void value(int) = 0;
virtual ~Base()
{
}
virtual bool operator ==(const Base& rhs) const
{
return value() == rhs.value();
}
};
//***************************************************************************
struct AnotherBase
{
virtual double another_value() const = 0;
virtual bool operator ==(const AnotherBase& rhs) const
{
return another_value() == rhs.another_value();
}
};
//***************************************************************************
struct Derived : Base
{
Derived(int v_)
: v1(v_)
{
}
int value() const override
{
return v1;
}
void value(int i) override
{
v1 = i;
}
int v1;
};
//***************************************************************************
struct MultiDerived : AnotherBase, Base
{
MultiDerived(int v1_, double v2_)
: v1(v1_)
, v2(v2_)
{
}
int value() const override
{
return v1;
}
void value(int i) override
{
v1 = i;
}
double another_value() const override
{
return v2;
}
int v1;
double v2;
};
//***************************************************************************
template <typename TSpan, typename TSource>
bool equal(const TSpan& span, TSource& source)
{
auto sb = std::begin(source);
return (span.size() == (std::end(source) - sb)) && std::equal(span.begin(), span.end(), sb);
}
SUITE(test_poly_span_fixed_extent)
{
//*************************************************************************
TEST(test_poly_span_default_construct)
{
etl::poly_span<Base, 4U> s;
CHECK_EQUAL(0U, s.size_of_element());
CHECK(!s.empty());
CHECK_EQUAL(4U, s.size());
CHECK_EQUAL(0U, s.size_bytes());
CHECK(s.begin() == s.end());
}
//*************************************************************************
TEST(test_poly_span_construct_from_iterators)
{
std::vector<Derived> data = { 1, 2, 3, 4 };
etl::poly_span<Base, 4U> s(data.begin(), data.end());
CHECK_EQUAL(sizeof(Derived), s.size_of_element());
CHECK(!s.empty());
CHECK_EQUAL(data.size(), s.size());
CHECK_EQUAL(s.size() * sizeof(Derived), s.size_bytes());
CHECK_EQUAL(data[0].value(), s[0].value());
CHECK_EQUAL(data[1].value(), s[1].value());
CHECK_EQUAL(data[2].value(), s[2].value());
CHECK_EQUAL(data[3].value(), s[3].value());
}
//*************************************************************************
TEST(test_poly_span_construct_from_c_array)
{
Derived data[] = { 1, 2, 3, 4 };
etl::poly_span<Base, 4U> s(data);
CHECK_EQUAL(sizeof(Derived), s.size_of_element());
CHECK(!s.empty());
CHECK_EQUAL(std::size(data), s.size());
CHECK_EQUAL(s.size() * sizeof(Derived), s.size_bytes());
CHECK_EQUAL(data[0].value(), s[0].value());
CHECK_EQUAL(data[1].value(), s[1].value());
CHECK_EQUAL(data[2].value(), s[2].value());
CHECK_EQUAL(data[3].value(), s[3].value());
}
//*************************************************************************
TEST(test_poly_span_construct_from_const_c_array)
{
const Derived data[] = { 1, 2, 3, 4 };
etl::poly_span<const Base, 4U> s(data);
CHECK_EQUAL(sizeof(Derived), s.size_of_element());
CHECK(!s.empty());
CHECK_EQUAL(std::size(data), s.size());
CHECK_EQUAL(s.size() * sizeof(Derived), s.size_bytes());
CHECK_EQUAL(data[0].value(), s[0].value());
CHECK_EQUAL(data[1].value(), s[1].value());
CHECK_EQUAL(data[2].value(), s[2].value());
CHECK_EQUAL(data[3].value(), s[3].value());
}
#if ETL_USING_STL
//*************************************************************************
TEST(test_poly_span_construct_from_std_array)
{
std::array data{ Derived(1), Derived(2), Derived(3), Derived(4) };
etl::poly_span<Base, 4U> s(data);
CHECK(!s.empty());
CHECK_EQUAL(data.size(), s.size());
CHECK_EQUAL(s.size() * sizeof(Derived), s.size_bytes());
CHECK_EQUAL(data[0].value(), s[0].value());
CHECK_EQUAL(data[1].value(), s[1].value());
CHECK_EQUAL(data[2].value(), s[2].value());
CHECK_EQUAL(data[3].value(), s[3].value());
}
//*************************************************************************
TEST(test_poly_span_construct_from_const_std_array)
{
const std::array data{ Derived(1), Derived(2), Derived(3), Derived(4) };
etl::poly_span<const Base, 4U> s(data);
CHECK(!s.empty());
CHECK_EQUAL(data.size(), s.size());
CHECK_EQUAL(s.size() * sizeof(Derived), s.size_bytes());
CHECK_EQUAL(data[0].value(), s[0].value());
CHECK_EQUAL(data[1].value(), s[1].value());
CHECK_EQUAL(data[2].value(), s[2].value());
CHECK_EQUAL(data[3].value(), s[3].value());
}
#endif
//*************************************************************************
TEST(test_poly_span_construct_from_etl_array)
{
etl::array data{ Derived(1), Derived(2), Derived(3), Derived(4) };
etl::poly_span<Base, 4U> s(data);
CHECK(!s.empty());
CHECK_EQUAL(data.size(), s.size());
CHECK_EQUAL(s.size() * sizeof(Derived), s.size_bytes());
CHECK_EQUAL(data[0].value(), s[0].value());
CHECK_EQUAL(data[1].value(), s[1].value());
CHECK_EQUAL(data[2].value(), s[2].value());
CHECK_EQUAL(data[3].value(), s[3].value());
}
//*************************************************************************
TEST(test_poly_span_construct_from_const_etl_array)
{
const etl::array data{ Derived(1), Derived(2), Derived(3), Derived(4) };
etl::poly_span<const Base, 4U> s(data);
CHECK(!s.empty());
CHECK_EQUAL(data.size(), s.size());
CHECK_EQUAL(s.size() * sizeof(Derived), s.size_bytes());
CHECK_EQUAL(data[0].value(), s[0].value());
CHECK_EQUAL(data[1].value(), s[1].value());
CHECK_EQUAL(data[2].value(), s[2].value());
CHECK_EQUAL(data[3].value(), s[3].value());
}
#if ETL_USING_STL
//*************************************************************************
TEST(test_poly_span_copy_construct)
{
std::array<Derived, 4U> a = { 1, 2, 3, 4 };
etl::poly_span<Base, 4U> s1 = a;
etl::poly_span<Base, 4U> s2 = s1;
const etl::poly_span<const Base, 4U> s3 = s1;
CHECK(!s2.empty());
CHECK(!s3.empty());
CHECK(std::equal(s1.begin(), s1.end(), s2.begin()));
}
//*************************************************************************
TEST(test_poly_span_assignment)
{
std::array<Derived, 4> a = { 1, 2, 3, 4 };
etl::poly_span<Base, 4U> s1 = a;
etl::poly_span<Base, 4U> s2 = a;
etl::poly_span<const Base, 4U> s3 = a;
s2 = s1;
s3 = s1;
CHECK(!s2.empty());
CHECK(!s3.empty());
CHECK(std::equal(s1.begin(), s1.end(), s2.begin()));
}
#endif
//*************************************************************************
TEST(test_poly_span_multi_derived)
{
std::vector<MultiDerived> data = { { 0, 1.2 }, { 1, 2.3 }, { 2, 3.4 }, { 3, 4.5 } };
etl::poly_span<Base, 4U> s1(data.begin(), data.end());
etl::poly_span<AnotherBase, 4U> s2(data.begin(), data.end());
CHECK_EQUAL(data[0].value(), s1[0].value());
CHECK_EQUAL(data[1].value(), s1[1].value());
CHECK_EQUAL(data[2].value(), s1[2].value());
CHECK_EQUAL(data[3].value(), s1[3].value());
CHECK_EQUAL(data[0].another_value(), s2[0].another_value());
CHECK_EQUAL(data[1].another_value(), s2[1].another_value());
CHECK_EQUAL(data[2].another_value(), s2[2].another_value());
CHECK_EQUAL(data[3].another_value(), s2[3].another_value());
}
//*************************************************************************
TEST(test_poly_span_front_back)
{
Derived data[] = { 1, 2, 3, 4 };
etl::poly_span<Base, 4U> s(data);
CHECK_EQUAL(data[0].value(), s.front().value());
CHECK_EQUAL(data[3].value(), s.back().value());
}
//*************************************************************************
TEST(test_poly_span_const_front_back)
{
const Derived data[] = { 1, 2, 3, 4 };
const etl::poly_span<const Base, 4U> s(data);
CHECK_EQUAL(data[0].value(), s.front().value());
CHECK_EQUAL(data[3].value(), s.back().value());
}
//*************************************************************************
TEST(test_poly_span_iterator)
{
Derived data[] = { 1, 2, 3, 4 };
etl::poly_span<Base, 4U> s1(data);
etl::poly_span<Base, 4U>::iterator itr1 = s1.begin();
CHECK(itr1 != s1.end());
CHECK_EQUAL(data[0].value(), (*itr1).value());
CHECK_EQUAL(data[0].value(), itr1->value());
++itr1;
CHECK_EQUAL(data[1].value(), (*itr1).value());
CHECK_EQUAL(data[1].value(), itr1->value());
itr1++;
CHECK_EQUAL(data[2].value(), (*itr1).value());
CHECK_EQUAL(data[2].value(), itr1->value());
itr1 += 1;
CHECK_EQUAL(data[3].value(), (*itr1).value());
CHECK_EQUAL(data[3].value(), itr1->value());
itr1 = itr1 + 1;
CHECK(itr1 == s1.end());
itr1 -= 1;
CHECK_EQUAL(data[3].value(), (*itr1).value());
CHECK_EQUAL(data[3].value(), itr1->value());
itr1 = itr1 - 1;
CHECK_EQUAL(data[2].value(), (*itr1).value());
CHECK_EQUAL(data[2].value(), itr1->value());
itr1 = s1.begin();
etl::poly_span<Base, 4U>::iterator itr2 = itr1 + 1;
CHECK(itr1 < itr2);
CHECK(itr1 <= itr1);
CHECK(itr1 <= itr2);
CHECK(itr2 > itr1);
CHECK(itr2 >= itr2);
CHECK(itr2 >= itr1);
CHECK(itr1 == itr1);
CHECK(itr2 == itr2);
CHECK(itr1 != itr2);
CHECK(itr2 != itr1);
CHECK(!(itr1 > itr2));
CHECK(!(itr2 <= itr1));
CHECK(!(itr2 < itr1));
CHECK(!(itr1 >= itr2));
CHECK(!(itr1 == itr2));
CHECK(!(itr2 == itr1));
CHECK(!(itr1 != itr1));
CHECK(!(itr2 != itr2));
itr1 = s1.begin();
(*itr1).value(2);
CHECK_EQUAL(2, (*itr1).value());
itr1->value(3);
CHECK_EQUAL(3, itr1->value());
etl::poly_span<Base, 4U> s2;
CHECK(s2.begin() == s2.end());
}
//*************************************************************************
TEST(test_poly_span_reverse_iterator)
{
Derived data[] = { 1, 2, 3, 4 };
etl::poly_span<Base, 4U> s1(data);
etl::poly_span<Base, 4U>::reverse_iterator itr1 = s1.rbegin();
CHECK(itr1 != s1.rend());
CHECK_EQUAL(data[3].value(), (*itr1).value());
CHECK_EQUAL(data[3].value(), itr1->value());
++itr1;
CHECK_EQUAL(data[2].value(), (*itr1).value());
CHECK_EQUAL(data[2].value(), itr1->value());
itr1++;
CHECK_EQUAL(data[1].value(), (*itr1).value());
CHECK_EQUAL(data[1].value(), itr1->value());
itr1 += 1;
CHECK_EQUAL(data[0].value(), (*itr1).value());
CHECK_EQUAL(data[0].value(), itr1->value());
itr1 = itr1 + 1;
CHECK(itr1 == s1.rend());
itr1 -= 1;
CHECK_EQUAL(data[0].value(), (*itr1).value());
CHECK_EQUAL(data[0].value(), itr1->value());
itr1 = itr1 - 1;
CHECK_EQUAL(data[1].value(), (*itr1).value());
CHECK_EQUAL(data[1].value(), itr1->value());
}
//*************************************************************************
TEST(test_poly_span_random_access_iterator_use)
{
int data[] = { 25, 4, 3, -2, 1 };
etl::poly_span<int, 5U> s = data;
std::sort(s.begin(), s.end());
CHECK(std::is_sorted(std::begin(data), std::end(data)));
}
//*************************************************************************
TEST(test_poly_span_subspan_dynamic)
{
Derived data[] = { 1, 2, 3, 4, 5 };
etl::poly_span<Base, 5U> s(data);
auto s1 = s.subspan(1, 2);
CHECK_EQUAL(2, s1.size());
CHECK_EQUAL(s[1].value(), s1[0].value());
CHECK_EQUAL(s[2].value(), s1[1].value());
auto s2 = s.subspan(2);
CHECK_EQUAL(5U, s2.size());
CHECK_EQUAL(s[2].value(), s2[0].value());
CHECK_EQUAL(s[3].value(), s2[1].value());
CHECK_EQUAL(s[4].value(), s2[2].value());
}
//*************************************************************************
TEST(test_poly_span_subspan_fixed)
{
Derived data[] = { 1, 2, 3, 4, 5 };
etl::poly_span<Base, 5U> s(data);
auto s1 = s.subspan<1, 2>();
CHECK_EQUAL(2U, s1.size());
CHECK_EQUAL(s[1].value(), s1[0].value());
CHECK_EQUAL(s[2].value(), s1[1].value());
auto s2 = s.subspan<2>();
CHECK_EQUAL(3U, s2.size());
CHECK_EQUAL(s[2].value(), s2[0].value());
CHECK_EQUAL(s[3].value(), s2[1].value());
CHECK_EQUAL(s[4].value(), s2[2].value());
}
//*************************************************************************
TEST(test_poly_span_first)
{
Derived data[] = { 1, 2, 3, 4 };
etl::poly_span<Base, 4U> s1(data);
auto s2 = s1.first(3);
auto s3 = s1.first<3>();
CHECK_EQUAL(data[0].value(), s2[0].value());
CHECK_EQUAL(data[1].value(), s2[1].value());
CHECK_EQUAL(data[2].value(), s2[2].value());
CHECK_EQUAL(data[0].value(), s3[0].value());
CHECK_EQUAL(data[1].value(), s3[1].value());
CHECK_EQUAL(data[2].value(), s3[2].value());
}
//*************************************************************************
TEST(test_poly_span_last)
{
Derived data[] = { 1, 2, 3, 4 };
etl::poly_span<Base, 4U> s1(data);
auto s2 = s1.last(3);
auto s3 = s1.last<3>();
CHECK_EQUAL(data[1].value(), s2[0].value());
CHECK_EQUAL(data[2].value(), s2[1].value());
CHECK_EQUAL(data[3].value(), s2[2].value());
CHECK_EQUAL(data[1].value(), s3[0].value());
CHECK_EQUAL(data[2].value(), s3[1].value());
CHECK_EQUAL(data[3].value(), s3[2].value());
}
//*************************************************************************
TEST(test_hash)
{
int data[] = { 1, 2, 3, 4 };
etl::poly_span<int, 4U> s1(data);
size_t hashdata = etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(&s1[0]),
reinterpret_cast<const uint8_t*>(&s1[s1.size()]));
size_t hashview = etl::hash<etl::poly_span<int, 4U>>()(s1);
CHECK_EQUAL(hashdata, hashview);
}
//*************************************************************************
TEST(test_template_deduction_guide_for_c_array)
{
int data[] = { 1, 2, 3, 4 };
etl::poly_span s = data;
CHECK_EQUAL(std::size(data), s.extent);
CHECK_EQUAL(std::size(data), s.size());
CHECK((std::is_same_v<int, std::remove_reference_t<decltype(s.front())>>));
}
#if ETL_USING_STL
//*************************************************************************
TEST(test_template_deduction_guide_for_std_array)
{
std::array<int, 4U> data = { 1, 2, 3, 4 };
etl::poly_span s = data;
CHECK_EQUAL(std::size(data), s.extent);
CHECK_EQUAL(std::size(data), s.size());
CHECK((std::is_same_v<int, std::remove_reference_t<decltype(s.front())>>));
}
#endif
//*************************************************************************
TEST(test_template_deduction_guide_for_etl_array)
{
etl::array<int, 4U> data = { 1, 2, 3, 4 };
etl::poly_span s = data;
CHECK_EQUAL(std::size(data), s.extent);
CHECK_EQUAL(std::size(data), s.size());
CHECK((std::is_same_v<int, std::remove_reference_t<decltype(s.front())>>));
}
//*************************************************************************
TEST(test_template_deduction_guide_for_iterators)
{
etl::array<int, 4U> data = { 1, 2, 3, 4 };
etl::poly_span s{ data.begin(), data.end() };
CHECK_EQUAL(etl::dynamic_extent, s.extent);
CHECK_EQUAL(4U, s.size());
CHECK((std::is_same_v<int, std::remove_reference_t<decltype(s.front())>>));
}
//*************************************************************************
TEST(test_template_deduction_guide_for_iterator_and_size)
{
etl::array<int, 4U> data = { 1, 2, 3, 4 };
etl::poly_span s{ data.begin(), data.size() };
CHECK_EQUAL(etl::dynamic_extent, s.extent);
CHECK_EQUAL(4U, s.size());
CHECK((std::is_same_v<int, std::remove_reference_t<decltype(s.front())>>));
}
}
}

View File

@ -38,7 +38,7 @@ SOFTWARE.
namespace
{
SUITE(test_span)
SUITE(test_span_dynamic_extent)
{
static const size_t SIZE = 10UL;
@ -630,6 +630,68 @@ namespace
CHECK_EQUAL(hashdata, hashcview);
}
//*************************************************************************
TEST(test_template_deduction_guide_for_c_array)
{
int data[] = { 1, 2, 3, 4 };
etl::span s = data;
CHECK_EQUAL(std::size(data), s.extent);
CHECK_EQUAL(std::size(data), s.size());
CHECK((std::is_same_v<int, std::remove_reference_t<decltype(s.front())>>));
}
#if ETL_USING_STL
//*************************************************************************
TEST(test_template_deduction_guide_for_std_array)
{
std::array<int, 4U> data = { 1, 2, 3, 4 };
etl::span s = data;
CHECK_EQUAL(std::size(data), s.extent);
CHECK_EQUAL(std::size(data), s.size());
CHECK((std::is_same_v<int, std::remove_reference_t<decltype(s.front())>>));
}
#endif
//*************************************************************************
TEST(test_template_deduction_guide_for_etl_array)
{
etl::array<int, 4U> data = { 1, 2, 3, 4 };
etl::span s = data;
CHECK_EQUAL(std::size(data), s.extent);
CHECK_EQUAL(std::size(data), s.size());
CHECK((std::is_same_v<int, std::remove_reference_t<decltype(s.front())>>));
}
//*************************************************************************
TEST(test_template_deduction_guide_for_iterators)
{
etl::array<int, 4U> data = { 1, 2, 3, 4 };
etl::span s{ data.begin(), data.end() };
CHECK_EQUAL(etl::dynamic_extent, s.extent);
CHECK_EQUAL(4U, s.size());
CHECK((std::is_same_v<int, std::remove_reference_t<decltype(s.front())>>));
}
//*************************************************************************
TEST(test_template_deduction_guide_for_iterator_and_size)
{
etl::array<int, 4U> data = { 1, 2, 3, 4 };
etl::span s{ data.begin(), data.size() };
CHECK_EQUAL(etl::dynamic_extent, s.extent);
CHECK_EQUAL(4U, s.size());
CHECK((std::is_same_v<int, std::remove_reference_t<decltype(s.front())>>));
}
//*************************************************************************
void f_issue_481(etl::span<const char, 10> value)
{

View File

@ -0,0 +1,749 @@
/******************************************************************************
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.
******************************************************************************/
#include "unit_test_framework.h"
#include "etl/span.h"
#include "etl/array.h"
#include <array>
#include <vector>
#include <algorithm>
#include <iterator>
namespace
{
SUITE(test_span_fixed_extent)
{
static const size_t SIZE = 10UL;
typedef etl::array<int, SIZE> EtlData;
typedef std::array<int, SIZE> StlData;
typedef std::vector<int> StlVData;
typedef etl::span<int, 10U> View;
typedef etl::span<const int, 10U> CView;
EtlData etldata = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
StlData stldata = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
StlVData stlvdata = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
EtlData etldatasmaller = { 0, 1, 2, 3, 4, 5, 5, 7, 8, 9 };
EtlData etloriginal = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
EtlData etlmodified = { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 };
const EtlData cetldata = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
const StlData cstldata = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
const StlVData cstlvdata = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int cdata[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int* pcdata = cdata;
const int ccdata[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
const int* pccdata = ccdata;
//*************************************************************************
TEST(test_default_constructor)
{
View view;
CHECK_EQUAL(10U, view.size());
CHECK_EQUAL(10U, view.max_size());
CHECK(!view.empty());
}
//*************************************************************************
TEST(test_constructor_etl_array_1)
{
View view(etldata);
CHECK_EQUAL(etldata.size(), view.size());
CHECK_EQUAL(etldata.max_size(), view.max_size());
bool isEqual = std::equal(view.begin(), view.end(), etldata.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST(test_constructor_etl_array_1_const)
{
CView view(cetldata);
CHECK_EQUAL(cetldata.size(), view.size());
CHECK_EQUAL(cetldata.max_size(), view.max_size());
bool isEqual = std::equal(view.begin(), view.end(), cetldata.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST(test_constructor_etl_array_2)
{
View view(etldata.begin(), etldata.end());
CHECK_EQUAL(SIZE, view.size());
CHECK_EQUAL(SIZE, view.max_size());
bool isEqual = std::equal(view.begin(), view.end(), etldata.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST(test_constructor_etl_array_2_const)
{
CView view(cetldata.begin(), cetldata.end());
CHECK_EQUAL(SIZE, view.size());
CHECK_EQUAL(SIZE, view.max_size());
bool isEqual = std::equal(view.begin(), view.end(), cetldata.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST(test_constructor_stl_array_1)
{
View view(stldata);
CHECK_EQUAL(stldata.size(), view.size());
CHECK_EQUAL(stldata.max_size(), view.max_size());
bool isEqual = std::equal(view.begin(), view.end(), stldata.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST(test_constructor_stl_array_1_const)
{
CView view(cstldata);
CHECK_EQUAL(cstldata.size(), view.size());
CHECK_EQUAL(cstldata.max_size(), view.max_size());
bool isEqual = std::equal(view.begin(), view.end(), cstldata.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST(test_constructor_stl_array_2)
{
View view(stldata.begin(), stldata.end());
CHECK_EQUAL(stldata.size(), view.size());
CHECK_EQUAL(stldata.max_size(), view.max_size());
bool isEqual = std::equal(view.begin(), view.end(), stldata.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST(test_constructor_stl_array_2_const)
{
CView view(cstldata.begin(), cstldata.end());
CHECK_EQUAL(cstldata.size(), view.size());
CHECK_EQUAL(cstldata.max_size(), view.max_size());
bool isEqual = std::equal(view.begin(), view.end(), cstldata.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST(test_constructor_stl_vector_1)
{
View view(stlvdata);
CHECK_EQUAL(stlvdata.size(), view.size());
CHECK_EQUAL(stlvdata.size(), view.max_size());
bool isEqual = std::equal(view.begin(), view.end(), stlvdata.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST(test_constructor_stl_vector_1_const)
{
CView view(cstlvdata);
CHECK_EQUAL(cstlvdata.size(), view.size());
CHECK_EQUAL(cstlvdata.size(), view.max_size());
bool isEqual = std::equal(view.begin(), view.end(), cstlvdata.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST(test_constructor_c_array_1)
{
View view(pcdata, SIZE);
CHECK_EQUAL(SIZE, view.size());
CHECK_EQUAL(SIZE, view.max_size());
bool isEqual = std::equal(view.begin(), view.end(), pcdata);
CHECK(isEqual);
}
//*************************************************************************
TEST(test_constructor_c_array_1_const)
{
CView view(pccdata, SIZE);
CHECK_EQUAL(SIZE, view.size());
CHECK_EQUAL(SIZE, view.max_size());
bool isEqual = std::equal(view.begin(), view.end(), pccdata);
CHECK(isEqual);
}
//*************************************************************************
TEST(test_constructor_c_array_2)
{
View view(cdata);
CHECK_EQUAL(SIZE, view.size());
CHECK_EQUAL(SIZE, view.max_size());
bool isEqual = std::equal(view.begin(), view.end(), cdata);
CHECK(isEqual);
}
//*************************************************************************
TEST(test_constructor_c_array_2_const)
{
CView view(ccdata);
CHECK_EQUAL(SIZE, view.size());
CHECK_EQUAL(SIZE, view.max_size());
bool isEqual = std::equal(view.begin(), view.end(), ccdata);
CHECK(isEqual);
}
//*************************************************************************
TEST(test_implicit_constructor_c_array_2)
{
CView view;
view = ccdata;
CHECK_EQUAL(SIZE, view.size());
CHECK_EQUAL(SIZE, view.max_size());
bool isEqual = std::equal(view.begin(), view.end(), ccdata);
CHECK(isEqual);
}
#if ETL_USING_CPP17 && ETL_HAS_INITIALIZER_LIST && !defined(ETL_TEMPLATE_DEDUCTION_GUIDE_TESTS_DISABLED)
//*************************************************************************
TEST(test_cpp17_deduced_constructor)
{
etl::array data{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::span span1{ data };
etl::span span2{ data.begin(), data.end() };
etl::span span3{ data.begin(), data.size() };
etl::span span4{ span1 };
int c_array[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
etl::span span5{ c_array };
bool isEqual = false;
isEqual = std::equal(span1.begin(), span1.end(), data.begin());
CHECK(isEqual);
isEqual = std::equal(span2.begin(), span2.end(), data.begin());
CHECK(isEqual);
isEqual = std::equal(span3.begin(), span3.end(), data.begin());
CHECK(isEqual);
isEqual = std::equal(span4.begin(), span4.end(), data.begin());
CHECK(isEqual);
isEqual = std::equal(span5.begin(), span5.end(), c_array);
CHECK(isEqual);
}
#endif
//*************************************************************************
TEST(test_constructor_range)
{
View view(etldata.begin(), etldata.end());
CHECK_EQUAL(etldata.size(), view.size());
CHECK_EQUAL(etldata.size(), view.max_size());
bool isEqual = std::equal(view.begin(), view.end(), etldata.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST(test_assign_from_span)
{
View view1(etldata);
View view2;
CView cview1(etldata);
CView cview2;
view2 = view1;
cview2 = cview1;
CHECK_EQUAL(view1.size(), view2.size());
CHECK_EQUAL(view1.max_size(), view2.max_size());
CHECK_EQUAL(cview1.size(), cview2.size());
CHECK_EQUAL(cview1.max_size(), cview2.max_size());
bool isEqual;
isEqual = std::equal(view1.begin(), view1.end(), view2.begin());
CHECK(isEqual);
isEqual = std::equal(cview1.begin(), cview1.end(), cview2.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST(test_modify_range)
{
View view(etloriginal.begin(), etloriginal.end());
CHECK_EQUAL(etloriginal.size(), view.size());
CHECK_EQUAL(etloriginal.size(), view.max_size());
std::fill(view.begin(), view.end(), 10);
bool isEqual;
isEqual = std::equal(etloriginal.begin(), etloriginal.end(), etlmodified.begin());
CHECK(isEqual);
isEqual = std::equal(etldata.begin(), etldata.end(), etlmodified.begin());
CHECK(!isEqual);
}
//*************************************************************************
TEST(test_begin_end)
{
View view(etldata.begin(), etldata.end());
CView cview(etldata.begin(), etldata.end());
CHECK_EQUAL(etldata.begin(), view.begin());
CHECK_EQUAL(etldata.begin(), cview.begin());
CHECK_EQUAL(etldata.end(), view.rbegin().base());
CHECK_EQUAL(etldata.end(), cview.rbegin().base());
CHECK_EQUAL(etldata.end(), view.end());
CHECK_EQUAL(etldata.end(), cview.end());
CHECK_EQUAL(etldata.begin(), view.rend().base());
CHECK_EQUAL(etldata.begin(), cview.rend().base());
}
//*************************************************************************
TEST(test_front_back)
{
View view(etldata.begin(), etldata.end());
CView cview(etldata.begin(), etldata.end());
CHECK_EQUAL(etldata.front(), view.front());
CHECK_EQUAL(etldata.front(), cview.front());
CHECK_EQUAL(etldata.back(), view.back());
CHECK_EQUAL(etldata.back(), cview.back());
}
//*************************************************************************
TEST(test_data)
{
View view(etldata.begin(), etldata.end());
CView cview(etldata.begin(), etldata.end());
CHECK_EQUAL(etldata.data(), view.data());
CHECK_EQUAL(etldata.data(), cview.data());
}
//*************************************************************************
TEST(test_index_operator)
{
View view(etldata.begin(), etldata.end());
CView cview(etldata.begin(), etldata.end());
for (size_t i = 0UL; i < etldata.size(); ++i)
{
CHECK_EQUAL(etldata[i], view[i]);
CHECK_EQUAL(etldata[i], cview[i]);
}
}
//*************************************************************************
TEST(test_assignment_operator)
{
View view(etldata);
CView cview = view;
CHECK_EQUAL(etldata.size(), view.size());
CHECK_EQUAL(etldata.max_size(), view.max_size());
bool isEqual = std::equal(view.begin(), view.end(), etldata.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST(test_empty)
{
View view1(etldata.begin(), etldata.begin());
CHECK(!view1.empty());
}
//*************************************************************************
TEST(test_size)
{
View view(etldata);
CHECK_EQUAL(etldata.size(), view.size());
}
//*************************************************************************
TEST(test_size_bytes)
{
View view(etldata);
CHECK_EQUAL(etldata.size() * sizeof(EtlData::value_type), view.size_bytes());
}
//*************************************************************************
TEST(test_swap)
{
View view1(etldata);
View view2(etldatasmaller);
std::swap(view1, view2);
CHECK_EQUAL(etldata.size(), view1.size());
CHECK_EQUAL(etldatasmaller.size(), view2.size());
bool isEqual;
isEqual = std::equal(view1.begin(), view1.end(), etldatasmaller.begin());
CHECK(isEqual);
isEqual = std::equal(view2.begin(), view2.end(), etldata.begin());
CHECK(isEqual);
}
//*************************************************************************
TEST(test_first)
{
std::vector<int> original = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int> first = { 0, 1, 2, 3, 4, 5 };
View view(original);
CView cview(original);
bool isEqual;
auto result = view.first<6>();
isEqual = std::equal(result.begin(), result.end(), first.begin());
CHECK(isEqual);
CHECK_EQUAL(first.size(), result.extent);
CHECK_EQUAL(first.size(), result.size());
auto cresult = cview.first<6>();
isEqual = std::equal(cresult.begin(), cresult.end(), first.begin());
CHECK(isEqual);
CHECK_EQUAL(first.size(), cresult.extent);
CHECK_EQUAL(first.size(), cresult.size());
}
//*************************************************************************
TEST(test_first_2)
{
std::vector<int> original = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int> first = { 0, 1, 2, 3, 4, 5 };
View view(original);
CView cview(original);
bool isEqual;
auto result = view.first(6);
isEqual = std::equal(result.begin(), result.end(), first.begin());
CHECK(isEqual);
CHECK_EQUAL(first.size(), result.size());
auto cresult = cview.first(6);
isEqual = std::equal(cresult.begin(), cresult.end(), first.begin());
CHECK(isEqual);
CHECK_EQUAL(first.size(), cresult.size());
}
//*************************************************************************
TEST(test_last)
{
std::vector<int> original = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int> last = { 4, 5, 6, 7, 8, 9 };
View view(original);
CView cview(original);
bool isEqual;
auto result = view.last<6>();
isEqual = std::equal(result.begin(), result.end(), last.begin());
CHECK(isEqual);
CHECK_EQUAL(last.size(), result.extent);
CHECK_EQUAL(last.size(), result.size());
auto cresult = cview.last<6>();
isEqual = std::equal(cresult.begin(), cresult.end(), last.begin());
CHECK(isEqual);
CHECK_EQUAL(last.size(), cresult.extent);
CHECK_EQUAL(last.size(), cresult.size());
}
//*************************************************************************
TEST(test_last_2)
{
std::vector<int> original = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int> last = { 4, 5, 6, 7, 8, 9 };
View view(original);
CView cview(original);
bool isEqual;
auto result = view.last(6);
isEqual = std::equal(result.begin(), result.end(), last.begin());
CHECK(isEqual);
CHECK_EQUAL(last.size(), result.size());
auto cresult = cview.last(6);
isEqual = std::equal(cresult.begin(), cresult.end(), last.begin());
CHECK(isEqual);
CHECK_EQUAL(last.size(), cresult.size());
}
//*************************************************************************
TEST(test_subspan)
{
std::vector<int> original = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
std::vector<int> sub1 = { 2, 3, 4, 5 };
std::vector<int> sub2 = { 2, 3, 4, 5, 6, 7 };
View view(original);
CView cview(original);
bool isEqual;
auto span1 = view.subspan<2, 4>();
isEqual = std::equal(span1.begin(), span1.end(), sub1.begin());
CHECK(isEqual);
CHECK_EQUAL(sub1.size(), span1.extent);
CHECK_EQUAL(sub1.size(), span1.size());
auto cspan1 = cview.subspan<2, 4>();
isEqual = std::equal(cspan1.begin(), cspan1.end(), sub1.begin());
CHECK(isEqual);
CHECK_EQUAL(sub1.size(), cspan1.extent);
CHECK_EQUAL(sub1.size(), cspan1.size());
auto span2 = view.subspan<2>();
isEqual = std::equal(sub2.begin(), sub2.end(), span2.begin());
CHECK(isEqual);
CHECK_EQUAL(span2.size(), span2.extent);
auto cspan2 = cview.subspan<2>();
isEqual = std::equal(sub2.begin(), sub2.end(), cspan2.begin());
CHECK(isEqual);
CHECK_EQUAL(original.size() - 2U, cspan2.extent);
auto span3 = view.subspan(2, 4);
isEqual = std::equal(sub1.begin(), sub1.end(), span3.begin());
CHECK(isEqual);
CHECK_EQUAL(etl::dynamic_extent, span3.extent);
auto cspan3 = cview.subspan(2, 4);
isEqual = std::equal(sub1.begin(), sub1.end(), cspan3.begin());
CHECK(isEqual);
CHECK_EQUAL(etl::dynamic_extent, cspan3.extent);
auto span4 = view.subspan(2);
isEqual = std::equal(sub2.begin(), sub2.end(), span4.begin());
CHECK(isEqual);
CHECK_EQUAL(etl::dynamic_extent, span4.extent);
auto cspan4 = cview.subspan(2);
isEqual = std::equal(sub2.begin(), sub2.end(), cspan4.begin());
CHECK(isEqual);
CHECK_EQUAL(etl::dynamic_extent, cspan4.extent);
}
//*************************************************************************
TEST(test_hash)
{
View view(etldata.begin(), etldata.end());
CView cview(etldata.begin(), etldata.end());
size_t hashdata = etl::private_hash::generic_hash<size_t>(reinterpret_cast<const uint8_t*>(&etldata[0]),
reinterpret_cast<const uint8_t*>(&etldata[etldata.size()]));
size_t hashview = etl::hash<View>()(view);
size_t hashcview = etl::hash<CView>()(cview);
CHECK_EQUAL(hashdata, hashview);
CHECK_EQUAL(hashdata, hashcview);
}
//*************************************************************************
TEST(test_template_deduction_guide_for_c_array)
{
int data[] = { 1, 2, 3, 4 };
etl::span s = data;
CHECK_EQUAL(std::size(data), s.extent);
CHECK_EQUAL(std::size(data), s.size());
CHECK((std::is_same_v<int, std::remove_reference_t<decltype(s.front())>>));
}
#if ETL_USING_STL
//*************************************************************************
TEST(test_template_deduction_guide_for_std_array)
{
std::array<int, 4U> data = { 1, 2, 3, 4 };
etl::span s = data;
CHECK_EQUAL(std::size(data), s.extent);
CHECK_EQUAL(std::size(data), s.size());
CHECK((std::is_same_v<int, std::remove_reference_t<decltype(s.front())>>));
}
#endif
//*************************************************************************
TEST(test_template_deduction_guide_for_etl_array)
{
etl::array<int, 4U> data = { 1, 2, 3, 4 };
etl::span s = data;
CHECK_EQUAL(std::size(data), s.extent);
CHECK_EQUAL(std::size(data), s.size());
CHECK((std::is_same_v<int, std::remove_reference_t<decltype(s.front())>>));
}
//*************************************************************************
TEST(test_template_deduction_guide_for_iterators)
{
etl::array<int, 4U> data = { 1, 2, 3, 4 };
etl::span s{ data.begin(), data.end() };
CHECK_EQUAL(etl::dynamic_extent, s.extent);
CHECK_EQUAL(4U, s.size());
CHECK((std::is_same_v<int, std::remove_reference_t<decltype(s.front())>>));
}
//*************************************************************************
TEST(test_template_deduction_guide_for_iterator_and_size)
{
etl::array<int, 4U> data = { 1, 2, 3, 4 };
etl::span s{ data.begin(), data.size() };
CHECK_EQUAL(etl::dynamic_extent, s.extent);
CHECK_EQUAL(4U, s.size());
CHECK((std::is_same_v<int, std::remove_reference_t<decltype(s.front())>>));
}
//*************************************************************************
void f_issue_481(etl::span<const char, 10> value)
{
}
TEST(test_issue_481)
{
// Should compile.
char c[10];
f_issue_481(c);
}
//*************************************************************************
struct C_issue_482 {};
void f_issue_482(etl::span<char>)
{
}
void f_issue_482(etl::span<C_issue_482>)
{
}
TEST(test_issue_482)
{
etl::array<C_issue_482, 10> c;
// Should compile without ambiguous function error.
f_issue_482(c);
}
//*************************************************************************
void f_issue_482_2(etl::span<char, 10>)
{
}
void f_issue_482_2(etl::span<C_issue_482, 10>)
{
}
TEST(test_issue_482_2)
{
etl::array<C_issue_482, 10> c;
// Should compile without ambiguous function error.
f_issue_482(c);
}
//*************************************************************************
void f_issue_486(etl::span<const char, 11> value)
{
}
TEST(test_issue_486)
{
//std::array<char, 10> c;
// Should not compile.
//etl::span<char, 11> value(c);
// Should not compile.
//f_issue_486(c);
}
};
}

View File

@ -11003,6 +11003,7 @@
<ClCompile Include="..\test_crc8_rohc.cpp" />
<ClCompile Include="..\test_crc8_wcdma.cpp" />
<ClCompile Include="..\test_poly_span_dynamic_extent.cpp" />
<ClCompile Include="..\test_poly_span_fixed_extent.cpp" />
<ClCompile Include="..\test_pseudo_moving_average.cpp" />
<ClCompile Include="..\test_delegate.cpp" />
<ClCompile Include="..\test_delegate_cpp03.cpp" />
@ -11746,7 +11747,8 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="..\test_singleton.cpp" />
<ClCompile Include="..\test_span.cpp" />
<ClCompile Include="..\test_span_dynamic_extent.cpp" />
<ClCompile Include="..\test_span_fixed_extent.cpp" />
<ClCompile Include="..\test_standard_deviation.cpp" />
<ClCompile Include="..\test_state_chart.cpp" />
<ClCompile Include="..\test_smallest.cpp" />

View File

@ -1739,7 +1739,7 @@
<ClCompile Include="..\test_set.cpp">
<Filter>Tests\Containers</Filter>
</ClCompile>
<ClCompile Include="..\test_span.cpp">
<ClCompile Include="..\test_span_dynamic_extent.cpp">
<Filter>Tests\Containers</Filter>
</ClCompile>
<ClCompile Include="..\test_stack.cpp">
@ -3269,6 +3269,12 @@
<ClCompile Include="..\test_poly_span_dynamic_extent.cpp">
<Filter>Tests\Containers</Filter>
</ClCompile>
<ClCompile Include="..\test_span_fixed_extent.cpp">
<Filter>Tests\Containers</Filter>
</ClCompile>
<ClCompile Include="..\test_poly_span_fixed_extent.cpp">
<Filter>Tests\Containers</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\..\library.properties">